{% extends "base.html" %} {% block content %}
{% if player.avatar_url %} {% else %}
{{ player.username[:2] | upper if player.username else '??' }}
{% endif %} {% if session.get('is_admin') %} {% endif %}

{{ player.username }}

{{ player.steam_id_64 }}

{% for tag in metadata.tags %} {{ tag }} {% if session.get('is_admin') %}
{% endif %}
{% endfor %} {% if session.get('is_admin') %}
{% endif %}
{% macro stat_card(label, metric_key, format_str, icon) %} {% set dist = distribution[metric_key] if distribution else None %}
{{ icon }} {{ label }}
{% if dist %} Rank #{{ dist.rank }} {% endif %}
{{ format_str.format(dist.val if dist else 0) }}
{% if dist %}
{% set range = dist.max - dist.min %} {% set percent = ((dist.val - dist.min) / range * 100) if range > 0 else 100 %}
{{ format_str.format(dist.min) }} Avg: {{ format_str.format(dist.avg) }} {{ format_str.format(dist.max) }}
{% else %}
No team data
{% endif %}
{% endmacro %} {{ stat_card('Rating', 'rating', '{:.2f}', 'โญ') }} {{ stat_card('K/D Ratio', 'kd', '{:.2f}', '๐Ÿ”ซ') }} {{ stat_card('ADR', 'adr', '{:.1f}', '๐Ÿ”ฅ') }} {{ stat_card('KAST', 'kast', '{:.1%}', '๐Ÿ›ก๏ธ') }}

๐Ÿ“ˆ ่ฟ‘ๆœŸ่กจ็Žฐ่ตฐๅŠฟ (Performance Trend)

Carry (>1.5)
Normal (1.0-1.5)
Poor (<0.6)

๐Ÿ•ธ๏ธ ่ƒฝๅŠ›ๅ…ญ็ปดๅ›พ (Capabilities)

๐Ÿ“Š ่ฏฆ็ป†ๆ•ฐๆฎ้ขๆฟ (Detailed Stats)

{% macro detail_item(label, value, key, format_str='{:.2f}', sublabel=None, count_label=None) %} {% set dist = distribution[key] if distribution else None %}
{{ label }} {% if dist %} #{{ dist.rank }} {% endif %}
{{ format_str.format(value if value is not none else 0) }} {% if sublabel %} {{ sublabel }} {% endif %}
{% if count_label is not none %}
{{ count_label }}
{% endif %}
{% if dist %}
{% set range = dist.max - dist.min %} {% set percent = ((dist.val - dist.min) / range * 100) if range > 0 else 100 %}
{% set avg_pct = ((dist.avg - dist.min) / range * 100) if range > 0 else 50 %}
L:{{ format_str.format(dist.min) }} H:{{ format_str.format(dist.max) }}
{% endif %}
{% endmacro %} {{ detail_item('Rating (่ฏ„ๅˆ†)', features['basic_avg_rating'], 'basic_avg_rating') }} {{ detail_item('KD Ratio (ๅ‡ปๆ€ๆฏ”)', features['basic_avg_kd'], 'basic_avg_kd') }} {{ detail_item('KAST (่ดก็Œฎ็އ)', features['basic_avg_kast'], 'basic_avg_kast', '{:.1%}') }} {{ detail_item('RWS (ๆฏๅฑ€ๅพ—ๅˆ†)', features['basic_avg_rws'], 'basic_avg_rws') }} {{ detail_item('ADR (ๅœบๅ‡ไผคๅฎณ)', features['basic_avg_adr'], 'basic_avg_adr', '{:.1f}') }} {{ detail_item('Avg HS (ๅœบๅ‡็ˆ†ๅคด)', features['basic_avg_headshot_kills'], 'basic_avg_headshot_kills') }} {{ detail_item('HS Rate (็ˆ†ๅคด็އ)', features['basic_headshot_rate'], 'basic_headshot_rate', '{:.1%}') }} {{ detail_item('Assists (ๅœบๅ‡ๅŠฉๆ”ป)', features['basic_avg_assisted_kill'], 'basic_avg_assisted_kill') }} {{ detail_item('AWP Kills (็‹™ๅ‡ปๅ‡ปๆ€)', features['basic_avg_awp_kill'], 'basic_avg_awp_kill') }} {{ detail_item('Jumps (ๅœบๅ‡่ทณ่ทƒ)', features['basic_avg_jump_count'], 'basic_avg_jump_count', '{:.1f}') }} {{ detail_item('MVP (ๆœ€ๆœ‰ไปทๅ€ผ)', features['basic_avg_mvps'], 'basic_avg_mvps') }} {{ detail_item('Plants (ไธ‹ๅŒ…)', features['basic_avg_plants'], 'basic_avg_plants') }} {{ detail_item('Defuses (ๆ‹†ๅŒ…)', features['basic_avg_defuses'], 'basic_avg_defuses') }} {{ detail_item('Flash Assist (้—ชๅ…‰ๅŠฉๆ”ป)', features['basic_avg_flash_assists'], 'basic_avg_flash_assists') }} {{ detail_item('First Kill (ๅœบๅ‡้ฆ–ๆ€)', features['basic_avg_first_kill'], 'basic_avg_first_kill') }} {{ detail_item('First Death (ๅœบๅ‡้ฆ–ๆญป)', features['basic_avg_first_death'], 'basic_avg_first_death') }} {{ detail_item('FK Rate (้ฆ–ๆ€็އ)', features['basic_first_kill_rate'], 'basic_first_kill_rate', '{:.1%}') }} {{ detail_item('FD Rate (้ฆ–ๆญป็އ)', features['basic_first_death_rate'], 'basic_first_death_rate', '{:.1%}') }} {{ detail_item('2K Rounds (ๅŒๆ€)', features['basic_avg_kill_2'], 'basic_avg_kill_2') }} {{ detail_item('3K Rounds (ไธ‰ๆ€)', features['basic_avg_kill_3'], 'basic_avg_kill_3') }} {{ detail_item('4K Rounds (ๅ››ๆ€)', features['basic_avg_kill_4'], 'basic_avg_kill_4') }} {{ detail_item('5K Rounds (ไบ”ๆ€)', features['basic_avg_kill_5'], 'basic_avg_kill_5') }} {{ detail_item('Perfect Kills (ๆ— ไผคๆ€)', features['basic_avg_perfect_kill'], 'basic_avg_perfect_kill') }} {{ detail_item('Revenge Kills (ๅคไป‡ๆ€)', features['basic_avg_revenge_kill'], 'basic_avg_revenge_kill') }}

๐Ÿ”ฌ ๆทฑๅฑ‚่ƒฝๅŠ›็ปดๅบฆ (Deep Capabilities Breakdown)

STA (Stability) & BAT (Aim/Battle)

{{ detail_item('Last 30 Rating (่ฟ‘30ๅœบ)', features['sta_last_30_rating'], 'sta_last_30_rating') }} {{ detail_item('Win Rating (่ƒœๅฑ€)', features['sta_win_rating'], 'sta_win_rating') }} {{ detail_item('Loss Rating (่ดฅๅฑ€)', features['sta_loss_rating'], 'sta_loss_rating') }} {{ detail_item('Volatility (ๆณขๅŠจ)', features['sta_rating_volatility'], 'sta_rating_volatility') }} {{ detail_item('Time Corr (่€ๅŠ›)', features['sta_time_rating_corr'], 'sta_time_rating_corr') }} {{ detail_item('High Elo KD Diff (้ซ˜ๅˆ†ๆŠ—ๅŽ‹)', features['bat_kd_diff_high_elo'], 'bat_kd_diff_high_elo') }} {{ detail_item('Duel Win% (ๅฏนๆžช่ƒœ็އ)', features['bat_avg_duel_win_rate'], 'bat_avg_duel_win_rate', '{:.1%}') }}

HPS (Clutch/Pressure) & PTL (Pistol)

{{ detail_item('Avg 1v1 (ๅœบๅ‡1v1)', features['hps_clutch_win_rate_1v1'], 'hps_clutch_win_rate_1v1', '{:.2f}') }} {{ detail_item('Avg 1v3+ (ๅœบๅ‡1v3+)', features['hps_clutch_win_rate_1v3_plus'], 'hps_clutch_win_rate_1v3_plus', '{:.2f}') }} {{ detail_item('Match Pt Win% (่ต›็‚น่ƒœ็އ)', features['hps_match_point_win_rate'], 'hps_match_point_win_rate', '{:.1%}') }} {{ detail_item('Pressure Entry (้€†้ฃŽ้ฆ–ๆ€)', features['hps_pressure_entry_rate'], 'hps_pressure_entry_rate', '{:.1%}') }} {{ detail_item('Comeback KD (็ฟป็›˜KD)', features['hps_comeback_kd_diff'], 'hps_comeback_kd_diff') }} {{ detail_item('Loss Streak KD (่ฟž่ดฅKD)', features['hps_losing_streak_kd_diff'], 'hps_losing_streak_kd_diff') }} {{ detail_item('Pistol Kills (ๆ‰‹ๆžชๅ‡ปๆ€)', features['ptl_pistol_kills'], 'ptl_pistol_kills') }} {{ detail_item('Pistol Win% (ๆ‰‹ๆžช่ƒœ็އ)', features['ptl_pistol_win_rate'], 'ptl_pistol_win_rate', '{:.1%}') }} {{ detail_item('Pistol KD (ๆ‰‹ๆžชKD)', features['ptl_pistol_kd'], 'ptl_pistol_kd') }} {{ detail_item('Pistol Util Eff (ๆ‰‹ๆžช้“ๅ…ท)', features['ptl_pistol_util_efficiency'], 'ptl_pistol_util_efficiency', '{:.1%}') }}

UTIL (Utility Usage)

{{ detail_item('Usage Rate (้“ๅ…ท้ข‘็އ)', features['util_usage_rate'], 'util_usage_rate') }} {{ detail_item('Nade Dmg (้›ท็ซไผค)', features['util_avg_nade_dmg'], 'util_avg_nade_dmg', '{:.1f}') }} {{ detail_item('Flash Time (่‡ด็›ฒๆ—ถ้—ด)', features['util_avg_flash_time'], 'util_avg_flash_time', '{:.2f}s') }} {{ detail_item('Flash Enemy (่‡ด็›ฒไบบๆ•ฐ)', features['util_avg_flash_enemy'], 'util_avg_flash_enemy') }}

SPECIAL (Clutch & Multi)

{% set matches = l2_stats.get('matches', 0) or 1 %} {% set rounds = l2_stats.get('total_rounds', 0) or 1 %}
{% set c1 = l2_stats.get('c1', 0) or 0 %} {% set a1 = l2_stats.get('att1', 0) or 0 %} {{ detail_item('1v1 Win% (1v1่ƒœ็އ)', c1 / a1 if a1 > 0 else 0, 'clutch_rate_1v1', '{:.1%}', count_label=c1 ~ '/' ~ a1) }} {% set c2 = l2_stats.get('c2', 0) or 0 %} {% set a2 = l2_stats.get('att2', 0) or 0 %} {{ detail_item('1v2 Win% (1v2่ƒœ็އ)', c2 / a2 if a2 > 0 else 0, 'clutch_rate_1v2', '{:.1%}', count_label=c2 ~ '/' ~ a2) }} {% set c3 = l2_stats.get('c3', 0) or 0 %} {% set a3 = l2_stats.get('att3', 0) or 0 %} {{ detail_item('1v3 Win% (1v3่ƒœ็އ)', c3 / a3 if a3 > 0 else 0, 'clutch_rate_1v3', '{:.1%}', count_label=c3 ~ '/' ~ a3) }} {% set c4 = l2_stats.get('c4', 0) or 0 %} {% set a4 = l2_stats.get('att4', 0) or 0 %} {{ detail_item('1v4 Win% (1v4่ƒœ็އ)', c4 / a4 if a4 > 0 else 0, 'clutch_rate_1v4', '{:.1%}', count_label=c4 ~ '/' ~ a4) }} {% set c5 = l2_stats.get('c5', 0) or 0 %} {% set a5 = l2_stats.get('att5', 0) or 0 %} {{ detail_item('1v5 Win% (1v5่ƒœ็އ)', c5 / a5 if a5 > 0 else 0, 'clutch_rate_1v5', '{:.1%}', count_label=c5 ~ '/' ~ a5) }} {% set mk_count = (l2_stats.get('k2', 0) or 0) + (l2_stats.get('k3', 0) or 0) + (l2_stats.get('k4', 0) or 0) + (l2_stats.get('k5', 0) or 0) %} {% set ma_count = (l2_stats.get('a2', 0) or 0) + (l2_stats.get('a3', 0) or 0) + (l2_stats.get('a4', 0) or 0) + (l2_stats.get('a5', 0) or 0) %} {{ detail_item('Multi-K Rate (ๅคšๆ€็އ)', mk_count / rounds, 'total_multikill_rate', '{:.1%}', count_label=mk_count) }} {{ detail_item('Multi-A Rate (ๅคšๅŠฉ็އ)', ma_count / rounds, 'total_multiassist_rate', '{:.1%}', count_label=ma_count) }}

SIDE (T/CT Preference)

{% macro vs_item_val(label, t_val, ct_val, format_str='{:.2f}') %} {% set diff = ct_val - t_val %} {# Dynamic Sizing #} {% set t_size = 'text-2xl' if t_val > ct_val else 'text-sm text-gray-500 dark:text-gray-400' %} {% set ct_size = 'text-2xl' if ct_val > t_val else 'text-sm text-gray-500 dark:text-gray-400' %} {% if t_val == ct_val %} {% set t_size = 'text-lg' %} {% set ct_size = 'text-lg' %} {% endif %}
{{ label }} {% if diff|abs > 0.001 %} {% if diff > 0 %}CT +{{ format_str.format(diff) }} {% else %}T +{{ format_str.format(diff|abs) }}{% endif %} {% endif %}
T-Side {{ format_str.format(t_val) }}
CT-Side {{ format_str.format(ct_val) }}
{% set total = t_val + ct_val %} {% if total > 0 %} {% set t_pct = (t_val / total) * 100 %}
{% else %}
{% endif %}
{% endmacro %} {% macro vs_item(label, t_key, ct_key, format_str='{:.2f}') %} {{ vs_item_val(label, features[t_key] or 0, features[ct_key] or 0, format_str) }} {% endmacro %}
{{ vs_item('Rating (Rating/KD)', 'side_rating_t', 'side_rating_ct') }} {{ vs_item('KD Ratio', 'side_kd_t', 'side_kd_ct') }} {{ vs_item('Win Rate (่ƒœ็އ)', 'side_win_rate_t', 'side_win_rate_ct', '{:.1%}') }} {{ vs_item('First Kill Rate (้ฆ–ๆ€็އ)', 'side_first_kill_rate_t', 'side_first_kill_rate_ct', '{:.1%}') }} {{ vs_item('First Death Rate (้ฆ–ๆญป็އ)', 'side_first_death_rate_t', 'side_first_death_rate_ct', '{:.1%}') }} {{ vs_item('KAST (่ดก็Œฎ็އ)', 'side_kast_t', 'side_kast_ct', '{:.1%}') }} {{ vs_item('RWS (Round Win Share)', 'side_rws_t', 'side_rws_ct') }} {{ vs_item('Headshot Rate (็ˆ†ๅคด็އ)', 'side_headshot_rate_t', 'side_headshot_rate_ct', '{:.1%}') }} {# New Comparisons #} {% set t_rounds = side_stats.get('T', {}).get('rounds', 0) or 1 %} {% set ct_rounds = side_stats.get('CT', {}).get('rounds', 0) or 1 %} {% set t_clutch = (side_stats.get('T', {}).get('total_clutch', 0) or 0) / t_rounds %} {% set ct_clutch = (side_stats.get('CT', {}).get('total_clutch', 0) or 0) / ct_rounds %} {{ vs_item_val('Clutch Win Rate (ๆฎ‹ๅฑ€็އ)', t_clutch, ct_clutch, '{:.1%}') }} {% set t_mk = (side_stats.get('T', {}).get('total_multikill', 0) or 0) / t_rounds %} {% set ct_mk = (side_stats.get('CT', {}).get('total_multikill', 0) or 0) / ct_rounds %} {{ vs_item_val('Multi-Kill Rate (ๅคšๆ€็އ)', t_mk, ct_mk, '{:.1%}') }} {% set t_ma = (side_stats.get('T', {}).get('total_multiassist', 0) or 0) / t_rounds %} {% set ct_ma = (side_stats.get('CT', {}).get('total_multiassist', 0) or 0) / ct_rounds %} {{ vs_item_val('Multi-Assist Rate (ๅคšๅŠฉๆ”ป)', t_ma, ct_ma, '{:.1%}') }}

๐Ÿ‘ฅ ็ป„ๆŽ’ไธŽๅˆ†ๅฑ‚่กจ็Žฐ (Party & Stratification)

Party Size Performance (็ป„ๆŽ’่กจ็Žฐ)
{{ detail_item('Solo Win% (ๅ•ๆŽ’่ƒœ็އ)', features['party_1_win_rate'], 'party_1_win_rate', '{:.1%}') }} {{ detail_item('Solo Rating (ๅ•ๆŽ’ๅˆ†)', features['party_1_rating'], 'party_1_rating') }} {{ detail_item('Solo ADR (ๅ•ๆŽ’ไผค)', features['party_1_adr'], 'party_1_adr', '{:.1f}') }} {{ detail_item('Duo Win% (ๅŒๆŽ’่ƒœ็އ)', features['party_2_win_rate'], 'party_2_win_rate', '{:.1%}') }} {{ detail_item('Duo Rating (ๅŒๆŽ’ๅˆ†)', features['party_2_rating'], 'party_2_rating') }} {{ detail_item('Duo ADR (ๅŒๆŽ’ไผค)', features['party_2_adr'], 'party_2_adr', '{:.1f}') }} {{ detail_item('Trio Win% (ไธ‰ๆŽ’่ƒœ็އ)', features['party_3_win_rate'], 'party_3_win_rate', '{:.1%}') }} {{ detail_item('Trio Rating (ไธ‰ๆŽ’ๅˆ†)', features['party_3_rating'], 'party_3_rating') }} {{ detail_item('Trio ADR (ไธ‰ๆŽ’ไผค)', features['party_3_adr'], 'party_3_adr', '{:.1f}') }} {{ detail_item('Quad Win% (ๅ››ๆŽ’่ƒœ็އ)', features['party_4_win_rate'], 'party_4_win_rate', '{:.1%}') }} {{ detail_item('Quad Rating (ๅ››ๆŽ’ๅˆ†)', features['party_4_rating'], 'party_4_rating') }} {{ detail_item('Quad ADR (ๅ››ๆŽ’ไผค)', features['party_4_adr'], 'party_4_adr', '{:.1f}') }} {{ detail_item('Full Win% (ไบ”ๆŽ’่ƒœ็އ)', features['party_5_win_rate'], 'party_5_win_rate', '{:.1%}') }} {{ detail_item('Full Rating (ไบ”ๆŽ’ๅˆ†)', features['party_5_rating'], 'party_5_rating') }} {{ detail_item('Full ADR (ไบ”ๆŽ’ไผค)', features['party_5_adr'], 'party_5_adr', '{:.1f}') }}
Performance Tiers (่กจ็Žฐๅˆ†ๅฑ‚)
{{ detail_item('Carry Rate (>1.5)', features['rating_dist_carry_rate'], 'rating_dist_carry_rate', '{:.1%}') }} {{ detail_item('Normal Rate (1.0-1.5)', features['rating_dist_normal_rate'], 'rating_dist_normal_rate', '{:.1%}') }} {{ detail_item('Sacrifice Rate (0.6-1.0)', features['rating_dist_sacrifice_rate'], 'rating_dist_sacrifice_rate', '{:.1%}') }} {{ detail_item('Sleeping Rate (<0.6)', features['rating_dist_sleeping_rate'], 'rating_dist_sleeping_rate', '{:.1%}') }}
Performance vs ELO (ไธๅŒๅˆ†ๆฎต่กจ็Žฐ)
{{ detail_item('<1200 Rating', features['elo_lt1200_rating'], 'elo_lt1200_rating') }} {{ detail_item('1200-1400 Rating', features['elo_1200_1400_rating'], 'elo_1200_1400_rating') }} {{ detail_item('1400-1600 Rating', features['elo_1400_1600_rating'], 'elo_1400_1600_rating') }} {{ detail_item('1600-1800 Rating', features['elo_1600_1800_rating'], 'elo_1600_1800_rating') }} {{ detail_item('1800-2000 Rating', features['elo_1800_2000_rating'], 'elo_1800_2000_rating') }} {{ detail_item('>2000 Rating', features['elo_gt2000_rating'], 'elo_gt2000_rating') }}

ๆฏ”่ต›่ฎฐๅฝ• (Match History)

{{ history|length }} Matches
{% for m in history | reverse %} {% else %} {% endfor %}
Date/Map Result Rating K/D ADR Link
{{ m.map_name }}
{{ 'WIN' if m.is_win else 'LOSS' }} {% if m.party_size and m.party_size > 1 %} ๐Ÿ‘ฅ {{ m.party_size }} {% endif %}
{% set r = m.rating or 0 %}
{{ "%.2f"|format(r) }}
{{ "%.2f"|format(m.kd_ratio or 0) }} {{ "%.1f"|format(m.adr or 0) }}
๐Ÿœ๏ธ
No matches recorded yet.

ๅœฐๅ›พๆ•ฐๆฎ (Map Stats)

{% for m in map_stats %}
{{ m.map_name[:3] }}
{{ m.map_name }}
{{ m.matches }} matches
{{ "%.2f"|format(m.rating) }}
{{ "%.0f"|format(m.win_rate * 100) }}% Win {{ "%.1f"|format(m.adr) }} ADR
{% else %}
No map data available.
{% endfor %}

็•™่จ€ๆฟ (Comments)

{% for comment in comments %}
{{ comment.username[:1] | upper }}
{{ comment.username }} {{ comment.created_at }}

{{ comment.content }}

{% else %}
No comments yet.
{% endfor %}
{% endblock %} {% block scripts %} {% endblock %}