
    $g/                    h   d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlmZ ddlmZmZ ddlmZ ddlmZmZmZmZmZ ddlmZ e	j        d	k    r	dd
lmZmZ ndd
lmZmZ ddlmZ ddl m!Z!m"Z" erddl#m$Z$  ed          Z% ej&        e'          Z(dZ)ddd\dZ*d]dZ+d^dZ,e	j        dk    re-j.        Z/nd_dZ/d`d!Z0e	j        d	k    rdd"l1m2Z2 nd# d$dad)Z2dbd,Z3dcd/Z4ddd1Z5ded4Z6 ej7        d5          Z8ded6Z9 ej:        d7          dfd9            Z;dgd<Z<dhdidAZ= ej:        d7          djdC            Z>	 dhdkdFZ?dG Z@dldIZA ej:        d7          dmdK            ZBdndMZCdodOZDdpdRZEdS ZFdT ZG G dU dV          ZH G dW dXejI                  ZJ G dY dZ          ZKdqd[ZLdS )rz
Standalone file utils.

Nothing in this module should have an knowledge of config or the layout
and structure of the site and pages in the site.
    )annotationsN)defaultdict)datetimetimezone)PurePath)TYPE_CHECKING
CollectionIterableMutableSequenceTypeVar)urlsplit)   
   )
EntryPointentry_points)
exceptions)get_yaml_loader	yaml_load)PageT)z	.markdownz.mdownz.mkdnz.mkdz.md)pagesr   Collection[Page] | Nonereturnintc                    | rLt          d | D                       }t          j        |                              t          j                  }nt                      }t          |                                          S )z
    Returns the number of seconds since the epoch for the latest updated page.

    In reality this is just today's date because that's how pages' update time is populated.
    c              3  $   K   | ]}|j         V  d S N)update_date).0ps     U/var/www/html/netbox-4.1.3/venv/lib/python3.11/site-packages/mkdocs/utils/__init__.py	<genexpr>z&get_build_timestamp.<locals>.<genexpr>7   s$      77A!-777777    )tzinfo)	maxr   fromisoformatreplacer   utcget_build_datetimer   	timestamp)r   date_stringdts      r!   get_build_timestampr-   /   sn      "7777777#K00888MM!!r||~~r#   r   c                     t           j                            d          } | t          j        t
          j                  S t          j        t          |           t
          j                  S )z
    Returns an aware datetime object.

    Support SOURCE_DATE_EPOCH environment variable for reproducible builds.
    See https://reproducible-builds.org/specs/source-date-epoch/
    SOURCE_DATE_EPOCH)	osenvirongetr   nowr   r(   fromtimestampr   )source_date_epochs    r!   r)   r)   >   sO     
':;; |HL)))!#&7"8"8(,GGGr#   strc                 D    t                                          d          S )z
    Returns the displayable date string.

    Support SOURCE_DATE_EPOCH environment variable for reproducible builds.
    See https://reproducible-builds.org/specs/source-date-epoch/
    z%Y-%m-%d)r)   strftime r#   r!   get_build_dater:   L   s     ((444r#   )r   	   ssuffixc                d    |r-|                      |          r| d t          |                    S | S r   )endswithlen)r<   r=   s     r!   _removesuffixrA   Z   s9     	%ajj(( 	%^F|^$$r#   data_setIterable[T]list[T]c                P    t          t                              |                     S )z4Reduce duplicate items in a list and preserve order.)listdictfromkeys)rB   s    r!   reduce_listrI   `   s    h''(((r#   )insortc                    | S r   r9   )vs    r!   <lambda>rM   i   s    Q r#   )keyaMutableSequence[T]xNonec                    ||          }t          |           }|dk    r;| || |dz
                     k     r#|dz  }|dk    r| || |dz
                     k     #|                     ||           d S )Nr      )r@   insert)rO   rQ   rN   kxis        r!   rJ   rJ   i   s    SVVFF!eeSS1q5]]**FA !eeSS1q5]]**	Ar#   source_pathoutput_pathc                R   t           j                            |          }t          j        |d           t           j                            |          r=t           j                            |t           j                            |                     }t          j        | |           dS )z}
    Copy source_path to output_path, making sure any parent directories exist.

    The output_path may be a directory.
    Texist_okN)	r0   pathdirnamemakedirsisdirjoinbasenameshutilcopyfile)rX   rY   
output_dirs      r!   	copy_filerf   q   s     --JK
T****	w}}[!! Ogll;0@0@0M0MNN
OK-----r#   contentbytesc                    t           j                            |          }t          j        |d           t	          |d          5 }|                    |            ddd           dS # 1 swxY w Y   dS )zGWrite content to output_path, making sure any parent directories exist.Tr[   wbN)r0   r]   r^   r_   openwrite)rg   rY   re   fs       r!   
write_filern   ~   s    --JK
T****	k4	 	  A	                 s   A))A-0A-	directoryc                t   t           j                            |           sdS t          j        |           D ]}|                    d          rt           j                            | |          }t           j                            |          rt          j        |d           mt          j	        |           dS )zKRemove the content of a directory recursively but not the directory itself.N.T)
r0   r]   existslistdir
startswithra   r`   rc   rmtreeunlink)ro   entryr]   s      r!   clean_directoryrx      s    7>>)$$ I&& 
 
 C   	w||Iu--7== 	M$%%%%IdOOOO
 
r#   r]   boolc                6    |                      t                    S )z
    Return True if the given file path is a Markdown file.

    https://superuser.com/questions/249436/file-extension-for-markdown-files
    )r?   markdown_extensionsr]   s    r!   is_markdown_filer}      s     ==,---r#   z^\d{3}\.html?$c                P    t          t                              |                     S )z=Return True if the given file path is an HTTP error template.)ry   _ERROR_TEMPLATE_REmatchr|   s    r!   is_error_templater      s    "((..///r#   )maxsize	list[str]c                    |                      d          sd| z   } t          j        |           dd          } | r|                     d          ng S )N/rT   )rt   	posixpathnormpathsplitr|   s    r!   _norm_partsr      sQ    ??3 Tzd##ABB'D"*4::c???*r#   urlotherc                n   |                     d          \  }}}d|v r|}t          |          }t          |           }d}t          ||          D ]\  }}	||	k    r n|dz  }dgt          |          |z
  z  ||d         z   }
d                    |
          pd}|                     d          r|dz   n|S )a  
    Return given url relative to other.

    Both are operated as slash-separated paths, similarly to the 'path' part of a URL.
    The last component of `other` is skipped if it contains a dot (considered a file).
    Actual URLs (with schemas etc.) aren't supported. The leading slash is ignored.
    Paths are normalized ('..' works as parent directory), but going higher than the
    root has no effect ('foo/../../bar' ends up just as 'bar').
    r   rq   r   rT   z..N)
rpartitionr   zipr@   ra   r?   )r   r   r^   _rb   other_parts
dest_partscommonrO   b	rel_partsrelurls               r!   get_relative_urlr      s     !++C00GQ
he$$KS!!JFK,,  166E!#k**V34z&''7JJIXXi  'CF<<,,86C<<&8r#    pagePage | Nonebasec                    t          |           \  } }|dk    r| S |%t          | |j                  }|dk    rd|z  |z   }|S t          j        ||           S )z:Return a URL relative to the given page or using the base.Nr   ../)_get_norm_urlr   r   r   ra   )r]   r   r   relative_levelresults        r!   normalize_urlr      sl    (..D.!$11A^+f4F>$%%%r#   tuple[str, int]c                   | sd} n8d| v r4t                               d|  d           |                     dd          } t          |           }|j        s|j        s|                     d          r| dfS t          j        |           dz   }d}|                    d	|d
z            r|dz  }|                    d	|d
z            | |fS )Nrq   \zPath 'zh' uses OS-specific separator '\'. That will be unsupported in a future release. Please change it to '/'.r   )r   #r   r   r   r   rT   )	logwarningr'   r   schemenetlocrt   r   r   )r]   parsednormr   s       r!   r   r      s    '	VT V V V	
 	
 	
 ||D#&&d^^F}  )D)D Rx d##c)DN
//%!!3
4
4 ! //%!!3
4
4 r#   	path_listIterable[str]c                $    fd| D             S )Soft-deprecated, do not use.c                2    g | ]}t          |          S r9   )r   )r   r]   r   r   s     r!   
<listcomp>z%create_media_urls.<locals>.<listcomp>   s%    BBBM$d++BBBr#   r9   )r   r   r   s    ``r!   create_media_urlsr      s$     CBBBB	BBBBr#   c                b    t          j        dt                     |                     dd          S )Nz=path_to_url is never used in MkDocs and will be removed soon.r   r   )warningswarnDeprecationWarningr'   r|   s    r!   path_to_urlr      s2    MGI[   <<c"""r#   namec                    t                      |          }t          j                            t          j                            |                                j                            S )z3Return the directory of an installed theme by name.)
get_themesr0   r]   r^   abspathload__file__)r   themes     r!   get_theme_dirr      s=    LLE7??27??5::<<+@AABBBr#   dict[str, EntryPoint]c                    i } t                               t          d                    }d |D             }|D ]}|j        J |j        |v r:|j        j        dk    r*t          j        d|j         d|j        j         d          |j        | v r[| |j                 j        }|J t                              d	|j         d
|j        j         d|j         d|j        j         d	           || |j        <   | S )z<Return a dict of all installed themes as {name: EntryPoint}.zmkdocs.themes)groupc                J    h | ] }|j         	|j         j        dk    |j        !S )Nmkdocs)distr   )r   eps     r!   	<setcomp>zget_themes.<locals>.<setcomp>  s0    ZZZB)<QYAYAYAYAYAYr#   Nr   zThe theme 'z&' is a builtin theme but the package 'z1' attempts to provide a theme with the same name.zA theme named 'z&' is provided by the Python packages 'z' and 'z'. The one in 'z' will be used.)	rG   rH   r   r   r   r   ConfigurationErrorr   r   )themesepsbuiltinsr   
other_dists        r!   r   r     sa    %'F"&--?0S0S0S"T"TCZZ#ZZZH # #z%%%:!!ejo&A&A/Bej B BPUPZP_ B B B   Z6!!
+0J)))KKY%* Y YTYT^Tc Y Y"Y Y8=
Y Y Y  
 #uzMr#   Collection[str]c                 B    t                                                      S )z.Return a list of all installed themes by name.)r   keysr9   r#   r!   get_theme_namesr   "  s    <<r#   r^   c                    | }|                     dd                               dd          }|                                |k    r|                                }|S )z2Return a page tile obtained from a directory name.- r   )r'   lower
capitalize)r^   titles     r!   dirname_to_titler   '  sS    EMM#s##++C55E{{}}  ""Lr#   markdown_src
str | Nonec                T   |                      dd                               dd                              d          }|rh|                    d                                          }|                                s>|                    d          sdS |                    d          S dS )r   z

r   z# N)r'   r   popstriprt   lstrip)r   lineslines      r!   get_markdown_titler   2  s      ..66tTBBHHNNE
 !yy||!!##zz|| 	t$$ 	4{{4   4r#   c                    | D ]&}t          |t                    s||v r
||         c S 'g }||i}|                     |           |S )z
    Given a list, look for dictionary with a key matching key and return it's
    value. If it doesn't exist, create it with the value of an empty list and
    return that.
    )
isinstancerG   append)branchrN   node
new_branchs       r!   find_or_create_noder   ?  so       $%% 	$;;9  JD
MM$r#   c                    g }| D ]V}t          |          j        j        }|}|D ]!}t          |          }t	          ||          }"|                    |           W|S )zk
    Given a list of paths, convert them into a nested structure that will match
    the pages config.
    )r   parentpartsr   r   r   )pathsnestedr]   r   r   parts         r!   
nest_pathsr   R  su    
 F  %+ 	7 	7D#D))D(66FFdMr#   c                  "    e Zd ZdZd
dZddZd	S )DuplicateFilterz!Avoid logging duplicate messages.r   rR   c                ,    t                      | _        d S r   )setmsgsselfs    r!   __init__zDuplicateFilter.__init__i  s    !ee			r#   recordlogging.LogRecordry   c                `    |j         | j        v}| j                            |j                    |S r   )msgr   addr   r   rvs      r!   __call__zDuplicateFilter.__call__l  s+    Zty(	fj!!!	r#   Nr   rR   )r   r   r   ry   )__name__
__module____qualname____doc__r   r   r9   r#   r!   r   r   f  sB        ++$ $ $ $     r#   r   c                  2     e Zd ZdZd fdZd Zd	dZ xZS )
CountHandlerz$Counts all logged messages >= level.r   rR   c                l    t          t                    | _         t                      j        di | d S )Nr9   )r   r   countssuperr   )r   kwargs	__class__s     r!   r   zCountHandler.__init__u  s5    &1#&6&6""6"""""r#   c                h    |                      |          }|r| j        |j        xx         dz  cc<   |S )NrT   )filterr	  levelnor   s      r!   handlezCountHandler.handley  s@    [[   	-K'''1,'''	r#   list[tuple[str, int]]c                f    d t          | j                                        d          D             S )Nc                @    g | ]\  }}t          j        |          |fS r9   )logginggetLevelName)r   krL   s      r!   r   z+CountHandler.get_counts.<locals>.<listcomp>  s,    cccA%a((!,cccr#   T)reverse)sortedr	  itemsr   s    r!   
get_countszCountHandler.get_counts  s2    cc@Q@Q@S@S]a9b9b9bccccr#   r  )r   r  )r  r  r  r  r   r  r  __classcell__)r  s   @r!   r  r  r  sn        ..# # # # # #  d d d d d d d dr#   r  c                       e Zd ZdZd ZddZdS )weak_propertyzHSame as a read-only property, but allows overwriting the field for good.c                ,    || _         |j        | _        d S r   )funcr  )r   r  s     r!   r   zweak_property.__init__  s    	|r#   Nc                4    || S |                      |          S r   )r  )r   instanceowners      r!   __get__zweak_property.__get__  s    Kyy"""r#   r   )r  r  r  r  r   r#  r9   r#   r!   r  r    s=        RR$ $ $# # # # # #r#   r  c                    | dk    r-t          j        dt                     t          j                    S t          dt          d|           )Nwarning_filterzwarning_filter doesn't do anything since MkDocs 1.2 and will be removed soon. All messages on the `mkdocs` logger get counted automatically.zmodule z has no attribute )r   r   r   r  FilterAttributeErrorr  )r   s    r!   __getattr__r(    sZ    M	
 	
 	

 ~
I8IIII
J
JJr#   )r   r   r   r   )r   r   )r   r6   )r<   r6   r=   r6   r   r6   )rB   rC   r   rD   )rO   rP   rQ   r   r   rR   )rX   r6   rY   r6   r   rR   )rg   rh   rY   r6   r   rR   )ro   r6   r   rR   )r]   r6   r   ry   )r]   r6   r   r   )r   r6   r   r6   r   r6   )Nr   )r]   r6   r   r   r   r6   r   r6   )r]   r6   r   r   )r   r   r   r   r   r6   r   r   )r   r6   r   r6   )r   r   )r   r   )r^   r6   r   r6   )r   r6   r   r   )r   r6   )Mr  
__future__r   	functoolsr  r0   r   rerc   sysr   collectionsr   r   r   pathlibr   typingr   r	   r
   r   r   urllib.parser   version_infoimportlib.metadatar   r   importlib_metadatar   r   mkdocs.utils.yamlr   r   mkdocs.structure.pagesr   r   	getLoggerr  r   r{   r-   r)   r:   r6   removesuffixrA   rI   bisectrJ   rf   rn   rx   r}   compiler   r   	lru_cacher   r   r   r   r   r   r   r   r   r   r   r   r   r   NullHandlerr  r  r(  r9   r#   r!   <module>r<     s    # " " " " "      				     				  



  # # # # # # ' ' ' ' ' ' ' '       P P P P P P P P P P P P P P ! ! ! ! ! !w;;;;;;;;;;;;;;;;;       8 8 8 8 8 8 8 8 ,++++++GCLLg!!  =A      H H H H5 5 5 5 v$MM   ) ) ) )
 w 4?;      
. 
. 
. 
.      $. . . .  RZ 122 0 0 0 0
 T"""+ + + #"+9 9 9 98& & & & & T"""      #" . EGC C C C C# # #C C C C T"""   #"6   
   
 
 
 
  &  (	 	 	 	 	 	 	 	d d d d d7& d d d$
# 
# 
# 
# 
# 
# 
# 
#	K 	K 	K 	K 	K 	Kr#   