
    iiNX                     \   d Z ddlZddlZddlZddlZddlZddlmZm	Z	 ddl
mZmZmZmZ ddlZej                            ej                            e                    Zej                            edd          Zi ddd	d
dddd	d
dddd	d
dddd	d
dddddddddddddddddddddddd d!dd"d#d d!dd$d%d&d'dd(d)d&d'dd*d+d,d-dd.d/d0d1dd2d3d4d5dd6d7d8d9dd:d;d<d=dd>d?d@dAdiZg dBZg dCZg dDZ G dE dF          ZdG ZedHk    r e             dS dS )IaS  
Advanced Data Collector for BetPredictAI

Collects comprehensive football data including:
- Historical match results (extended)
- League standings/tables
- Team statistics
- Head-to-head records
- Goal patterns
- Home/Away performance

Data sources:
- football-data.co.uk (primary, free CSVs)
- OpenLigaDB (Bundesliga fixtures, free API)
    N)datetime	timedelta)DictListTupleOptionalz..dataE0zPremier LeagueEnglandu   🏴󠁧󠁢󠁥󠁮󠁧󠁿)namecountryflagE1ChampionshipE2z
League OneE3z
League TwoD1
BundesligaGermanyu   🇩🇪D2z2. BundesligaI1zSerie AItalyu   🇮🇹I2zSerie BSP1zLa LigaSpainu   🇪🇸SP2z	La Liga 2F1zLigue 1Franceu   🇫🇷F2zLigue 2N1
EredivisieNetherlandsu   🇳🇱B1z
Pro LeagueBelgiumu   🇧🇪P1zPrimeira LigaPortugalu   🇵🇹T1z	Super LigTurkeyu   🇹🇷G1zSuper LeagueGreeceu   🇬🇷SC0PremiershipScotlandu   🏴󠁧󠁢󠁳󠁣󠁴󠁿)
1516161717181819192020212122222323242425)r
   r   r   r   r   )r   r   r    r#   r%   r+   c                      e Zd ZdZd Zd#dededeej	                 fdZ
d$d	ee         d
ee         dej	        fdZdej	        dededej	        fdZdej	        defdZd%dej	        dedej	        fdZdededefdZd%dej	        dedededef
dZdej	        dej	        fdZdej	        defdZdedefdZd&d!efd"ZdS )'AdvancedDataCollectorz2Collects and processes comprehensive football datac                 f    t          j        t          d           g | _        i | _        i | _        d S )NT)exist_ok)osmakedirsDATA_DIRall_matches	standings
team_stats)selfs    ;/var/www/html/bet.cuttalo.com/ml/advanced_data_collector.py__init__zAdvancedDataCollector.__init__B   s1    
Ht,,,,       urlretriesreturnc                     t          |          D ]m}	 t          j        |dd          }|c S # t          $ rC}||dz
  k     rt	          j        d           Y d}~Jt          d| d|            Y d}~ dS d}~ww xY wdS )z,Download CSV with retries and error handlingzutf-8skip)encodingon_bad_lines   Nz  Error downloading : )rangepdread_csv	Exceptiontimesleepprint)rB   rG   rH   attemptdfes         rC   download_csvz"AdvancedDataCollector.download_csvH   s    W~~ 		 		G[wVLLL			   Wq[((JqMMMHHHH7S77A77888tttttt			 		s   .
A;A6A66A;Nleaguesseasonsc           
      &   |t           }|t          }g }|D ]-}t                              |i           }t	          d|                    d|           d|                    dd           d           |D ]}d| d	| d
}t	          d|dd          d|dd          ddd           |                     |          }|`t          |          dk    rM|                     |||          }|                    |           t	          dt          |           d           nt	          d           t          j
        d           ϐ/|r8t          j        |d          }	t	          dt          |	           d           |	S t          j                    S )z!Collect all historical match dataNu   
📊 Collecting r   z (r   Unknown)z(https://www.football-data.co.uk/mmz4281//z.csvz  Season 20   /20rO    T)endflushr   u   ✓  matchesu   ✗ No datag333333?)ignore_indexu   
✓ Total: z matches collected)CORE_LEAGUESSEASONSFOOTBALL_DATA_LEAGUESgetrV   rZ   len_standardize_columnsappendrT   rU   rQ   concat	DataFrame)
rB   r[   r\   all_dataleagueleague_infoseasonrG   rX   combineds
             rC   collect_historical_matchesz0AdvancedDataCollector.collect_historical_matchesU   s   ?"G?G 	  	 F/33FB??Kr{vv'F'Frr+//ZcenJoJorrrsss!    VVV&VVVAF2A2JAA6!"":AAArQUVVVV&&s++>c"ggkk222vvFFBOOB'''2R2223333-(((
3   	y===HC#h--CCCDDDO|~~rE   rX   rr   rt   c                 L   i ddddddddd	d
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1}fd2|                                 D             }                    |3          |d<   d4|d5d6          d7|d6d5          d8<   t                              |i           }|                    d9|          d:<   |                    d;d<          d;<   |                    d=d>          d=<   t	          j        d         d?d@A          d<   S )BzStandardize DataFrame columnsDivleague_codeDatedateHomeTeam	home_teamAwayTeam	away_teamFTHG
home_goalsFTAG
away_goalsFTRresultHTHGht_home_goalsHTAGht_away_goalsHTR	ht_resultHS
home_shotsAS
away_shotsHSThome_shots_targetASTaway_shots_targetHF
home_foulsAF
away_foulsHChome_cornersaway_cornershome_yellowaway_yellowhome_redaway_redodds_home_b365odds_draw_b365odds_away_b365odds_home_bwodds_draw_bwodds_away_bwodds_home_psodds_draw_psodds_away_ps)ACHYAYHRARB365HB365DB365ABWHBWDBWAPSHPSDPSAc                 .    i | ]\  }}|j         v ||S  columns).0kvrX   s      rC   
<dictcomp>z>AdvancedDataCollector._standardize_columns.<locals>.<dictcomp>   s&    OOO1qBJq!rE   r   20Nra   rb   rt   r   league_namer   r^   r   rc   Tcoerce)dayfirsterrors)itemsrenamerj   rk   rQ   to_datetime)rB   rX   rr   rt   col_mappingrename_dictrs   s    `     rC   rm   z*AdvancedDataCollector._standardize_columnsw   s   !
=!
F!
 !
 	!

 L!
 L!
 8!
 O!
 O!
 ;!
 ,!
 ,!
 &!
 &!
 ,!
  ,!!
" .#!
$ !%%%!!!!!!A!
 !
 !
H POOO(9(9(;(;OOOYY{Y++ #=7F2A2J776!"":778+//;;'OOFF;;=#	9==9 __VR006
 ^BvJhOOO6
	rE   c                    i }|d                                          D ]}||d         |k                                             }|d                                          D ]p}||d         |k             }i }|                                D ]\  }}	|	d         }
|	d         }|	                    dd          pd}|	                    dd          pd}|
|fD ]}||vrdddddddd||<   ||
         d	xx         d
z  cc<   ||
         dxx         |z  cc<   ||
         dxx         |z  cc<   ||         d	xx         d
z  cc<   ||         dxx         |z  cc<   ||         dxx         |z  cc<   ||k    rD||
         dxx         d
z  cc<   ||
         dxx         dz  cc<   ||         dxx         d
z  cc<   ,||k     rD||         dxx         d
z  cc<   ||         dxx         dz  cc<   ||
         dxx         d
z  cc<   v||
         dxx         d
z  cc<   ||         dxx         d
z  cc<   ||
         dxx         d
z  cc<   ||         dxx         d
z  cc<   |D ](}||         d         ||         d         z
  ||         d<   )t	          |                                d d          }||d t          |          D             d|| d| <   r|S )z*Calculate league standings from match datary   rt   r}   r   r   r   r   )playedwondrawnlost	goals_forgoals_againstpointsr   rN   r   r   r   r   rF   r   r   	goal_diffc                 T    | d         d         | d         d         | d         d         fS )NrN   r   r   r   r   )xs    rC   <lambda>z;AdvancedDataCollector.calculate_standings.<locals>.<lambda>   s'    1Q4>1Q43Dad;FW"X rE   T)keyreversec                 @    g | ]\  }}|d z   |d         d|d          S )rN   r   )positionteamr   )r   its      rC   
<listcomp>z=AdvancedDataCollector.calculate_standings.<locals>.<listcomp>   s5    jjj$!Q1Q3!EE!EjjjrE   )rr   rt   table_)uniquecopyiterrowsrk   sortedr   	enumerate)rB   rX   r@   rr   	league_dfrt   	season_dfteamsr   matchhomeawayhgagr   sorted_teamss                   rC   calculate_standingsz)AdvancedDataCollector.calculate_standings   s   	'..00 8	 8	F2m,67<<>>I#H-4466 5 5%i&9V&CD	 ) 2 2 4 4 #3 #3HAu -D -D<338qB<338qB!%t  u,,*+A1-.a+ +E$K $K)))Q.)))$K,,,2,,,$K000B6000 $K)))Q.)))$K,,,2,,,$K000B6000BwwdE***a/***dH---2---dF+++q0++++bdE***a/***dH---2---dF+++q0++++dG,,,1,,,dG,,,1,,,dH---2---dH---2---- " g gD/4T{;/G%PT+VeJf/fE$K,,%ekkmmXX  "  "  "
 %$jjR[\hRiRijjj3 3	V..f..//c5n rE      last_n_matchesc           
         g }|                     d                              d          }i }|                                D ]\  }}|d         }|d         }|d         }	|d         }
||fD ]}|
 d| }||vrg g g g g g d||<   |
 d| }|
 d| }|                     ||         |          }|                     ||         |          }|                     ||||	d	
          }|                    d|id |                                D             d |                                D             |           |                    dd          pd}|                    dd          pd}||         d                             |	||d|||k    rdn	||k    rdndd           ||         d                             ||         d         d                    ||         d                             |	||d|||k    rdn	||k    rdndd           ||         d                             ||         d         d                    t          j	        |          }|                    d          }|j
        D ]}|dk    r||         ||<   |S )z0Calculate rolling team statistics for each matchr{   T)dropr}   r   ry   r   )matcheshome_matchesaway_matchesgoals_scoredgoals_concededresultsr   )last_nidxc                      i | ]\  }}d | |S )home_r   r   r   r   s      rC   r   z>AdvancedDataCollector.calculate_team_stats.<locals>.<dictcomp>  $    AAAda;1;;AAArE   c                      i | ]\  }}d | |S )away_r   r   s      rC   r   z>AdvancedDataCollector.calculate_team_stats.<locals>.<dictcomp>  r   rE   r   r   r   r   WDL)r{   r   r   is_homeopponentr   r   Fr   )sort_valuesreset_indexr   _calc_rolling_stats_calc_h2h_statsrn   r   rk   rQ   rp   r   )rB   rX   r   stats_columnsteam_historyr   rowr   r   r{   rr   r   r   home_keyaway_key
home_stats
away_stats	h2h_statsr   r   stats_dfcols                         rC   calculate_team_statsz*AdvancedDataCollector.calculate_team_stats   sS    ^^F##//T/::  7	a 7	aHC{#D{#Dv;D'F t 
 
(($((l**#%(*(*(**,#%) )L% !))4))H ))4))H 11,x2H.YYJ11,x2H.YYJ ,,RtT!,LLI   s"AAj.>.>.@.@AAA" BAj.>.>.@.@AAA" 	"    q)).QBq)).QB "9-442T!#b##bBhhssC6 6   
 ">299,x:PQZ:[\^:_``` "9-442 d!#b##bBhhssC6 6   
 ">299,x:PQZ:[\^:_```` <..^^^&&# 	( 	(Ce||"3-3	rE   historync                    |d         r|d         | d         ng }|d         r|d         | d         ng }|d         r|d         | d         ng }|sdddddddddddddddS t          d |D                       }t          d |D                       }t          d	 |D                       }|d
z  |z   }	t          d |D                       }
t          d |D                       }d}t          |          D ]6}|d         dk    r|dk    r|dz  } n|d         dk    r|dk    r|dz  }4 n |r)t          d |D                       t          |          z  nd}|r)t          d |D                       t          |          z  nd}|r)t          d |D                       t          |          z  nd}|r)t          d |D                       t          |          z  nd}|	t          |          z  |
t          |          z  |t          |          z  |t          |          z  ||||||||t          d |D                       t          d |D                       dS )z.Calculate rolling statistics from team historyr   Nr   r   r   )form_ppgform_gpg	form_gapgform_win_ratehome_ppghome_gpgaway_ppgaway_gpg	form_wins
form_drawsform_lossesstreakclean_sheetsfailed_to_scorec              3   2   K   | ]}|d          dk    dV  dS )r   r   rN   Nr   r   ms     rC   	<genexpr>z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>K  s0      <<8););1););););<<rE   c              3   2   K   | ]}|d          dk    dV  dS )r   r   rN   Nr   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>L  s0      ==!!H+*<*<A*<*<*<*<==rE   c              3   2   K   | ]}|d          dk    dV  dS )r   r  rN   Nr   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>M  s0      >>11X;#+=+=Q+=+=+=+=>>rE   rF   c              3   &   K   | ]}|d          V  dS r   Nr   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>O  s&      881+888888rE   c              3   &   K   | ]}|d          V  dS )r   Nr   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>P  s'      @@1Ao.@@@@@@rE   r   r   rN   r  c              3   R   K   | ]"}|d          dk    rdn|d          dk    rdndV  #dS r   r   rF   r   rN   r   Nr   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>c  H      kkYZAhK3..qq!H+:L:LQQRSkkkkkkrE   c              3   &   K   | ]}|d          V  dS r,  r   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>d  &      <<!q~<<<<<<rE   c              3   R   K   | ]"}|d          dk    rdn|d          dk    rdndV  #dS r/  r   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>e  r0  rE   c              3   &   K   | ]}|d          V  dS r,  r   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>f  r2  rE   c              3   2   K   | ]}|d          dk    dV  dS )r   r   rN   Nr   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>u  s1      NNaa6HA6M6M6M6M6M6MNNrE   c              3   2   K   | ]}|d          dk    dV  dS )r   r   rN   Nr   r&  s     rC   r(  z<AdvancedDataCollector._calc_rolling_stats.<locals>.<genexpr>v  s0      "M"M;19L9L19L9L9L9L"M"MrE   )sumreversedrl   )rB   r  r  r   r   r   winsdrawslossesr   r   r   r"  r'  r  r  r  r  s                     rC   r  z)AdvancedDataCollector._calc_rolling_stats<  s5   -4Y-?G')$aRSS))R7>~7NVw~.rss33TV7>~7NVw~.rss33TV 	11q1!aQ1	   <<g<<<<<==w=====>>>>>>>E!8888888	@@@@@@@ '"" 	 	A{c!!Q;;aKFFE8##Q;;aKFFE DP  W3kk^jkkkkknqr~nn  VWT`g3<<|<<<<<s<?P?PPPfg DP  W3kk^jkkkkknqr~nn  VWT`g3<<|<<<<<s<?P?PPPfg W-!CLL0&W5!CLL0    !NN7NNNNN""M"Mg"M"M"MMM
 
 	
rE   r   r   r   c                    ||d         |k    |d         |k    z  |d         |k    |d         |k    z  z  |d         |k     z                                |          }t          |          dk    r
ddddddddS d}d}d}	d}
d}|                                D ]\  }}|                    dd          pd}|                    dd          pd}|d         |k    r(|
|z  }
||z  }||k    r|dz  }W||k     r|dz  }c|	dz  }	i|
|z  }
||z  }||k    r|dz  }||k     r|dz  }|	dz  }	t          |          }||dk    r||z  nd|dk    r|	|z  nd|dk    r||z  nd|dk    r|
|z  nd|dk    r||z  nd|dk    r|
|z   |z  nddS )	z!Calculate head-to-head statisticsr}   r   r{   r   )h2h_matchesh2h_home_wins	h2h_drawsh2h_away_winsh2h_home_goalsh2h_away_goalsh2h_total_goalsr   r   rN   )tailrl   r   rk   )rB   rX   r   r   before_dater   r=  	home_wins	away_winsr:  r   r   r   r   r   r   r  s                    rC   r  z%AdvancedDataCollector._calc_h2h_statsy  s<   +$&2k?d+BC+$&2k?d+BCEZ+%'
 $v,,	 	 {q   11WX"#qQ  
 		

#,,.. 	 	HAu<++0qB<++0qB[!T))b 
b 
77NII"WWNIIQJEEb 
b 
77NII"WWNIIQJEE./!eeY]]&'!ee./!eeY]]01Aj1nn101Aj1nn1@AA
Z 71<<1
 
 	
rE   c                    dD ]}d| }d| }d| }t          fd|||fD                       rd|                             dt          j                  z  d| <   d|                             dt          j                  z  d	| <   d|                             dt          j                  z  d
| <   d|          d	|          z   d
|          z   }d|          |z  d| <   d	|          |z  d	| <   d
|          |z  d
| <   d j        D             }d j        D             }d j        D             }	|r]|                             d          d<   |                             d          d<   |	                             d          d<   dj        v rdj        v rxd         d         z
  d<   d         d         z
  d<   d         d         z
  d<   d         d         z
  d<   d         d         z
  d <   d!         d"         z
  d#<   d$j        v rtd$                             d          d%                             d          z   d&<   d$                             d          d%                             d          z
  d'<   d(                             d)ddd*          d+<   S ),z(Calculate advanced features for ML model)b365bwps
odds_home_
odds_draw_
odds_away_c              3   *   K   | ]}|j         v V  d S )Nr   )r   r  rX   s     rC   r(  zDAdvancedDataCollector.calculate_advanced_features.<locals>.<genexpr>  s*      FF3"*$FFFFFFrE   rN   r   
impl_home_
impl_draw_
impl_away_c                 <    g | ]}|                     d           |S )rP  
startswithr   cs     rC   r   zEAdvancedDataCollector.calculate_advanced_features.<locals>.<listcomp>  )    NNN1<<3M3MN!NNNrE   c                 <    g | ]}|                     d           |S )rQ  rT  rV  s     rC   r   zEAdvancedDataCollector.calculate_advanced_features.<locals>.<listcomp>  rX  rE   c                 <    g | ]}|                     d           |S )rR  rT  rV  s     rC   r   zEAdvancedDataCollector.calculate_advanced_features.<locals>.<listcomp>  rX  rE   )axis	impl_home	impl_draw	impl_awayhome_form_ppgaway_form_ppgppg_diffhome_form_gpgaway_form_gpgattack_diffaway_form_gapghome_form_gapgdefense_diffhome_form_win_rateaway_form_win_ratewin_rate_diffhome_home_ppgaway_away_ppghome_home_vs_away_awayhome_streakaway_streakstreak_diffr   r   total_goalsr   r   ra   )Hr   Aresult_code)allreplacenpnanr   meanfillnamap)
rB   rX   	bookmakerh_cold_cola_coltotalimpl_home_colsimpl_draw_colsimpl_away_colss
    `        rC   calculate_advanced_featuresz1AdvancedDataCollector.calculate_advanced_features  s    . 	T 	TI,,,E,,,E,,,EFFFFu0EFFFFF 	T/02e93D3DQ3O3O/O+	++,/02e93D3DQ3O3O/O+	++,/02e93D3DQ3O3O/O+	++, 3	334r:Ry:R:R7SSVXYqfoYqYqVrr/12Jy2J2J/Ke/S+	++,/12Jy2J2J/Ke/S+	++,/12Jy2J2J/Ke/S+	++, ONRZNNNNNRZNNNNNRZNNN 	> 05515==B{O 05515==B{O 05515==B{O bj((_
-J-J02o3FFBzN "? 3b6I IB}!#$4!5;K8L!LB~"$%9":R@T=U"UB ,.o+>OAT+TB'( !#= 1B}4E EB} 2:%% "< 0 7 7 : :R=M=T=TUV=W=W WB} .55a882l;K;R;RST;U;UUB{O xL,,111-E-EFF=	rE   filenamec                     t           j                            t          |          }|                    |d           t          dt          |           d|            dS )zSave DataFrame to CSVF)indexu
   ✓ Saved z records to N)r<   pathjoinr>   to_csvrV   rl   )rB   rX   r  r  s       rC   	save_datazAdvancedDataCollector.save_data  sX    w||Hh//
		$e	$$$:3r77::::;;;;;rE   r@   c                    t           j                            t          |          }t	          |d          5 }t          j        ||dt                     ddd           n# 1 swxY w Y   t          dt          |           d|            dS )zSave standings to JSONwra   )indentdefaultNu   ✓ Saved standings for z league-seasons to )
r<   r  r  r>   openjsondumpstrrV   rl   )rB   r@   r  r  fs        rC   save_standingsz$AdvancedDataCollector.save_standings  s    w||Hh//$__ 	;Ii1c::::	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	;VYVVHVVWWWWWs   A  A$'A$Fextendedc           
         t          d           t          d           t          d           t          |rt          ng z   }t          d           t          d           |                     |t                    }t          |          dk    rt          d           dS t          d           t          d           |                     |d	
          }t          dt          |           d           t          d           t          d           |                     |          }t          dt          |j                   d           t          d           t          d           | 	                    |          }t          dt          |           d           t          d           t          d           | 
                    |d           |                     |d           t          d           t          d           t          d           t          dt          |          d           t          dt          |d                                                               t          dt          |d                                                               t          dt          t          |d                                                   t          |d                                                    z                        t          d!t          |j                              d" |j        D             }t          d#t          |                      |S )$z%Run complete data collection pipelinez<============================================================u,   🚀 BetPredictAI - Advanced Data Collectionu,   
📥 Phase 1: Collecting Historical Matchesz(----------------------------------------r   u   ❌ No data collected!Nu*   
📊 Phase 2: Calculating Team Statisticsr   )r   u!   ✓ Calculated rolling stats for rf   u,   
🧮 Phase 3: Calculating Advanced Featuresu   ✓ Added advanced features (z total columns)u$   
🏆 Phase 4: Calculating Standingsu   ✓ Calculated standings for z league-seasonsu   
💾 Phase 5: Saving Datazadvanced_historical_matches.csvzstandings.jsonz=
============================================================u   ✅ DATA COLLECTION COMPLETEz  Total matches: ,z  Leagues: ry   z  Seasons: rt   z	  Teams: r}   r   z  Features: c                 <    g | ]}|                     d           |S ))r   r   h2h_impl_ppg_attack_defense_rT  rV  s     rC   r   z=AdvancedDataCollector.run_full_collection.<locals>.<listcomp>%  sH      C  C  Ca  ?A  2B  2B  C  C  C  CrE   z
  ML Features available: )rV   rh   EXTENDED_LEAGUESrv   ri   rl   r  r  r   r   r  r  r   set)rB   r  r[   rX   r@   feature_colss         rC   run_full_collectionz)AdvancedDataCollector.run_full_collection  s0   f<===fh"F"2"2BG 	=>>>f,,Wg>>r77a<<*+++F 	;<<<f&&r!&<<C#b''CCCDDD 	=>>>f--b11Nc"*ooNNNOOO 	5666f,,R00	Mc)nnMMMNNN 	+,,,fr<===I'7888 	m,---f-#b''---...=C= 1 8 8 : :;;==>>>8C8 3 3 5 56688999^#c"[/"8"8":":;;c"[/BXBXBZBZ>[>[[\\^^___.S__../// C  C2:  C  C  C?C,=,=??@@@	rE   )rF   )NN)r   )F)__name__
__module____qualname____doc__rD   r  intr   rQ   rp   rZ   r   rv   rm   r   r   r  r  r  r  r  r  boolr  r   rE   rC   r9   r9   ?   s1       <<    c (2<:P       $s)  TRUY  bdbn        D6r| 6S 6# 6RTR^ 6 6 6 6p>bl >t > > > >@K Kr| KS KQSQ] K K K KZ;
4 ;
C ;
D ;
 ;
 ;
 ;
z4
 4
", 4
c 4
 4
[^ 4
gk 4
 4
 4
 4
l3bl 3r| 3 3 3 3j<BL <C < < < <X X X X X X7 7D 7 7 7 7 7 7rE   r9   c                      t                      } |                     d          Lt          d           g d}fd|D             }|r+t          |                                                    d S d S d S )NT)r  u   
📋 Sample Features:)r_  r`  r>  r\  ra  c                 &    g | ]}|j         v |S r   r   )r   rW  rX   s     rC   r   zmain.<locals>.<listcomp>5  s     @@@1RZQrE   )r9   r  rV   describe)	collectorr  	availablerX   s      @rC   mainr  +  s    %''I 
	&	&	&	5	5B	~'(((ccc@@@@@@@	 	,"Y-((**+++++ ~
	, 	,rE   __main__)r  r<   r  pandasrQ   numpyrw  requestsr   r   typingr   r   r   r   rT   r  dirnameabspath__file__BASE_DIRr  r>   rj   ri   rh   r  r9   r  r  r   rE   rC   <module>r     s     
			           ( ( ( ( ( ( ( ( . . . . . . . . . . . .  7??27??844557<<$//#	Ca
b
b>iA_
`
` 	<I?]
^
^ 	<I?]
^
^	
 	<Iz
J
J 	?y*
M
M 	9*
E
E 	9*
E
E 
I':FF 
KGZHH 	9:
F
F 	9:
F
F 	<M:
N
N 	<Iz
J
J 	?z:
N
N  	;8Z
H
H!" 	>h

K
K#$ 
MjB`aa%  , [
Z
Z /.. 988 i i i i i i i iX, , , zDFFFFF rE   