a
    ~by                  %   @   sz  d dl mZmZ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
m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mZ d dlmZ d dlmZmZmZ d d	lmZ d d
lmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' d dl(m)Z)m*Z*m+Z+ d dl,m-Z-m.Z.m/Z/ d dl0m1Z1 d dl2m3Z3 zd dl4m5Z5 W n   i Z5Y n0 ddl6m7Z7 ddl8m9Z9 ddl:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZD ddlEmFZFmGZG ddlHmIZI e;ejJZKejLejLejLejMejMejNejNejNejOejOejOejPejPejPejQejQejRejSejSejSejTejUejVejVejVejWejXejYejZej[ej\ej]ej^ej_ej`ejad$Zbdd Zcdd Zddd Zedd Zfd d! Zgdad"d#Zhed$d% Zid&d' Zjd(d) Zkd*d+ Zldbd.d/Zmd0d1 Zndcd4d5Zod6d7 Zpd8d9 Zqddd;d<Zrd=d> Zsded?d@ZtdAdB ZudCdD ZvedfdEdFZwdGdH ZxdIdJ ZydKdL ZzG dMdN dNe{Z|dOdP Z}dQdR Z~g fdSdTZdUdV ZdWdX ZdYdZ Zd[d\ Zd]d^ Zd_d` ZdS )g    )absolute_importdivisionunicode_literalsN)FunctionType)defaultdict)contextmanager)serialize_jsonsilence)	WidgetBoxRowColumn)tools)
Model
ToolbarBoxFactorRangeRange1dPlotSpacerCustomJSGridBoxDatetimeAxisCategoricalAxis)FuncTickFormatterTickFormatterPrintfTickFormatter)	DataTableTabsDiv)Figure)Theme)built_in_themes   )	NdMapping)Overlay)
LooseVersion_getargspec
basestringcallable_namecftime_typescftime_to_timestamppdunique_array	isnumericarraylike_types)get_nested_dmaps
DynamicMap   )dim_axis_label)$ZpanZxpanZypanZ
xwheel_panZ
ywheel_panZ
wheel_zoomZxwheel_zoomZywheel_zoomZzoom_inZxzoom_inZyzoom_inZzoom_outZ	xzoom_outZ	yzoom_outZclickZtapZ	crosshairZ
box_selectZxbox_selectZybox_selectZpoly_selectZlasso_selectZbox_zoomZ	xbox_zoomZ	ybox_zoomZhoverZsaveZundoZredoresethelpZbox_editZ
point_drawZ	poly_drawZ	poly_editZfreehand_drawc                 C   s"   t j| d }t|jddS )z3
    Converts bokehJS timestamp to datetime64.
         @@N)Ztzinfo)dtdatetimeZutcfromtimestampnp
datetime64replace)Z	timestampr7    r;   <lib/python3.9/site-packages/holoviews/plotting/bokeh/util.pyconvert_timestampY   s    r=   c                 C   s&   | du p$t | to$d| v o$| d du S )z+
    Checks if property value is None.
    Nvalue)
isinstancedict)r>   r;   r;   r<   prop_is_nonea   s    
rA   c                 C   sh   t jjdks*t| r*t| tr.| jjdkr.| S dd | D }t| tj	rRt
|S t| trdt|S |S )zi
    Decodes an array, list or tuple of bytestrings to avoid python 3
    bokeh serialization errors
    r1   Oc                 S   s$   g | ]}t |tr|d n|qS )zutf-8)r?   bytesdecode.0vr;   r;   r<   
<listcomp>r       z decode_bytes.<locals>.<listcomp>)sysversion_infomajorlenr?   r.   Zdtypekindr8   ndarrayZasarraytuple)arrayZdecodedr;   r;   r<   decode_bytesj   s    


rR   c                 C   s  t tt t }}t| D ]T\}}t|D ]B\}}|dur*||\}}	t|| |||< t|| |	||< q*qg }
t| D ]\}}|
g  t|D ]d\}}|du rt|| || }n2t|dr|jdkr|j	dkr|| |_|| |_	|
| | qq||
S )zB
    Pads Nones in a list of lists of plots with empty plots.
    N
plot_widthr   )
r   int	enumerateZget_sizemaxappend
empty_plothasattrrS   plot_height)plotsZrendererwidthsheightsrrowcpwidthheightZexpanded_plotsr;   r;   r<   layout_paddingz   s$    


rd   c           
      C   s  t | trftdd | jD ddgd}|d}|d}tdd |D }tdd |D }||fS t | ttfrxd	S t | tt	t
tfr| jsd	S t | tst | tr| jd
vrtjtj }}n(t | trtjtj }}ntjtj }}tdd | jD  \}}	||||	fS t | trl| jr0| j}n| j| j | j }| jrR| j}n| j| j | j }||fS t | tttfr| j| jfS d	S dS )z{
    Computes the size of bokeh models that make up a layout such as
    figures, rows, columns, widgetboxes and Plot.
    c                 S   s   i | ]\}}}||f|qS r;   r;   )rF   Zfigyxr;   r;   r<   
<dictcomp>   rI   z%compute_plot_size.<locals>.<dictcomp>rf   re   )kdimsc                 S   s   g | ]}t d d |D qS )c                 S   s   g | ]}t |d  qS )r   compute_plot_sizerF   fr;   r;   r<   rH      rI   0compute_plot_size.<locals>.<listcomp>.<listcomp>rV   )rF   colr;   r;   r<   rH      rI   z%compute_plot_size.<locals>.<listcomp>c                 S   s   g | ]}t d d |D qS )c                 S   s   g | ]}t |d  qS )   ri   rk   r;   r;   r<   rH      rI   rm   rn   )rF   r_   r;   r;   r<   rH      rI   )r   r   )rightleftc                 S   s   g | ]}t |qS r;   ri   rF   childr;   r;   r<   rH      rI   N)r?   r   r#   childrengroupbysumr   r   r   r   r   r   toolbar_locationr8   rV   zipr   rS   frame_widthZmin_border_rightZmin_border_leftrZ   frame_heightZmin_border_bottomZmin_border_topr   r   r   rb   rc   )
plotZ	ndmappingZcolsZrowsrb   rc   Zw_aggZh_aggr\   r]   r;   r;   r<   rj      s:    




rj   c                 C   s  |p|}|p|}|p|}|dkr&d}n|dkr2d}|du r>dn
t ||	 }| du rVdn
t | |	 } |du rndn
t ||	 }|du rdn
t ||	 }|p| }|p|}|durd} |durd}d}|rh|r|rd}|
r|
d n|rd}|rdnd}nr|rd} |r
dnd	}nXd
\} }|rD|dkr.d}n|dkr>d}nd}n$|dkrTd}n|dkrdd}nd}|rR|ox| |o| kr|
r|
d |rdnd}|r|r|r|dkrd}n|sRd}|
rR|
d|  nj|r|rd}d}|
rR|
d nD|r4|r4d} d}|
rR|
d n|dkrDd}n|dkrRd}|dkrv|rvd}|
rv|
d |dkr|rd}|
r|
d d}d}d}|rd}|r|r|p| |p| }}n"|s|sd}n|s|sd} |}|dkr
d}n
|r|}nx|r$|r$njt|rt|r:|}n8|rZ|}t || }d
\} }nt || }|}d
\} }n|dur|
r|
d ||||d|||| dfS )a'  
    Utility to compute the aspect, plot width/height and sizing_mode
    behavior.

    Args:
      width (int): Plot width
      height (int): Plot height
      frame_width (int): Plot frame width
      frame_height (int): Plot frame height
      explicit_width (list): List of user supplied widths
      explicit_height (list): List of user supplied heights
      aspect (float): Plot aspect
      data_aspect (float): Scaling between x-axis and y-axis ranges
      responsive (boolean): Whether the plot should resize responsively
      size_multiplier (float): Multiplier for supplied plot dimensions
      logger (param.Parameters): Parameters object to issue warnings on

    Returns:
      Returns two dictionaries one for the aspect and sizing modes,
      and another for the plot dimensions.
    Zsquarerp   ZequalNfixedFzSresponsive mode could not be enabled because fixed width and height were specified.Zstretch_heightZstretch_width)NNrb   Zscale_widthrc   Zscale_heightZ
scale_bothZstretch_botha9  Due to internal constraints, when aspect and width/height is set, the bokeh backend uses those values as frame_width/frame_height instead. This ensures the aspect is respected, but means that the plot might be slightly larger than anticipated. Set the frame_width/frame_height explicitly to suppress this warning.data_aspectaspectz%s value was ignored because absolute width and height values were provided. Either supply explicit frame_width and frame_height to achieve desired aspect OR supply a combination of width or height and an aspect value.zSresponsive mode could not be enabled because fixed width and aspect were specified.zTresponsive mode could not be enabled because fixed height and aspect were specified.zMresponsive width mode could not be enabled because a fixed width was defined.zOresponsive height mode could not be enabled because a fixed height was defined.TzUaspect value of type %s not recognized, provide a numeric value, 'equal' or 'square'.)aspect_ratioaspect_scalematch_aspectsizing_mode)rz   r{   rZ   rS   )rT   warningr-   )rb   rc   rz   r{   Zexplicit_widthZexplicit_heightr   r~   Z
responsiveZsize_multiplierloggerZfixed_widthZfixed_heightZfixed_aspectZactual_widthZactual_heightr   Zaspect_typer   r   r   r;   r;   r<   compute_layout_properties   s    



 










r   c               
   g   sL   | D ]}t | qzdV  W | D ]}t |d q n| D ]}t |d q60 dS )zB
    Context manager for silencing bokeh validation warnings.
    NFr	   )warningsr   r;   r;   r<   silence_warningsl  s    
r   c                 C   s   t | |dS )zD
    Creates an empty and invisible plot of the specified size.
    rb   rc   )r   r   r;   r;   r<   rX   z  s    rX   c                    sP   g d} fdd| j D | j dd< |D ] }t| |} |v r*|  q*dS )z-
    Removes a legend from a bokeh plot.
    )rr   rq   abovebelowcenterc                    s   g | ]}| ur|qS r;   r;   )rF   llegendr;   r<   rH     rI   z!remove_legend.<locals>.<listcomp>N)r   getattrremove)r|   r   Zvalid_placesZplacer;   r   r<   remove_legend  s    
r   c                 C   s   | du st | tsdS ddd}td| }td| }|r@|rP|r\|d dkr\t|d S |r|d |v rtt|d ||d   S dS )	z-
    Convert a fontsize to a pixel value
    N   gUUUUUU?)Zemptz\d+z[a-z]+r   Zpx)r?   r'   refindallrT   )sizeZconversionsvalZunitr;   r;   r<   font_size_to_pixels  s    
r   F#   c	                 C   s  t t|j|}tdd |D }	t|d}
tddd}t|}d}tt	|
d|d	}|

d
| i }|rt||d< |r||d< t|}|d u rd}t|}|d u rd}t|}| dkrd}t|tt||	| d   | | }t	d||
|||d}nL|rdnd}t|tt||	| d   | | }t	|||
||d}tf d g d|}d|_d|j_| dkrd|_d|j_|jd } |r|j|_g |_|j|jd d < n6d|j_|jd } |r|j|_g |_|j|jd d < || _|| _d| _| j f i | |S )Nc                 S   s   g | ]}t |qS r;   )rM   rk   r;   r;   r<   rH     rI   zmake_axis.<locals>.<listcomp>)factorsr   rp   )startendz1range.setv({start: 0, end: range.factors.length}))range)argscoder   Zaxis_label_text_font_sizeZmajor_label_text_font_size   
   rf   r   g=
ףp=?auto)Zx_axis_typeZx_axis_labelx_rangey_rangerZ   rS   rr   rq   )Zy_axis_labelr   r   rS   rZ   )rx   r   r   FZmiddle)!listmappprint_valuer8   rV   r   r   r2   r   r@   Zjs_on_changer   ZradiansrT   absZsinZcosr   Zoutline_line_alphaZgridZgrid_line_alphaalignZyaxisZvisibleZxaxisr   r   rr   rq   Zmajor_label_orientationZmajor_label_text_alignZmajor_label_text_baselineupdate)axisr   r   dimZflipZrotationZ
label_sizeZ	tick_sizeZaxis_heightZncharsZrangesZranges2Z
axis_labelr3   ZcustomjsZ
axis_propsZtick_pxZlabel_pxr   rc   Zoptsrb   ra   r;   r;   r<   	make_axis  s    







r   c              	      s   fddt dD \}}}|j}t|d }|d | }|}d| }t|}t|}|d; }t|}t|}t|}t|}d|tt|t|||g  | }	tg dg d	g d
g dg dg dg}
|	|
| t	t
|dddf f }||d S )z
    Vectorized HSV to RGB conversion, adapted from:
    http://stackoverflow.com/questions/24852345/hsv-to-rgb-color-conversion
    c                 3   s   | ]} d |f V  qdS ).Nr;   )rF   ihsvr;   r<   	<genexpr>  rI   zhsv_to_rgb.<locals>.<genexpr>r"   g      @g      ?   rp   )r   r"   rp   )r1   r   rp   )rp   r   r"   )rp   r1   r   )r"   rp   r   )r   rp   r1   N)r"   )r   shaper8   Zint_ravelZvstackZ
zeros_likeZ	ones_likerQ   ZarangeZprodZreshape)r   hsrG   r   r   rl   qtZclistorderZrgbr;   r   r<   
hsv_to_rgb  s"    





*.(r   333333?333333?c                 C   s   t | tr0dd | jD }tdd |D }nt | tr`dd | jD }tdd |D }nt | trdd | jD }tdd |D }| jD ]} || _	t
|| }qnFt | tr| j	}t
|| | _	n&t | ttfr| j	}n| r| j}nd}|S )	zi
    Computes the width of a model and sets up appropriate padding
    for Tabs and DataTable types.
    c                 S   s   g | ]}t |qS r;   	pad_widthrs   r;   r;   r<   rH     rI   zpad_width.<locals>.<listcomp>c                 S   s   g | ]}|d ur|qS Nr;   rE   r;   r;   r<   rH     rI   c                 S   s   g | ]}t |qS r;   r   rs   r;   r;   r<   rH     rI   c                 S   s   g | ]}|d ur|qS r   r;   rE   r;   r;   r<   rH     rI   c                 S   s   g | ]}t |qS r;   r   )rF   r   r;   r;   r<   rH   	  rI   c                 S   s   g | ]}|d ur|qS r   r;   rE   r;   r;   r<   rH   
  rI   r   )r?   r   ru   r8   rV   r   rw   r   Ztabsrb   rT   r   r   r   rS   )modelZtable_paddingZtabs_paddingZvalsrb   r;   r;   r<   r     s*    




r   c                 C   sP   g }| D ].}g }|D ]}t |}|| q|| qdd t| |D } | S )z
    Accepts a grid of bokeh plots in form of a list of lists and
    wraps any DataTable or Tabs in a WidgetBox with appropriate
    padding. Required to avoid overlap in gridplot.
    c                 S   s$   g | ]\}}d d t ||D qS )c                 S   s.   g | ]&\}}t |ttfr&t||d n|qS ))rb   )r?   r   r   r   )rF   ra   wr;   r;   r<   rH   '  s   z(pad_plots.<locals>.<listcomp>.<listcomp>)ry   )rF   r_   wsr;   r;   r<   rH   '  s   zpad_plots.<locals>.<listcomp>)r   rW   ry   )r[   r\   r_   Z
row_widthsra   rb   r;   r;   r<   	pad_plots  s    r   c                 C   s:   t | trdd | D } nt| dr6dd | jD | _| S )zi
    Filters out toolboxes out of a list of plots to be able to compose
    them into a larger plot.
    c                 S   s   g | ]}t |qS r;   )filter_toolboxes)rF   r|   r;   r;   r<   rH   2  rI   z$filter_toolboxes.<locals>.<listcomp>ru   c                 S   s   g | ]}t |tst|qS r;   )r?   r   r   rs   r;   r;   r<   rH   4  s   
)r?   r   rY   ru   )r[   r;   r;   r<   r   ,  s
    

r    c              
   C   s   zddl m} W n& ty6   tjj|d  Y dS 0 z|| d}W nN ty } z6d|}|dd}tjj||  W Y d}~dS d}~0 0 t	| j
}|rd	|d  nd
}d}d|||g}	td|	}
|	d|
  d |	|
 d  S )zB
    Uses py2js to compile a python tick formatter to JS code
    r   )py2jszNEnsure pscript is installed ("conda install pscript" or "pip install pscript")N	formatterzPyscript raised an error: {0}%z%%zvar %s = tick;r   zreturn formatter();

z,(formatter \= function flx_formatter \(.*\))zformatter = function ())Zpscriptr   ImportErrorparammainr   	Exceptionformatr:   r&   r   joinr   searchr   r   )r   msgr   Zjscodeeerrorr   Z
arg_defineZ	return_jsjsfuncmatchr;   r;   r<   py2js_tickformatter9  s(    

r   c                 C   s   t |trl|dur\g }|jrN||j |j|jdd jkrZ||j q`||j n| }d|}nddd t	|j
| D }|S )zv
    Computes a title for bokeh tabs from the key in the overlay, the
    element and the containing (Nd)Overlay.
    Nexistinggroup z | c                 S   s   g | ]\}}| |qS r;   )Zpprint_value_string)rF   dkr;   r;   r<   rH   f  rI   z!get_tab_title.<locals>.<listcomp>)r?   r$   ZlabelrW   r   r   Zobjectsdefaultr   ry   rh   )keyframeZoverlaytitler;   r;   r<   get_tab_titleT  s    


r   c                 C   sB   d}|dur(t |trt| }|| }| |}|j| ||S )z@
    Looks up the default value for a bokeh model property.
    N)r?   strr!   Z
_for_classlookuppropertyZthemed_default)r   namethemeZ	overridesZ
descriptorr;   r;   r<   get_defaultk  s    


r   c                 C   s   t | D ]v\}}t|tr:d|v r:d|v r0q|d }nt|tsFq| | }z&tt|dkrr|d ||< | |= W q   Y q0 qdS )z
    Iterates over the data and mapping for a ColumnDataSource and
    replaces columns with repeating values with a scalar. This is
    purely and optimization for scalar types.
    ZfieldZ	transformrp   r   N)r   itemsr?   r@   r'   rM   r,   )datamappingr   rG   valuesr;   r;   r<   filter_batched_datax  s    


r   c                    sZ   dd | j  D }dd   D } fdd| j D }t|oV|oV|oV|d |d kS )z
    Determine if the CDS.data requires a full replacement or simply
    needs to be updated. A replacement is required if untouched
    columns are not the same length as the columns being updated.
    c                 S   s$   g | ]}t |tft rt|qS r;   )r?   r   r.   rM   rE   r;   r;   r<   rH     s   z&cds_column_replace.<locals>.<listcomp>c                 S   s$   g | ]}t |ttjfrt|qS r;   )r?   r   r8   rO   rM   rE   r;   r;   r<   rH     rI   c                    s   g | ]}| vr|qS r;   r;   )rF   r   r   r;   r<   rH     rI   r   )r   r   bool)sourcer   Zcurrent_lengthZ
new_lengthZ	untouchedr;   r   r<   cds_column_replace  s    r   c              	   c   s   t tdkr| jj}|| j_n| j}|| _z8dV  W |rF|sF|   qt tdkr\|| j_q|| _n0|rv|sv|   nt tdkr|| j_n|| _0 dS )z@
    Context manager to temporary override the hold policy.
    2.4N)bokeh_versionr%   	callbacksZ
hold_valueZ_holdZunhold)documentZpolicyZserverZ
old_policyr;   r;   r<   hold_policy  s"    




r   c           	      C   s  i }|   }| D ]\}}t|trt| |}t|t|u rX|j dd}t|| qzt| || W q ty } z4t|t	rd|v rt| ||d  n|W Y d}~qd}~0 0 q||v r||| krt|t	rd|v r|d }|||< q| j
f i | dS )z
    Recursively updates attributes on a model including other
    models. If the type of the new model matches the old model
    properties are simply updated, otherwise the model is replaced.
    F)Zinclude_defaultsr>   N)Zproperties_with_valuesr   r?   r   r   typerecursive_model_updatesetattrr   r@   r   )	r   ZpropsZupdatesZvalid_propertiesr   rG   Znested_modelZnested_propsr   r;   r;   r<   r     s&    


r   c                    s    fdd}|S )a3  
    Context manager to ensures data sources shared between multiple
    plots are cleared and updated appropriately avoiding warnings and
    allowing empty frames on subplots. Expects a list of
    shared_sources and a mapping of the columns expected columns for
    each source in the plots handles.
    c                    s   | j di }| j dg }| j}|D ]8j  |r&ttdkrJ|jn|}|jd d |_q&| g|R i |}|D ]b|t	 }fdd|D }	|	rt
j|	d  t
jng   fdd	|D }
j|
 qz|S )
Nsource_colsshared_sourcesr   c                    s   g | ]}| j v r|qS r;   r   rF   r`   )r   r;   r<   rH     rI   z:update_shared_sources.<locals>.wrapper.<locals>.<listcomp>r   c                    s   i | ]}|j vr| qS r;   r   r   emptyr   r;   r<   rg     rI   z:update_shared_sources.<locals>.wrapper.<locals>.<dictcomp>)Zhandlesgetr   r   clearr   r%   r   Z_held_eventsidr8   Z	full_likeZNaNr   )selfr   kwargsr   r   docZ	event_objretZexpectedfoundZpatchrl   r   r<   wrapper  s     
 z&update_shared_sources.<locals>.wrapperr;   )rl   r  r;   r  r<   update_shared_sources  s    r	  c                    s   t  fdd| D S )z
    Uses a Dimension instance to convert an array of values to categorical
    (i.e. string) values and applies escaping for colons, which bokeh
    treats as a categorical suffix.
    c                    s   g | ]}  |qS r;   )r   )rF   rf   r   r;   r<   rH     rI   z$categorize_array.<locals>.<listcomp>)r8   rQ   )rQ   r   r;   r
  r<   categorize_array  s    r  c                   @   sV   e Zd ZdZdd Zedd Zdd Zdd
dZdd Z	dd Z
dd Zdd ZdS )periodiczq
    Mocks the API of periodic Thread in hv.core.util, allowing a smooth
    API transition on bokeh server.
    c                 C   s4   || _ d | _d | _d | _d | _d | _d | _d | _d S r   )r   callbackperiodcountcounter_start_timetimeout_pcb)r  r   r;   r;   r<   __init__  s    zperiodic.__init__c                 C   s
   | j d u S r   )r  r  r;   r;   r<   	completed  s    zperiodic.completedc                 C   s4   t   | _| jd u rtd| j| j| j| _d S )NzKperiodic was registered to be run on bokehserver but no document was found.)timer  r   RuntimeErrorZadd_periodic_callback_periodic_callbackr  r  r  r;   r;   r<   r     s    

zperiodic.startNFc                 C   sZ   t |tr|dk r4tdnt|td ur4td|| _|d | _|| _|| _d| _| S )Nr   zCount value must be positivez.Count value must be a positive integer or Noner5   )	r?   rT   
ValueErrorr   r  r  r  r  r  )r  r  r  r  r  blockr;   r;   r<   __call__  s    

zperiodic.__call__c                 C   s\   |  | j |  jd7  _| jd urDt | j }|| jkrD|   | j| jkrX|   d S Nrp   )r  r  r  r  r  stopr  )r  r6   r;   r;   r<   r    s    

zperiodic._periodic_callbackc                 C   s<   d | _ d | _z| j| j W n ty0   Y n0 d | _d S r   )r  r  r   Zremove_periodic_callbackr  r  r  r;   r;   r<   r  '  s    zperiodic.stopc                 C   s   d| j | jt| jf S )Nzperiodic(%s, %s, %s))r  r  r(   r  r  r;   r;   r<   __repr__0  s    zperiodic.__repr__c                 C   s   t | S r   )reprr  r;   r;   r<   __str__4  s    zperiodic.__str__)NF)__name__
__module____qualname____doc__r  r   r  r   r  r  r  r  r!  r;   r;   r;   r<   r    s   


	r  c                    s    fdd} j |tgS )z=
    Attaches plot refresh to all streams on the object.
    c                    s    t | D ]} t j| j_qd S r   )r/   r  r   Z_periodic_util)Zdmapr|   r;   r<   append_refresh<  s    z'attach_periodic.<locals>.append_refresh)ZhmapZtraverser0   )r|   r'  r;   r&  r<   attach_periodic8  s    r(  c                 C   s   t r2t| t jr2z|  } W n   |  } Y n0 t| tjrN| dtS t| t	rbt
| dS t| drt|  d }ntd|S )a  Converts support date types to milliseconds since epoch

    Attempts highest precision conversion of different datetime
    formats to milliseconds since the epoch (1970-01-01 00:00:00).
    If datetime is a cftime with a non-standard calendar the
    caveats described in hv.core.util.cftime_to_timestamp apply.

    Args:
        date: Date- or datetime-like object

    Returns:
        Milliseconds since 1970-01-01 00:00:00
    zdatetime64[ms]ms	timetuplei  zDatetime type not recognized)r+   r?   Z	TimestampZto_datetime64Zto_datetimer8   r9   astypefloatr)   r*   rY   calendarZtimegmr*  r  )dateZdt_intr;   r;   r<   date_to_integerB  s    


r/  c                    s"   t  fdd}t |dS )aU  
    Orders a set of glyph handles using regular sort and an explicit
    sort order. The explicit draw order must take the form of a list
    of glyph names while the keys should be glyph names with a custom
    suffix. The draw order may only match subset of the keys and any
    matched items will take precedence over other entries.
    c                    s:    fddD }|r( |d  fS d    fS )Nc                    s   g | ]}  |r|qS r;   )
startswith)rF   itemglyphr;   r<   rH   l  rI   z1glyph_order.<locals>.order_fn.<locals>.<listcomp>r   g    eA)index)r3  matches
draw_orderkeysr2  r<   order_fnk  s    zglyph_order.<locals>.order_fn)r   )sorted)r8  r7  r9  r;   r6  r<   glyph_orderb  s    r;  c           
      C   s   | ddddf   }|ddddf   }| ddddf   }|ddddf   }| ddddf   }|ddddf   }| ddddf   }|ddddf   }	t|||||g} t||||	|g}| |fS )zY
    Generates line paths for a quadmesh given 2D arrays of X and Y
    coordinates.
    r   r   rp   N)r   r8   column_stack)
XYZX1ZY1ZX2ZY2ZX3ZY3ZX4ZY4r;   r;   r<   	colormeshr  s    r?  c                 C   sL   t | tr(| tv r(t|  jd |i S t | trD| jd |i S i S d S )Nattrs)r?   r   r!   Z_jsonr   r    )r   attrr;   r;   r<   theme_attr_json  s
    
rB  c              	      sZ   fdd j D \}}  }g g  }}t|||D ]\}}}dd |D }	dd |D }
t||g}tt|ddddf djd	d
d }t	|rt
||d	 n|g}g g  }}tt||	|
D ]d\}\}}}|t	|d	 kr|dd }||dddf g|  ||ddd	f g|  q|| || q6||fS )z
    Expands polygon data which contains holes to a bokeh multi_polygons
    representation. Multi-polygons split by nans are expanded and the
    correct list of holes is assigned to each sub-polygon.
    c                 3   s   | ]} j |d dV  qdS )F)ZexpandedN)Zdimension_values)rF   Zkdelementr;   r<   r     rI   z&multi_polygons_data.<locals>.<genexpr>c                 S   s   g | ]}d d |D qS )c                 S   s   g | ]}|d d df qS )Nr   r;   rF   r   r;   r;   r<   rH     rI   2multi_polygons_data.<locals>.<listcomp>.<listcomp>r;   rF   Zholer;   r;   r<   rH     rI   z'multi_polygons_data.<locals>.<listcomp>c                 S   s   g | ]}d d |D qS )c                 S   s   g | ]}|d d df qS r  r;   rE  r;   r;   r<   rH     rI   rF  r;   rG  r;   r;   r<   rH     rI   Nr1   r,  rp   )r   r   r   )rh   holesry   r8   r<  whereZisnanr+  rw   rM   splitrU   rW   )rD  ZxsZysrH  ZxshZyshrf   re   Z
multi_holeZxhsZyhsrQ   ZsplitsZarraysZmulti_xsZmulti_ysr   pathhxZhyr;   rC  r<   multi_polygons_data  s$    
2

rM  c                 C   sr   | du s |du s t | t |kr$dS t| |D ]>\}}t||D ]*\}}|du s@|du rZq@||kr@  dS q@q.dS )a&  Matches dimension specs used to link axes.

    Axis dimension specs consists of a list of tuples corresponding
    to each dimension, each tuple spec has the form (name, label, unit).
    The name and label must match exactly while the unit only has to
    match if both specs define one.
    NFT)rM   ry   )Zspecs1Zspecs2Zspec1Zspec2s1s2r;   r;   r<   match_dim_specs  s     rP  c                 C   s8   t | d tr|dkS t | d tr,|dkS |dv S dS )zE
    Ensure the range_type matches the axis model being matched.
    r   Zcategoricalr7   )r   logN)r?   r   r   )axZ
range_typer;   r;   r<   match_ax_type  s
    rS  c                 C   sL   t | trn<t | tr>d| }t| |}|r8t|d} qHd} n
t| d} | S )zV
    Wraps formatting function or string in
    appropriate bokeh formatter type.
    z6%sformatter could not be converted to tick formatter. )r   N)r   )r?   r   r   r   r   r   )r   r   r   r   r;   r;   r<   wrap_formatter  s    



rT  )N)Fr   NNr   )r   r   )r   )N)F)Z
__future__r   r   r   r   r  rJ   r-  r7   r6   typesr   collectionsr   
contextlibr   r   ZbokehZnumpyr8   Zbokeh.core.json_encoderr   Zbokeh.core.validationr
   Zbokeh.layoutsr   r   r   Zbokeh.modelsr   r   r   r   r   r   r   r   r   r   r   Zbokeh.models.formattersr   r   r   Zbokeh.models.widgetsr   r   r   Zbokeh.plottingr   Zbokeh.themes.themer    Zbokeh.themesr!   Zcore.ndmappingr#   Zcore.overlayr$   Z	core.utilr%   r&   r'   r(   r)   r*   r+   r,   r-   r.   Zcore.spacesr/   r0   utilr2   __version__r   ZPanToolZWheelPanToolZWheelZoomToolZ
ZoomInToolZZoomOutToolZTapToolZCrosshairToolZBoxSelectToolZPolySelectToolZLassoSelectToolZBoxZoomToolZ	HoverToolZSaveToolZUndoToolZRedoToolZ	ResetToolZHelpToolZBoxEditToolZPointDrawToolZPolyDrawToolZPolyEditToolZFreehandDrawToolZ
TOOL_TYPESr=   rA   rR   rd   rj   r   r   rX   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r	  r  objectr  r(  r/  r;  r?  rB  rM  rP  rS  rT  r;   r;   r;   r<   <module>   s   0
0
(	, 
 1
  
C


	D
 	