{"id":472686,"date":"2025-08-30T15:01:31","date_gmt":"2025-08-30T15:01:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=472686"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=472686","title":{"rendered":"<span>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f8a\/21e\/564\/f8a21e564b56e1268f1e5859b892c33c.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439\" width=\"1156\" height=\"679\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/f8a\/21e\/564\/f8a21e564b56e1268f1e5859b892c33c.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f8a\/21e\/564\/f8a21e564b56e1268f1e5859b892c33c.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043e <a href=\"https:\/\/habr.com\/ru\/articles\/926598\/\" rel=\"noopener noreferrer nofollow\">\u043c\u043d\u043e\u0433\u043e\u043c\u0435\u0440\u043d\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u044f\u0434\u043e\u0432<\/a> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/github.com\/akardapolov\/dimension-ui\" rel=\"noopener noreferrer nofollow\">Dimension-UI<\/a>, \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0430\u043d\u043d\u044b\u043c, \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c, \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430.\u00a0\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435.\u00a0\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439: \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0433\u043e\u043b\u0430\u043c, \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u0441\u0447\u0451\u0442\u0443, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0432 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0445 \u0438 \u0433\u043e\u0441\u0442\u0435\u0432\u044b\u0445 \u043c\u0430\u0442\u0447\u0430\u0445.<\/p>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0431\u0443\u0434\u0435\u0442 <a href=\"https:\/\/github.com\/LesnoyChelovek\/footballstats\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0441 \u0432\u0435\u0431-\u0441\u0430\u0439\u0442\u0430 <a href=\"https:\/\/fbref.com\/en\/matches\/\" rel=\"noopener noreferrer nofollow\">fbref.com<\/a>. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u044b\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 <a class=\"mention\" href=\"\/users\/lesnoychelovek\">@LesnoyChelovek<\/a>\u0432 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/habr.com\/ru\/articles\/895008\/\" rel=\"noopener noreferrer nofollow\">\u00ab\u041f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b \u0431\u043e\u043b\u0435\u0435 260 \u0442\u044b\u0441\u044f\u0447 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043f\u043e\u0440\u0438\u0442\u044c \u0441 \u0443\u0447\u0451\u043d\u044b\u043c\u0438-\u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430\u043c\u0438\u00bb<\/a>.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u044f\u0434\u043e\u0432, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f, \u043a\u0430\u043a\u043e\u0435 \u043f\u043e\u043b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0442\u043a\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0414\u0430\u0442\u0430 \u043c\u0430\u0442\u0447\u0430 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430, \u043d\u043e \u043e\u043d\u0430 \u0435\u0441\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"https:\/\/fbref.com\/en\/matches\/\" rel=\"noopener noreferrer nofollow\">fbref.com<\/a>, \u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u0437\u044f\u0442\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430. \u0420\u0435\u0448\u0438\u043b \u043d\u0435 \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u043c \u0441\u0431\u043e\u0440\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0432\u0437\u044f\u0442\u044c \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u043c\u0435\u0442\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0433\u043e\u043b\u043e\u0432 \u0432 \u043c\u0430\u0442\u0447\u0435 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0447\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0439\u0434\u0435\u0442. \u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u0430\u0442\u0447\u0438 \u0431\u0435\u0437 \u0433\u043e\u043b\u043e\u0432 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 \u0432\u044b\u0431\u043e\u0440\u043a\u0443, \u0445\u043e\u0442\u044f \u0438\u0445 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0442\u043e\u0436\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c.<\/p>\n<p> \u0418\u0442\u0430\u043a, \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0433\u0440\u0443\u0437\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 JSON \u0444\u0430\u0439\u043b\u043e\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <em>raw_matches.<\/em><\/p>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 \u043d\u0430 python, \u043b\u044e\u0431\u0435\u0437\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c\u044e <a href=\"https:\/\/chat.deepseek.com\/\" rel=\"noopener noreferrer nofollow\">DeepSeek<\/a>, \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 PostgreSQL. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 WSL2 \u043d\u0430 Windows, \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0434\u043e\u043a\u0435\u0440\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 raw_matches<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">CREATE TABLE raw_matches (     id SERIAL PRIMARY KEY,     season INTEGER,     data JSONB );<\/code><\/pre>\n<pre><code class=\"python\">import json import os import psycopg2 import sys from typing import Any, List  # Database connection try:     conn = psycopg2.connect(         host=\"localhost\",         port=5432,         dbname=\"football\",         user=\"postgres\",         password=\"postgres\"     )     cur = conn.cursor() except psycopg2.Error as e:     print(f\"Database connection error: {e}\")     sys.exit(1)  # Directory containing JSON files json_dir = '\/mnt\/c\/Disk\/dimension\/footballstats\/JSON'  def flatten_matches(data: Any) -&gt; List[Any]:     \"\"\"Flatten nested match structures\"\"\"     matches = []          if isinstance(data, list):         for item in data:             if isinstance(item, dict) and 'home_team' in item and 'away_team' in item:                 # This is a match object                 matches.append(item)             elif isinstance(item, list):                 # This is a nested list, recursively flatten                 matches.extend(flatten_matches(item))             else:                 print(f\"Unexpected item type: {type(item)}\")     elif isinstance(data, dict):         # Check if this is a match object         if 'home_team' in data and 'away_team' in data:             matches.append(data)         else:             # This might be a container with matches inside             for key, value in data.items():                 if isinstance(value, (list, dict)):                     matches.extend(flatten_matches(value))          return matches  for filename in os.listdir(json_dir):     if filename.startswith('match_data') and filename.endswith('.json'):         filepath = os.path.join(json_dir, filename)                  try:             # Extract season from filename             season = int(filename[10:14])         except ValueError as e:             print(f\"Error extracting season from {filename}: {e}\")             continue          try:             with open(filepath, 'r', encoding='utf-8') as f:                 raw_data = json.load(f)                              # Debug: Print the type and structure of the loaded data             print(f\"DEBUG: {filename} - Type of loaded data: {type(raw_data)}\")             if isinstance(raw_data, list) and len(raw_data) &gt; 0:                 print(f\"DEBUG: {filename} - First element type: {type(raw_data[0])}\")                          # Flatten the data structure to extract all matches             matches = flatten_matches(raw_data)             print(f\"DEBUG: {filename} - Found {len(matches)} matches after flattening\")                          if len(matches) &gt; 0:                 print(f\"DEBUG: {filename} - First match: {json.dumps(matches[0], indent=2)}\")                      except Exception as e:             print(f\"Error reading\/parsing {filename}: {e}\")             continue          match_count = 0         error_count = 0                  for match in matches:             try:                 cur.execute(                     \"INSERT INTO raw_matches (season, data) VALUES (%s, %s)\",                     (season, json.dumps(match))                 )                 match_count += 1             except psycopg2.Error as e:                 error_count += 1                 print(f\"Database error inserting match from {filename}: {e}\")                 print(f\"Problematic match data: {json.dumps(match)}\")             except Exception as e:                 error_count += 1                 print(f\"Unexpected error with match from {filename}: {e}\")                 print(f\"Problematic match data: {json.dumps(match)}\")          print(f\"Loaded {match_count} matches from {filename} with {error_count} errors\")                  try:             conn.commit()         except psycopg2.Error as e:             print(f\"Commit error after {filename}: {e}\")             try:                 conn.rollback()             except:                 pass  cur.close() conn.close()<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043f\u043e \u043c\u0435\u0442\u043a\u0430\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b matches.<\/p>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b raw_matches \u0432 matches<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">CREATE TABLE matches (     year VARCHAR,     home_team VARCHAR,     away_team VARCHAR,     score VARCHAR,     goals_minutes_1 TIMESTAMP,     goals_minutes_2 TIMESTAMP,     goals_minutes_3 TIMESTAMP,     goals_minutes_4 TIMESTAMP,     goals_minutes_5 TIMESTAMP,     goals_minutes_6 TIMESTAMP,     goals_minutes_7 TIMESTAMP,     goals_minutes_8 TIMESTAMP,     goals_minutes_9 TIMESTAMP,     goals_minutes_10 TIMESTAMP,     home_goals INTEGER,     away_goals INTEGER,     goals INTEGER,     home_result VARCHAR,     away_result VARCHAR );<\/code><\/pre>\n<pre><code class=\"python\">import psycopg2 import json import logging from datetime import datetime, timedelta from typing import Optional, Dict, Any, List  # Set up logging logging.basicConfig(     level=logging.INFO,     format='%(asctime)s - %(levelname)s - %(message)s',     handlers=[         logging.FileHandler('data_load.log'),         logging.StreamHandler()     ] )  def parse_goal_minute(minute_str: str) -&gt; Optional[int]:     \"\"\"     Parse goal minute string, handling additional time notation     Examples:      - \"45+1'\" becomes 46     - \"90+2'\" becomes 92     - \"30'\" becomes 30     \"\"\"     try:         if not minute_str:             return None                      # Remove any trailing apostrophes\/quotes         minute_str = minute_str.rstrip(\"'\u2019\\\"\")                  if '+' in minute_str:             parts = minute_str.split('+')             base_minute = int(parts[0])             added_minutes = int(parts[1])             return base_minute + added_minutes         else:             return int(minute_str)     except (ValueError, IndexError, AttributeError) as e:         logging.error(f\"Error parsing goal minute '{minute_str}': {e}\")         return None  def clean_score(score_str: str) -&gt; str:     \"\"\"     Clean score string by removing asterisks and other non-numeric characters     \"\"\"     if not score_str:         return score_str          # Remove asterisks and other non-standard characters     cleaned = score_str.replace('*', '').replace('--', '0')          # Handle cases like \"0 - 3*\" -&gt; \"0 - 3\"     if ' - ' in cleaned:         parts = cleaned.split(' - ')         # Ensure both parts are numeric or can be converted to 0         try:             int(parts[0])         except ValueError:             parts[0] = '0'         try:             int(parts[1])         except ValueError:             parts[1] = '0'         cleaned = ' - '.join(parts)          return cleaned  def process_matches():     conn = None     cursor = None     processed_count = 0     error_count = 0     skipped_count = 0          try:         # Database connection - update with your credentials         conn = psycopg2.connect(             host=\"localhost\",             database=\"football\",             user=\"postgres\",             password=\"postgres\",             port=5432         )          cursor = conn.cursor()         logging.info(\"Connected to database successfully\")          # Fetch raw matches         cursor.execute(\"SELECT id, season, data FROM raw_matches ORDER BY id\")         raw_matches = cursor.fetchall()         logging.info(f\"Fetched {len(raw_matches)} raw matches\")          # Process each match         for match_id, season, data in raw_matches:             try:                 # data is already a dict from psycopg2 for JSONB fields                 match_data = data                                  # Log full data for problematic matches (for debugging)                 if match_id in [3177, 4941, 5002, 5640, 9710, 14831, 15279, 17657, 20733,                                27177, 28565, 28633, 32717, 36030, 36052, 39788, 39794, 39862, 40158]:                     logging.warning(f\"DEBUG - Problematic match {match_id} full data: {match_data}\")                                  # Validate required fields                 required_fields = ['score', 'home_team', 'away_team']                 missing_fields = [field for field in required_fields if field not in match_data]                 if missing_fields:                     logging.warning(f\"Match {match_id} missing required fields: {missing_fields}. Full data: {match_data}\")                     error_count += 1                     continue                                  # Parse score safely with cleaning                 try:                     original_score = match_data['score']                     cleaned_score = clean_score(original_score)                                          score_parts = cleaned_score.split(' - ')                     if len(score_parts) != 2:                         raise ValueError(f\"Invalid score format after cleaning: {cleaned_score} (original: {original_score})\")                                          home_goals = int(score_parts[0])                     away_goals = int(score_parts[1])                     total_goals = home_goals + away_goals                                          # Skip matches with more than 10 goals                     if total_goals &gt; 10:                         logging.info(f\"Skipping match {match_id} with {total_goals} goals (more than 10)\")                         skipped_count += 1                         continue                                          # Determine results                     home_result = 'Wins' if home_goals &gt; away_goals else 'Draws' if home_goals == away_goals else 'Losses'                     away_result = 'Wins' if away_goals &gt; home_goals else 'Draws' if away_goals == home_goals else 'Losses'                                      except (ValueError, IndexError) as e:                     logging.error(f\"Error parsing score for match {match_id}: {e}. Original score: '{match_data['score']}'. Full data: {match_data}\")                     error_count += 1                     continue                                  # Collect all goal times from both teams                 all_goal_times = []                                  # Process home goals                 home_goals_minutes = match_data.get('home_goals_minutes', [])                 for minute_str in home_goals_minutes:                     minute = parse_goal_minute(minute_str)                     if minute is not None:                         goal_time = datetime(2000, 1, 1) + timedelta(minutes=minute)                         all_goal_times.append(goal_time)                                  # Process away goals                 away_goals_minutes = match_data.get('away_goals_minutes', [])                 for minute_str in away_goals_minutes:                     minute = parse_goal_minute(minute_str)                     if minute is not None:                         goal_time = datetime(2000, 1, 1) + timedelta(minutes=minute)                         all_goal_times.append(goal_time)                                  # Sort goal times chronologically                 all_goal_times.sort()                                  # Prepare goal columns                 goal_columns = [None] * 10                 for i, goal_time in enumerate(all_goal_times):                     if i &lt; 10:  # Only store up to 10 goals                         goal_columns[i] = goal_time                                  # Insert the match record                 cursor.execute(\"\"\"                     INSERT INTO matches (                         year, home_team, away_team, score,                          goals_minutes_1, goals_minutes_2, goals_minutes_3,                          goals_minutes_4, goals_minutes_5, goals_minutes_6,                          goals_minutes_7, goals_minutes_8, goals_minutes_9,                          goals_minutes_10,                         home_goals, away_goals, goals,                         home_result, away_result                     ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)                 \"\"\", (                     str(season),                      match_data['home_team'],                      match_data['away_team'],                      match_data['score'],                     goal_columns[0], goal_columns[1], goal_columns[2],                      goal_columns[3], goal_columns[4], goal_columns[5],                      goal_columns[6], goal_columns[7], goal_columns[8],                      goal_columns[9],                     home_goals,                      away_goals,                      total_goals,                     home_result,                      away_result                 ))                                  processed_count += 1                 if processed_count % 1000 == 0:                     logging.info(f\"Progress: {processed_count} matches processed\")                              except Exception as e:                 logging.error(f\"Error processing match {match_id}: {e}. Full data: {match_data}\")                 error_count += 1                 continue                  # Commit the transaction         conn.commit()         logging.info(f\"Data load completed: {processed_count} matches processed, {skipped_count} skipped, {error_count} errors\")              except Exception as e:         logging.error(f\"Database connection error: {e}\")         if conn:             conn.rollback()     finally:         if cursor:             cursor.close()         if conn:             conn.close()         logging.info(\"Database connection closed\")  def test_parse_goal_minute():     \"\"\"Test function for goal minute parsing\"\"\"     test_cases = [         (\"45+1'\", 46),         (\"90+2'\", 92),         (\"30'\", 30),         (\"26'\", 26),         (\"7'\", 7),         (\"\", None),         (None, None),         (\"invalid\", None)     ]          logging.info(\"Testing goal minute parsing...\")     for input_str, expected in test_cases:         result = parse_goal_minute(input_str)         status = \"\u2713\" if result == expected else \"\u2717\"         logging.info(f\"{status} '{input_str}' -&gt; {result} (expected: {expected})\")  def test_clean_score():     \"\"\"Test function for score cleaning\"\"\"     test_cases = [         (\"0 - 2*\", \"0 - 2\"),         (\"3* - 0\", \"3 - 0\"),         (\"0 - 3*\", \"0 - 3\"),         (\"-- - --*\", \"0 - 0\"),         (\"1 - 0\", \"1 - 0\"),         (\"2 - 2\", \"2 - 2\"),     ]          logging.info(\"Testing score cleaning...\")     for input_str, expected in test_cases:         result = clean_score(input_str)         status = \"\u2713\" if result == expected else \"\u2717\"         logging.info(f\"{status} '{input_str}' -&gt; '{result}' (expected: '{expected}')\")  if __name__ == \"__main__\":     # Run tests first     test_parse_goal_minute()     test_clean_score()          # Process matches     process_matches()<\/code><\/pre>\n<pre><code class=\"sql\">-- Basic indexes for common filtering CREATE INDEX idx_matches_year ON matches (\"year\"); CREATE INDEX idx_matches_home_team ON matches (home_team); CREATE INDEX idx_matches_away_team ON matches (away_team); CREATE INDEX idx_matches_home_result ON matches (home_result); CREATE INDEX idx_matches_away_result ON matches (away_result);  -- Composite indexes for common query patterns CREATE INDEX idx_matches_team_year ON matches (home_team, \"year\"); CREATE INDEX idx_matches_away_year ON matches (away_team, \"year\"); CREATE INDEX idx_matches_year_result ON matches (\"year\", home_result);  -- Indexes for goal-related queries CREATE INDEX idx_matches_home_goals ON matches (home_goals); CREATE INDEX idx_matches_away_goals ON matches (away_goals); CREATE INDEX idx_matches_total_goals ON matches (goals);  -- Indexes for score column CREATE INDEX idx_matches_score ON matches (score);  -- Indexes for goals_minutes columns CREATE INDEX idx_matches_goals_minutes_1 ON matches (goals_minutes_1); CREATE INDEX idx_matches_goals_minutes_2 ON matches (goals_minutes_2); CREATE INDEX idx_matches_goals_minutes_3 ON matches (goals_minutes_3); CREATE INDEX idx_matches_goals_minutes_4 ON matches (goals_minutes_4); CREATE INDEX idx_matches_goals_minutes_5 ON matches (goals_minutes_5); CREATE INDEX idx_matches_goals_minutes_6 ON matches (goals_minutes_6); CREATE INDEX idx_matches_goals_minutes_7 ON matches (goals_minutes_7); CREATE INDEX idx_matches_goals_minutes_8 ON matches (goals_minutes_8); CREATE INDEX idx_matches_goals_minutes_9 ON matches (goals_minutes_9); CREATE INDEX idx_matches_goals_minutes_10 ON matches (goals_minutes_10);<\/code><\/pre>\n<p>\u0412\u0430\u0436\u043d\u043e! \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0434\u0435\u043a\u0441\u044b.<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e 327 584 \u043c\u0430\u0442\u0447\u0430\u043c 5 172 \u043a\u043e\u043c\u0430\u043d\u0434.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 <a href=\"https:\/\/github.com\/akardapolov\/dimension-ui\" rel=\"noopener noreferrer nofollow\">Dimension-UI<\/a> \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u044f\u0434\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u0421\u0442\u0430\u0432\u0438\u043c Java \u043d\u0435 \u043d\u0438\u0436\u0435 21 \u0432\u0435\u0440\u0441\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>C\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c Java \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p>C\u043e\u0437\u0434\u0430\u0435\u043c JDBC \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432 Configuration;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0434\u0435\u043c \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 Ad-hoc. \u0412 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 Connection -&gt; Schema\/Catalog (\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0445\u0435\u043c\u0443, \u0443 \u043c\u0435\u043d\u044f public) -&gt; Table (\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 matches) -&gt; \u0412\u043a\u043b\u0430\u0434\u043a\u0430 Timestamp (\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c goals_minutes_1) -&gt; \u0412\u043a\u043b\u0430\u0434\u043a\u0430 Column (\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c YEAR).<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f \u043d\u0430\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043a\u0440\u0430\u0441\u043e\u0442\u044b:<\/p>\n<ul>\n<li>\n<p>Range -Custom \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432 01-01-2000 00:00:00 \u0438 01-01-2000 01:40:00;<\/p>\n<\/li>\n<li>\n<p>Time range \u043f\u043e Year \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432 Minute;<\/p>\n<\/li>\n<li>\n<p>Normalization \u0442\u043e\u0436\u0435 \u043f\u043e Year \u0432 None.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u043e \u0441\u0447\u0435\u0442\u0443 (SCORE), \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0433\u043e\u043b\u043e\u0432 \u0432 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0445 \u043c\u0430\u0442\u0447\u0430\u0445 (HOME_GOALS) \u0438\u043b\u0438 \u043d\u0430 \u0432\u044b\u0435\u0437\u0434\u0435 (AWAY_GOALS) \u0438 \u043e\u0431\u0449\u0435\u043c\u0443 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0433\u043e\u043b\u043e\u0432 (GOALS = HOME_GOALS + AWAY_GOALS).<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/591\/53f\/f6f\/59153ff6f056f118c0ea00af73ed5e85.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439 \u0441 \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043f\u043e \u0441\u0447\u0435\u0442\u0443 \u0432 Dimension UI\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439 \u0441 \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043f\u043e \u0441\u0447\u0435\u0442\u0443 \u0432 Dimension UI\" width=\"1919\" height=\"1031\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/591\/53f\/f6f\/59153ff6f056f118c0ea00af73ed5e85.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/591\/53f\/f6f\/59153ff6f056f118c0ea00af73ed5e85.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439 \u0441 \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043f\u043e \u0441\u0447\u0435\u0442\u0443 \u0432 Dimension UI<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u0435\u0439, \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0445 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 Column \u0438 \u0432 Range \u0436\u043c\u0435\u043c Apply \u2013 \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u0441\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e \u0438 \u0432\u0441\u0435 \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Time range \u0438 Normalization \u0442\u043e\u0436\u0435 \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u043e\u043d\u0438 \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043c\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u2013 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437.<\/p>\n<details class=\"spoiler\">\n<summary>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430, screencast \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f Dimension-UI<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0dc\/beb\/a0f\/0dcbeba0fd950b1e0441652aa8f6db31.gif\" alt=\"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Dimension-UI \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439\" title=\"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Dimension-UI \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439\" width=\"1915\" height=\"1007\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0dc\/beb\/a0f\/0dcbeba0fd950b1e0441652aa8f6db31.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0dc\/beb\/a0f\/0dcbeba0fd950b1e0441652aa8f6db31.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Dimension-UI \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439<\/figcaption><\/div>\n<\/figure>\n<\/div>\n<\/details>\n<h2>\u041e\u0431\u0449\u0430\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430<\/h2>\n<p>\u0418\u0442\u0430\u043a, \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b, \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u2013 \u043f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u044e.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/46c\/73d\/c42\/46c73dc427b2ac301e0db4f90349d208.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0441\u0447\u0435\u0442\u0443\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0441\u0447\u0435\u0442\u0443\" width=\"1666\" height=\"683\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/46c\/73d\/c42\/46c73dc427b2ac301e0db4f90349d208.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/46c\/73d\/c42\/46c73dc427b2ac301e0db4f90349d208.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0441\u0447\u0435\u0442\u0443<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043c\u0430\u0441\u0441\u0430 \u043f\u0435\u0440\u0432\u044b\u0445 \u0433\u043e\u043b\u043e\u0432 \u0437\u0430\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430 \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u043f\u043b\u0435\u0441\u043a \u0435\u0441\u0442\u044c \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0432\u0442\u043e\u0440\u043e\u0433\u043e. \u0422\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u0432 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0433\u043e\u043b\u044b \u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430, \u043f\u043e\u043a\u0430 \u043e\u043d\u0438 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0442\u0430\u043a. \u0427\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043c\u0430\u0442\u0447\u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0441\u043e \u0441\u0447\u0435\u0442\u043e\u043c 1:1.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/967\/6e5\/fe9\/9676e5fe9986a6a32cbfffc7432a6c85.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e\u0431\u0435\u0434, \u043f\u043e\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u043d\u0438\u0447\u044c\u0438\u0445\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e\u0431\u0435\u0434, \u043f\u043e\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u043d\u0438\u0447\u044c\u0438\u0445\" width=\"1660\" height=\"677\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/967\/6e5\/fe9\/9676e5fe9986a6a32cbfffc7432a6c85.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/967\/6e5\/fe9\/9676e5fe9986a6a32cbfffc7432a6c85.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e\u0431\u0435\u0434, \u043f\u043e\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u043d\u0438\u0447\u044c\u0438\u0445<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u043a\u0438: \u00ab\u0434\u043e\u043c\u0430 \u0438 \u0441\u0442\u0435\u043d\u044b \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442\u00bb \u2014 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c \u043a\u0440\u0430\u0439\u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e \u043f\u043e\u0431\u0435\u0436\u0434\u0430\u0442\u044c \u043d\u0430 \u0432\u044b\u0435\u0437\u0434\u0435.<\/p>\n<p>\u0418\u0437\u043c\u0435\u043d\u0438\u043c \u043c\u0435\u0442\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 goals_minutes_1 \u043d\u0430 goals_minutes_2 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 Timestamp \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0443\u0431\u0440\u0430\u0432 \u0441 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u0433\u0440\u0430\u0444\u0438\u043a\u0438 (\u043e\u043d\u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043a Timestamp goals_minutes_1). \u0422\u0430\u043a \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0433\u043e\u043b\u0430\u043c:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a4f\/290\/69f\/a4f29069fde549f97cb1d946817f17f0.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0432\u0442\u043e\u0440\u044b\u043c \u0433\u043e\u043b\u0430\u043c\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0432\u0442\u043e\u0440\u044b\u043c \u0433\u043e\u043b\u0430\u043c\" width=\"1661\" height=\"679\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/a4f\/290\/69f\/a4f29069fde549f97cb1d946817f17f0.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a4f\/290\/69f\/a4f29069fde549f97cb1d946817f17f0.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0432\u0442\u043e\u0440\u044b\u043c \u0433\u043e\u043b\u0430\u043c<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u0438\u0434\u0438\u043c \u044f\u0432\u043d\u044b\u0439 \u0432\u0441\u043f\u043b\u0435\u0441\u043a \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u0433\u043e\u043b\u0430\u043c \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 47 \u043c\u0438\u043d\u0443\u0442\u044b \u043c\u0430\u0442\u0447\u0430 \u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 (\u043d\u043e \u043e\u0442\u0447\u0435\u0442\u043b\u0438\u0432\u043e \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u044b\u0435 \u043d\u0435\u0432\u043e\u043e\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u043c \u0433\u043b\u0430\u0437\u043e\u043c) \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 1:30 \u0438 1:20 \u0438 1:10.<\/p>\n<p>\u0427\u0442\u043e \u043f\u043e\u0434\u0432\u0442\u0435\u0440\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e (\u043f\u043e goals_minutes_1 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 Timestamp).<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/dd8\/d38\/090\/dd8d380905c172a09d318bd5283e59af.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0432 Gantt \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0432 Gantt \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \" width=\"1663\" height=\"677\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/dd8\/d38\/090\/dd8d380905c172a09d318bd5283e59af.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/dd8\/d38\/090\/dd8d380905c172a09d318bd5283e59af.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0432 Gantt \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 <\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0443\u0437\u043d\u0430\u0442\u044c, \u0441 \u043a\u0430\u043a\u0438\u043c \u0441\u0447\u0435\u0442\u043e\u043c \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u043c\u0430\u0442\u0447\u0438, \u0432\u0442\u043e\u0440\u044b\u0435 \u0433\u043e\u043b\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0437\u0430\u0431\u0438\u0432\u0430\u043b\u0438 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430. \u041f\u0435\u0440\u0435\u0432\u0435\u0441 \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043a\u043e\u043c\u0430\u043d\u0434 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u0434\u043e\u043c\u0430, 2-1 \u0438 \u0434\u0430\u043b\u0435\u0435 \u2013 \u0447\u0442\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u043e\u043c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 HOME_RESULT.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/537\/e1b\/f44\/537e1bf449008e3d2a97db27e240eb70.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0441\u0447\u0435\u0442\u0443 \u0432\u0441\u0442\u0440\u0435\u0447 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u0430\u0442\u0447\u0435\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0441\u0447\u0435\u0442\u0443 \u0432\u0441\u0442\u0440\u0435\u0447 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u0430\u0442\u0447\u0435\" width=\"1663\" height=\"680\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/537\/e1b\/f44\/537e1bf449008e3d2a97db27e240eb70.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/537\/e1b\/f44\/537e1bf449008e3d2a97db27e240eb70.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0441\u0447\u0435\u0442\u0443 \u0432\u0441\u0442\u0440\u0435\u0447 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u0430\u0442\u0447\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u0430 \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u043f\u043b\u0435\u0441\u043a \u0432\u0442\u043e\u0440\u044b\u0445 \u0433\u043e\u043b\u043e\u0432 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u0430\u0442\u0447\u0435, \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 1:30? \u0422\u0443\u0442 \u0432 \u0442\u043e\u043f\u0435 \u043d\u0438\u0447\u044c\u0438 \u0438 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u0432\u0438\u0434\u043d\u043e \u043f\u043e HOME_RESULT \u043f\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c\u0443 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0443.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9e7\/54b\/634\/9e754b63434d0a9aca097132a24f4810.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0441\u0447\u0435\u0442\u0443 \u0432\u0441\u0442\u0440\u0435\u0447 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u0430\u0442\u0447\u0435\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0441\u0447\u0435\u0442\u0443 \u0432\u0441\u0442\u0440\u0435\u0447 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u0430\u0442\u0447\u0435\" width=\"1660\" height=\"675\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/9e7\/54b\/634\/9e754b63434d0a9aca097132a24f4810.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9e7\/54b\/634\/9e754b63434d0a9aca097132a24f4810.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0441\u0447\u0435\u0442\u0443 \u0432\u0441\u0442\u0440\u0435\u0447 \u043f\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0433\u043e\u043b\u0430\u043c \u0437\u0430\u0431\u0438\u0442\u044b\u043c \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u0430\u0442\u0447\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u0432\u0441\u0435 \u0433\u043e\u043b\u0430\u043c, \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0434\u043e \u0434\u0435\u0441\u044f\u0442\u043e\u0433\u043e, \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u0433\u043e\u043b\u0430\u043c \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u043e \u0434\u0435\u0441\u044f\u0442\u044b\u0439<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/989\/64b\/58e\/98964b58ee79ac55f74159499f7f4932.png\" alt=\"\u041f\u0435\u0440\u0432\u044b\u0439 \u0433\u043e\u043b\" title=\"\u041f\u0435\u0440\u0432\u044b\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/989\/64b\/58e\/98964b58ee79ac55f74159499f7f4932.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/989\/64b\/58e\/98964b58ee79ac55f74159499f7f4932.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041f\u0435\u0440\u0432\u044b\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0a8\/9e4\/770\/0a89e4770b76dc00a609ecb98a3476c0.png\" alt=\"\u0412\u0442\u043e\u0440\u043e\u0439 \u0433\u043e\u043b\" title=\"\u0412\u0442\u043e\u0440\u043e\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/0a8\/9e4\/770\/0a89e4770b76dc00a609ecb98a3476c0.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0a8\/9e4\/770\/0a89e4770b76dc00a609ecb98a3476c0.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0412\u0442\u043e\u0440\u043e\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/35f\/cc2\/b7c\/35fcc2b7c71bf4af2398f568a535eed1.png\" alt=\"\u0422\u0440\u0435\u0442\u0438\u0439 \u0433\u043e\u043b\" title=\"\u0422\u0440\u0435\u0442\u0438\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/35f\/cc2\/b7c\/35fcc2b7c71bf4af2398f568a535eed1.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/35f\/cc2\/b7c\/35fcc2b7c71bf4af2398f568a535eed1.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0422\u0440\u0435\u0442\u0438\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0cd\/b91\/7c6\/0cdb917c65da4ae3ed03b41c46df2ad6.png\" alt=\"\u0427\u0435\u0442\u0432\u0435\u0440\u0442\u044b\u0439 \u0433\u043e\u043b\" title=\"\u0427\u0435\u0442\u0432\u0435\u0440\u0442\u044b\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/0cd\/b91\/7c6\/0cdb917c65da4ae3ed03b41c46df2ad6.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0cd\/b91\/7c6\/0cdb917c65da4ae3ed03b41c46df2ad6.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0427\u0435\u0442\u0432\u0435\u0440\u0442\u044b\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/372\/462\/eb6\/372462eb677a97b1b6693496709a2633.png\" alt=\"\u041f\u044f\u0442\u044b\u0439 \u0433\u043e\u043b\" title=\"\u041f\u044f\u0442\u044b\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/372\/462\/eb6\/372462eb677a97b1b6693496709a2633.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/372\/462\/eb6\/372462eb677a97b1b6693496709a2633.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041f\u044f\u0442\u044b\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/323\/f05\/6e9\/323f056e93fe6531ac31b801c1c3c713.png\" alt=\"\u0428\u0435\u0441\u0442\u043e\u0439 \u0433\u043e\u043b\" title=\"\u0428\u0435\u0441\u0442\u043e\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/323\/f05\/6e9\/323f056e93fe6531ac31b801c1c3c713.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/323\/f05\/6e9\/323f056e93fe6531ac31b801c1c3c713.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0428\u0435\u0441\u0442\u043e\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a39\/48c\/89e\/a3948c89ede2be95d273ae3968121e47.png\" alt=\"\u0421\u0435\u0434\u044c\u043c\u043e\u0439 \u0433\u043e\u043b\" title=\"\u0421\u0435\u0434\u044c\u043c\u043e\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/a39\/48c\/89e\/a3948c89ede2be95d273ae3968121e47.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a39\/48c\/89e\/a3948c89ede2be95d273ae3968121e47.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0435\u0434\u044c\u043c\u043e\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bc5\/429\/c61\/bc5429c61f24dd52d27659d915593f79.png\" alt=\"\u0412\u043e\u0441\u044c\u043c\u043e\u0439 \u0433\u043e\u043b\" title=\"\u0412\u043e\u0441\u044c\u043c\u043e\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/bc5\/429\/c61\/bc5429c61f24dd52d27659d915593f79.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bc5\/429\/c61\/bc5429c61f24dd52d27659d915593f79.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0412\u043e\u0441\u044c\u043c\u043e\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/923\/4ff\/9c8\/9234ff9c817d0ae2f3f5de95f697cf30.png\" alt=\"\u0414\u0435\u0432\u044f\u0442\u044b\u0439 \u0433\u043e\u043b\" title=\"\u0414\u0435\u0432\u044f\u0442\u044b\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/923\/4ff\/9c8\/9234ff9c817d0ae2f3f5de95f697cf30.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/923\/4ff\/9c8\/9234ff9c817d0ae2f3f5de95f697cf30.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0414\u0435\u0432\u044f\u0442\u044b\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/942\/2be\/366\/9422be36672195405b7655be7a6dfc54.png\" alt=\"\u0414\u0435\u0441\u044f\u0442\u044b\u0439 \u0433\u043e\u043b\" title=\"\u0414\u0435\u0441\u044f\u0442\u044b\u0439 \u0433\u043e\u043b\" width=\"1579\" height=\"250\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/942\/2be\/366\/9422be36672195405b7655be7a6dfc54.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/942\/2be\/366\/9422be36672195405b7655be7a6dfc54.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0414\u0435\u0441\u044f\u0442\u044b\u0439 \u0433\u043e\u043b<\/figcaption><\/div>\n<\/figure>\n<\/div>\n<\/details>\n<h2>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c<\/h2>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0438\u0441\u043f\u0430\u043d\u0441\u043a\u0438\u0439 \u0447\u0435\u043c\u043f\u0438\u043e\u043d\u0430\u0442 \u0438 \u0435\u0433\u043e \u0433\u0440\u0430\u043d\u0434\u043e\u0432:\u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0443 \u0438 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0438\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0435\u0440\u0432\u044b\u0445 \u0437\u0430\u0431\u0438\u0442\u044b\u0445 \u043c\u044f\u0447\u0435\u0439, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u0438\u0433\u0440\u0430\u044e\u0442 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0432 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u043c \u043c\u0430\u0442\u0447\u0435 \u0438\u043b\u0438 \u043d\u0430 \u0432\u044b\u0435\u0437\u0434\u0435.<\/p>\n<p>\u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0441\u0432\u043e\u0435\u043c \u043f\u043e\u043b\u0435, \u0443 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u044b \u2013 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/14a\/beb\/160\/14abeb16039c8de3d1a1b2cadea8ff1a.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (home) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (away)\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (home) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (away)\" width=\"1660\" height=\"682\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/14a\/beb\/160\/14abeb16039c8de3d1a1b2cadea8ff1a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/14a\/beb\/160\/14abeb16039c8de3d1a1b2cadea8ff1a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (home) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (away)<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1df\/878\/9e6\/1df8789e6d555226730b6bba3c6cb8ef.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (away) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (home)\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (away) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (home)\" width=\"1662\" height=\"680\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/1df\/878\/9e6\/1df8789e6d555226730b6bba3c6cb8ef.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1df\/878\/9e6\/1df8789e6d555226730b6bba3c6cb8ef.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (away) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (home)<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u0438\u0434\u043d\u043e \u0438 \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u0437\u0430\u043a\u043e\u043d\u043e\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c, \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 \u0438\u0433\u0440\u0430\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 \u0440\u0430\u0432\u043d\u044b\u0445 \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0432\u044b\u0439 \u0433\u043e\u043b \u0437\u0430\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0435\u0440\u0432\u044b\u0435 15 \u043c\u0438\u043d\u0443\u0442, \u0435\u0441\u043b\u0438 \u0436\u0435 \u043f\u0435\u0440\u0432\u044b\u0439 \u0433\u043e\u043b \u0437\u0430\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f (\u043d\u0435\u0432\u0430\u0436\u043d\u043e \u043a\u0435\u043c) \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430 \u2013 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043f\u043e\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0432 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u043c \u043c\u0430\u0442\u0447\u0435.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/006\/445\/7cf\/0064457cfb254b31a418c494759a6574.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (home) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (away) - \u043d\u0430\u0447\u0430\u043b\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (home) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (away) - \u043d\u0430\u0447\u0430\u043b\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430\" width=\"1659\" height=\"682\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/006\/445\/7cf\/0064457cfb254b31a418c494759a6574.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/006\/445\/7cf\/0064457cfb254b31a418c494759a6574.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (home) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (away) &#8212; \u043d\u0430\u0447\u0430\u043b\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/056\/b8a\/455\/056b8a455f467881f335784f302c8f86.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (home) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (away) - \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (home) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (away) - \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430\" width=\"1665\" height=\"680\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/056\/b8a\/455\/056b8a455f467881f335784f302c8f86.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/056\/b8a\/455\/056b8a455f467881f335784f302c8f86.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043c\u0430\u0442\u0447\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0420\u0435\u0430\u043b \u041c\u0430\u0434\u0440\u0438\u0434 (home) \u0438 \u0411\u0430\u0440\u0441\u0435\u043b\u043e\u043d\u0430 (away) &#8212; \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043c\u0441\u044f \u043d\u0430 \u0440\u043e\u0434\u0438\u043d\u0443 \u0444\u0443\u0442\u0431\u043e\u043b\u0430, \u0432 \u0410\u043d\u0433\u043b\u0438\u044e. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u0433\u043e\u043b\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0432 \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u0433\u0440\u0430\u043d\u0434\u043e\u0432 Liverpool, Chelsea \u0438 Arsenal, Manchester United, Manchester City, Everton. \u041d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0435\u0435 \u0447\u0438\u0441\u043b\u043e \u0433\u043e\u043b\u043e\u0432 \u0431\u044b\u043b\u043e \u0437\u0430\u0431\u0438\u0442\u043e \u043d\u0430 6-\u0439, 11-\u0439 \u0438 15-\u0439 \u043c\u0438\u043d\u0443\u0442\u0430\u0445. <\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4a5\/d4b\/ed0\/4a5d4bed08f65002787cc7f76866fb20.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0433\u043e\u043b\u043e\u0432 \u043f\u043e Liverpool, Chelsea \u0438 Arsenal, Manchester United, Manchester City, Everton (home)\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0433\u043e\u043b\u043e\u0432 \u043f\u043e Liverpool, Chelsea \u0438 Arsenal, Manchester United, Manchester City, Everton (home)\" width=\"1634\" height=\"683\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/4a5\/d4b\/ed0\/4a5d4bed08f65002787cc7f76866fb20.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4a5\/d4b\/ed0\/4a5d4bed08f65002787cc7f76866fb20.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0433\u043e\u043b\u043e\u0432 \u043f\u043e Liverpool, Chelsea \u0438 Arsenal, Manchester United, Manchester City, Everton (home)<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0435\u043c\u0435\u0446\u043a\u0430\u044f \u0431\u0443\u043d\u0434\u0435\u0441\u043b\u0438\u0433\u0430. \u041c\u044e\u043d\u0445\u0435\u043d\u0441\u043a\u0430\u044f \u0411\u0430\u0432\u0430\u0440\u0438\u044f \u0438 \u0414\u043e\u0440\u0442\u043c\u0443\u043d\u0434\u0441\u043a\u0430\u044f \u0411\u043e\u0440\u0443\u0441\u0441\u0438\u044f \u043d\u0435 \u043b\u044e\u0431\u044f\u0442 \u0437\u0430\u0431\u0438\u0432\u0430\u0442\u044c \u043d\u0430 14 \u0438 20 \u043c\u0438\u043d\u0443\u0442\u0430\u0445 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0430. \u0410 \u0432\u043e\u0442 \u043c\u0435\u0436\u0434\u0443 \u044d\u0442\u0438\u043c\u0438 \u043f\u0435\u0440\u0438\u043e\u0434\u0430\u043c\u0438 &#8212; \u044f\u0432\u043d\u044b\u0439 \u0432\u0441\u043f\u043b\u0435\u0441\u043a \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438. \u0412\u0441\u0435 \u044d\u0442\u043e \u0432 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0445 \u043c\u0430\u0442\u0447\u0430\u0445. <\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/413\/803\/519\/4138035195930e66261f7806124f100f.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0433\u043e\u043b\u043e\u0432 \u041c\u044e\u043d\u0445\u0435\u043d\u0441\u043a\u0430\u044f \u0411\u0430\u0432\u0430\u0440\u0438\u044f \u0438 \u0414\u043e\u0440\u0442\u043c\u0443\u043d\u0434\u0441\u043a\u0430\u044f \u0411\u043e\u0440\u0443\u0441\u0441\u0438\u044f (home)\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0433\u043e\u043b\u043e\u0432 \u041c\u044e\u043d\u0445\u0435\u043d\u0441\u043a\u0430\u044f \u0411\u0430\u0432\u0430\u0440\u0438\u044f \u0438 \u0414\u043e\u0440\u0442\u043c\u0443\u043d\u0434\u0441\u043a\u0430\u044f \u0411\u043e\u0440\u0443\u0441\u0441\u0438\u044f (home)\" width=\"1631\" height=\"682\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/413\/803\/519\/4138035195930e66261f7806124f100f.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/413\/803\/519\/4138035195930e66261f7806124f100f.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0433\u043e\u043b\u043e\u0432 \u041c\u044e\u043d\u0445\u0435\u043d\u0441\u043a\u0430\u044f \u0411\u0430\u0432\u0430\u0440\u0438\u044f \u0438 \u0414\u043e\u0440\u0442\u043c\u0443\u043d\u0434\u0441\u043a\u0430\u044f \u0411\u043e\u0440\u0443\u0441\u0441\u0438\u044f (home)<\/figcaption><\/div>\n<\/figure>\n<p>\u0418\u0442\u0430\u043b\u044c\u044f\u043d\u0441\u043a\u0438\u0439 \u0447\u0435\u043c\u043f\u0438\u043e\u043d\u0430\u0442, Juventus \u0438 Milan. \u042d\u0442\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0435 \u0442\u0430\u0439\u043c\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u0441\u043f\u043b\u0435\u0441\u043a \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u0431\u0438\u0442\u044b\u0445 \u043f\u0435\u0440\u0432\u044b\u0445 \u0433\u043e\u043b\u043e\u0432 \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 13 \u043c\u0438\u043d\u0443\u0442\u044b.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/492\/85d\/afb\/49285dafbb52f6fa8571792b03712c49.png\" alt=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0433\u043e\u043b\u043e\u0432 Juventus \u0438 Milan (home)\" title=\"\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0433\u043e\u043b\u043e\u0432 Juventus \u0438 Milan (home)\" width=\"1631\" height=\"684\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/492\/85d\/afb\/49285dafbb52f6fa8571792b03712c49.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/492\/85d\/afb\/49285dafbb52f6fa8571792b03712c49.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0433\u043e\u043b\u043e\u0432 Juventus \u0438 Milan (home)<\/figcaption><\/div>\n<\/figure>\n<p>\u0418 \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a, \u043d\u0438\u0434\u0435\u0440\u043b\u0430\u043d\u0434\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0443\u0431 Zwolle \u0438\u0437 \u043e\u0434\u043d\u043e\u0438\u043c\u0451\u043d\u043d\u043e\u0433\u043e \u0433\u043e\u0440\u043e\u0434\u0430  \u2013 \u044d\u0442\u0438 \u0440\u0435\u0431\u044f\u0442\u0430, \u043f\u043e\u0445\u043e\u0436\u0435, \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u044f\u0442 \u0447\u0438\u0441\u043b\u043e 7 \u0438 \u0441\u0442\u0430\u0440\u0430\u044e\u0442\u0441\u044f (\u043a\u0430\u043a \u043c\u043e\u0433\u0443\u0442 \u043a\u043e\u043d\u0435\u0447\u043d\u043e) \u0437\u0430\u0431\u0438\u0442\u044c \u043d\u0430 7 \u043c\u0438\u043d\u0443\u0442\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0433\u043e\u043b\u043e\u0432 \u0438 \u0441\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0443 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043a \u043d\u0438\u0447\u044c\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>Screencast \u043f\u043e Zwolle<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e7a\/16f\/115\/e7a16f115f063488c12867323422b37f.gif\" alt=\"\" title=\"\" width=\"1915\" height=\"1007\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e7a\/16f\/115\/e7a16f115f063488c12867323422b37f.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e7a\/16f\/115\/e7a16f115f063488c12867323422b37f.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<\/div>\n<\/details>\n<h2>\u0418\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f<\/h2>\n<ul>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u043e\u043a\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a (Filter, Custom -&gt; Range, Range etc) \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044e dashboard-a \u0441 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u0438. \u0421\u0434\u0435\u043b\u0430\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0444\u043e\u043a\u0443\u0441 \u043c\u044b\u0448\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u2013 \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u043e\u043a\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c, \u043d\u043e \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0438 Legend, Detail \u0432 Ad-Hoc \u043f\u043e\u043a\u0430 \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043e\u043d\u0438 \u043d\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 Connection \u0432 Ad-Hoc, \u043d\u0430\u0434\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (\u043f\u043e\u0447\u0443\u0432\u0441\u0442\u0432\u0443\u0439 \u0441\u0435\u0431\u044f \u043d\u0430 \u043c\u0438\u043d\u0443\u0442\u0443 SRE (senior reboot engeneer));<\/p>\n<\/li>\n<li>\n<p>\u0424\u0438\u043b\u044c\u0442\u0440\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e OR, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u043f\u043e \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u043c \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e AND. \u0422\u043e\u0436\u0435 \u0432 \u0440\u0430\u0431\u043e\u0442\u0435.<\/p>\n<\/li>\n<\/ul>\n<h2>\u0418\u0442\u043e\u0433\u0438<\/h2>\n<p>\u0414\u0443\u043c\u0430\u044e, \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f \u043c\u043d\u043e\u0433\u043e\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043d\u044f\u0442\u043d\u0430. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b\u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Dimension UI \u043d\u0430 \u0434\u043e\u043c\u0435\u043d\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439. \u041c\u043e\u0451 \u043b\u0438\u0447\u043d\u043e\u0435 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435 \u2014 \u0434\u0430, \u0443\u0434\u043e\u0431\u043d\u043e. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0449\u0438 \u0434\u0435\u043b\u0430\u044e\u0442\u0441\u044f \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u0432 \u043e\u0434\u0438\u043d-\u0434\u0432\u0430 \u043a\u043b\u0438\u043a\u0430. \u041f\u0440\u043e\u0431\u0443\u0439\u0442\u0435, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0439\u0442\u0435, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f (\u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0438\u0447 \u043d\u0430 Java Swing \u0438 \u043f\u0440\u043e\u0447\u0435\u0435).<\/p>\n<p>\u041d\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u0432 \u0447\u0430\u0441\u0442\u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0445 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u043d\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0438 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u043c \u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438, \u043f\u0440\u0438\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c (\u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u043e\u043a\u043d\u043e Filter) \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435\u043c\/\u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043b\u0438\u0441\u0442\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u0441\u043f\u0438\u0441\u043e\u043a.<\/p>\n<p>\u0423\u0441\u043f\u0435\u0445\u043e\u0432 \u0432 \u0430\u043d\u0430\u043b\u0438\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043d\u0435 \u0437\u0430\u0441\u0438\u0436\u0438\u0432\u0430\u0439\u0442\u0435\u0441\u044c \u0437\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043e\u043c \u2014 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u0440\u044b\u0432\u044b \u043d\u0430 \u0441\u043f\u043e\u0440\u0442: \u0444\u0443\u0442\u0431\u043e\u043b, \u0431\u0435\u0433 \u0438\u043b\u0438 \u0447\u0442\u043e \u0432\u0430\u043c \u043f\u043e \u0434\u0443\u0448\u0435.<\/p>\n<p>\u0412\u0440\u043e\u0434\u0435 \u0432\u0441\u0435, \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430\u00a0\u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/942352\/\"> https:\/\/habr.com\/ru\/articles\/942352\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\">\n<div><figcaption>\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043e <a href=\"https:\/\/habr.com\/ru\/articles\/926598\/\" rel=\"noopener noreferrer nofollow\">\u043c\u043d\u043e\u0433\u043e\u043c\u0435\u0440\u043d\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u044f\u0434\u043e\u0432<\/a> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/github.com\/akardapolov\/dimension-ui\" rel=\"noopener noreferrer nofollow\">Dimension-UI<\/a>, \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0430\u043d\u043d\u044b\u043c, \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c, \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430.\u00a0\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435.\u00a0\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439: \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0433\u043e\u043b\u0430\u043c, \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c, \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u0441\u0447\u0451\u0442\u0443, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0432 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0445 \u0438 \u0433\u043e\u0441\u0442\u0435\u0432\u044b\u0445 \u043c\u0430\u0442\u0447\u0430\u0445.<\/p>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0431\u0443\u0434\u0435\u0442 <a href=\"https:\/\/github.com\/LesnoyChelovek\/footballstats\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0441 \u0432\u0435\u0431-\u0441\u0430\u0439\u0442\u0430 <a href=\"https:\/\/fbref.com\/en\/matches\/\" rel=\"noopener noreferrer nofollow\">fbref.com<\/a>. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u044b\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 <a class=\"mention\" href=\"\/users\/lesnoychelovek\">@LesnoyChelovek<\/a>\u0432 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/habr.com\/ru\/articles\/895008\/\" rel=\"noopener noreferrer nofollow\">\u00ab\u041f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b \u0431\u043e\u043b\u0435\u0435 260 \u0442\u044b\u0441\u044f\u0447 \u0444\u0443\u0442\u0431\u043e\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043f\u043e\u0440\u0438\u0442\u044c \u0441 \u0443\u0447\u0451\u043d\u044b\u043c\u0438-\u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430\u043c\u0438\u00bb<\/a>.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u044f\u0434\u043e\u0432, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f, \u043a\u0430\u043a\u043e\u0435 \u043f\u043e\u043b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0442\u043a\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0414\u0430\u0442\u0430 \u043c\u0430\u0442\u0447\u0430 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430, \u043d\u043e \u043e\u043d\u0430 \u0435\u0441\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"https:\/\/fbref.com\/en\/matches\/\" rel=\"noopener noreferrer nofollow\">fbref.com<\/a>, \u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u0437\u044f\u0442\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430. \u0420\u0435\u0448\u0438\u043b \u043d\u0435 \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u043c \u0441\u0431\u043e\u0440\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0432\u0437\u044f\u0442\u044c \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u043c\u0435\u0442\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0433\u043e\u043b\u043e\u0432 \u0432 \u043c\u0430\u0442\u0447\u0435 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0447\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0439\u0434\u0435\u0442. \u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u0430\u0442\u0447\u0438 \u0431\u0435\u0437 \u0433\u043e\u043b\u043e\u0432 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 \u0432\u044b\u0431\u043e\u0440\u043a\u0443, \u0445\u043e\u0442\u044f \u0438\u0445 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0442\u043e\u0436\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c.<\/p>\n<p> \u0418\u0442\u0430\u043a, \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0433\u0440\u0443\u0437\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 JSON \u0444\u0430\u0439\u043b\u043e\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <em>raw_matches.<\/em><\/p>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 \u043d\u0430 python, \u043b\u044e\u0431\u0435\u0437\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c\u044e <a href=\"https:\/\/chat.deepseek.com\/\" rel=\"noopener noreferrer nofollow\">DeepSeek<\/a>, \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 PostgreSQL. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 WSL2 \u043d\u0430 Windows, \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0434\u043e\u043a\u0435\u0440\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 raw_matches<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">CREATE TABLE raw_matches (     id SERIAL PRIMARY KEY,     season INTEGER,     data JSONB );<\/code><\/pre>\n<pre><code class=\"python\">import json import os import psycopg2 import sys from typing import Any, List  # Database connection try:     conn = psycopg2.connect(         host=\"localhost\",         port=5432,         dbname=\"football\",         user=\"postgres\",         password=\"postgres\"     )     cur = conn.cursor() except psycopg2.Error as e:     print(f\"Database connection error: {e}\")     sys.exit(1)  # Directory containing JSON files json_dir = '\/mnt\/c\/Disk\/dimension\/footballstats\/JSON'  def flatten_matches(data: Any) -&gt; List[Any]:     \"\"\"Flatten nested match structures\"\"\"     matches = []          if isinstance(data, list):         for item in data:             if isinstance(item, dict) and 'home_team' in item and 'away_team' in item:                 # This is a match object                 matches.append(item)             elif isinstance(item, list):                 # This is a nested list, recursively flatten                 matches.extend(flatten_matches(item))             else:                 print(f\"Unexpected item type: {type(item)}\")     elif isinstance(data, dict):         # Check if this is a match object         if 'home_team' in data and 'away_team' in data:             matches.append(data)         else:             # This might be a container with matches inside             for key, value in data.items():                 if isinstance(value, (list, dict)):                     matches.extend(flatten_matches(value))          return matches  for filename in os.listdir(json_dir):     if filename.startswith('match_data') and filename.endswith('.json'):         filepath = os.path.join(json_dir, filename)                  try:             # Extract season from filename             season = int(filename[10:14])         except ValueError as e:             print(f\"Error extracting season from {filename}: {e}\")             continue          try:             with open(filepath, 'r', encoding='utf-8') as f:                 raw_data = json.load(f)                              # Debug: Print the type and structure of the loaded data             print(f\"DEBUG: {filename} - Type of loaded data: {type(raw_data)}\")             if isinstance(raw_data, list) and len(raw_data) &gt; 0:                 print(f\"DEBUG: {filename} - First element type: {type(raw_data[0])}\")                          # Flatten the data structure to extract all matches             matches = flatten_matches(raw_data)             print(f\"DEBUG: {filename} - Found {len(matches)} matches after flattening\")                          if len(matches) &gt; 0:                 print(f\"DEBUG: {filename} - First match: {json.dumps(matches[0], indent=2)}\")                      except Exception as e:             print(f\"Error reading\/parsing {filename}: {e}\")             continue          match_count = 0         error_count = 0                  for match in matches:             try:                 cur.execute(                     \"INSERT INTO raw_matches (season, data) VALUES (%s, %s)\",                     (season, json.dumps(match))                 )                 match_count += 1             except psycopg2.Error as e:                 error_count += 1                 print(f\"Database error inserting match from {filename}: {e}\")                 print(f\"Problematic match data: {json.dumps(match)}\")             except Exception as e:                 error_count += 1                 print(f\"Unexpected error with match from {filename}: {e}\")                 print(f\"Problematic match data: {json.dumps(match)}\")          print(f\"Loaded {match_count} matches from {filename} with {error_count} errors\")                  try:             conn.commit()         except psycopg2.Error as e:             print(f\"Commit error after {filename}: {e}\")             try:                 conn.rollback()             except:                 pass  cur.close() conn.close()<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043f\u043e \u043c\u0435\u0442\u043a\u0430\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b matches.<\/p>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b raw_matches \u0432 matches<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">CREATE TABLE matches (     year VARCHAR,     home_team VARCHAR,     away_team VARCHAR,     score VARCHAR,     goals_minutes_1 TIMESTAMP,     goals_minutes_2 TIMESTAMP,     goals_minutes_3 TIMESTAMP,     goals_minutes_4 TIMESTAMP,     goals_minutes_5 TIMESTAMP,     goals_minutes_6 TIMESTAMP,     goals_minutes_7 TIMESTAMP,     goals_minutes_8 TIMESTAMP,     goals_minutes_9 TIMESTAMP,     goals_minutes_10 TIMESTAMP,     home_goals INTEGER,     away_goals INTEGER,     goals INTEGER,     home_result VARCHAR,     away_result VARCHAR );<\/code><\/pre>\n<pre><code class=\"python\">import psycopg2 import json import logging from datetime import datetime, timedelta from typing import Optional, Dict, Any, List  # Set up logging logging.basicConfig(     level=logging.INFO,     format='%(asctime)s - %(levelname)s - %(message)s',     handlers=[         logging.FileHandler('data_load.log'),         logging.StreamHandler()     ] )  def parse_goal_minute(minute_str: str) -&gt; Optional[int]:     \"\"\"     Parse goal minute string, handling additional time notation     Examples:      - \"45+1'\" becomes 46     - \"90+2'\" becomes 92     - \"30'\" becomes 30     \"\"\"     try:         if not minute_str:             return None                      # Remove any trailing apostrophes\/quotes         minute_str = minute_str.rstrip(\"'\u2019\\\"\")                  if '+' in minute_str:             parts = minute_str.split('+')             base_minute = int(parts[0])             added_minutes = int(parts[1])             return base_minute + added_minutes         else:             return int(minute_str)     except (ValueError, IndexError, AttributeError) as e:         logging.error(f\"Error parsing goal minute '{minute_str}': {e}\")         return None  def clean_score(score_str: str) -&gt; str:     \"\"\"     Clean score string by removing asterisks and other non-numeric characters     \"\"\"     if not score_str:         return score_str          # Remove asterisks and other non-standard characters     cleaned = score_str.replace('*', '').replace('--', '0')          # Handle cases like \"0 - 3*\" -&gt; \"0 - 3\"     if ' - ' in cleaned:         parts = cleaned.split(' - ')         # Ensure both parts are numeric or can be converted to 0         try:             int(parts[0])         except ValueError:             parts[0] = '0'         try:             int(parts[1])         except ValueError:             parts[1] = '0'         cleaned = ' - '.join(parts)          return cleaned  def process_matches():     conn = None     cursor = None     processed_count = 0     error_count = 0     skipped_count = 0          try:         # Database connection - update with your credentials         conn = psycopg2.connect(             host=\"localhost\",             database=\"football\",             user=\"postgres\",             password=\"postgres\",             port=5432         )          cursor = conn.cursor()         logging.info(\"Connected to database successfully\")          # Fetch raw matches         cursor.execute(\"SELECT id, season, data FROM raw_matches ORDER BY id\")         raw_matches = cursor.fetchall()         logging.info(f\"Fetched {len(raw_matches)} raw matches\")          # Process each match         for match_id, season, data in raw_matches:             try:                 # data is already a dict from psycopg2 for JSONB fields                 match_data = data                                  # Log full data for problematic matches (for debugging)                 if match_id in [3177, 4941, 5002, 5640, 9710, 14831, 15279, 17657, 20733,                                27177, 28565, 28633, 32717, 36030, 36052, 39788, 39794, 39862, 40158]:                     logging.warning(f\"DEBUG - Problematic match {match_id} full data: {match_data}\")                                  # Validate required fields                 required_fields = ['score', 'home_team', 'away_team']                 missing_fields = [field for field in required_fields if field not in match_data]                 if missing_fields:                     logging.warning(f\"Match {match_id} missing required fields: {missing_fields}. Full data: {match_data}\")                     error_count += 1                     continue                                  # Parse score safely with cleaning                 try:                     original_score = match_data['score']                     cleaned_score =<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-472686","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/472686","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=472686"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/472686\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=472686"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=472686"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=472686"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}