
    ee                        d 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
 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mZ dd
lmZmZmZ ddlmZmZmZ ddlmZ ddl m!Z! ddlm"Z" ddddZ#dZ$eZ%d Z&d Z'd Z(d Z) G d dej*                  Z+ G d dej*                  Z, G d de,          Z- G d de-          Z. G d  d!e!e-          Z/dS )"z
Provides Dimension objects for tracking the properties of a value,
axis or map dimension. Also supplies the Dimensioned abstract
baseclass for classes that accept Dimension values.
    N)Counterdefaultdict)Iterable)partial)chain)
itemgetter   )util)ApplyOptsRedim)OptionsStorecleanup_custom_options)PrettyPrinter)AttrTree)bytes_to_unicodekdimsvdimscdims)key_dimensionsvalue_dimensionsconstant_dimensionsz{name}: {val}{unit}c                     t                                           D ]-\  }}d| d}d| d}|| v r|                     |          | |<   .| S )z
    Called from __setstate__ in LabelledData in order to load
    old pickles with outdated parameter names.

    Warning: We want to keep pickle hacking to a minimum!
    __param_value)ALIASESitemspop)doldnew	old_param	new_params        8lib/python3.11/site-packages/holoviews/core/dimension.pyparam_aliasesr&   #   sc     MMOO , ,S))))	))))	>>55++AiLH    c                 N    t          | t                    r| nt          |           S )a  Convert the input to a Dimension.

    Args:
        dimension: tuple, dict or string type to convert to Dimension

    Returns:
        A Dimension object constructed from the dimension spec. No
        copy is performed if the input is already a Dimension.
    
isinstance	Dimension	dimensions    r%   asdimr.   2   s%     #9i88R99i	>R>RRr'   c                 ,   t          | t                    r| j        S t          | t                    r| S t          | t                    r| d         S t          | t
                    r| d         S | dS t          dt          |           j        z            )a  Return the Dimension.name for a dimension-like object.

    Args:
        dimension: Dimension or dimension string, tuple or dict

    Returns:
        The name of the Dimension or what would be the name if the
        input as converted to a Dimension.
    r   nameNz|%s type could not be interpreted as Dimension. Dimensions must be declared as a string, tuple, dictionary or Dimension type.)	r*   r+   r0   strtupledict
ValueErrortype__name__r,   s    r%   dimension_namer7   ?   s     )Y'' 5~	Is	#	# 5	Iu	%	% 
5|	It	$	$ 5  		t 9  	??34 5 5 	5r'   c           	      6   i }d| fd|ffD ]\  }}|t          |t          t          t          t          f          r|g}nJt          |t
                    s5t          d                    |t          |          j	                            d |D             ||<   |S )a  Converts kdims and vdims to Dimension objects.

    Args:
        kdims: List or single key dimension(s) specified as strings,
            tuples dicts or Dimension objects.
        vdims: List or single value dimension(s) specified as strings,
            tuples dicts or Dimension objects.

    Returns:
        Dictionary containing kdims and vdims converted to Dimension
        objects:

        {'kdims': [Dimension('x')], 'vdims': [Dimension('y')]
    r   r   Nz{} argument expects a Dimension or list of dimensions, specified as tuples, strings, dictionaries or Dimension instances, not a {} type. Ensure you passed the data as the first argument.c                 ,    g | ]}t          |          S  )r.   .0r    s     r%   
<listcomp>z&process_dimensions.<locals>.<listcomp>t   s    444!U1XX444r'   )
r*   r2   r1   r+   r3   listr4   formatr5   r6   )r   r   
dimensionsgroupdimss        r%   process_dimensionsrC   Z   s     J %(7E*:; 
5 
5t<uc9d;<< 	S6DDD$'' 	S / 06veT$ZZ=P/Q/QS S S 54t444
5r'   c                   T    e Zd ZdZ ej        d          Z ej        dd          Z ej        dd          Z	 ej
        dd	          Z ej        dd
          Z ej        dd          Z ej        dd          Z ej        dd          Z ej
        dd          Z ej        ddd          Z ej        dd          Z ej        g d          Zi ZdZi Z fdZed             Zd$dZd Z  fdZ!d Z"d Z#d Z$d Z%d Z&ed              Z'd! Z(d%d"Z)d# Z* xZ+S )&r+   a  
    Dimension objects are used to specify some important general
    features that may be associated with a collection of values.

    For instance, a Dimension may specify that a set of numeric values
    actually correspond to 'Height' (dimension name), in units of
    meters, with a descriptive label 'Height of adult males'.

    All dimensions object have a name that identifies them and a label
    containing a suitable description. If the label is not explicitly
    specified it matches the name.

    These two parameters define the core identity of the dimension
    object and must match if two dimension objects are to be considered
    equivalent. All other parameters are considered optional metadata
    and are not used when testing for equality.

    Unlike all the other parameters, these core parameters can be used
    to construct a Dimension object from a tuple. This format is
    sufficient to define an identical Dimension:

    Dimension('a', label='Dimension A') == Dimension(('a', 'Dimension A'))

    Everything else about a dimension is considered to reflect
    non-semantic preferences. Examples include the default value (which
    may be used in a visualization to set an initial slider position),
    how the value is to rendered as text (which may be used to specify
    the printed floating point precision) or a suitable range of values
    to consider for a particular analysis.

    Units
    -----

    Full unit support with automated conversions are on the HoloViews
    roadmap. Once rich unit objects are supported, the unit (or more
    specifically the type of unit) will be part of the core dimension
    specification used to establish equality.

    Until this feature is implemented, there are two auxiliary
    parameters that hold some partial information about the unit: the
    name of the unit and whether or not it is cyclic. The name of the
    unit is used as part of the pretty-printed representation and
    knowing whether it is cyclic is important for certain operations.
    z
       Short name associated with the Dimension, such as 'height' or
       'weight'. Valid Python identifiers make good names, because they
       can be used conveniently as a keyword in many contexts.)docNz
        Unrestricted label used to describe the dimension. A label
        should succinctly describe the dimension and may contain any
        characters, including Unicode and LaTeX expression.defaultrE   Fz
        Whether the range of this feature is cyclic such that the
        maximum allowed value (defined by the range parameter) is
        continuous with the minimum allowed value.z
        Default value of the Dimension which may be useful for widget
        or other situations that require an initial or default value.z{
        Optional missing-data value for integer data.
        If non-None, data with this value will be replaced with NaN.NNz
        Specifies the minimum and maximum allowed values for a
        Dimension. None is used to represent an unlimited bound.zf
        Specifies a minimum and maximum reference value, which
        may be overridden by the data.z
        Optional floating point step specifying how frequently the
        underlying space should be sampled. May be used to define a
        discrete sampling over the range.z
        Optional type associated with the Dimension values. The type
        may be an inbuilt constructor (such as int, str, float) or a
        custom class object.Tz
        Optional unit string associated with the Dimension. For
        instance, the string 'm' may be used represent units of meters
        and 's' to represent units of seconds.)rG   
allow_NonerE   zB
        Formatting function applied to each value before display.z
        Optional specification of the allowed value set for the
        dimension that may also be used to retain a categorical
        ordering.z	 ({unit})c                 `   d|v rt          d          i }t          |t                    r.|                    |j                                                   nWt          |t                    r||                    dd          f| j        	                                v r\| j        t          |          t          |d                   f         }|                    |j                                                   n|| j        v r8|                    | j        |         j                                                   nB|f| j        v r8|                    | j        |f         j                                                   ||d<   ||d<   n%t          |t                    r	 |\  |d<   |d<   n2# t          $ r%}t          dt          |          z            |d}~ww xY wd|v r>|d         |d         k    r,| j                            d|d         d|d                    nt          |t                    rU|                    |           	 |                    d|d                    nF# t           $ r}t          d	          |d}~ww xY wt          d
t          |          j        z            |                    |           |d         st          d          |d         st          d          |                    dg           }t          |t                    r"|dk    r| j                            d           g }t#          t%          j        |                    |d<    t)                      j        di | | j        | j        r*| j        |vr!t          | d| j         d| j                   | j        dk    ri| j        d         | j        | j        d         k     s#| j        d         ;| j        | j        d         k    r't          | d| j         d| j                   dS dS dS dS )zG
        Initializes the Dimension object with the given name.
        r0   z=Dimension name must only be passed as the positional argumentunitNlabelzXDimensions specified as a tuple must be a tuple consisting of the name and label not: %s$Using label as supplied by keyword (), ignoring tuple value z7Dimension specified as a dict must contain a "name" keyz}%s type could not be interpreted as Dimension.  Dimensions must be declared as a string, tuple, dictionary or Dimension type.zDimension name cannot be emptyzDimension label cannot be emptyvaluesinitialzAThe 'initial' string for dimension values is no longer supported.z	 default z not found in declared values: rH   r   r	   z not in declared range: r:   )KeyErrorr*   r+   updateparamrO   r1   getpresetskeysr2   r4   warningr3   
setdefaultr5   r6   r>   r
   unique_arraysuper__init__rG   range)selfspecparams
all_paramspresetexcrO   	__class__s          r%   r[   zDimension.__init__   s    VZ[[[
dI&& %	dj//112222c"" #	fjj../4<3D3D3F3FFFs4yy#fVn2E2E&FG!!&,"5"5"7"78888%%!!$,t"4":"A"A"C"CDDDDDL((!!$,w"7"="D"D"F"FGGG!%Jv"&Jwe$$ 	:>7
6"Jw$7$7    ?ADTK  
 &  VG_
78K%K%K
""D6'? D D,6w,?D DE E E d## 	d###%%gtF|<<<<    M 
 Mt**%&  
 	&!!!&! 	?=>>>'" 	@>???Hb))fc"" 	v':':J  9 : : :F#D$5f$=$=>>
8&&:&&&<#{ it|699 D!o!oT\!o!obfbm!o!oppp*,,JqM-$,A2N2NJqM-$,A2N2N D!g!gT\!g!g[_[e!g!ghhh $# -,--2N2Ns0   "F. .
G8 GGI+ +
J
5JJ
c                     | j         | j        fS )zw"Returns the Dimensions tuple specification

        Returns:
            tuple: Dimension tuple specification
        r0   rL   r]   s    r%   r^   zDimension.spec(  s     	4:&&r'   c                    t          | j                                        fi |}|"| j        |                    d| j                  f}d|v r t          |t                    r||d         f}ngd|v rct          |t                    rN|d         |d         k    r,| j        	                    d|d         d|d                    |d         |d         f} | j
        |fi d |                                D             S )ae  Clones the Dimension with new parameters

        Derive a new Dimension that inherits existing parameters
        except for the supplied, explicit overrides

        Args:
            spec (tuple, optional): Dimension tuple specification
            **overrides: Dimension parameter overrides

        Returns:
            Cloned Dimension object
        NrL   r	   rM   rN   r   c                 "    i | ]\  }}|d v	||S )re   r:   r<   kvs      r%   
<dictcomp>z#Dimension.clone.<locals>.<dictcomp>J  s6     'F 'F 'Fsq*+3D*D*D ()*D*D*Dr'   )r3   rS   rO   r0   rT   rL   r*   r1   r2   rW   rc   r   )r]   r^   	overridessettingss       r%   clonezDimension.clone1  sH    
))++99y99<Iy}}WdjAABDiJtS$9$9)G,-DD	!!ju&=&=!!T!W,,
""89W;M 8 8,0G8 89 9 9 Gi01Dt~d G G 'F 'Fhnn6F6F 'F 'F 'F G G 	Gr'   c                 *    t          | j                  S )z=Hashes object on Dimension spec, i.e. (name, label).
        )hashr^   rf   s    r%   __hash__zDimension.__hash__M  s     DIr'   c                 n    t                                          |           d|vr| j        | _        dS dS )zR
        Compatibility for pickles before alias attribute was introduced.
        _label_param_valueN)rZ   __setstate__r0   rL   )r]   r    rc   s     r%   ru   zDimension.__setstate__R  s=     	Qq((DJJJ )(r'   c                     t          |t                    r| j        |j        k    S || j        | j        t          j        | j                  fv S )z:Implements equals operator including sanitized comparison.)r*   r+   r^   r0   rL   r
   dimension_sanitizerr]   others     r%   __eq__zDimension.__eq__Z  sJ     eY'' 	+9
** DJ0H0S0STTTr'   c                 .    |                      |           S )z=Implements not equal operator including sanitized comparison.)rz   rx   s     r%   __ne__zDimension.__ne__c  s    ;;u%%%%r'   c                 b    t          |t                    r| j        |j        k     n
| j        |k     S )z.Dimensions are sorted alphanumerically by name)r*   r+   r0   rx   s     r%   __lt__zDimension.__lt__g  s-    )3E9)E)E\ty5:%%49W\K\\r'   c                     | j         S Nr0   rf   s    r%   __str__zDimension.__str__k  s
    yr'   c                 *    |                                  S r   )pprintrf   s    r%   __repr__zDimension.__repr__n  s    {{}}r'   c                     | j         dn: t          | j                   | j                                      | j                   }t	          | j                  t	          |          z   S )z1The pretty-printed label string for the DimensionN )rK   )rK   r5   unit_formatr?   r   rL   )r]   rK   s     r%   pprint_labelzDimension.pprint_labelq  s^     i'$T$)__T%566==49=MM 	
++.>t.D.DDDr'   c                    | j                             d          t          fddD                       dk    rd| j        dS | j                             d          t          t                                                    fd	
          }d                    fd|D                       }d| j        d| dS )NT)onlychangedc                 <    h | ]}                     ||          S r:   )rT   r<   rj   changeds     r%   	<setcomp>z#Dimension.pprint.<locals>.<setcomp>z  s'    <<<aAq!!<<<r'   re   r	   z
Dimension()existingc                 X    |          j         t          d           n|          j         S )Ninf)
precedencefloat)rj   r_   s    r%   <lambda>z"Dimension.pprint.<locals>.<lambda>  s+    !'!5!=uAY) r'   )keyz, c              3   >   K   | ]}|d k    | d|         V  dS )r0   =Nr:   r   s     r%   	<genexpr>z#Dimension.pprint.<locals>.<genexpr>  s9      OO!1;;1--wqz--;;;;OOr'   )rS   rO   lenr0   objectssortedrV   join)r]   orderingkwsr   r_   s      @@r%   r   zDimension.pprintx  s    *###55<<<<+;<<<==BB.	....##J//7<<>>"" )+ )+ )+ )+, , , iiOOOOxOOOOO1DI1131111r'   c                    | j         t          |          n| j         }| j        r| j        n| j                            |          }|rt	          |          r ||          }nt          |t                    rt          |t          j        t          j	        f          r|
                    |          }nt          |t          j                  r(t          j        |          
                    |          }nMt          j        d|          r|                    |          }n"||z  }nt          t%          |                    }|r!| j        |dz   t%          | j                  z   }|S )zApplies the applicable formatter to the value.

        Args:
            value: Dimension value to format

        Returns:
            Formatted dimension value
        Nz	\{(\w+)\} )r5   value_formattype_formattersrT   callabler*   r1   dtdatetimedatestrftimenp
datetime64r
   
dt64_to_dtrefindallr?   r   rK   )r]   value
print_unitown_type	formatterformatted_values         r%   pprint_valuezDimension.pprint_value  s^    #')"34;;;*.*; =T&&.228<< 	 	;	"" 
8"+)E"2"2Is++ 8ebk27%;<< 8&+nnY&?&?OOr}55 8&*oe&<&<&E&Ei&P&POOZi88 8&/&6&6u&=&=OO&/%&7O!"25"9"9::O 	R$)/-36Fty6Q6QQOr'   c                     | j         dndt          | j                   z   }|                     |          }t                              t          | j                  ||          S )zPretty print the dimension value and unit with title_format

        Args:
            value: Dimension value to format

        Returns:
            Formatted dimension value string with unit
        Nr   r   )r0   valrK   )rK   r   r   title_formatr?   rL   )r]   r   rK   s      r%   pprint_value_stringzDimension.pprint_value_string  s^     Y&rrC2B492M2M,M!!%((""(8(D(D%VZ"[[[r'   r   )F),r6   
__module____qualname____doc__rS   Stringr0   rL   Booleancyclic	ParameterrG   IntegernodataTupler\   
soft_rangeNumberstepr5   rK   Callabler   ListrO   r   r   rU   r[   propertyr^   ro   rr   ru   rz   r|   r~   r   r   r   r   r   r   __classcell__rc   s   @r%   r+   r+   y   s       + +Z 5< B C C CD
 EL ,? @ @ @E
 U]5 /6 7 7 7F
 eod 1I J J JG U]4 .H I I IF EK 3D E E EE \ 8* + + +J 5< +- . . .D
 5?4 .  ! ! !D
 5< <2 3 3 3D
 "5>$ 5E F F FL UZ )   F OKGCi Ci Ci Ci CiJ ' ' X'G G G G8  
# # # # #U U U& & &] ] ]     E E XE2 2 2   >\ \ \ \ \ \ \r'   r+   c                        e Zd ZdZ ej        d dd          Z ej        ddd          ZdZd fd		Z	e
d
             Zej        d             ZddZddZd ZddZddZd Z fdZ xZS )LabelledDataa  
    LabelledData is a mix-in class designed to introduce the group and
    label parameters (and corresponding methods) to any class
    containing data. This class assumes that the core data contents
    will be held in the attribute called 'data'.

    Used together, group and label are designed to allow a simple and
    flexible means of addressing data. For instance, if you are
    collecting the heights of people in different demographics, you
    could specify the values of your objects as 'Height' and then use
    the label to specify the (sub)population.

    In this scheme, one object may have the parameters set to
    [group='Height', label='Children'] and another may use
    [group='Height', label='Adults'].

    Note: Another level of specification is implicit in the type (i.e
    class) of the LabelledData object. A full specification of a
    LabelledData object is therefore given by the tuple
    (<type>, <group>, label>). This additional level of specification is
    used in the traverse method.

    Any strings can be used for the group and label, but it can be
    convenient to use a capitalized string of alphanumeric characters,
    in which case the keys used for matching in the matches and
    traverse method will correspond exactly to {type}.{group}.{label}.
    Otherwise the strings provided will be sanitized to be valid
    capitalized Python identifiers, which works fine but can sometimes
    be confusing.
    Tz
       A string describing the type of data contained by the object.
       By default this will typically mirror the class name.rG   constantrE   r   z
       Optional label describing the data, typically reflecting where
       or how it was measured. The label should allow a specific
       measurement or dataset to be referenced for a given group.FNc                    || _         d| _        || _        |pt          j        |           | _        t          |                    dd          t                    r(|d         \  }}t          j	        j
        di ||i ||d<   t          |                    dd          t                    r(|d         \  }}t          j        j
        di ||i ||d<    t                      j        di | t          j                            | j                  st!          d| j        z            t          j	                            | j                  st!          d| j        z            dS )a  
        All LabelledData subclasses must supply data to the
        constructor, which will be held on the .data attribute.
        This class also has an id instance attribute, which
        may be set to associate some custom options with the object.
        NrL   rA   z.Supplied group %r contains invalid characters.z.Supplied label %r contains invalid characters.r:   )data_ididbuiltins_plot_idr*   rT   r2   r
   label_sanitizeradd_aliasesgroup_sanitizerrZ   r[   	allowablerA   r4   rL   )r]   r   r   plot_idr_   alias	long_namerc   s          r%   r[   zLabelledData.__init__  sw    	48;t#4#4fjj..66 	(!'UI ,AAi/@AAA'F7Ofjj..66 	(!'UI ,AAi/@AAA'F7O""6"""#--dj99 	)M!Z( ) ) )%//
;; 	)M!Z( ) ) )	) 	)r'   c                     | j         S r   r   rf   s    r%   r   zLabelledData.id  s	    xr'   c                 0   | j         }|| _         |t          |           |r||k    rn|t          j        vrg t          j        |<   t	          j        | t          t          |                    }t          j        |                             |           dS dS dS )z+Handles tracking and cleanup of custom ids.N)r   r   r   	_weakrefsweakrefrefr   append)r]   opts_idold_idr   s       r%   r   zLabelledData.id   s     "6***7f#4#4eo--+-(+dG,BG$L$LMMCOG$++C00000	 #4#4r'   c                 p  
 | j                                         }|| j        }n|}|j                             d          

fd|                                D             }|                    d          | j                             d          d         j        k    r|                    d           t          |fi |}	d|	vr
| j	        |	d<   ||r| j
        }|r
| j        |	d<   t          | dt          |           j        z   dz   g            ||g|R i fd	|	                                D             S )
ag  Clones the object, overriding data and parameters.

        Args:
            data: New data replacing the existing data
            shared_data (bool, optional): Whether to use existing data
            new_type (optional): Type to cast object to
            link (bool, optional): Whether clone should be linked
                Determines whether Streams and Links attached to
                original object will be inherited.
            *args: Additional arguments to pass to constructor
            **overrides: New keyword arguments to pass to constructor

        Returns:
            Cloned object
        Nr   c                 $    i | ]\  }}|v 	||S r:   r:   )r<   rj   rk   
new_paramss      r%   rl   z&LabelledData.clone.<locals>.<dictcomp>%  s/     * * *tq!j (r'   rA   r   r   r   __pos_paramsc                 $    i | ]\  }}|v	||S r:   r:   )r<   rj   rk   pos_argss      r%   rl   z&LabelledData.clone.<locals>.<dictcomp>3  s6     *@ *@ *@#!A-.h->-> +,A->->->r'   )rS   rO   rc   r   r   rT   rG   r   r3   r   r   r   getattrr5   r6   )r]   r   shared_datanew_typelinkargsrm   r_   
clone_typern   r   r   s             @@r%   ro   zLabelledData.clone  s   " ""$$JJ!J!//
;;J* * * *v||~~ * * *Fzz'""dj&8&8&D&DW&M&UUU

7###,,),,x!WHTN<K<9D 4&*m#4tDzz':!:^!KRPPz$ A A A A *@ *@ *@ *@9I9I *@ *@ *@ A A 	Ar'   r   c                 (   | j         }|dk    rdt          | dd          rSg }| j                                         D ]7\  }}|                    |||dz
            }|                    ||f           8d|fd|fg}d |D             }	 | j        |fi |	S )	a  Clone object and apply new group and/or label.

        Applies relabeling to children up to the supplied depth.

        Args:
            label (str, optional): New label to apply to returned object
            group (str, optional): New group to apply to returned object
            depth (int, optional): Depth to which relabel will be applied
                If applied to container allows applying relabeling to
                contained objects up to the specified depth

        Returns:
            Returns relabelled object
        r   _deep_indexableFr	   )rA   rL   depthrL   rA   c                     i | ]
\  }}|||S r   r:   ri   s      r%   rl   z(LabelledData.relabel.<locals>.<dictcomp>M  s    ===41aq}!Q}}}r'   )r   r   r   relabelr   ro   )
r]   rL   rA   r   new_datarj   rk   
relabelledkeywordskwargss
             r%   r   zLabelledData.relabel7  s     9AII74):EBBIH	)) 1 11YYU%uQwYOO
J0000e$w&67==8===tz(--f---r'   c                 "   t          |          r t          |t                    s ||           S t          |t                    rt          | |          S | j        j        | j        | j        f}t          |t                    s"t          |                    d                    n|}t          d |D              \  }}t          |          rdS t          d t          |          D              } ||          } ||dt          |                             |k    }|rdS t          j        t          j        t          j        g}t          d t          ||          D                       }	 ||	dt          |                             |k    }
|
S )a  Whether the spec applies to this object.

        Args:
            spec: A function, spec or type to check for a match
                * A 'type[[.group].label]' string which is compared
                  against the type, group and label of this object
                * A function which is given the object and returns
                  a boolean.
                * An object type matched using isinstance.

        Returns:
            bool: Whether the spec matched this object.
        .c              3   2   K   | ]}|d k    s|dn|dfV  dS )*NNTFr:   )r<   ss     r%   r   z'LabelledData.matches.<locals>.<genexpr>c  sM       &9 &9() 783hh!)llRSUZQ[ &9 &9 &9 &9 &9 &9r'   Tc              3   $   K   | ]\  }}||V  d S r   r:   )r<   idxncs      r%   r   z'LabelledData.matches.<locals>.<genexpr>f  s+      RRRrRRRRRRRr'   Nc              3   6   K   | ]\  }} ||d           V  dS )F)escapeNr:   )r<   identfns      r%   r   z'LabelledData.matches.<locals>.<genexpr>k  sQ       )Z )Z-6UB *,E%)@)@)@ )Z )Z )Z )Z )Z )Zr'   )r   r*   r5   rc   r6   rA   rL   r2   splitzipallr   	enumerater   r
   sanitize_identifierr   r   )r]   r^   specification
split_spec	nocomparematch_fn	self_specunescaped_match
sanitizersidentifier_specificationidentifier_matchs              r%   matcheszLabelledData.matchesQ  s    D>> 	C*T4"8"8 	Cd:Kd##BJtT,B,B%B0$*djI3=dE3J3JTU4::c??+++PT
 # &9 &9-7&9 &9 &9 !:
Iy>>&$$RR9Y3G3GRRRSHZ((	"(=1A#j//1A#BCCyP'44.0DdFZ[
#( )Z )Z:=mZ:X:X)Z )Z )Z $Z $Z #8$<=Mc*oo=M$NOOS\\r'   c                 D   |d }|%t          |t          t          t          f          s|g}g }|du }|s|D ]}|                     |          }|r n|r|                     ||                      | j        r&| D ]#}|||                    |||          z  }|s n$|S )a   Traverses object returning matching items
        Traverses the set of children of the object, collecting the
        all objects matching the defined specs. Each object can be
        processed with the supplied function.
        Args:
            fn (function, optional): Function applied to matched objects
            specs: List of specs to match
                Specs must be types, functions or type[.group][.label]
                specs to select objects to return, by default applies
                to all objects.
            full_breadth: Whether to traverse all objects
                Whether to traverse the full set of objects on each
                container or only the first.
        Returns:
            list: List of objects that matched
        Nc                     | S r   r:   xs    r%   r   z'LabelledData.traverse.<locals>.<lambda>  s    1 r'   )r*   r>   setr2   r  r   r   traverse)r]   r  specsfull_breadthaccumulatorr  r^   els           r%   r  zLabelledData.traversep  s    " :BZc57I%J%JGE4- 	" " ",,t,,!EE! 	)rr$xx(((  	+ + +:r{{2ulCCC#*UU*r'   c                 ~    |%t          |t          t          t          f          s|g}|du pt	           fd|D                       } j        ra|r                     d          n }                                 D ]#\  }}|                    |||          }||||<   $|r ||          }|S |r |           n S )a  Map a function to all objects matching the specs

        Recursively replaces elements using a map function when the
        specs apply, by default applies to all objects, e.g. to apply
        the function to all contained Curve objects:

            dmap.map(fn, hv.Curve)

        Args:
            map_fn: Function to apply to each object
            specs: List of specs to match
                List of types, functions or type[.group][.label] specs
                to select objects to return, by default applies to all
                objects.
            clone: Whether to clone the object or transform inplace

        Returns:
            Returns the object after the map_fn has been applied
        Nc              3   B   K   | ]}                     |          V  d S r   r  r<   r^   r]   s     r%   r   z#LabelledData.map.<locals>.<genexpr>  s/      &L&Ldt||D'9'9&L&L&L&L&L&Lr'   Fr   )	r*   r>   r  r2   anyr   ro   r   map)	r]   map_fnr  ro   appliesdeep_mappedrj   rk   new_vals	   `        r%   r&  zLabelledData.map  s    ( Zc57I%J%JGE4-L3&L&L&L&Le&L&L&L#L#L 		5;@J$***777dK

 - -1%%u55&%,KN9ff[&9&9#*466$<<<4r'   c                 Z   | j                                         	 t          j        rS                    dd          =dd         z  }|vr-fdt          j                                        D             |<   ndd<   n*# t          $ r | j        	                    d           Y nw xY wS )z5Ensures pickles save options applied to this objects.r   Nz_custom_option_%dc                 H    i | ]\  }}d          |v ||d                   S r   r:   )r<   backendr   obj_dicts      r%   rl   z-LabelledData.__getstate__.<locals>.<dictcomp>  sD     ,E ,E ,E09/7!/C/C -4Ahuo4F/C/C/Cr'   z*Could not pickle custom style information.)
__dict__copyr   save_option_staterT   _custom_optionsr   	ExceptionrS   rW   )r]   
custom_keyr.  s     @r%   __getstate__zLabelledData.__getstate__  s    =%%''
	M& 'HLL,E,E,Q08E?B
X--,E ,E ,E ,E=B=R=X=X=Z=Z,E ,E ,EHZ( #' 	M 	M 	MJKLLLLL	Ms   A$B $B('B(c                    t          |          }d|v r|d         n|                    dd          }	 t          j        du}|rTd |D             }|D ]3}t	          |                    d          d                   t          j        z   }t          ||         t                    sd||         i}n||         }|                                D ]7\  }}	|t          j	        vri t          j	        |<   |	t          j	        |         |<   8|rj|t          j
        vrg t          j
        |<   t          j        | t          t          |                    }
t          j
        |                             |
           |                    |           5||t          j        z  }n*# t           $ r | j                            d           Y nw xY w||d<   | j                            |           t+                                          i            dS )	z(Restores options applied to this object.r   r   Nc                 <    g | ]}|                     d           |S )_custom_option)
startswithr<   rj   s     r%   r=   z-LabelledData.__setstate__.<locals>.<listcomp>  s*    JJJ1<<8H+I+IJ1JJJr'   r   
matplotlibz,Could not unpickle custom style information.)r&   r   r   load_counter_offsetintr  r*   r3   r   r2  r   r   r   r   r   r   r3  rS   rW   r/  rR   rZ   ru   )r]   r    r   load_optionsr  match	custom_idbackend_infor-  infor   rc   s              r%   ru   zLabelledData.__setstate__  s   ! $qjj!E((aeeD$.?.?	O 4D@L 9JJaJJJ$ ! !E #EKK$4$4R$8 9 9%:S SI%ah55 0(4QuX'>'(x*6*<*<*>*> I I"%*???=?E1':DH-g6yAA# =$EO;;9;EOI6%k$8NPY0Z0Z[[077<<<EE%LLLL&u88G 	O 	O 	OJMNNNNN	O%QR     s   E%F $G GrH   )NTNT)NNr   )NNTr   )r6   r   r   r   rS   r   rA   rL   r   r[   r   r   setterro   r   r  r  r&  r5  ru   r   r   s   @r%   r   r     sc        > EL$ E@ A A AE ELd 9E F F FE
 O) ) ) ) ) )<   X Y
1 
1 Y
1&A &A &A &AR. . . .4     >% % % %P!5 !5 !5 !5H  ""! "! "! "! "! "! "! "! "!r'   r   c                       e Zd ZdZ ej        i d          Z ej        ddd          Z ej        ddd          Z	 ej
        d dd	
          ZdZg dZ edddd          Zd' fd	Zed             Zed             Zed             Zd Zed             Zd(dZd)dZd Zd Zd Zd*dZd+d Zd+d!Zd" Zd# Z dd$d%Z!d'd&Z" xZ#S ),Dimensioneda	  
    Dimensioned is a base class that allows the data contents of a
    class to be associated with dimensions. The contents associated
    with dimensions may be partitioned into one of three types

    * key dimensions: These are the dimensions that can be indexed via
                      the __getitem__ method. Dimension objects
                      supporting key dimensions must support indexing
                      over these dimensions and may also support
                      slicing. This list ordering of dimensions
                      describes the positional components of each
                      multi-dimensional indexing operation.

                      For instance, if the key dimension names are
                      'weight' followed by 'height' for Dimensioned
                      object 'obj', then obj[80,175] indexes a weight
                      of 80 and height of 175.

                      Accessed using either kdims.

    * value dimensions: These dimensions correspond to any data held
                        on the Dimensioned object not in the key
                        dimensions. Indexing by value dimension is
                        supported by dimension name (when there are
                        multiple possible value dimensions); no
                        slicing semantics is supported and all the
                        data associated with that dimension will be
                        returned at once. Note that it is not possible
                        to mix value dimensions and deep dimensions.

                        Accessed using either vdims.

    * deep dimensions: These are dynamically computed dimensions that
                       belong to other Dimensioned objects that are
                       nested in the data. Objects that support this
                       should enable the _deep_indexable flag. Note
                       that it is not possible to mix value dimensions
                       and deep dimensions.

                       Accessed using either ddims.

    Dimensioned class support generalized methods for finding the
    range and type of values along a particular Dimension. The range
    method relies on the appropriate implementation of the
    dimension_values methods on subclasses.

    The index of an arbitrary dimension is its positional index in the
    list of all dimensions, starting with the key dimensions, followed
    by the value dimensions and ending with the deep dimensions.
    z
       The constant dimensions defined as a dictionary of Dimension:value
       pairs providing additional dimension information about the object.

       Aliased with constant_dimensions.rF   )r   NTa0  
       The key dimensions defined as list of dimensions that may be
       used in indexing (and potential slicing) semantics. The order
       of the dimensions listed here determines the semantics of each
       component of a multi-dimensional indexing operation.

       Aliased with key_dimensions.)boundsr   rE   a   
       The value dimensions defined as the list of dimensions used to
       describe the components of the data. If multiple value
       dimensions are supplied, a particular value dimension may be
       indexed by name after the key dimensions.

       Aliased with value_dimensions.z;
       A string describing the data wrapped by the object.r   )r   r   r   ddimsr   r   r   rH  )r   r   r   deep_dimensionsNc                    |                     t          ||                     d|v r'd |d                                         D             |d<    t                      j        |fi | t          | j                  | _        d | j                                        D             }t          |          | _
        d | _        d S )Nr   c                 b    i | ],\  }}t          |t                    r|nt          |          |-S r:   r)   r<   r    r   s      r%   rl   z(Dimensioned.__init__.<locals>.<dictcomp>G  sN     F F F#)1c %/q)$<$<Nqq)A,,PS F F Fr'   c                 &    g | ]\  }}|j         |fS r:   r   rL  s      r%   r=   z(Dimensioned.__init__.<locals>.<listcomp>K  s"    @@@61c!&#@@@r'   )rR   rC   r   rZ   r[   r   r   ndimsr   r3   _cached_constants	_settings)r]   r   r   r   r_   r   rc   s         r%   r[   zDimensioned.__init__D  s    (66777fF F-3G_-B-B-D-DF F FF7O(((((__
@@TZ-=-=-?-?@@@!%er'   c                      t          |           S r   )r   rf   s    r%   applyzDimensioned.applyQ      T{{r'   c                      t          |           S r   )r   rf   s    r%   optszDimensioned.optsU  s    Dzzr'   c                      t          |           S r   )r   rf   s    r%   redimzDimensioned.redimY  rS  r'   c                     || j         }nt          |t                    s|g}g }|D ]O}t          |t                    r|j        }|| j         vrt          d| d          |                    |           P|S )zSValidates key dimension input

        Returns kdims if no dimensions are specifiedNzSupplied dimensions  not found.)r   r*   r>   r+   r0   r3  r   )r]   r@   valid_dimensionsdims       r%   _valid_dimensionszDimensioned._valid_dimensions]  s     JJJ-- 	&$J 	) 	)C#y))93$*$$ Gs G G GHHH##C((((r'   c                 p    | j         r.| r,|                                 d                                         S g S )zThe list of deep dimensionsr   )r   rO   r@   rf   s    r%   rH  zDimensioned.ddimso  s:      	D 	;;==#..000Ir'   r	  Fc                 
   	 dv rdndk    rdnrt          d          d ddifd	 i fd
 i fd}dddd	|dv r d  j        D             } fd|D             }nt          |t                    r	 fd|D             }nr	                    |          |v r<	                    ||          }||         \  }}  j        |fi |}d |D             }nt          dt          |          z            fd|D             S )a  Lists the available dimensions on the object

        Provides convenient access to Dimensions on nested Dimensioned
        objects. Dimensions can be selected by their type, i.e. 'key'
        or 'value' dimensions. By default 'all' dimensions are
        returned.

        Args:
            selection: Type of dimensions to return
                The type of dimension, i.e. one of 'key', 'value',
                'constant' or 'all'.
            label: Whether to return the name, label or Dimension
                Whether to return the Dimension objects (False),
                the Dimension names (True/'name') or labels ('label').

        Returns:
            List of Dimension objects or their names or labels
        )r0   TshortrL   longz7label needs to be one of True, False, 'name' or 'label'c                     | j         S r   )r   r  s    r%   r   z(Dimensioned.dimensions.<locals>.<lambda>      17 r'   r  Fc                     | j         S r   r   r  s    r%   r   z(Dimensioned.dimensions.<locals>.<lambda>  rb  r'   c                     | j         S r   r   r  s    r%   r   z(Dimensioned.dimensions.<locals>.<lambda>  rb  r'   )rj   rk   crj   rk   rg  )r   r   r   )r	  rangesc                     g | ]
}|d k    |S rf  r:   r;   s     r%   r=   z*Dimensioned.dimensions.<locals>.<listcomp>  s    BBBAQ'\\a\\\r'   c                 :    g | ]}t          |          D ]}|S r:   )r   )r<   rA   r[  r]   s      r%   r=   z*Dimensioned.dimensions.<locals>.<listcomp>  sG     5 5 5E&tU335 5  5 5 5 5r'   c                 f    g | ]-}t                              |           d           D ]}|.S )rB   )r   rT   )r<   rA   r[  aliasesr]   s      r%   r=   z*Dimensioned.dimensions.<locals>.<listcomp>  se     L L LU 'U1C1C.I.I.I J JL L  L L L Lr'   c                     g | ]	}|D ]}|
S r:   r:   )r<   keydimsr[  s      r%   r=   z*Dimensioned.dimensions.<locals>.<listcomp>  s%    HHHGHHCHHHHr'   zQInvalid selection %r, valid selections include'all', 'value' and 'key' dimensionsc                 @    g | ]}rd k    r|j         n|j        n|S )r`  )rL   r0   )r<   r[  rL   s     r%   r=   z*Dimensioned.dimensions.<locals>.<listcomp>  sB     3 3 3&)5"evoo388!3 3 3r'   )r4   _dim_groupsr*   r>   rT   r  rQ   repr)
r]   	selectionrL   lambdasgroupsrB   lmbdr   key_traversalrl  s
   ` `      @r%   r@   zDimensioned.dimensionsx  s   & N""EEgEE 	XVWWW**^U,CD**B/**B/1 1 ==)))BB!1BBBF5 5 5 5V 5 5 5DD	4(( 
	TL L L L Li L L LDD[[##w..Iy99I"9-LD&)DM$99&99MHH}HHHDD ACG	??S T T T3 3 3 3-13 3 3 	3r'   c                 6   Ft          t          t          t          f          s$t	          dt                    j        z            |                                 }t          t                    r<dcxk    rt          |          k     rn n|         S |rt          dd          |S t          t                    r0fd|D             }|r|st          d          |r|d         S dS t                    d |D             }|                    d	 |D                        |                    d
 |D                        |                    d |D                        |r|vrt          dd          |                    |          S )ad  Get a Dimension object by name or index.

        Args:
            dimension: Dimension to look up by name or integer index
            default (optional): Value returned if Dimension not found
            strict (bool, optional): Raise a KeyError if not found

        Returns:
            Dimension object for the requested dimension or default
        NzgDimension lookup supports int, string, and Dimension instances, cannot lookup Dimensions using %s type.r   
Dimension z
 not foundc                      g | ]
}|k    |S r:   r:   )r<   r    r-   s     r%   r=   z-Dimensioned.get_dimension.<locals>.<listcomp>  s    :::!9>>A>>>r'   rY  c                     i | ]
}|j         |S r:   )r^   r<   r[  s     r%   rl   z-Dimensioned.get_dimension.<locals>.<dictcomp>  s    :::##:::r'   c                     i | ]
}|j         |S r:   r   r{  s     r%   rl   z-Dimensioned.get_dimension.<locals>.<dictcomp>  s    ???sSXs???r'   c                     i | ]
}|j         |S r:   rL   r{  s     r%   rl   z-Dimensioned.get_dimension.<locals>.<dictcomp>  s    @@@SY@@@r'   c                 B    i | ]}t          j        |j                  |S r:   )r
   rw   r0   r{  s     r%   rl   z-Dimensioned.get_dimension.<locals>.<dictcomp>  s'    YYYT5ch??YYYr'   )r*   r>  r1   r+   	TypeErrorr5   r6   r@   r   rQ   r7   rR   rT   )r]   r-   rG   strictall_dimsrB   name_maps    `     r%   get_dimensionzDimensioned.get_dimension  s     IS)?T)U)U  8:>y//:RS T T T ??$$i%% 	I----H-----	** CICCCDDDi++ 	8::::x:::D d ):::;;; Awt&y11I:::::HOO??h???@@@OO@@x@@@AAAOOYYPXYYYZZZ 8)833DIDDDEEE||Iw777r'   c                    t          |t                    rV|| j        t          | j                  z   k     s%|t          |                                           k     r|S t          d          S t          |          	 | j        | j        z   }t          fdt          |          D                       S # t          $ r" t          d d| j        j         d          dw xY w)zGet the index of the requested dimension.

        Args:
            dimension: Dimension to look up by name or by index

        Returns:
            Integer index of the requested dimension
        zDimension index out of boundsc              3   .   K   | ]\  }}|k    |V  d S r   r:   )r<   ir    r[  s      r%   r   z2Dimensioned.get_dimension_index.<locals>.<genexpr>  s+      HHdaqCxxxxxxHHr'   rx   not found in r   N)r*   r>  rN  r   r   r@   
IndexErrorr7   r   nextr
  StopIterationr3  rc   r6   )r]   r-   r@   r[  s      @r%   get_dimension_indexzDimensioned.get_dimension_index  s     i%% 	CTZ#dj//9::C 1 12222  !"ABBBY''	bDJ.JHHHHi
&;&;HHHHHH 	b 	b 	bVVVDN<SVVVWW]aa	bs   =6B4 4,C c                     |                      |          }|r|j        |j        S d |                     |          D             }t          t	          |                    dk    r|d         S dS )aB  Get the type of the requested dimension.

        Type is determined by Dimension.type attribute or common
        type of the dimension values, otherwise None.

        Args:
            dimension: Dimension to look up by name or by index

        Returns:
            Declared type of values along the dimension
        Nc                 ,    g | ]}t          |          S r:   )r5   r<   rk   s     r%   r=   z2Dimensioned.get_dimension_type.<locals>.<listcomp>  s    @@@DGG@@@r'   r	   r   )r  r5   dimension_valuesr   r  )r]   r[  dim_objdim_valss       r%   get_dimension_typezDimensioned.get_dimension_type  sw     $$S)) 	 w|/<@@T%:%:3%?%?@@@s8}}""A;4r'   c                     | S )a  
        Multi-dimensional indexing semantics is determined by the list
        of key dimensions. For instance, the first indexing component
        will index the first key dimension.

        After the key dimensions are given, *either* a value dimension
        name may follow (if there are multiple value dimensions) *or*
        deep dimensions may then be listed (for applicable deep
        dimensions).
        r:   )r]   r   s     r%   __getitem__zDimensioned.__getitem__  s	     r'   c           	          |t          |t          t          f          s|g} j        r j        dgz   ng  j        fd|                                D             }|;t          |t          t          f          s|g}t           fd|D                       }nd}|r|r j        }t           fd|D                       rt           j         j        z             }d t          |          D             }|                                D ]H\  }}|dk    r||gz  }t          |t                    r	t          | }||                     |          <   I j        r<                     t          |          d          }	|	                     d	          }	n t          |                   }	n }	t          |	t                    s|	S t!          |	          t!                     urXt          |	t                    rC|	                                dgz   t          fd
|D                       r |	j        dd|i|}	nt          |	t                    r|	j        rg }
|	                                D ]t\  }}|                                dgz   t          fd|D                       r%|
                    | |j        dd|i|f           ]|
                    ||f           u|	                    |
          }	|	S )a?  Applies selection by dimension name

        Applies a selection along the dimensions of the object using
        keyword arguments. The selection may be narrowed to certain
        objects using selection_specs. For container objects the
        selection will be applied to all children as well.

        Selections may select a specific value, slice or set of values:

        * value: Scalar values will select rows along with an exact
                 match, e.g.:

            ds.select(x=3)

        * slice: Slices may be declared as tuples of the upper and
                 lower bound, e.g.:

            ds.select(x=(0, 3))

        * values: A list of values may be selected using a list or
                  set, e.g.:

            ds.select(x=[0, 1, 2])

        Args:
            selection_specs: List of specs to match on
                A list of types, functions, or type[.group][.label]
                strings specifying which objects to apply the
                selection on.
            **selection: Dictionary declaring selections by dimension
                Selections can be scalar values, tuple ranges, lists
                of discrete values and boolean arrays

        Returns:
            Returns an Dimensioned object containing the selected data
            or a scalar if a single value was selected
        Nr   c                 *    i | ]\  }}|z   v ||S r:   r:   )r<   rj   rk   r   r   s      r%   rl   z&Dimensioned.select.<locals>.<dictcomp><  s7     - - -Ae++ 1+++r'   c              3   B   K   | ]}                     |          V  d S r   r"  r#  s     r%   r   z%Dimensioned.select.<locals>.<genexpr>C  sC       7 7" ,,t,, 7 7 7 7 7 7r'   Tc              3   *   K   | ]}|j         v V  d S r   rd  )r<   r    r]   s     r%   r   z%Dimensioned.select.<locals>.<genexpr>K  s)      33q1
?333333r'   c                 ,    g | ]}t          d           S r   )slice)r<   r   s     r%   r=   z&Dimensioned.select.<locals>.<listcomp>M  s    888aeDkk888r'   Fr$  c              3       K   | ]}|v V  	d S r   r:   r<   kwr@   s     r%   r   z%Dimensioned.select.<locals>.<genexpr>b  s(      552#555555r'   selection_specsc              3       K   | ]}|v V  	d S r   r:   r  s     r%   r   z%Dimensioned.select.<locals>.<genexpr>i  s(      99BrZ'999999r'   r:   )r*   r>   r2   r   r   r   r%  rN  r   r\   r  r  r   rT   ro   rF  r5   r@   selectr   )r]   r  r   local_kwargsr  rN  r  r[  r   rr  r   rj   rk   r@   r   r   s   `            @@@r%   r  zDimensioned.select  s   L &z/DRW=/Y/Y&./O )-
:
G9$$
- - - - - - - - &oe}== 4#2"3 7 7 7 7&57 7 7 7 7GG G  	G 	JE3333F33333 3DJtz122885<<888F(..00 @ @S'>>seOFF!#u--@UC[s<?F433C8899# 0 HHU6]]D99	$ $

u
 = =I v/		I)[11 	/)__DJJ..:i3U3U."--//7);J5555f55555 X,I,WW_WPVWW		;// 		/I4M 		/E!)) ) )1\\^^wi7
9999&99999 )LL!XQX%X%Xo%XQW%X%X!YZZZZLL!Q((((!..Ir'   c                     | j                             |d          }|rt          j        |g          S t	          d| d| j        j         d          )a  Return the values along the requested dimension.

        Args:
            dimension: The dimension to return values for
            expanded (bool, optional): Whether to expand values
                Whether to return the expanded values, behavior depends
                on the type of data:
                  * Columnar: If false returns unique values
                  * Geometry: If false returns scalar values per geometry
                  * Gridded: If false returns 1D coordinates
            flat (bool, optional): Whether to flatten array

        Returns:
            NumPy array of values along the requested dimension
        Nrx  r  r   )rO  rT   r   arrayr3  rc   r6   )r]   r-   expandedflatr   s        r%   r  zDimensioned.dimension_valuesq  s\      $((D99 	^8SE??"\\\$.BY\\\]]]r'   c                   
 |                      |          }||s|sdS t          d |j        D                       r	|r|j        S |r|| j        | j        z   v r2|                     |j                  }t          j        |          \  }}nX|j        

fd}
fd}| 	                    ||g          }	t          j
        |	          \  }}nt          j        t          j        }}|s||fS t          j        |||j        |j                  S )a  Return the lower and upper bounds of values along dimension.

        Args:
            dimension: The dimension to compute the range on.
            data_range (bool): Compute range from data values
            dimension_range (bool): Include Dimension ranges
                Whether to include Dimension range and soft_range
                in range calculation

        Returns:
            Tuple containing the lower and upper bound
        NrH   c              3   >   K   | ]}t          j        |          V  d S r   )r
   isfiniter  s     r%   r   z$Dimensioned.range.<locals>.<genexpr>  s,      ;;aq!!;;;;;;r'   c                 &    | j         | j        z   v S r   )r   r   r  dnames    r%   r   z#Dimensioned.range.<locals>.<lambda>  s    Uag.?%? r'   c                 .    |                                S r   )r\   r  s    r%   r   z#Dimensioned.range.<locals>.<lambda>  s    QWWU^^ r'   )r  r	  r\   r   r   r  r0   r
   
find_ranger  	max_ranger   nandimension_ranger   )r]   r-   
data_ranger  r  lowerupperr  range_fnrh  r  s             @r%   r\   zDimensioned.range  s+    &&y11	Z<;;9?;;;;; 	, 	,?" 	,DJtz11100@@#x88uu!????3333x(<<#~f55uuFBF5E 	 %<#E5)/9CWXXXr'   c                 *    t          j        |           S r   )r   r   rf   s    r%   r   zDimensioned.__repr__  s    #D)))r'   c                      t          |           S r   )rq  rf   s    r%   r   zDimensioned.__str__  s    Dzzr'   )ro   c                   |                     dd          }|s|sd}n%|r&t          |d         t                    r|d         |i}n|r5t          |d         t                    r|rt	          d          |d         }n|r-d |                                D             rt	          d          |rkt          d |D                       rRt          |          dk    r| j        	                    d	           d
 |d         
                                D             }n*|rt          |          }n|rt          |           j        |i}ddlm} ||i fg}nEt          |t                    r|                    ||          }n||                    ||          fg}| }|D ]"\  }}	|j                            |	||          }#|S )a  Applies simplified option definition returning a new object.

        Applies options on an object or nested group of objects in a
        flat format returning a new object with the options
        applied. If the options are to be set directly on the object a
        simple format may be used, e.g.:

            obj.options(cmap='viridis', show_title=False)

        If the object is nested the options must be qualified using
        a type[.group][.label] specification, e.g.:

            obj.options('Image', cmap='viridis', show_title=False)

        or using:

            obj.options({'Image': dict(cmap='viridis', show_title=False)})

        Identical to the .opts method but returns a clone of the object
        by default.

        Args:
            *args: Sets of options to apply to object
                Supports a number of formats including lists of Options
                objects, a type[.group][.label] followed by a set of
                keyword options to apply and a dictionary indexed by
                type[.group][.label] specs.
            backend (optional): Backend to apply options to
                Defaults to current selected backend
            clone (bool, optional): Whether to clone object
                Options can be applied inplace with clone=False
            **kwargs: Keywords of options
                Set of options to apply to the object

        Returns:
            Returns the cloned object with the options applied
        r-  Nr   z@Please specify a list of option objects, or kwargs, but not bothc                     g | ]
}|d k    |S )r-  r:   r:  s     r%   r=   z'Dimensioned.options.<locals>.<listcomp>  s    BBBQ1	>>q>>>r'   a  Options must be defined in one of two formats. Either supply keywords defining the options for the current object, e.g. obj.options(cmap='viridis'), or explicitly define the type, e.g. obj.options({'Image': {'cmap': 'viridis'}}). Supplying both formats is not supported.c              3   @   K   | ]}t          |t                    V  d S r   )r*   r3   )r<   r  s     r%   r   z&Dimensioned.options.<locals>.<genexpr>  s,      >>2*R..>>>>>>r'   r	   zeOnly a single dictionary can be passed as a positional argument. Only processing the first dictionaryc                 .    g | ]\  }}t          |fi |S r:   )r   )r<   r^   r   s      r%   r=   z'Dimensioned.options.<locals>.<listcomp>  s,    LLLSwt++s++LLLr'      )rU  )r-  ro   )rT   r*   r1   r>   r4   rV   r	  r   rS   rW   r   r5   r6   r
   rU  _expand_by_backend_expand_options_dispatch_opts)
r]   ro   r   r   r-  optionsrU  expanded_backendsobjr  s
             r%   r  zDimensioned.options  s4   L **Y-- 	4 	4GG 	4ja#.. 	4Aw'GG 	4ja$// 	4 e !cddd1gGG 	4BB&++--BBB 	4 H I I I  		4c>>>>>>> 		44yy1}}
"" $: ; ; ; MLDGMMOOLLLGG 	44jjGG 	4Dzz*F3G?")2&& 	T $ 7 7 I I")4+?+?+Q+Q!R S!2 	R 	RGX())(G5)QQCC
r'   c                 *    t          j        |           S )z
        Resolves the class hierarchy for the class rendering the
        object using any display hooks registered on Store.display
        hooks.  The output of all registered display_hooks is then
        combined and returned.
        )r   render)r]   includeexcludes      r%   _repr_mimebundle_zDimensioned._repr_mimebundle_  s     |D!!!r'   rH   )r	  F)NFr   TT)$r6   r   r   r   rS   Dictr   r   r   r   r   rA   _Dimensioned__abstractrp  r3   _dim_aliasesr[   r   rR  rU  rW  r\  rH  r@   r  r  r  r  r  r  r\   r   r   r  r  r   r   s   @r%   rF  rF    s|       1 1f EJr (, - - -E EJi$ =' ( ( (E EJi$ =) * * *E EL D> ? ? ?E J666K4w,3WN N NL	 	 	 	 	 	   X   X   X     $   X.3 .3 .3 .3b)8 )8 )8 )8Xb b b.  ,  ^ ^ ^ ^B^ ^ ^ ^. Y  Y  Y  YD* * *   $( M M M M M^" " " " " " " "r'   rF  c                   >    e Zd ZdZdZdZ ej        d d          ZdS )ViewableElementa~  
    A ViewableElement is a dimensioned datastructure that may be
    associated with a corresponding atomic visualization. An atomic
    visualization will display the data on a single set of axes
    (i.e. excludes multiple subplots that are displayed at once). The
    only new parameter introduced by ViewableElement is the title
    associated with the object for display.
    TFrG   r   N)	r6   r   r   r   _ViewableElement__abstract_auxiliary_componentrS   r   rA   r:   r'   r%   r  r  
  s<          J EL!2TBBBEEEr'   r  c                        e Zd ZdZ ej        d d          ZdZddZe	d             Z
 fdZe	d             Ze	d	             Zed
             Zd fd	Zd Z xZS )ViewableTreez
    A ViewableTree is an AttrTree with Viewable objects as its leaf
    nodes. It combines the tree like data structure of a tree while
    extending it with the deep indexable properties of Dimensioned
    and LabelledData objects.
    Tr  Nc                    |r.t          d |D                       r|                     |          }fdt          | j                  ddgz   D             }t	          j        | |||fi  t          j        | | j        fi | d S )Nc              3   @   K   | ]}t          |t                    V  d S r   )r*   rF  )r<   items     r%   r   z(ViewableTree.__init__.<locals>.<genexpr>(  s,      II4D+66IIIIIIr'   c                 D    i | ]}|v |                     |          S r:   )r   )r<   pr   s     r%   rl   z)ViewableTree.__init__.<locals>.<dictcomp>*  s1    ^^^qRSW]R]R]!VZZ]]R]R]R]r'   r   r   )r	  _process_itemsr>   rS   r   r[   rF  r   )r]   r   
identifierparentr   r_   s       ` r%   r[   zViewableTree.__init__'  s     	/SII5IIIII 	/''..E^^^^D,<,<dI=N,N^^^$z6DDVDDDT497777777r'   c                 <   ddl m} t          |          | u r|j        S t	          ||t
          f          r|g}n$t	          |t                    rt          |          }g }t          d           }| 	                    |||           | 
                    |          }|S )z7Processes list of items assigning unique paths to each.r	   )AdjointLayoutc                      dS )Nr	   r:   r:   r'   r%   r   z-ViewableTree._process_items.<locals>.<lambda>=      Q r'   )layoutr  r5   r   r*   r1   r   r>   r   _unpack_paths_deduplicate_items)clsvalsr  r   countss        r%   r  zViewableTree._process_items/  s     	*)))))::9}c233 	 6DDh'' 	::DYY''$v...&&u--r'   c                     |                     dd          }d|d<   t          t          |                               |           || j        d<   dS )zd
        Ensure that object does not try to reference its parent during
        unpickling.
        r  N)r   rZ   r   ru   r/  )r]   r    r  rc   s      r%   ru   zViewableTree.__setstate__C  sQ    
 x&&(h**1---"(hr'   c                    t          d |D                       }t          |                                          t          |          k    r|S g }t	          d           }|D ]\  }}||         dk    r"|t          j        ||         dz             fz   }n@d}||         r6|dd         t          j        ||         |z             fz   }|dz  }||         6|                    ||f           ||xx         dz  cc<   |S )z5Deduplicates assigned paths by incrementing numberingc                 n    g | ]2\  }}t          d t          |          d z             D ]}|d|         3S )r	   N)r\   r   )r<   pathr   r  s       r%   r=   z3ViewableTree._deduplicate_items.<locals>.<listcomp>Q  sF    XXXa%3t99UV;BWBWXXQ48XXXXr'   c                      dS )Nr   r:   r:   r'   r%   r   z1ViewableTree._deduplicate_items.<locals>.<lambda>V  r  r'   r	   Nr;  )r   sumrO   r   r   r
   int_to_romanr   )r  r   counter	new_itemsr  r  r  incs           r%   r  zViewableTree._deduplicate_itemsN  s)    XX5XXXYYw~~  CLL00L	YY'' 		 		JD$t}q  t0a@@BBTl 9(9&,s:J(K(K'MMD1HC Tl  dD\***4LLLALLLLr'   c                    t          |          | u r|                                }|D ]}t          |t                    r|nd|f\  }}t          |          | u r|                     |||           I|du pt          |          dk    }|rt          j        |          n|}t          j        |||          }|	                    ||f           dS )z
        Recursively unpacks lists and ViewableTree-like objects, accumulating
        into the supplied list of items.
        Nr	   )
r5   r   r*   r2   r  r   r
   get_pathmake_path_uniquer   )	r  objsr   r  r  r  r  r"   new_paths	            r%   r  zViewableTree._unpack_pathsd  s     ::::<<D 	* 	*D *4 7 7IdD\ID#CyyC!!#uf555$,0#d))q.C*-74=&&&4D,T63??HLL(C))))	* 	*r'   c                 $    ddl m}  ||           S )z-Whether items in tree have uniform dimensionsr	   )uniform)	traversalr  )r]   r  s     r%   r  zViewableTree.uniformw  s$     	'&&&&&wt}}r'   c                 P   |                      d          j        |                     d           }t          j        |          v r:fd| D             }t          j        |          }|r|nt          j        |          S t                      
                    ||          S )a  Return the values along the requested dimension.

        Concatenates values on all nodes with requested dimension.

        Args:
            dimension: The dimension to return values for
            expanded (bool, optional): Whether to expand values
                Whether to return the expanded values, behavior depends
                on the type of data:
                  * Columnar: If false returns unique values
                  * Geometry: If false returns scalar values per geometry
                  * Gridded: If false returns 1D coordinates
            flat (bool, optional): Whether to flatten array

        Returns:
            NumPy array of values along the requested dimension
        T)r  c                 >    d |                                  D             S )Nc                     g | ]	}|j         
S r:   r   r;   s     r%   r=   zCViewableTree.dimension_values.<locals>.<lambda>.<locals>.<listcomp>  s    +K+K+KqAF+K+K+Kr'   )r@   r  s    r%   r   z/ViewableTree.dimension_values.<locals>.<lambda>  s    +K+KALLNN+K+K+K r'   c                 j    g | ]/}|                     d           v |                              0S )Tr~  )r@   r  )r<   r  r-   s     r%   r=   z1ViewableTree.dimension_values.<locals>.<listcomp>  sL     A A A"bmm$m&?&??? )))44???r'   )r  r0   r  r   from_iterabler   concatenater
   rY   rZ   r  )r]   r-   r  r  r  rO   r  rc   s    `     r%   r  zViewableTree.dimension_values~  s    $ &&y&>>C	==!K!KLL+H5555A A A At A A AF>&))D#@44):4)@)@@77++8T+ + +r'   c                 *    t          | j                  S r   )r   r   rf   s    r%   __len__zViewableTree.__len__  s    49~~r'   )NNNr  )r6   r   r   r   rS   r   rA   r   r[   classmethodr  ru   r  r  r   r  r  r  r   r   s   @r%   r  r    s         EL$???EO8 8 8 8   [&) ) ) ) )   [* * * [*$   X+ + + + + +:      r'   r  )0r   r   r   r   r   r   collectionsr   r   collections.abcr   	functoolsr   	itertoolsr   operatorr   numpyr   rS   r   r
   	accessorsr   r   r   r  r   r   r   r   r   treer   r   r   r   rW  r&   r.   r7   rC   Parameterizedr+   r   rF  r  r  r:   r'   r%   <module>r	     s   
      				  , , , , , , , , $ $ $ $ $ $                              ) ) ) ) ) ) ) ) ) ) ; ; ; ; ; ; ; ; ; ; ! ! ! ! ! !       " " " " " " %'")+ + %  
S 
S 
S5 5 56  >w\ w\ w\ w\ w\# w\ w\ w\t	|! |! |! |! |!5& |! |! |!~	T" T" T" T" T", T" T" T"pC C C C Ck C C C"A A A A A8[ A A A A Ar'   