§
    ‹hþhlB  ã            	       ó0  — 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mZmZ dZdZdZdZd	Zd
ZdZdZdZdddddddddœZd„ Zd„ Zd„ Zd„ Z G d„ dej        ¦  «        Z G d„ de¦  «        Zd„ Z d „ Z!d-d"„Z"d#„ Z#d$„ Z$d%„ Z%d.d)„Z&d-d*„Z'd+„ Z(d,„ Z)dS )/é    N©Úreduce)Ú
get_module)ÚImageUriValidatorÚcopy_to_readonly_numpy_arrayÚis_homogeneous_arrayi€ÿÿÿé   i €ÿÿiÿ  i   €iÿÿÿéÿ   iÿÿ  l   ÿÿ Úi1Úu1Úi2Úu2Úi4Úu4Úf4Úf8)Úint8Úuint8Úint16Úuint16Úint32Úuint32Úfloat32Úfloat64c                 ód  — t          | ¦  «        } t          dd¬¦  «        }|r t          | |j        ¦  «        r| j        dk    r| S t          | j        ¦  «        }|dk    r®|                      ¦   «         }|                      ¦   «         }|t          k    r!|t          k    r|                      d¦  «        } nÿ|t          k    r!|t          k    r|                      d¦  «        } nÓ|t          k    r!|t          k    r|                      d¦  «        } n§| S |d	k    rŸ|                      ¦   «         }|                      ¦   «         }|t           k    r|dk    r|                      d
¦  «        } nP|t"          k    r|dk    r|                      d¦  «        } n)|t$          k    r|dk    r|                      d¦  «        } n| S t          | j        ¦  «        }|t&          v rat&          |         t)          j        | ¦  «                             d¦  «        dœ}| j        dk    rt          | j        ¦  «        dd…         |d<   |S | S )zi
    Convert numpy array to plotly.js typed array spec
    If not possible return the original value
    ÚnumpyF©Úshould_loadr   Úint64r   r   r   Úuint64r   r   r   Úascii)ÚdtypeÚbdataé   éÿÿÿÿÚshape)r   r   Ú
isinstanceÚndarrayÚsizeÚstrr"   ÚmaxÚminÚint8maxÚint8minÚastypeÚint16maxÚint16minÚint32maxÚint32minÚuint8maxÚ	uint16maxÚ	uint32maxÚplotlyjsShortTypesÚbase64Ú	b64encodeÚdecodeÚndimr&   )ÚvÚnpr"   r+   r,   ÚarrObjs         úJ/var/www/histauto/venv/lib/python3.11/site-packages/_plotly_utils/utils.pyÚto_typed_array_specr@   '   s  € õ
 	% QÑ'Ô'€Aõ 
�G¨Ð	/Ñ	/Ô	/€BØð •Z  2¤:Ñ.Ô.ð °!´&¸A²+°+Øˆå�”‰LŒL€Eð �ÒÐØ�eŠe‰gŒgˆØ�eŠe‰gŒgˆØ•'Š>ˆ>˜c¥Wšn˜nØ—’˜Ñ Ô ˆAˆAØ•HŠ_ˆ_ ­¢ Ø—’˜Ñ!Ô!ˆAˆAØ•HŠ_ˆ_ ­¢ Ø—’˜Ñ!Ô!ˆAˆAàˆHà	�(Ò	Ð	Ø�eŠe‰gŒgˆØ�eŠe‰gŒgˆØ•(Š?ˆ?˜s ašx˜xØ—’˜Ñ!Ô!ˆAˆAØ•IÒÐ #¨¢( (Ø—’˜Ñ"Ô"ˆAˆAØ•IÒÐ #¨¢( (Ø—’˜Ñ"Ô"ˆAˆAàˆHå�”‰LŒL€EàÕ"Ð"Ð"å'¨Ô.ÝÔ% aÑ(Ô(×/Ò/°Ñ8Ô8ð
ð 
ˆð
 Œ6�AŠ:ˆ:Ý! !¤'™lœl¨1¨R¨4Ô0ˆF�7‰Oàˆà€Hó    c                 óB   ‡ — g d¢}t          ˆ fd„|D ¦   «         ¦  «        S )zR
    Return whether the key is skipped for conversion to the typed array spec
    )ÚgeojsonÚlayerÚlayersÚrangec              3   ó$   •K  — | ]
}|‰k    V — Œd S ©N© )Ú.0Úskipped_keyÚkeys     €r?   ú	<genexpr>z!is_skipped_key.<locals>.<genexpr>d   s(   øè è € ÐBÐB kˆ{˜cÒ!ÐBÐBÐBÐBÐBÐBrA   )Úany)rL   Úskipped_keyss   ` r?   Úis_skipped_keyrP   _   s3   ø€ ð ;Ð:Ð:€LÝÐBÐBÐBÐB°\ÐBÑBÔBÑBÔBÐBrA   c                 ój  — t          | t          ¦  «        r]|                      ¦   «         D ]F\  }}t          |¦  «        rŒt	          |¦  «        rt          |¦  «        | |<   Œ7t          |¦  «         ŒGd S t          | t          ¦  «        st          | t          ¦  «        r| D ]}t          |¦  «         Œd S d S rH   )	r'   ÚdictÚitemsrP   r   r@   Úconvert_to_base64ÚlistÚtuple)ÚobjrL   Úvalues      r?   rT   rT   g   sÙ   € Ý�#•tÑÔð 
%ØŸ)š)™+œ+ð 	)ð 	)‰JˆC�Ý˜cÑ"Ô"ð )ØÝ% eÑ,Ô,ð )Ý.¨uÑ5Ô5��C‘�å! %Ñ(Ô(Ð(Ð(ð	)ð 	)õ 
�C�Ñ	Ô	ð %¥*¨Sµ%Ñ"8Ô"8ð %Øð 	%ð 	%ˆEÝ˜eÑ$Ô$Ð$Ð$ð%ð %ð	%ð 	%rA   c                 ó.   — d„ }t          || g ¦  «        }|S )z0
    Custom cumsum to avoid a numpy import.
    c                 óL   — t          | ¦  «        dk    r|gS | | d         |z   gz   S ©Nr   r%   )Úlen)ÚaÚxs     r?   Ú_reducerzcumsum.<locals>._reducerz   s,   € Ýˆq‰6Œ6�QŠ;ˆ;Ø�3ˆJØ�A�b”E˜A‘I�;‰ÐrA   r   )r^   r_   Úrets      r?   Úcumsumra   u   s)   € ð
ð ð õ
 �˜1˜bÑ
!Ô
!€CØ€JrA   c                   óô   ‡ — e Zd ZdZd„ Zˆ fd„Zd„ Zed„ ¦   «         Zed„ ¦   «         Z	ed„ ¦   «         Z
ed„ ¦   «         Zed	„ ¦   «         Zed
„ ¦   «         Zed„ ¦   «         Zed„ ¦   «         Zed„ ¦   «         Zˆ xZS )ÚPlotlyJSONEncodera9  
    Meant to be passed as the `cls` kwarg to json.dumps(obj, cls=..)

    See PlotlyJSONEncoder.default for more implementation information.

    Additionally, this encoder overrides nan functionality so that 'Inf',
    'NaN' and '-Inf' encode to 'null'. Which is stricter JSON than the Python
    version.

    c                 ó   — |dv rdS |S )zU
        This is used to ultimately *encode* into strict JSON, see `encode`

        )ÚInfinityz	-InfinityÚNaNNrI   )ÚselfÚconsts     r?   Úcoerce_to_strictz"PlotlyJSONEncoder.coerce_to_strict�   s   € ð Ð4Ð4Ð4Ø�4àˆLrA   c                 ó6  •— t          t          | ¦  «                             |¦  «        }d|v sd|v s|S 	 t          j        || j        ¬¦  «        }t          j        || j        | j        | j	        | j
        f¬¦  «        S # t          $ r t          d¦  «        ‚w xY w)zœ
        Load and then dump the result using parse_constant kwarg

        Note that setting invalid separators will cause a failure at this step.

        rf   re   )Úparse_constant)Ú	sort_keysÚindentÚ
separatorszSEncoding into strict JSON failed. Did you set the separators valid JSON separators?)Úsuperrc   ÚencodeÚ_jsonÚloadsri   Údumpsrl   rm   Úitem_separatorÚkey_separatorÚ
ValueError)rg   ÚoÚ	encoded_oÚnew_oÚ	__class__s       €r?   rp   zPlotlyJSONEncoder.encodeš   sÆ   ø€ õ Õ+¨TÑ2Ô2×9Ò9¸!Ñ<Ô<ˆ	ð ˜Ð"Ð" j°IÐ&=Ð&=ØÐð
	Ý”K 	¸$Ô:OÐPÑPÔPˆEõ ”;ØØœ.Ø”{Ø Ô/°Ô1CÐDð	ñ ô ð øõ ð 	ð 	ð 	åð)ñô ð ð	øøøs   µA> Á>Bc           	      óö   — | j         | j        | j        | j        | j        | j        | j        | j        | j        f	}|D ]}	  ||¦  «        c S # t          $ r Y Œw xY wt          j                             | |¦  «        S )a  
        Accept an object (of unknown type) and try to encode with priority:
        1. builtin:     user-defined objects
        2. sage:        sage math cloud
        3. pandas:      dataframes/series
        4. numpy:       ndarrays
        5. datetime:    time/datetime objects

        Each method throws a NotEncoded exception if it fails.

        The default method will only get hit if the object is not a type that
        is naturally encoded by json:

            Normal objects:
                dict                object
                list, tuple         array
                str, unicode        string
                int, long, float    number
                True                true
                False               false
                None                null

            Extended objects:
                float('nan')        'NaN'
                float('infinity')   'Infinity'
                float('-infinity')  '-Infinity'

        Therefore, we only anticipate either unknown iterables or values here.

        )Úencode_as_plotlyÚencode_as_sageÚencode_as_numpyÚencode_as_pandasÚencode_as_datetimeÚencode_as_dateÚencode_as_listÚencode_as_decimalÚencode_as_pilÚNotEncodablerq   ÚJSONEncoderÚdefault)rg   rW   Úencoding_methodsÚencoding_methods       r?   r‡   zPlotlyJSONEncoder.default¾   s¨   € ðB Ô!ØÔØÔ ØÔ!ØÔ#ØÔØÔØÔ"ØÔð

Ðð  0ð 	ð 	ˆOðØ&� sÑ+Ô+Ð+Ð+Ð+øÝð ð ð Ø�ðøøøåÔ ×(Ò(¨¨sÑ3Ô3Ð3s   ¾
AÁ
AÁAc                 óV   — 	 |                       ¦   «         S # t          $ r t          ‚w xY w)z1Attempt to use a builtin `to_plotly_json` method.)Úto_plotly_jsonÚAttributeErrorr…   ©rW   s    r?   r|   z"PlotlyJSONEncoder.encode_as_plotlyð   s:   € ð	Ø×%Ò%Ñ'Ô'Ð'øÝð 	ð 	ð 	ÝÐð	øøøó   ‚ –(c                 óX   — t          | d¦  «        r|                      ¦   «         S t          ‚)z@Attempt to use `tolist` method to convert to normal Python list.Útolist)Úhasattrr�   r…   r�   s    r?   r‚   z PlotlyJSONEncoder.encode_as_listø   s*   € õ �3˜Ñ!Ô!ð 	Ø—:’:‘<”<ÐåÐrA   c                 ó    — t          d¦  «        }|st          ‚| |j        v rt          | ¦  «        S | |j        v rt          | ¦  «        S t          ‚)z@Attempt to convert sage.all.RR to floats and sage.all.ZZ to intszsage.all)r   r…   ÚRRÚfloatÚZZÚint)rW   Úsage_alls     r?   r}   z PlotlyJSONEncoder.encode_as_sage   sV   € õ ˜jÑ)Ô)ˆØð 	ÝÐà�(”+ÐÐÝ˜‘:”:ÐØ�H”KÐÐÝ�s‘8”8ˆOåÐrA   c                 ó�   — t          dd¬¦  «        }|st          ‚| |j        u rdS t          |d¦  «        r| |j        u rdS t          ‚)z)Attempt to convert pandas.NaT / pandas.NAÚpandasFr   NÚNA)r   r…   ÚNaTr‘   rš   )rW   r™   s     r?   r   z"PlotlyJSONEncoder.encode_as_pandas  sa   € õ ˜H°%Ð8Ñ8Ô8ˆØð 	ÝÐà�&”*ÐÐØ�4õ �6˜4Ñ Ô ð 	 S¨F¬IÐ%5Ð%5Ø�4åÐrA   c                 óB  — t          dd¬¦  «        }|st          ‚| |j        j        j        u rt          d¦  «        S t          | |j        ¦  «        rH| j        j	        dk    r8	 | 
                    | ¦  «                             ¦   «         S # t          $ r Y nw xY wt          ‚)z'Attempt to convert numpy.ma.core.maskedr   Fr   ÚnanÚM)r   r…   ÚmaÚcoreÚmaskedr”   r'   r(   r"   ÚkindÚdatetime_as_stringr�   Ú	TypeError)rW   r   s     r?   r~   z!PlotlyJSONEncoder.encode_as_numpy  s±   € õ ˜7°Ð6Ñ6Ô6ˆØð 	ÝÐà�%”(”-Ô&Ð&Ð&Ý˜‘<”<ÐÝ˜˜Uœ]Ñ+Ô+ð 	°´	´À#Ò0EÐ0EðØ×/Ò/°Ñ4Ô4×;Ò;Ñ=Ô=Ð=øÝð ð ð Ø�ðøøøõ Ðs   Á#&B
 Â

BÂBc                 óV   — 	 |                       ¦   «         S # t          $ r t          ‚w xY w)z.Convert datetime objects to iso-format strings)Ú	isoformatrŒ   r…   r�   s    r?   r€   z$PlotlyJSONEncoder.encode_as_datetime/  s6   € ð	Ø—=’=‘?”?Ð"øÝð 	ð 	ð 	ÝÐð	øøørŽ   c                 ót   — 	 |                       ¦   «         }t          |¦  «        S # t          $ r t          ‚w xY w)z=Attempt to convert to utc-iso time string using date methods.)r¦   Úiso_to_plotly_time_stringrŒ   r…   )rW   Útime_strings     r?   r�   z PlotlyJSONEncoder.encode_as_date7  sG   € ð	:ØŸ-š-™/œ/ˆKõ -¨[Ñ9Ô9Ð9øõ ð 	ð 	ð 	ÝÐð	øøøs   ‚% ¥7c                 ób   — t          | t          j        ¦  «        rt          | ¦  «        S t          ‚)z3Attempt to encode decimal by converting it to float)r'   ÚdecimalÚDecimalr”   r…   r�   s    r?   rƒ   z#PlotlyJSONEncoder.encode_as_decimalA  s*   € õ �c�7œ?Ñ+Ô+ð 	Ý˜‘:”:ÐåÐrA   c                 ó„   — t          d¦  «        }|�)t          | |j        ¦  «        rt          j        | ¦  «        S t
          ‚)z5Attempt to convert PIL.Image.Image to base64 data uriz	PIL.Image)r   r'   ÚImager   Úpil_image_to_urir…   )rW   Úimages     r?   r„   zPlotlyJSONEncoder.encode_as_pilI  s?   € õ ˜;Ñ'Ô'ˆØÐ¥¨C°´Ñ!=Ô!=ÐÝ$Ô5°cÑ:Ô:Ð:åÐrA   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ri   rp   r‡   Ústaticmethodr|   r‚   r}   r   r~   r€   r�   rƒ   r„   Ú__classcell__)rz   s   @r?   rc   rc   ƒ   sU  ø€ € € € € ð	ð 	ð	ð 	ð 	ð"ð "ð "ð "ð "ðH04ð 04ð 04ðd ðð ñ „\ðð ðð ñ „\ðð ðð ñ „\ðð ðð ñ „\ðð ðð ñ „\ðð  ðð ñ „\ðð ð:ð :ñ „\ð:ð ðð ñ „\ðð ðð ñ „\ðð ð ð ð rA   rc   c                   ó   — e Zd ZdS )r…   N)r±   r²   r³   rI   rA   r?   r…   r…   S  s   € € € € € Ø€DrA   r…   c                 óv  — |                       d¦  «        dd…         dk    s|                       d¦  «        d         dk    rt          d¦  «        ‚|                      dd	¦  «                             d
d	¦  «        } |                      d¦  «        r|                      dd	¦  «        S |                      dd¦  «        S )z=Remove timezone info and replace 'T' delimeter with ' ' (ws).ú-Né   z00:00ú+r   z]Plotly won't accept timestrings with timezone info.
All timestrings are assumed to be in UTC.z-00:00Ú z+00:00z	T00:00:00ÚTú )ÚsplitÚ	ExceptionÚreplaceÚendswith)Ú
iso_strings    r?   r¨   r¨   W  sÃ   € ð 	×Ò˜ÑÔ˜b˜q˜bÔ! WÒ,Ð,°*×2BÒ2BÀ3Ñ2GÔ2GÈÔ2JÈgÒ2UÐ2UÝð8ñ
ô 
ð 	
ð
 ×#Ò# H¨bÑ1Ô1×9Ò9¸(ÀBÑGÔG€Jà×Ò˜;Ñ'Ô'ð ,Ø×!Ò! +¨rÑ2Ô2Ð2à×!Ò! # sÑ+Ô+Ð+rA   c                  ó   ‡ — ˆ fd„}|S )Nc                 ót   •— t           j        d d…         dk    s| j        � | j        j        di ‰¤Ž| _        | S )Né   )rº   rÆ   rI   )ÚsysÚversion_infor´   Úformat)ÚfuncÚnamess    €r?   Ú
_decoratorz template_doc.<locals>._decoratori  sC   ø€ ÝÔ   Ô# vÒ-Ð-ØŒ|Ð'Ø2˜tœ|Ô2Ð;Ð;°UÐ;Ð;�”ØˆrA   rI   )rË   rÌ   s   ` r?   Útemplate_docrÍ   h  s$   ø€ ðð ð ð ð ð ÐrA   Fc                 ó,   — d„ }t          | ||¬¦  «        S )Nc                 óÚ   — t          j        d| ¦  «        }t          t          |¦  «        ¦  «        D ]+}	 t	          ||         ¦  «        ||<   Œ# t
          $ r Y Œ(w xY wt          |¦  «        S )Nz(\d+))Úrer¿   rF   r\   r–   rv   rV   )r<   Úv_partsÚis      r?   rL   z"_natural_sort_strings.<locals>.keys  sx   € Ý”(˜8 QÑ'Ô'ˆÝ•s˜7‘|”|Ñ$Ô$ð 	ð 	ˆAðÝ  ¨¤™_œ_�˜‘
�
øÝð ð ð à�ðøøøõ �W‰~Œ~Ðs   µAÁ
AÁA)rL   Úreverse©Úsorted)ÚvalsrÓ   rL   s      r?   Ú_natural_sort_stringsr×   r  s(   € ðð ð õ �$˜C¨Ð1Ñ1Ô1Ð1rA   c                  óZ   — t          dd¬¦  «        } | rt          | j        f}nt          f}|S )Nr   Fr   )r   r–   Úinteger)r=   Úint_types     r?   Ú_get_int_typerÛ   €  s6   € Ý	�G¨Ð	/Ñ	/Ô	/€BØ	ð Ý˜œÐ$ˆˆå�6ˆØ€OrA   c                 óº   ‡— t          |¦  «        dk    r| S |                     ¦   «         Št          d„ t          ˆfd„| ¦  «        ¦  «        } t	          | |¦  «        S )ar  
    Split all the strings in ss at any of the characters in chars.
    Example:

        >>> ss = ["a.string[0].with_separators"]
        >>> chars = list(".[]_")
        >>> split_multichar(ss, chars)
        ['a', 'string', '0', '', 'with', 'separators']

    :param (list) ss: A list of strings.
    :param (list) chars: Is a list of chars (note: not a string).
    r   c                 ó   — | |z   S rH   rI   )r^   Úys     r?   ú<lambda>z!split_multichar.<locals>.<lambda>™  s
   € ˜Q ™U€ rA   c                 ó.   •— |                       ‰¦  «        S rH   )r¿   )r^   Úcs    €r?   rß   z!split_multichar.<locals>.<lambda>™  s   ø€ °!·'²'¸!±*´*€ rA   )r\   Úpopr   ÚmapÚsplit_multichar)ÚssÚcharsrá   s     @r?   rä   rä   ‰  s]   ø€ õ ˆ5�z„z�Q‚€Øˆ	Ø�	Š	‰Œ€AÝ	Ð"Ð"¥CÐ(<Ð(<Ð(<Ð(<¸bÑ$AÔ$AÑ	BÔ	B€BÝ˜2˜uÑ%Ô%Ð%rA   c                 ó   — t          t          d„ t          t          t	          | ¦  «        ¦  «        t          dgt          t          t          | dd…         ¦  «        ¦  «        z   ¦  «        ¦  «        ¦  «        ¦  «        S )a  
    Given a list of strings split using split_multichar, return a list of
    integers representing the indices of the first character of every string in
    the original string.
    Example:

        >>> ss = ["a.string[0].with_separators"]
        >>> chars = list(".[]_")
        >>> ss_split = split_multichar(ss, chars)
        >>> ss_split
        ['a', 'string', '0', '', 'with', 'separators']
        >>> split_string_positions(ss_split)
        [0, 2, 9, 11, 12, 17]

    :param (list) ss: A list of strings.
    c                 ó$   — | d         | d         z   S )Nr   r$   rI   )Úts    r?   rß   z(split_string_positions.<locals>.<lambda>°  s   € �a˜”d˜Q˜qœT‘k€ rA   r   Nr%   )rU   rã   ÚziprF   r\   ra   )rå   s    r?   Úsplit_string_positionsrë   �  sk   € õ" ÝØ!Ð!Ý••c˜"‘g”g‘”¥¨ s­Tµ#µc¸2¸c¸r¸c¼7Ñ2CÔ2CÑ-DÔ-DÑ'DÑ EÔ EÑFÔFñ	
ô 	
ñô ð rA   r$   ú^Tc                 óH  — d„ t          t          | ¦  «        dz   |z   |z   ¦  «        D ¦   «         }d}|€%| D ]!}t          |¦  «        D ]}	||z   |	z   }|||<   ŒŒ"n%t          |¦  «        D ]}	| |         |z   |	z   }|||<   Œd                     |¦  «        }
|r|
d|dz   …         }
|
S )a»  
    Return a string that is whitespace except at p[i] which is replaced with char.
    If i is None then all the indices of the string in p are replaced with char.

    Example:

        >>> ss = ["a.string[0].with_separators"]
        >>> chars = list(".[]_")
        >>> ss_split = split_multichar(ss, chars)
        >>> ss_split
        ['a', 'string', '0', '', 'with', 'separators']
        >>> ss_pos = split_string_positions(ss_split)
        >>> ss[0]
        'a.string[0].with_separators'
        >>> display_string_positions(ss_pos,4)
        '            ^'
        >>> display_string_positions(ss_pos,4,offset=1,length=3,char="~",trim=False)
        '             ~~~      '
        >>> display_string_positions(ss_pos)
        '^ ^      ^ ^^    ^'
    :param (list) p: A list of integers.
    :param (integer|None) i: Optional index of p to display.
    :param (integer) offset: Allows adding a number of spaces to the replacement.
    :param (integer) length: Allows adding a replacement that is the char
                             repeated length times.
    :param (str) char: allows customizing the replacement character.
    :param (boolean) trim: trims the remaining whitespace if True.
    c                 ó   — g | ]}d ‘ŒS )r¾   rI   )rJ   Ú_s     r?   ú
<listcomp>z,display_string_positions.<locals>.<listcomp>Ó  s   € Ð:Ð:Ð:�ˆÐ:Ð:Ð:rA   r$   r   Nr¼   )rF   r+   Újoin)ÚprÒ   ÚoffsetÚlengthÚcharÚtrimÚsÚmaxaddrÚp_Útempr`   s              r?   Údisplay_string_positionsrû   ¶  sæ   € ð: 	;Ð:•e�C ™FœF Q™J¨Ñ/°&Ñ8Ñ9Ô9Ð:Ñ:Ô:€AØ€GØ€yØð 	"ð 	"ˆBÝ˜f™œð "ð "�Ø˜v™+¨Ñ,�Ø!��'‘
�
ð"ð	"õ
 ˜&‘M”Mð 	ð 	ˆDØ˜”d˜V‘m dÑ*ˆGØˆAˆg‰JˆJØ
�'Š'�!‰*Œ*€CØð !Ø�-�G˜a‘K�-Ô ˆØ€JrA   c           
      óz  — d„ }|r" |t           || ¦  «        |¦  «        ¦  «        S t          | ¦  «        s| S t          t          t          | ¦  «        ¦  «        dk    r|t          | ¦  «        dz
  z  gS  G d„ d¦  «        }t	          t          t          t           ||¦  «        | dg¦  «        ¦  «        ¦  «        S )aÈ  
    Given a list of strings, some of which are the empty string "", replace the
    empty strings with c and combine them with the closest non-empty string on
    the left or "" if it is the first string.
    Examples:
    for c="_"
    ['hey', '', 'why', '', '', 'whoa', '', ''] -> ['hey_', 'why__', 'whoa__']
    ['', 'hi', '', "I'm", 'bob', '', ''] -> ['_', 'hi_', "I'm", 'bob__']
    ['hi', "i'm", 'a', 'good', 'string'] -> ['hi', "i'm", 'a', 'good', 'string']
    Some special cases are:
    [] -> []
    [''] -> ['']
    ['', ''] -> ['_']
    ['', '', '', ''] -> ['___']
    If reverse is true, empty strings are combined with closest non-empty string
    on the right or "" if it is the last string.
    c                 ó,   — d„ | D ¦   «         d d d…         S )Nc                 ó$   — g | ]}|d d d…         ‘ŒS )Nr%   rI   )rJ   r÷   s     r?   rð   z5chomp_empty_strings.<locals>._rev.<locals>.<listcomp>ø  s"   € Ð&Ð&Ð&˜A��$�$�B�$”Ð&Ð&Ð&rA   r%   rI   )rÖ   s    r?   Ú_revz!chomp_empty_strings.<locals>._rev÷  s!   € Ø&Ð& Ð&Ñ&Ô& t t¨ tÔ,Ð,rA   r   r$   c                   ó   — e Zd Zd„ Zd„ ZdS )ú%chomp_empty_strings.<locals>._Chomperc                 ó   — || _         d S rH   )rá   )rg   rá   s     r?   Ú__init__z.chomp_empty_strings.<locals>._Chomper.__init__  s   € ØˆDŒFˆFˆFrA   c                 ól   — t          |¦  «        dk    r|d d…         |d         | j        z   gz   S ||gz   S r[   )r\   rá   )rg   r^   rÞ   s      r?   Ú__call__z.chomp_empty_strings.<locals>._Chomper.__call__  s>   € õ
 �1‰vŒv˜Š{ˆ{Ø˜˜"˜”v  2¤¨¬¡Ð 0Ñ0Ð0à˜A˜3‘w�rA   N)r±   r²   r³   r  r  rI   rA   r?   Ú_Chomperr    s2   € € € € € ð	ð 	ð 	ð	ð 	ð 	ð 	ð 	rA   r  r¼   )Úchomp_empty_stringsr\   Úsumrã   rU   Úfilterr   )Ústringsrá   rÓ   rÿ   r  s        r?   r  r  ä  sß   € ð&-ð -ð -ð ð ;ØˆtÕ'¨¨¨W©¬°qÑ9Ô9Ñ:Ô:Ð:Ýˆw‰<Œ<ð ØˆÝ
�3�s�GÑÔÑÔ Ò"Ð"Ø•S˜‘\”\ AÑ%Ñ&Ð'Ð'ðð ð ð ð ñ ô ð õ ••s�F 8 8¨A¡;¤;°¸"¸Ñ>Ô>Ñ?Ô?Ñ@Ô@Ð@rA   c           	      óð  — t          | ¦  «        t          |¦  «        k     rt          || ¦  «        S t          |¦  «        dk    rt          | ¦  «        S t          t          |¦  «        dz   ¦  «        }t          | ¦  «        D ]n\  }}|dz   g}t          |¦  «        D ]Q\  }}||dz            dz   }||         dz   }	||         ||k    z   }
|                     t          ||	|
¦  «        ¦  «         ŒR|}Œo|d         S )Nr   r$   r%   )r\   ÚlevenshteinrF   Ú	enumerateÚappendr,   )Ús1Ús2Úprevious_rowrÒ   Úc1Úcurrent_rowÚjÚc2Ú
insertionsÚ	deletionsÚsubstitutionss              r?   r  r    s  € Ý
ˆ2�w„w•�R‘”ÒÐÝ˜2˜rÑ"Ô"Ð"Ý
ˆ2�w„w�!‚|€|Ý�2‰wŒwˆÝ�˜R™œ 1™Ñ%Ô%€LÝ˜2‘”ð 	#ð 	#‰ˆˆ2Ø˜1‘u�gˆÝ˜r‘]”]ð 	Jð 	J‰EˆAˆrð & a¨!¡eÔ,¨qÑ0ˆJØ# Aœ¨Ñ*ˆIØ(¨œO¨r°RªxÑ8ˆMØ×Ò�s :¨y¸-ÑHÔHÑIÔIÐIÐIØ"ˆˆØ˜ÔÐrA   c                 ó<   ‡ — ˆ fd„}t          ||¬¦  «        d         S )Nc                 ó(   •— t          | ‰¦  «        | fS rH   )r  )r÷   Ústrings    €r?   Ú_keyz!find_closest_string.<locals>._key(  s   ø€ õ ˜A˜vÑ&Ô&¨Ð*Ð*rA   )rL   r   rÔ   )r  r
  r  s   `  r?   Úfind_closest_stringr  '  s6   ø€ ð+ð +ð +ð +ð +õ
 �'˜tÐ$Ñ$Ô$ QÔ'Ð'rA   )F)Nr   r$   rì   T)*r8   r«   Újsonrq   rÇ   rÐ   Ú	functoolsr   Ú_plotly_utils.optional_importsr   Ú_plotly_utils.basevalidatorsr   r   r   r.   r-   r1   r0   r3   r2   r4   r5   r6   r7   r@   rP   rT   ra   r†   rc   rÀ   r…   r¨   rÍ   r×   rÛ   rä   rë   rû   r  r  r  rI   rA   r?   ú<module>r"     s6  ðØ €€€Ø €€€Ø Ð Ð Ð Ø 
€
€
€
Ø 	€	€	€	Ø Ð Ð Ð Ð Ð à 5Ð 5Ð 5Ð 5Ð 5Ð 5ðð ð ð ð ð ð ð ð ð ð €Ø
€Ø€Ø€Ø€Ø€à€Ø€	Ø€	ð ØØØØØØØð	ð 	Ð ð5ð 5ð 5ðpCð Cð Cð%ð %ð %ðð ð ðMð Mð Mð Mð M˜Ô)ñ Mô Mð Mð`	ð 	ð 	ð 	ð 	�9ñ 	ô 	ð 	ð,ð ,ð ,ð"ð ð ð2ð 2ð 2ð 2ðð ð ð&ð &ð &ð(ð ð ð2+ð +ð +ð +ð\+Að +Að +Að +Að`ð ð ð&(ð (ð (ð (ð (rA   