
    d*\                        d Z ddlmZ ddlmZ ddl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mZ ddlZddlZddlZddlmZ ej        dk    rddlmZ nddlmZ 	 dd	lmZ n# e$ r	 dd	lmZ Y nw xY w ed
          Z ed          Zd ZddddddZ d e !                                D             Z"g dZ#g dZ$g dZ%d Z&d Z'd Z(d Z)	 	 	 	 	 d#dZ*deeef         fdZ+d$d Z,d%d!Z-d" Z.dS )&z
Utility routines
    )Mapping)deepcopyN)CallableTypeVarAny)
SchemaBase)   
   )	ParamSpec)infer_dtype_V_Pc                     t          t          d          s<	 t          dgd           dt          _        n# t          $ r dt          _        Y nw xY wt          j        rt          | d          S t          |           S )zInfer the dtype of the value.

    This is a compatibility function for pandas infer_dtype,
    with skipna=False regardless of the pandas version.
    _supports_skipna   F)skipnaT)hasattrr   _infer_dtyper   	TypeError)values    1lib/python3.11/site-packages/altair/utils/core.pyr   r   #   s     ; 233 0	0!U++++
 ,0K((	  	1 	1 	1+0K(((	1
 # #E%0000E"""s   6 AAONQTG)ordinalnominalquantitativetemporalgeojsonc                     i | ]\  }}||	S  r#   ).0kvs      r   
<dictcomp>r'   ?   s    :::TQAq:::    )argmaxargminaveragecountdistinctmaxmeanmedianminmissingproductq1q3ci0ci1stderrstdevstdevpsumvalidvaluesvariance	variancep)
row_numberrank
dense_rankpercent_rank	cume_distntilelagleadfirst_value
last_value	nth_value)Pyearquartermonthweekday	dayofyeardatehoursminutessecondsmillisecondsyearquarteryearquartermonth	yearmonthyearmonthdateyearmonthdatehoursyearmonthdatehoursminutes yearmonthdatehoursminutessecondsyearweekyearweekdayyearweekdayhoursyearweekdayhoursminutesyearweekdayhoursminutessecondsyeardayofyearquartermonth	monthdatemonthdatehoursmonthdatehoursminutesmonthdatehoursminutessecondsweekdayweeksdayhoursweekdayhoursminutesweekdayhoursminutessecondsdayhoursdayhoursminutesdayhoursminutessecondshoursminuteshoursminutessecondsminutessecondssecondsmillisecondsutcyear
utcquarterutcmonthutcweekutcdayutcdayofyearutcdateutchours
utcminutes
utcsecondsutcmillisecondsutcyearquarterutcyearquartermonthutcyearmonthutcyearmonthdateutcyearmonthdatehoursutcyearmonthdatehoursminutes#utcyearmonthdatehoursminutessecondsutcyearweekutcyearweekdayutcyearweekdayhoursutcyearweekdayhoursminutes!utcyearweekdayhoursminutessecondsutcyeardayofyearutcquartermonthutcmonthdateutcmonthdatehoursutcmonthdatehoursminutesutcmonthdatehoursminutesseconds
utcweekdayutcweeksdayhoursutcweekdayhoursminutesutcweekdayhoursminutessecondsutcdayhoursutcdayhoursminutesutcdayhoursminutessecondsutchoursminutesutchoursminutessecondsutcminutessecondsutcsecondsmillisecondsc                     t          |           }|dv rdS |dk    r,| j        j        r d| j        j                                        fS |dv rdS |dv rdS t          j        d	                    |          d
           dS )z
    From an array-like input, infer the correct vega typecode
    ('ordinal', 'nominal', 'quantitative', or 'temporal')

    Parameters
    ----------
    data: Numpy array or Pandas Series
    )floatingzmixed-integer-floatintegerzmixed-integercomplexr   categoricalr   )stringbytesr   booleanmixedunicoder   )datetime
datetime64	timedeltatimedelta64rQ   timeperiodr    zJI don't know how to infer vegalite type from '{}'.  Defaulting to nominal.r   
stacklevel)r   catordered
categoriestolistwarningswarnformat)datatyps     r   infer_vegalite_typer      s     d

C
    ~			$("2	48.557788	Q	Q	Qy	  
 
 z%%+VC[[	
 	
 	
 	

 yr(   c                       fddD             }	  d                              |            d         }n# t          t          f$ r |}Y nw xY w|S )zc
    Merge properties with geometry
    * Overwrites 'type' and 'geometry' entries if existing
    c                 "    i | ]}||         S r#   r#   )r$   r%   feats     r   r'   z$merge_props_geom.<locals>.<dictcomp>   s    5551AtAw555r(   typegeometry
properties)updateAttributeErrorKeyError)r   geom
props_geoms   `  r   merge_props_geomr      s|     6555 4555D\!!$''','

H%    



 s   #5 A
Ac                 ,   t          |           } |                                 D ]Y}t          t          | |                   j                                      d          r| |                                         | |<   Zt          j        t          j	        |                     } | d         dk    rC| d         } t          |           dk    r't          |           D ]\  }}t          |          | |<   n!| d         dk    rt          |           } nd| d} | S )zSantize a geo_interface to prepare it for serialization.

    * Make a copy
    * Convert type array or _Array to list
    * Convert tuples to lists (using json.loads/dumps)
    * Merge properties with geometry
    )_Arrayarrayr   FeatureCollectionfeaturesr   Featurer   )r   keysstrr   __name__
startswithr   jsonloadsdumpslen	enumerater   )geokeyidxr   s       r   sanitize_geo_interfacer      s    3--C xxzz ) )tCH~~&''223FGG 	)3x((CH *TZ__
%
%C 6{)))*os88a<<&s^^ 2 2	T+D11C	V		!	!s## c22Jr(   c                 T	   |                                  } t          | j        t          j                  r$| j                            t                    | _        | j        D ]9}t          |t                    s"t          d                    |                    :t          | j	        t          j
                  rt          d          t          | j        t          j
                  rt          d          d }| j                                        D ]\  }}t          |          dk    rL| |                             t                    }|                    |                                d          | |<   et          |          dk    rL| |                             t                    }|                    |                                d          | |<   t          |          dk    r$| |                             t                    | |<   t          |          dk    rM| |                             t                    }|                    |                                d          | |<   [t          |                              d	          r5| |                             d
                               dd          | |<   t          |                              d          r$t          d                    ||                    t          |                              d          rt          |          dv rM| |                             t                    }|                    |                                d          | |<   zt'          j        |t&          j                  r%| |                             t                    | |<   t'          j        |t&          j                  re| |         }|                                t'          j        |          z  }|                    t                                        | d          | |<   B|t          k    rH| |                             |d          }|                    |                                d          | |<   | S )a  Sanitize a DataFrame to prepare it for serialization.

    * Make a copy
    * Convert RangeIndex columns to strings
    * Raise ValueError if column names are not strings
    * Raise ValueError if it has a hierarchical index.
    * Convert categoricals to strings.
    * Convert np.bool_ dtypes to Python bool objects
    * Convert np.int dtypes to Python int objects
    * Convert floats to objects and replace NaNs/infs with None.
    * Convert DateTime dtypes into appropriate string representations
    * Convert Nullable integers to objects and replace NaN with None
    * Convert Nullable boolean to objects and replace NaN with None
    * convert dedicated string column to objects and replace NaN with None
    * Raise a ValueError for TimeDelta dtypes
    zKDataframe contains invalid column name: {0!r}. Column names must be stringsz"Hierarchical indices not supportedc                 b    t          | t          j                  r|                                 S | S N)
isinstancenpndarrayr   )vals    r   to_list_if_arrayz,sanitize_dataframe.<locals>.to_list_if_arrayA  s)    c2:&& 	::<<Jr(   categoryNr   boolr   r   c                 *    |                                  S r   )	isoformat)xs    r   <lambda>z$sanitize_dataframe.<locals>.<lambda>c  s    Q[[]] r(   NaT r   zField "{col_name}" has type "{dtype}" which is not supported by Altair. Please convert to either a timestamp or a numerical value.)col_namedtyper   >
   Int8Int16Int32Int64UInt8UInt16UInt32UInt64Float32Float64F)convert_dtype)copyr   columnspd
RangeIndexastyper   
ValueErrorr   index
MultiIndexdtypesitemsobjectwherenotnullr   applyreplacer   
issubdtyper   r   isnullisinf)dfcolr   r   r   
bad_valuess         r   sanitize_dataframer	    s   " 
B"*bm,, ,Z&&s++
z  #s## 	//5vc{{  	 "(BM** ?=>>>"*bm,, ?=>>>   9??,, E: E:%u::## X,%%f--C99S[[]]D99BxLLZZ8## X,%%f--C99S[[]]D99BxLLZZ6!!h<..v66BxLLZZ9$$ X,%%f--C99S[[]]D99BxLLZZ"":.. 1	: 8""#:#:;;CCE2NN xLL ZZ"";// '	: 685699	   ZZ"":..  	: ZZ 
 
 
 X,%%f--C99S[[]]D99BxLL]5"*-- 	:h<..v66BxLL]5"+.. 
	: X,C5J::f--33ZKFFBxLLf__ X,$$%5U$KKC99S[[]]D99BxLIr(   TFc                 B   
  si S t          t                    t          t                    z   }dd                    d                    |                    ddd                    d                    t
                              d                    d                    t
          t          z                       d                    d                    t                              d	
g }|r,|                    d
g           |                    dg           |r,|                    dg           |                    dg           |r|                    dg           |                    dg           |r%t          t          j
        d |D                        }
fd|D             }t           t                    r }	nt           fd|D                       }	d|	v r*t                              |	d         |	d                   |	d<   |	ddik    rd|	d<   d|	v r	d|	vrd|	d<   t          |t          j                  rd|	vrd|	v r|	d                             dd          |j        v rot'          ||	d                             dd                             |	d<   t          |	d         t(                    r"|	d         d         |	d<   |	d         d         |	d<   d|	v rd|	d         v r|	d         |	d                             d          dz
           dk    rt-          d                     |	d                             d          d!                   d"                    d#                    t                                                              z   d$z   d%z   d&z             |	S )'a<	  General tool to parse shorthand values

    These are of the form:

    - "col_name"
    - "col_name:O"
    - "average(col_name)"
    - "average(col_name):O"

    Optionally, a dataframe may be supplied, from which the type
    will be inferred if not specified in the shorthand.

    Parameters
    ----------
    shorthand : dict or string
        The shorthand representation to be parsed
    data : DataFrame, optional
        If specified and of type DataFrame, then use these values to infer the
        column type if not provided by the shorthand.
    parse_aggregates : boolean
        If True (default), then parse aggregate functions within the shorthand.
    parse_window_ops : boolean
        If True then parse window operations within the shorthand (default:False)
    parse_timeunits : boolean
        If True (default), then parse timeUnits from within the shorthand
    parse_types : boolean
        If True (default), then parse typecodes within the shorthand

    Returns
    -------
    attrs : dict
        a dictionary of attributes extracted from the shorthand

    Examples
    --------
    >>> data = pd.DataFrame({'foo': ['A', 'B', 'A', 'B'],
    ...                      'bar': [1, 2, 3, 4]})

    >>> parse_shorthand('name') == {'field': 'name'}
    True

    >>> parse_shorthand('name:Q') == {'field': 'name', 'type': 'quantitative'}
    True

    >>> parse_shorthand('average(col)') == {'aggregate': 'average', 'field': 'col'}
    True

    >>> parse_shorthand('foo:O') == {'field': 'foo', 'type': 'ordinal'}
    True

    >>> parse_shorthand('min(foo):Q') == {'aggregate': 'min', 'field': 'foo', 'type': 'quantitative'}
    True

    >>> parse_shorthand('month(col)') == {'field': 'col', 'timeUnit': 'month', 'type': 'temporal'}
    True

    >>> parse_shorthand('year(col):O') == {'field': 'col', 'timeUnit': 'year', 'type': 'ordinal'}
    True

    >>> parse_shorthand('foo', data) == {'field': 'foo', 'type': 'nominal'}
    True

    >>> parse_shorthand('bar', data) == {'field': 'bar', 'type': 'quantitative'}
    True

    >>> parse_shorthand('bar:O', data) == {'field': 'bar', 'type': 'ordinal'}
    True

    >>> parse_shorthand('sum(bar)', data) == {'aggregate': 'sum', 'field': 'bar', 'type': 'quantitative'}
    True

    >>> parse_shorthand('count()', data) == {'aggregate': 'count', 'type': 'quantitative'}
    True
    z(?P<field>.*)z(?P<type>{})|z(?P<aggregate>count)z(?P<op>count)z(?P<aggregate>{})z
(?P<op>{})z(?P<timeUnit>{}))fieldr   	agg_countop_count	aggregate	window_optimeUnitz{agg_count}\(\)z{aggregate}\({field}\)z{op_count}\(\)z{window_op}\({field}\)z{timeUnit}\({field}\)z{field}c              3   $   K   | ]}|d z   |fV  dS )z:{type}Nr#   )r$   ps     r   	<genexpr>z"parse_shorthand.<locals>.<genexpr>  s+      )O)O1y=!*<)O)O)O)O)O)Or(   c           	   3   x   K   | ]4}t          j        d  |j        di z   dz   t           j                  V  5dS )z\Az\ZNr#   )recompiler   DOTALL)r$   r  unitss     r   r  z"parse_shorthand.<locals>.<genexpr>  s^        EF
5818,,e,,,u4bi@@     r(   c              3      K   | ]@}|                               |                                                               V  Ad S r   )match	groupdict)r$   exp	shorthands     r   r  z"parse_shorthand.<locals>.<genexpr>	  s`       
 
14399YCWCW
IIi  **,,
 
 
 
 
 
r(   r   r  r,   r   r  r    r  \r   r   sortr   :z"{}" z0is not one of the valid encoding data types: {}.z, zi
For more details, see https://altair-viz.github.io/user_guide/encodings/index.html#encoding-data-types. z>If you are trying to use a column name that contains a colon, zPprefix it with a backslash; for example "column\:name" instead of "column:name".)listTYPECODE_MAPINV_TYPECODE_MAPr   join
AGGREGATESWINDOW_AGGREGATES	TIMEUNITSextend	itertoolschainr   dictnextgetr   	DataFramer  r   r   tuplerfindr   splitr=   )r  r   parse_aggregatesparse_window_opsparse_timeunitsparse_typesvalid_typecodespatternsregexpsattrsr  s   `         @r   parse_shorthandr<    s   d  	<((40@+A+AAO !%%chh&?&?@@+#(//0D0DEE!((*?P2P)Q)QRR&--chhy.A.ABB E H 5+,---23444 5*+,,,23444 412333OOZL!!! R	)O)Oh)O)O)OPQQ   JR  G
 )T"" 
 
 
 
 
8?
 
 
 
 

 (,,U6]E&MJJf g&&&&f UvU22"f $%% 1&*=*=eg 6 6tR @ @DL P P/U7^5K5KDRT5U5U0VWWE&M%-// 1 %fa 0f %fa 0f
 	55>!!'N5>//44q89TAANN5>//44R899@GG		,--//00  {	{
 OO bb
 
 	
 Lr(   Objc                 n     dt           dt          f         dt           t          t          f         f fd}|S )zEApply call signature and documentation of Obj to the decorated methodf.returnc                 @   j         | _        | _        j        rj                                        }dj         d|d<   | j        r&| j        d                    |dd                    z   }nd                    |          }	 || _        n# t          $ r Y nw xY w| S )NzRefer to :class:``r   
r   )__init____wrapped___uses_signature__doc__
splitlinesr   r&  r   )r?  doclinesdocr=  s      r   decoratezuse_signature.<locals>.decorate9  s      ; 	 {--//H=cl===HQKy *i$))HQRRL"9"99ii))		!    s   B 
BB)r   r   r   )r=  rK  s   ` r   use_signaturerL  6  sH    HS"W% (2r6*:      2 Or(   c                    |rt          |           } |                                D ]d\  }}t          |t                    rE|                     |i           }t          |t                    rt          ||          | |<   Y|| |<   _|| |<   e| S )a  Update nested dictionaries

    Parameters
    ----------
    original : dict
        the original (nested) dictionary, which will be updated in-place
    update : dict
        the nested dictionary of updates
    copy : bool, default False
        if True, then copy the original dictionary rather than modifying it

    Returns
    -------
    original : dict
        a reference to the (modified) original dict

    Examples
    --------
    >>> original = {'x': {'b': 2, 'c': 4}}
    >>> update = {'x': {'b': 5, 'd': 6}, 'y': 40}
    >>> update_nested(original, update)  # doctest: +SKIP
    {'x': {'b': 5, 'c': 4, 'd': 6}, 'y': 40}
    >>> original  # doctest: +SKIP
    {'x': {'b': 5, 'c': 4, 'd': 6}, 'y': 40}
    )r   r   r   r   r/  update_nested)originalr   r   r   r   orig_vals         r   rN  rN  U  s    4  &H%%LLNN    Sc7## 	 ||C,,H(G,, $ -h < < #HSMMOr(   c                     t          j                    }| rddlm}  |            }nd }||                    |           d S t          j        |  d S )Nr   )get_ipython)sysexc_infoIPython.core.getipythonrR  showtraceback	tracebackprint_exception)
in_ipythonrT  rR  ips       r   display_tracebackr[  }  sl    |~~H 777777[]]	~
"""""!8,,,,r(   c                    fdt                    D             }d |D             }d |D             }i |                                D ]\\  }}                    |i           }|j                            d          rd}n|j                            d          rd}nd}|||<   ]| D ]}	t          |	t          t          f          r)t          |	          d	k    rt          |	d	                   }
nt          |	          }
|
                    |
d
          }|"t          d                    |
                    ||v r"t          d                    |                    |	||<   fdfd|                                D             S )a  Infer typed keyword arguments for args and kwargs

    Parameters
    ----------
    args : tuple
        List of function args
    kwargs : dict
        Dict of function kwargs
    channels : module
        The module containing all altair encoding channel classes.

    Returns
    -------
    kwargs : dict
        All args and kwargs in a single dict, with keys and types
        based on the channels mapping.
    c              3   8   K   | ]}t          |          V  d S r   )getattr)r$   namechannelss     r   r  z'infer_encoding_types.<locals>.<genexpr>  s-      FFGHd++FFFFFFr(   c              3   n   K   | ]0}t          |t                    t          |t                    ,|V  1d S r   )r   r   
issubclassr   r$   cs     r   r  z'infer_encoding_types.<locals>.<genexpr>  sW        :a#6#6;Ea;T;T	     r(   c                     i | ]
}||j         S r#   )_encoding_namerc  s     r   r'   z(infer_encoding_types.<locals>.<dictcomp>  s    AAAqq!*AAAr(   DatumdatumValuer   r  r   Nzpositional of type {}zencoding {} specified twice.c                    t          | t                    r| S t          | t                    rd| i} t          | t          t          f          rfd| D             S vr+t          j        d                              d           | S          }d| v r|d         n|d         }	 |                    | d	          S # t          j
        $ r | cY S w xY w)
Nr  c                 (    g | ]} |          S r#   r#   )r$   subobj_wrap_in_channel_classencodings     r   
<listcomp>zHinfer_encoding_types.<locals>._wrap_in_channel_class.<locals>.<listcomp>  s'    OOO**68<<OOOr(   z"Unrecognized encoding channel '{}'r   r   r   r  F)validate)r   r   r   r#  r1  r   r   r   	from_dict
jsonschemaValidationError)objrn  classesclsrm  name_to_channels    `  r   rm  z4infer_encoding_types.<locals>._wrap_in_channel_class  s   c:&& 	Jc3 	%$CcD%=)) 	POOOOO3OOOO?**M4;;HEERS    J!(+")S..gggg6F	 ==u=555) 	 	 	JJJ	s   *C CCc                 0    i | ]\  }}| ||          S r#   r#   )r$   rn  rt  rm  s      r   r'   z(infer_encoding_types.<locals>.<dictcomp>  s=       Hc 	((h77  r(   )dirr   
setdefaultr   endswithr   r#  r1  r   r   r/  NotImplementedErrorr   r   )argskwargsr`  channel_objschannel_to_namechanr_  chansr   argtype_rn  rm  rw  s     `         @@r   infer_encoding_typesr    s   ( GFFFHFFFL   L BALAAAOO%++--  
d**444=!!'** 	CC]##G,, 	CCCc

   cD%=)) 	c#hhllQLLEEIIE"&&ud33%&@&G&G&N&NOOOv;BB8LLMMMx     6   #\\^^   r(   )NTFTT)F)T)/rG  collections.abcr   r   r   r   r+  r  rS  rW  r   typingr   r   r   rr  pandasr   numpyr   altair.utils.schemapir   version_infor   typing_extensionspandas.api.typesr   r   ImportError
pandas.libr   r   r$  r   r%  r'  r(  r)  r   r   r   r	  r<  rL  rN  r[  r  r#   r(   r   <module>r     s    $ # # # # #            				 



      ) ) ) ) ) ) ) ) ) )             , , , , , ,w       ++++++7<<<<<<< 7 7 7666666667 WT]]Yt__# # #*   ;:\%7%7%9%9:::   
6   Q Q Q	h( ( (V  $  Bn n nf 
c c c cLxC(    >% % % %P- - - - P P P P Ps   A# #A10A1