
    MhȬ                   @   U d dl mZ d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mZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z" d d	l#m$Z$m%Z% er6d d
l&m'Z' d dl(m)Z) d dl*m+Z+ d dlm,Z,m-Z- d dl.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z: e!ed         eed                  f         Z;de<d<   ee!d                  Z=de<d<    e>d          Z? ej@        d          ZAde<d<   dWdZBdZCde<d<    ej@        d           ZDde<d!<    eEg d"          ZFd#e<d$<    G d% d&eG          ZH G d' d(eG          ZI G d) d*eI          ZJ G d+ d,eeG                   ZK G d- d.eeef                   ZL G d/ d0eL          ZM G d1 d2eL          ZN G d3 d4eI          ZO G d5 d6eP          ZQ G d7 deGeQ          ZR G d8 d9eR          ZS G d: d;eS          ZT G d< d=eS          ZU G d> d?eU          ZV G d@ dAeS          ZW G dB dCeS          ZX G dD dEeS          ZY G dF dGeR          ZZ G dH dIeR          Z[ G dJ dKeR          Z\ G dL dMeR          Z] G dN dOeR          Z^ G dP dQeQ          Z_ e dReQS          Z` G dT dUee`         ee`                   Zad dVl*mbZb dS )X    )annotationsMITNCSS)_deprecated_deprecated_alias_deprecated_function_alias)	FormatterHTMLFormatterXMLFormatter)!AttributeResemblesVariableWarning)AnyCallableDictGenericIterableIteratorListMappingOptionalPatternSetTYPE_CHECKINGTupleTypeTypeVarUnioncast)Self	TypeAliasBeautifulSoup)TreeBuilderElementFilter)_EntitySubstitutionFunction_FormatterOrName)_AtMostOneElement_AttributeValue_AttributeValues	_Encoding_InsertableElement_OneElement_QueryResults_RawOrProcessedAttributeValues_StrainableElement_StrainableAttribute_StrainableAttributes_StrainableStringNavigableStringr    _OneOrMoreStringTypes)r0   r%   _FindMethodNamezYThe {name} attribute was deprecated in version 4.7.0. If you need it, make your own copy.)whitespace_rez\s+Pattern[str]_deprecated_whitespace_renamestrreturnr   c                    | t           v rTt           |          }t          j        |                    |           t          d           t                      d|           S t          dt          d|           )Nr:      
stacklevel_deprecated_zmodule z has no attribute )_deprecated_nameswarningswarnformatDeprecationWarningglobalsAttributeError__name__)r:   messages     K/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/bs4/element.py__getattr__rM   T   sv       #D)gnn$n//1CPQRRRRyy...//
I8IIII
J
JJ    utf-8DEFAULT_OUTPUT_ENCODINGz\S+nonwhitespace_re)idnambcsoempalmospunycoderaw_unicode_escape	undefinedunicode_escapezraw-unicode-escapezunicode-escapezstring-escapestring_escapezSet[_Encoding]PYTHON_SPECIFIC_ENCODINGSc                  @    e Zd ZU dZded<   ded<   ded<   	 	 d
dd	ZdS )NamespacedAttributezA namespaced attribute (e.g. the 'xml:lang' in 'xml:lang="en"')
    which remembers the namespace prefix ('xml') and the name ('lang')
    that were used to create it.
    Optional[str]prefixr:   	namespaceNr<   r   c                    |sd }|st                               | |          }n?|st                               | |          }n!t                               | |dz   |z             }||_        ||_        ||_        |S )N:)r;   __new__r_   r:   r`   )clsr_   r:   r`   objs        rL   rc   zNamespacedAttribute.__new__   s      	 D 	8++c6**CC 	8++c4((CC++c6C<$#677C
!
rN   )NN)r_   r^   r:   r^   r`   r^   r<   r   )rJ   
__module____qualname____doc____annotations__rc    rN   rL   r]   r]      sg          
 
 ##'	      rN   r]   c                  &    e Zd ZU dZded<   ddZdS )	%AttributeValueWithCharsetSubstitutiona  An abstract class standing in for a character encoding specified
    inside an HTML ``<meta>`` tag.

    Subclasses exist for each place such a character encoding might be
    found: either inside the ``charset`` attribute
    (`CharsetMetaAttributeValue`) or inside the ``content`` attribute
    (`ContentMetaAttributeValue`)

    This allows Beautiful Soup to replace that part of the HTML file
    with a different encoding when ouputting a tree as a string.
    r;   original_valueeventual_encodingr<   c                    t                      )zDo whatever's necessary in this implementation-specific
        portion an HTML document to substitute in a specific encoding.
        NotImplementedErrorselfrn   s     rL   substitute_encodingz9AttributeValueWithCharsetSubstitution.substitute_encoding   s     "###rN   N)rn   r;   r<   r;   )rJ   rf   rg   rh   ri   rt   rj   rN   rL   rl   rl      sB         
 
 $ $ $ $ $ $rN   rl   c                  $    e Zd ZdZddZddd
ZdS )CharsetMetaAttributeValueaz  A generic stand-in for the value of a ``<meta>`` tag's ``charset``
    attribute.

    When Beautiful Soup parses the markup ``<meta charset="utf8">``, the
    value of the ``charset`` attribute will become one of these objects.

    If the document is later encoded to an encoding other than UTF-8, its
    ``<meta>`` tag will mention the new encoding instead of ``utf8``.
    rm   r;   r<   r   c                J    t                               | |          }||_        |S N)r;   rc   rm   rd   rm   re   s      rL   rc   z!CharsetMetaAttributeValue.__new__   s$     kk#~..+
rN   rO   rn   r+   c                    |t           v rdS |S )zWhen an HTML document is being encoded to a given encoding, the
        value of a ``<meta>`` tag's ``charset`` becomes the name of
        the encoding.
         )r[   rr   s     rL   rt   z-CharsetMetaAttributeValue.substitute_encoding   s    
  9992  rN   Nrm   r;   r<   r   rO   rn   r+   r<   r;   )rJ   rf   rg   rh   rc   rt   rj   rN   rL   rv   rv      sK            ! ! ! ! ! ! !rN   rv   c                      e Zd ZdZdS )AttributeValueLista-  Class for the list used to hold the values of attributes which
    have multiple values (such as HTML's 'class'). It's just a regular
    list, but you can subclass it and pass it in to the TreeBuilder
    constructor as attribute_value_list_class, to have your subclass
    instantiated instead.
    NrJ   rf   rg   rh   rj   rN   rL   r   r                 rN   r   c                      e Zd ZdZdS )AttributeDictzSuperclass for the dictionary used to hold a tag's
    attributes. You can use this, but it's just a regular dict with no
    special logic.
    Nr   rj   rN   rL   r   r      s           rN   r   c                  $     e Zd ZdZd	 fdZ xZS )
XMLAttributeDictzyA dictionary for holding a Tag's attributes, which processes
    incoming values for consistency with the HTML spec.
    keyr;   valuer   r<   Nonec                    |d}t          |t                    rn+t          |t          t          f          rt	          |          }t                                          ||           dS )zSet an attribute value, possibly modifying it to comply with
        the XML spec.

        This just means converting common non-string values to
        strings: XML attributes may have "any literal string as a
        value."
        Nr{   )
isinstanceboolintfloatr;   super__setitem__rs   r   r   	__class__s      rL   r   zXMLAttributeDict.__setitem__   si     =EeT"" 	
 U|,, 	 JJEC'''''rN   r   r;   r   r   r<   r   rJ   rf   rg   rh   r   __classcell__r   s   @rL   r   r      sG         ( ( ( ( ( ( ( ( ( (rN   r   c                  $     e Zd ZdZd	 fdZ xZS )
HTMLAttributeDicta  A dictionary for holding a Tag's attributes, which processes
    incoming values for consistency with the HTML spec, which says
    'Attribute values are a mixture of text and character
    references...'

    Basically, this means converting common non-string values into
    strings, like XMLAttributeDict, though HTML also has some rules
    around boolean attributes that XML doesn't have.
    r   r;   r   r   r<   r   c                &   |dv r	|| v r| |= dS t          |t                    r t          |t                    r|j        }n.|}n+t          |t          t
          f          rt          |          }t                                          ||           dS )z\Set an attribute value, possibly modifying it to comply
        with the HTML spec,
        )FNN)	r   r   r]   r:   r   r   r;   r   r   r   s      rL   r   zHTMLAttributeDict.__setitem__  s     M!! d{{IFeT"" 	 #233 U|,, 	 JJEC'''''rN   r   r   r   s   @rL   r   r   	  sG         ( ( ( ( ( ( ( ( ( (rN   r   c                  \    e Zd ZU dZ ej        dej                  Zded<   dd	Z	dddZ
dS )ContentMetaAttributeValuea  A generic stand-in for the value of a ``<meta>`` tag's ``content``
    attribute.

    When Beautiful Soup parses the markup:
     ``<meta http-equiv="content-type" content="text/html; charset=utf8">``

    The value of the ``content`` attribute will become one of these objects.

    If the document is later encoded to an encoding other than UTF-8, its
    ``<meta>`` tag will mention the new encoding instead of ``utf8``.
    z((^|;)\s*charset=)([^;]*)r8   
CHARSET_RErm   r;   r<   r   c                ~    | j                             |           t                              | |          }||_        |S rx   )r   searchr;   rc   rm   ry   s      rL   rc   z!ContentMetaAttributeValue.__new__F  s8    n---kk#~..+
rN   rO   rn   r+   c                    t           v r | j                            d| j                  S dfd}| j                            || j                  S )zWhen an HTML document is being encoded to a given encoding, the
        value of the ``charset=`` in a ``<meta>`` tag's ``content`` becomes
        the name of the encoding.
        r{   matchre.Match[str]r<   r;   c                4    |                      d          z   S )N   )group)r   rn   s    rL   rewritez>ContentMetaAttributeValue.substitute_encoding.<locals>.rewriteT  s    ;;q>>$555rN   )r   r   r<   r;   )r[   r   subrm   )rs   rn   r   s    ` rL   rt   z-ContentMetaAttributeValue.substitute_encodingL  sg    
  999?&&r4+>???	6 	6 	6 	6 	6 	6 ""7D,?@@@rN   Nr|   r}   r~   )rJ   rf   rg   rh   recompileMr   ri   rc   rt   rj   rN   rL   r   r   4  sx         
 
  *rz*FMMJMMMM   A A A A A A ArN   r   c                     e Zd ZU dZdZded<   ded<   ded<   d	ed
<   d	ed<   d	ed<   d	ed<   dZded<   	 	 	 	 	 dddZddZddZ	e
dd            Z eddd          Z eddd          Zddd$Zdd%Z e            Zd&ed'<   defdd+Ze
dd,            Zd-defdd0ZeZ e
e          Zdd2Z ed3d4d          Zdd7Zddd:Zdd;Z	 ddd?Z ed@dAd          ZddDZ ddEZ!di dfddNZ" edOdPd          Z#di dddQfddVZ$ edWdXd          Z%di dfddYZ& edZd[d          Z'di dddQfdd\Z( ed]d^d          Z) ed_d^d`          Z*di dfddaZ+ edbdcd`          Z,di dddQfdddZ- ededfd          Z. edgdfd`          Z/di dfddhZ0 edidjd          Z1di dddQfddkZ2 edldmd          Z3 edndmd`          Z4di fddoZ5 edpdqd          Z6di ddQfddrZ7 edsdtd          Z8 edudtd`          Z9e
ddv            Z:e
ddw            Z;ddzZ<	 ddd~Z=e
dd            Z>e
dd            Z?e
dd            Z@e
dd            ZAe
dd            ZBe
dd            ZCe
dd            ZDe
dd            ZEe
dd            ZFe
dd            ZGddZHe
dd            ZI eJdd          dd            ZK eJdd          dd            ZL eJdd          dd            ZM eJdd          dd            ZN eJdd          dd            ZOdS )PageElementaz  An abstract class representing a single element in the parse tree.

    `NavigableString`, `Tag`, etc. are all subclasses of
    `PageElement`. For this reason you'll see a lot of methods that
    return `PageElement`, but you'll never see an actual `PageElement`
    object. For the most part you can think of `PageElement` as
    meaning "a `Tag` or a `NavigableString`."
    NOptional[bool]	known_xmlr   _decomposedOptional[Tag]parentr(   next_elementprevious_elementnext_siblingprevious_siblingFhiddenr<   r   c                6   || _         || _        | j        | | j        _        || _        | j        | | j        _        || _        | j        | | j        _        |%| j         | j         j        r| j         j        d         }|| _        | j        | | j        _        dS dS )aI  Sets up the initial relations between this element and
        other elements.

        :param parent: The parent of this element.

        :param previous_element: The element parsed immediately before
            this one.

        :param next_element: The element parsed immediately after
            this one.

        :param previous_sibling: The most recently encountered element
            on the same level of the parse tree as this one.

        :param previous_sibling: The next element to be encountered
            on the same level of the parse tree as this one.
        N)r   r   r   r   r   contents)rs   r   r   r   r   r   s         rL   setupzPageElement.setupx  s    2  0 ,15D!.((15D.((15D. $'$ (  ${3B7 0 ,15D!... -,rN   sr;   	formatterOptional[_FormatterOrName]c                    ||S t          |t                    s|                     |          }|                    |          }|S )zFormat the given string using the given formatter.

        :param s: A string.
        :param formatter: A Formatter object, or a string naming one of the standard formatters.
        )r   r
   formatter_for_name
substitute)rs   r   r   outputs       rL   format_stringzPageElement.format_string  sL     H)Y// 	;//	::I%%a((rN   formatter_name4Union[_FormatterOrName, _EntitySubstitutionFunction]r
   c                    t          |t                    r|S | j        rt          }t          j        }nt
          }t
          j        }t          |          r ||          S ||         S )a  Look up or create a Formatter for the given identifier,
        if necessary.

        :param formatter: Can be a `Formatter` object (used as-is), a
            function (used as the entity substitution hook for an
            `bs4.formatter.XMLFormatter` or
            `bs4.formatter.HTMLFormatter`), or a string (used to look
            up an `bs4.formatter.XMLFormatter` or
            `bs4.formatter.HTMLFormatter` in the appropriate registry.

        )entity_substitution)r   r
   _is_xmlr   REGISTRYr   callable)rs   r   cregistrys       rL   r   zPageElement.formatter_for_name  sr     ni00 	"!! < 	.A#,HHA$-HN## 	918888''rN   c                f    | j         | j         S | j        t          | dd          S | j        j        S )a  Is this element part of an XML tree or an HTML tree?

        This is used in formatter_for_name, when deciding whether an
        XMLFormatter or HTMLFormatter is more appropriate. It can be
        inefficient, but it should be called very rarely.
        Nis_xmlF)r   r   getattrr   rs   s    rL   r   zPageElement._is_xml  s?     >% >!
 ; 45111{""rN   nextSibling4.0.0previousSiblingmemoDict[Any, Any]	recursiver   c                    t                      rx   rp   rs   r   r   s      rL   __deepcopy__zPageElement.__deepcopy__  s    !###rN   c                ,    |                      i           S )zA copy of a PageElement can only be a deep copy, because
        only one PageElement can occupy a given place in a parse tree.
        )r   r   s    rL   __copy__zPageElement.__copy__  s       $$$rN   Iterable[type[NavigableString]]defaultstriptypesIterator[str]c                    t                      )zYield all strings of certain classes, possibly stripping them.

        This is implemented differently in `Tag` and `NavigableString`.
        rp   )rs   r   r   s      rL   _all_stringszPageElement._all_strings  s     "###rN   c              #  B   K   |                      d          D ]}|V  dS )zYield all interesting strings in this PageElement, stripping them
        first.

        See `Tag` for information on which strings are considered
        interesting in a given context.
        TNr   )rs   strings     rL   stripped_stringszPageElement.stripped_strings  s:       ''-- 	 	FLLLL	 	rN   r{   	separatorIterable[Type[NavigableString]]c                j    |                     d |                     ||          D                       S )a  Get all child strings of this PageElement, concatenated using the
        given separator.

        :param separator: Strings will be concatenated using this separator.

        :param strip: If True, strings will be stripped before being
            concatenated.

        :param types: A tuple of NavigableString subclasses. Any
            strings of a subclass not found in this list will be
            ignored. Although there are exceptions, the default
            behavior in most cases is to consider only NavigableString
            and CData objects. That means no comments, processing
            instructions, etc.

        :return: A string.
        c                    g | ]}|S rj   rj   ).0r   s     rL   
<listcomp>z(PageElement.get_text.<locals>.<listcomp>#  s    PPPQqPPPrN   )r   )joinr   )rs   r   r   r   s       rL   get_textzPageElement.get_text  s8    . ~~PP$*;*;E*;*O*OPPPQQQrN   argsc                     j         t          d          t          |          dk    r|d          u r S t           fd|D                       rt          d           j         } j                                        }                     |           t          ||          D ]\  }}|                    ||            S )	zReplace this `PageElement` with one or more other `PageElement`,
        objects, keeping the rest of the tree the same.

        :return: This `PageElement`, no longer part of the tree.
        Nz^Cannot replace one element with another when the element to be replaced is not part of a tree.r   r   c              3  *   K   | ]}|j         u V  d S rx   r   r   xrs   s     rL   	<genexpr>z+PageElement.replace_with.<locals>.<genexpr>6  s*      ..AqDK......rN   z%Cannot replace a Tag with its parent._self_index)start)r   
ValueErrorlenanyindexextract	enumerateinsert)rs   r   
old_parentmy_indexidxreplace_withs   `     rL   r  zPageElement.replace_with(  s     ;@   t99>>d1gooK......... 	FDEEE[
;$$T*****!*4x!@!@!@ 	1 	1Cc<0000rN   replaceWithr  wrap_insideTagc                Z    |                      |          }|                    |           |S )zWrap this `PageElement` inside a `Tag`.

        :return: ``wrap_inside``, occupying the position in the tree that used
           to be occupied by this object, and with this object now inside it.
        )r  append)rs   r  mes      rL   wrapzPageElement.wrapA  s1     {++2rN   r   Optional[int]c                
   | j         )|| j                             |           }| j         j        |= |                                 }t	          t
          |          }|j        }| j        | j        |ur|| j        _        ||| j        ur| j        |_        d| _        d|_        d| _         | j        | j        | j	        ur| j	        | j        _	        | j	        | j	        | j        ur| j        | j	        _        dx| _        | _	        | S )a'  Destructively rips this element out of the tree.

        :param _self_index: The location of this element in its parent's
           .contents, if known. Passing this in allows for a performance
           optimization.

        :return: this `PageElement`, no longer part of the tree.
        N)
r   r   r   _last_descendantr   r   r   r   r   r   )rs   r   
last_childr   s       rL   r   zPageElement.extractK  s    ;"""k//55$[1
 **,,
 +z22
!. ,$L885A%2#D<Q(Q(Q,0,AL) $"&
!-%T->>>151BD!.)!)>>>151FD.488 1rN   c                    |                                   | }d}|I|j        }|j                                         t	          |t
                    rg |_        d|_        |}|GdS dS )a  Recursively destroys this `PageElement` and its children.

        The element will be removed from the tree and wiped out; so
        will everything beneath it.

        The behavior of a decomposed `PageElement` is undefined and you
        should never use one for anything, but if you need to *check*
        whether an element has been decomposed, you can use the
        `PageElement.decomposed` property.
        NT)r   r   __dict__clearr   r  r   r   )rs   enext_ups      rL   	decomposezPageElement.decompose{  so     	#%)mnGJ!S!!  
 AMA mmmmmrN   Tis_initializedaccept_selfc                    |r| j         | j         j        }nG| }t          |t                    r0|j        r)|j        d         }t          |t                    r|j        )|s|| u rd}|S )ap  Finds the last element beneath this object to be parsed.

        Special note to help you figure things out if your type
        checking is tripped up by the fact that this method returns
        _AtMostOneElement instead of PageElement: the only time
        this method returns None is if `accept_self` is False and the
        `PageElement` has no children--either it's a NavigableString
        or an empty Tag.

        :param is_initialized: Has `PageElement.setup` been called on
            this `PageElement` yet?

        :param accept_self: Is ``self`` an acceptable answer to the
            question?
        Nr   )r   r   r   r  r   )rs   r  r  r  s       rL   r  zPageElement._last_descendant  s    $  	5d/;*;JJJZ-- 5*2E 5'04
 Z-- 5*2E 5 	zT11JrN   _lastRecursiveChildr  r,   List[PageElement]c                h     j         }|t          d          t           fd|D                       rt          d          g }|D ]i}t          |t                    r|                                 |                               }|                    |                    ||                     j|S )aV  Makes the given element(s) the immediate predecessor of this one.

        All the elements will have the same `PageElement.parent` as
        this one, and the given elements will occur immediately before
        this one.

        :param args: One or more PageElements.

        :return The list of PageElements that were inserted.
        Nz2Element has no parent, so 'before' has no meaning.c              3      K   | ]}|u V  	d S rx   rj   r   s     rL   r   z,PageElement.insert_before.<locals>.<genexpr>  '      ''QqDy''''''rN   z&Can't insert an element before itself.	r   r   r   r   r   r   r   extendr   )rs   r   r   resultspredecessorr   s   `     rL   insert_beforezPageElement.insert_before  s     >QRRR''''$''''' 	GEFFF%' 	> 	>K +{33 &##%%%LL&&ENN6==<<====rN   c                     j         }|t          d          t           fd|D                       rt          d          d}g }|D ]t}t          |t                    r|                                 |                               }|                    |                    |dz   |z   |                     |dz  }u|S )aO  Makes the given element(s) the immediate successor of this one.

        The elements will have the same `PageElement.parent` as this
        one, and the given elements will occur immediately after this
        one.

        :param args: One or more PageElements.

        :return The list of PageElements that were inserted.
        Nz1Element has no parent, so 'after' has no meaning.c              3      K   | ]}|u V  	d S rx   rj   r   s     rL   r   z+PageElement.insert_after.<locals>.<genexpr>  r  rN   z%Can't insert an element after itself.r   r   r  )rs   r   r   offsetr  	successorr   s   `      rL   insert_afterzPageElement.insert_after  s     >PQQQ''''$''''' 	FDEEE%' 	 	I )[11 $!!###LL&&ENN6==V);YGGHHHaKFFrN   r:   r6   attrsr2   r   Optional[_StrainableString]kwargsr1   c                .     | j         | j        |||fi |S )a  Find the first PageElement that matches the given criteria and
        appears later in the document than this PageElement.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param string: A filter for a NavigableString with specific text.
        :kwargs: Additional filters on attribute values.
        )	_find_onefind_all_nextrs   r:   r%  r   r'  s        rL   	find_nextzPageElement.find_next  s'    $ t~d0$vPPPPPrN   findNextr,  r?   limit_stacklevelr   r.   c                :     | j         ||||| j        fd|dz   i|S )a}  Find all `PageElement` objects that match the given criteria and
        appear later in the document than this `PageElement`.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param string: A filter for a NavigableString with specific text.
        :param limit: Stop looking after finding this many results.
        :param _stacklevel: Used internally to improve warning messages.
        :kwargs: Additional filters on attribute values.
        r/  r   )	_find_allnext_elementsrs   r:   r%  r   r.  r/  r'  s          rL   r*  zPageElement.find_all_next  I    , t~
 
 $a
 
 
 	
rN   findAllNextr*  c                .     | j         | j        |||fi |S )a  Find the closest sibling to this PageElement that matches the
        given criteria and appears later in the document.

        All find_* methods take a common set of arguments. See the
        online documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param string: A filter for a `NavigableString` with specific text.
        :kwargs: Additional filters on attribute values.
        )r)  find_next_siblingsr+  s        rL   find_next_siblingzPageElement.find_next_sibling#  s'    $ t~d5tUFUUfUUUrN   findNextSiblingr8  c                :     | j         ||||| j        fd|dz   i|S )ap  Find all siblings of this `PageElement` that match the given criteria
        and appear later in the document.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param string: A filter for a `NavigableString` with specific text.
        :param limit: Stop looking after finding this many results.
        :param _stacklevel: Used internally to improve warning messages.
        :kwargs: Additional filters on attribute values.
        r/  r   )r1  next_siblingsr3  s          rL   r7  zPageElement.find_next_siblings;  r4  rN   findNextSiblingsr7  fetchNextSiblings3.0.0c                .     | j         | j        |||fi |S )a  Look backwards in the document from this `PageElement` and find the
        first `PageElement` that matches the given criteria.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param string: A filter for a `NavigableString` with specific text.
        :kwargs: Additional filters on attribute values.
        )r)  find_all_previousr+  s        rL   find_previouszPageElement.find_previousb  s'    $ t~d4dE6TTVTTTrN   findPreviousrA  c                :     | j         ||||| j        fd|dz   i|S )ay  Look backwards in the document from this `PageElement` and find all
        `PageElement` that match the given criteria.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param string: A filter for a `NavigableString` with specific text.
        :param limit: Stop looking after finding this many results.
        :param _stacklevel: Used internally to improve warning messages.
        :kwargs: Additional filters on attribute values.
        r/  r   )r1  previous_elementsr3  s          rL   r@  zPageElement.find_all_previousx  I    , t~"
 
 $a
 
 
 	
rN   findAllPreviousr@  fetchAllPreviousc                .     | j         | j        |||fi |S )a  Returns the closest sibling to this `PageElement` that matches the
        given criteria and appears earlier in the document.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param string: A filter for a `NavigableString` with specific text.
        :kwargs: Additional filters on attribute values.
        )r)  find_previous_siblingsr+  s        rL   find_previous_siblingz!PageElement.find_previous_sibling  s3    $ t~'uf
 
@F
 
 	
rN   findPreviousSiblingrJ  c                :     | j         ||||| j        fd|dz   i|S )aq  Returns all siblings to this PageElement that match the
        given criteria and appear earlier in the document.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param string: A filter for a NavigableString with specific text.
        :param limit: Stop looking after finding this many results.
        :param _stacklevel: Used internally to improve warning messages.
        :kwargs: Additional filters on attribute values.
        r/  r   )r1  previous_siblingsr3  s          rL   rI  z"PageElement.find_previous_siblings  rE  rN   findPreviousSiblingsrI  fetchPreviousSiblingsc                B    d} | j         ||dfddi|}|r|d         }|S )a  Find the closest parent of this PageElement that matches the given
        criteria.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param self: Whether the PageElement itself should be considered
           as one of its 'parents'.
        :kwargs: Additional filters on attribute values.
        Nr   r/     r   )find_parents)rs   r:   r%  r'  rr  s         rL   find_parentzPageElement.find_parent  sQ    ( #$#%
 
()
-3
 
  	
ArN   
findParentrT  c                >    | j         } | j        ||d||fd|dz   i|S )a  Find all parents of this `PageElement` that match the given criteria.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param limit: Stop looking after finding this many results.
        :param _stacklevel: Used internally to improve warning messages.
        :kwargs: Additional filters on attribute values.
        Nr/  r   )parentsr1  )rs   r:   r%  r.  r/  r'  iterators          rL   rR  zPageElement.find_parents  sE    & <t~%uh
 
<G!O
OU
 
 	
rN   findParentsrR  fetchParentsc                    | j         S )z?The `PageElement`, if any, that was parsed just after this one.r   r   s    rL   nextzPageElement.next  s       rN   c                    | j         S )z@The `PageElement`, if any, that was parsed just before this one.r   r   s    rL   previouszPageElement.previous       $$rN   methodr   c                :    d } ||||dfddi|}|r|d         }|S )Nr   r/     r   rj   )rs   rb  r:   r%  r   r'  rS  r  s           rL   r)  zPageElement._find_one%  sB      $!'eVQ!X!XA!XQW!X!X 	
ArN   rQ  	generatorIterator[PageElement]c                   |5d|v r1|                     d          }t          j        dt          |           d|v r8t          j        t          j        t          dd          z  t          |           dd	lm} t          ||          r|}	nt          |||fi |}	||s|s|s|d
u s|d |D             }
t          |	|
          S t          |t                    r|                    d          dk    r|                    dd          \  }}nd}|}g }
|D ]P}t          |t                    s|j        |k    s|j        |k    r"||j        |k    r|
                    |           Qt          |	|
          S |	                    ||          S )z8Iterates over a generator looking for things that match.NtextzOThe 'text' argument to find()-type methods is deprecated. Use 'string' instead.r@   _classclass_)originalautocorrectr   r$   Tc              3  D   K   | ]}t          |t                    |V  d S rx   )r   r  )r   elements     rL   r   z(PageElement._find_all.<locals>.<genexpr>a  s2      WWgjRU>V>VW'WWWWWWrN   rb   r   )poprD   rE   rG   r   MESSAGEdict
bs4.filterr%   r   SoupStrainer	ResultSetr;   countsplitr  r:   r_   r  find_all)rs   r:   r%  r   r.  re  r/  r'  r%   matcherresultr_   
local_namern  s                 rL   r1  zPageElement._find_all7  s    >f..ZZ''FMa"&    vM19% (  
 2&    	-,,,,,dM** 	BGG"4AA&AAG >%>>f>t||t|WWWWW &111D#&& 2::c??a'' *.C););&FJJ!F!%J( / /G%gs33 ! |t++
22#^w~/G/Gg... &111	5111rN   c              #  >   K   | j         }||j         }|V  |}|dS dS )z1All PageElements that were parsed after this one.Nr\  rs   ir#  s      rL   r2  zPageElement.next_elements{  s9       mIGGGA mmmmmrN   c                6    |                      | j                  S )zBThis PageElement, then all PageElements that were parsed after it.)	_self_andr2  r   s    rL   self_and_next_elementsz"PageElement.self_and_next_elements       ~~d0111rN   c              #  >   K   | j         }||j         }|V  |}|dS dS )zVAll PageElements that are siblings of this one but were parsed
        later.
        N)r   r|  s      rL   r;  zPageElement.next_siblings  s9      
 mIGGGA mmmmmrN   c                6    |                      | j                  S )z+This PageElement, then all of its siblings.)r  r;  r   s    rL   self_and_next_siblingsz"PageElement.self_and_next_siblings  r  rN   c              #  >   K   | j         }||j         }|V  |}|dS dS )zhAll PageElements that were parsed before this one.

        :yield: A sequence of PageElements.
        Nr_  r|  s      rL   rD  zPageElement.previous_elements  s:       !m*IGGGA mmmmmrN   c                6    |                      | j                  S )zEThis PageElement, then all elements that were parsed
        earlier.)r  rD  r   s    rL   self_and_previous_elementsz&PageElement.self_and_previous_elements       ~~d4555rN   c              #  >   K   | j         }||j         }|V  |}|dS dS )zAll PageElements that are siblings of this one but were parsed
        earlier.

        :yield: A sequence of PageElements.
        N)r   r|  s      rL   rM  zPageElement.previous_siblings  s:       !m*IGGGA mmmmmrN   c                6    |                      | j                  S )zLThis PageElement, then all of its siblings that were parsed
        earlier.)r  rM  r   s    rL   self_and_previous_siblingsz&PageElement.self_and_previous_siblings  r  rN   Iterator[Tag]c              #  >   K   | j         }||j         }|V  |}|dS dS )zAll elements that are parents of this PageElement.

        :yield: A sequence of Tags, ending with a BeautifulSoup object.
        Nr   r|  s      rL   rW  zPageElement.parents  s8       KmIGGGA mmmmmrN   c                6    |                      | j                  S )zThis element, then all of its parents.

        :yield: A sequence of PageElements, ending with a BeautifulSoup object.
        )r  rW  r   s    rL   self_and_parentszPageElement.self_and_parents  s     ~~dl+++rN   other_generatorc              #  2   K   | j         s| V  |D ]}|V  dS )zmModify a generator by yielding this element, then everything
        yielded by the other generator.
        N)r   )rs   r  r}  s      rL   r  zPageElement._self_and  s?       { 	JJJ  	 	AGGGG	 	rN   c                (    t          | dd          pdS )z0Check whether a PageElement has been decomposed.r   F)r   r   s    rL   
decomposedzPageElement.decomposed  s     t]E22;e;rN   r2  c                    | j         S z:meta private:)r2  r   s    rL   nextGeneratorzPageElement.nextGenerator       !!rN   r;  c                    | j         S r  )r;  r   s    rL   nextSiblingGeneratorz PageElement.nextSiblingGenerator  r  rN   rD  c                    | j         S r  )rD  r   s    rL   previousGeneratorzPageElement.previousGenerator       %%rN   rM  c                    | j         S r  )rM  r   s    rL   previousSiblingGeneratorz$PageElement.previousSiblingGenerator  r  rN   rW  c                    | j         S r  )rW  r   s    rL   parentGeneratorzPageElement.parentGenerator  s     |rN   )NNNNN)r   r   r   r(   r   r(   r   r(   r   r(   r<   r   )r   r;   r   r   r<   r;   )r   r   r<   r
   r<   r   Fr   r   r   r   r<   r   r<   r   )r   r   r   r   r<   r   r<   r   )r   r;   r   r   r   r   r<   r;   )r   r   r<   r   )r  r  r<   r  rx   )r   r	  r<   r   r<   r   )TT)r  r   r  r   r<   r(   )r   r,   r<   r  )
r:   r6   r%  r2   r   r&  r'  r1   r<   r(   )r:   r6   r%  r2   r   r&  r.  r	  r/  r   r'  r1   r<   r.   )r:   r6   r%  r2   r'  r1   r<   r(   )r:   r6   r%  r2   r.  r	  r/  r   r'  r1   r<   r.   )r<   r(   )rb  r   r:   r6   r%  r2   r   r&  r'  r1   r<   r(   )rQ  )r:   r6   r%  r2   r   r&  r.  r	  re  rf  r/  r   r'  r1   r<   r.   r<   rf  )r<   r  )r  rf  r<   rf  )PrJ   rf   rg   rh   r   ri   r   r   r   r   propertyr   r   r   r   r   r   tupler   r   r   r   getTextrh  r  r	   r  r  r   r  r  r  r  r$  r,  r-  r*  r5  r8  r9  r7  r<  r=  rA  rB  r@  rF  rG  rJ  rK  rI  rN  rO  rT  rU  rR  rY  rZ  r]  r`  r)  r1  r2  r  r;  r  rD  r  rM  r  rW  r  r  r  r   r  r  r  r  r  rj   rN   rL   r   r   Z  s          !%I$$$$ ####''''####'''' F !%.2*..2*.06 06 06 06 06d   ( ( ( (8 # # # X#, $#M>7KKK''(9;MwWWO$ $ $ $ $% % % % 05uwwG6666 "G$ $ $ $ $    X 18	R R R R R2 G8HD   . -,]NGTTK   . . . . .`   . @D    8 ,+17    6   B !%').2	Q Q Q Q Q( *)*k7KKH !%').2#
 
 
 
 
@ -,]OWUUK !%').2	V V V V V( 10. O !%').2#
 
 
 
 
@ 210'  3217  !%').2	U U U U U( .-nowWWL !%').2#
 
 
 
 
@ 10. O 21/  !%').2	
 
 
 
 
, 546  !%').2#
 
 
 
 
@ 65 8'  76!97  !%')    8 ,+L-QQJ !%')#
 
 
 
 
0 -,]NGTTK--nngVVL! ! ! X! % % % X%   2 @2 @2 @2 @2 @2H    X 2 2 2 X2    X 2 2 2 X2 	 	 	 X	 6 6 6 X6
 
 
 
 X
 6 6 6 X6
 	 	 	 X	 , , , X,    < < < X< ['**" " " +*" ['**" " " +*" [$g..& & & /.& [$g..& & & /.& [G$$   %$  rN   r   c                       e Zd ZU dZdZded<   dZded<   d%d
Zd&d'dZd(dZ	d) fdZ
ed*d            Zd+d,dZed-d            Zej        d.d            Zdej        fd/d#Zed0d$            Z xZS )1r4   zA Python string that is part of a parse tree.

    When Beautiful Soup parses the markup ``<b>penguin</b>``, it will
    create a `NavigableString` for the string "penguin".
    r{   r;   PREFIXSUFFIXr   Union[str, bytes]r<   r   c                    t          |t                    rt                              | |          }n!t                              | |t                    }d|_        |                                 |S )a-  Create a new NavigableString.

        When unpickling a NavigableString, this method is called with
        the string in DEFAULT_OUTPUT_ENCODING. That encoding needs to be
        passed in to the superclass's __new__ or the superclass won't know
        how to handle non-ASCII characters.
        F)r   r;   rc   rP   r   r   )rd   r   us      rL   rc   zNavigableString.__new__  s[     eS!! 	AC''AAC(?@@A				rN   Fr   r   r   r   c                2     t          |           |           S )a>  A copy of a NavigableString has the same contents and class
        as the original, but it is not connected to the parse tree.

        :param recursive: This parameter is ignored; it's only defined
           so that NavigableString.__deepcopy__ implements the same
           signature as Tag.__deepcopy__.
        )typer   s      rL   r   zNavigableString.__deepcopy__  s     tDzz$rN   
Tuple[str]c                "    t          |           fS rx   )r;   r   s    rL   __getnewargs__zNavigableString.__getnewargs__%  s    D		|rN   r   Union[int | slice]c                    t          |t                    r,t          d                    |j        j                            t          t          |                               |          S )zRaise an exception zZstring indices must be integers, not '{0}'. Are you treating a NavigableString like a Tag?)	r   r;   	TypeErrorrF   r   rJ   r   r4   __getitem__)rs   r   r   s     rL   r  zNavigableString.__getitem__*  ss    c3 	Yx  AD  AN  AW  X  X  Y  Y  Y_d++77<<<rN   c                    | S )zConvenience property defined to match `Tag.string`.

        :return: This property always returns the `NavigableString` it was
           called on.

        :meta private:
        rj   r   s    rL   r   zNavigableString.string0  s	     rN   minimalr   r'   c                R    |                      | |          }| j        |z   | j        z   S )zRun the string through the provided formatter, making it
        ready for output as part of an HTML or XML document.

        :param formatter: A `Formatter` object, or a string naming one
            of the standard formatters.
        r   r  r  )rs   r   r   s      rL   output_readyzNavigableString.output_ready;  s-     ##D)44{V#dk11rN   r   c                    dS )a  Since a NavigableString is not a Tag, it has no .name.

        This property is implemented so that code like this doesn't crash
        when run on a mixture of Tag and NavigableString objects:
            [x.name for x in tag.children]

        :meta private:
        Nrj   r   s    rL   r:   zNavigableString.nameE  s	     trN   r:   c                     t          d          )zRPrevent NavigableString.name from ever being set.

        :meta private:
        z)A NavigableString cannot be given a name.rI   )rs   r:   s     rL   r:   zNavigableString.nameQ  s     HIIIrN   r   r   r5   r   c              #    K   || j         u rt          j        }t          |           }|"t	          |t                    r||urdS n||vrdS | }|r|                                }n| }t          |          dk    r|V  dS dS )a  Yield all strings of certain classes, possibly stripping them.

        This makes it easy for NavigableString to implement methods
        like get_text() as conveniences, creating a consistent
        text-extraction API across all PageElements.

        :param strip: If True, all strings will be stripped before being
            yielded.

        :param types: A tuple of NavigableString subclasses. If this
            NavigableString isn't one of those subclasses, the
            sequence will be empty. By default, the subclasses
            considered are NavigableString and CData objects. That
            means no comments, processing instructions, etc.

        :yield: A sequence that either contains this string, or is empty.
        Nr   )r   r  MAIN_CONTENT_STRING_TYPESr  r   r   r   )rs   r   r   my_typer   final_values         rL   r   zNavigableString._all_stringsY  s      ( DL   1E t**%&& %''F (%% 	++--KKK{a  rN   c                *    |                                  S )a1  Yield this string, but only if it is interesting.

        This is defined the way it is for compatibility with
        `Tag.strings`. See `Tag` for information on which strings are
        interesting in a given context.

        :yield: A sequence that either contains this string, or is empty.
        r   r   s    rL   stringszNavigableString.strings  s       """rN   )r   r  r<   r   r  r  )r<   r  )r   r  r<   r;   r<   r;   )r  )r   r'   r<   r;   r  )r:   r;   r<   r   r   r   r   r5   r<   r   r  )rJ   rf   rg   rh   r  ri   r  rc   r   r  r  r  r   r  r:   setterr   r   r   r  r   r   s   @rL   r4   r4     ss          F
 F                
= = = = = =    X2 2 2 2 2 	 	 	 X	 
[J J J [J "+BU0 0 0 0 0d 	# 	# 	# X	# 	# 	# 	# 	#rN   c                  :    e Zd ZU dZdZded<   dZded<   ddd
ZdS )PreformattedStringzA `NavigableString` not subject to the normal formatting rules.

    This is an abstract class used for special kinds of strings such
    as comments (`Comment`) and CDATA blocks (`CData`).
    r{   r;   r  r  Nr   r   r<   c                V    ||                      | |           | j        | z   | j        z   S )a  Make this string ready for output by adding any subclass-specific
            prefix or suffix.

        :param formatter: A `Formatter` object, or a string naming one
            of the standard formatters. The string will be passed into the
            `Formatter`, but only to trigger any side effects: the return
            value is ignored.

        :return: The string, with any subclass-specific prefix and
           suffix added on.
        r  )rs   r   s     rL   r  zPreformattedString.output_ready  s4      tY///{T!DK//rN   rx   )r   r   r<   r;   )rJ   rf   rg   rh   r  ri   r  r  rj   rN   rL   r  r    s]           FF0 0 0 0 0 0 0rN   r  c                  0    e Zd ZU dZdZded<   dZded<   dS )CDatazQA `CDATA section <https://dev.w3.org/html5/spec-LC/syntax.html#cdata-sections>`_.z	<![CDATA[r;   r  z]]>r  NrJ   rf   rg   rh   r  ri   r  rj   rN   rL   r  r    s:         [[FFrN   r  c                  0    e Zd ZU dZdZded<   dZded<   dS )ProcessingInstructionzA SGML processing instruction.<?r;   r  >r  Nr  rj   rN   rL   r  r    s:         ((FFrN   r  c                  0    e Zd ZU dZdZded<   dZded<   dS )XMLProcessingInstructionzIAn `XML processing instruction <https://www.w3.org/TR/REC-xml/#sec-pi>`_.r  r;   r  ?>r  Nr  rj   rN   rL   r  r    s:         SSFFrN   r  c                  0    e Zd ZU dZdZded<   dZded<   dS )CommentzAn `HTML comment <https://dev.w3.org/html5/spec-LC/syntax.html#comments>`_ or `XML comment <https://www.w3.org/TR/REC-xml/#sec-comments>`_.z<!--r;   r  z-->r  Nr  rj   rN   rL   r  r    s@          V  VFFrN   r  c                  0    e Zd ZU dZdZded<   dZded<   dS )DeclarationzFAn `XML declaration <https://www.w3.org/TR/REC-xml/#sec-prolog-dtd>`_.r  r;   r  r  r  Nr  rj   rN   rL   r  r    s:         PPFFrN   r  c                  `    e Zd ZU dZedd            Zedd	            Zd
Zded<   dZ	ded<   dS )DoctypezKA `document type declaration <https://www.w3.org/TR/REC-xml/#dt-doctype>`_.r:   r;   pub_idr^   	system_idr<   c                J    t          |                     |||                    S )a  Generate an appropriate document type declaration for a given
        public ID and system ID.

        :param name: The name of the document's root element, e.g. 'html'.
        :param pub_id: The Formal Public Identifier for this document type,
            e.g. '-//W3C//DTD XHTML 1.1//EN'
        :param system_id: The system identifier for this document type,
            e.g. 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'
        )r  _string_for_name_and_ids)rd   r:   r  r  s       rL   for_name_and_idszDoctype.for_name_and_ids  s$     s33D&)LLMMMrN   c                L    |pd}||d|z  z  }||d|z  z  }n
||d|z  z  }|S )zGenerate a string to be used as the basis of a Doctype object.

        This is a separate method from for_name_and_ids() because the lxml
        TreeBuilder needs to call it.
        r{   Nz PUBLIC "%s"z "%s"z SYSTEM "%s"rj   )rs   r:   r  r  r   s        rL   r  z Doctype._string_for_name_and_ids  sR     
^f,,E$9,,"^i//ErN   z
<!DOCTYPE r  z>
r  N)r:   r;   r  r^   r  r^   r<   r  )r:   r;   r  r^   r  r^   r<   r;   )
rJ   rf   rg   rh   classmethodr  r  r  ri   r  rj   rN   rL   r  r    s~         UUN N N [N    [" FFrN   r  c                      e Zd ZdZdS )
StylesheetzA `NavigableString` representing the contents of a `<style> HTML
    tag <https://dev.w3.org/html5/spec-LC/Overview.html#the-style-element>`_
    (probably CSS).

    Used to distinguish embedded stylesheets from textual content.
    Nr   rj   rN   rL   r  r    r   rN   r  c                      e Zd ZdZdS )ScriptzA `NavigableString` representing the contents of a `<script>
    HTML tag
    <https://dev.w3.org/html5/spec-LC/Overview.html#the-script-element>`_
    (probably Javascript).

    Used to distinguish executable code from textual content.
    Nr   rj   rN   rL   r  r    s           rN   r  c                      e Zd ZdZdS )TemplateStringa  A `NavigableString` representing a string found inside an `HTML
    <template> tag <https://html.spec.whatwg.org/multipage/scripting.html#the-template-element>`_
    embedded in a larger document.

    Used to distinguish such strings from the main body of the document.
    Nr   rj   rN   rL   r  r    r   rN   r  c                      e Zd ZdZdS )RubyTextStringzA NavigableString representing the contents of an `<rt> HTML
    tag <https://dev.w3.org/html5/spec-LC/text-level-semantics.html#the-rt-element>`_.

    Can be used to distinguish such strings from the strings they're
    annotating.
    Nr   rj   rN   rL   r  r    r   rN   r  c                      e Zd ZdZdS )RubyParenthesisStringzA NavigableString representing the contents of an `<rp> HTML
    tag <https://dev.w3.org/html5/spec-LC/text-level-semantics.html#the-rp-element>`_.
    Nr   rj   rN   rL   r  r  #  s           rN   r  c                  F   e Zd ZU dZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dddZd ed!<   d"ed<   ded	<   ded
<   d#ed<   ded<   ded<   ded$<   d%ed&<   d'ed(<   ded<   ded<   ded<   ded<    ed)d!d*          Zddd1Zdd2Z	e
dd3            Z ed4d*          dd5            Ze
dd6            Zej        dd9            ZeehZd:ej        fdd?Z e
e          ZddDZddFZddGZeZ edHd*          ddJ            ZddMZddPZdddRZddSZddUZ 	 dddYZ!	 ddd\Z"dd]Z#dd^Z$dd`Z%ddbZ&ddcZ'ddfZ(ddgZ)ddiZ*ddjZ+di d+dddkfddtZ,ddwZ-ddyZ.ddzZ/dd{Z0e0xZ1Z2e3dd|d}fddZ4de3d|dfddZ5 G d de6          Z7 e7            Z8 e7            Z9 e7            Z: e7            Z;	 dddZ<ddZ=ddZ>dddZ?	 	 dddZ@de3d|fddZAde3d|fddZB edd*          e3d:dfdd            ZCdi d+dfddZD eEddd          ZFdi d+dddkfddZG eEddd*          ZH eEddd          ZIe
dd            ZJe
dd            ZKe
dd            ZL	 dddZM	 	 dddZNe
dd            ZO edd*          dd            ZP edd*          dd            ZQ edd*          dd            ZRdS )r  a	  An HTML or XML tag that is part of a parse tree, along with its
    attributes, contents, and relationships to other parts of the tree.

    When Beautiful Soup parses the markup ``<b>penguin</b>``, it will
    create a `Tag` object representing the ``<b>`` tag. You can
    instantiate `Tag` objects directly, but it's not necessary unless
    you're adding entirely new markup to a parsed document. Most of
    the constructor arguments are intended for use by the `TreeBuilder`
    that's parsing a document.

    :param parser: A `BeautifulSoup` object representing the parse tree this
        `Tag` will be part of.
    :param builder: The `TreeBuilder` being used to build the tree.
    :param name: The name of the tag.
    :param namespace: The URI of this tag's XML namespace, if any.
    :param prefix: The prefix for this tag's XML namespace, if any.
    :param attrs: A dictionary of attribute values.
    :param parent: The `Tag` to use as the parent of this `Tag`. May be
       the `BeautifulSoup` object itself.
    :param previous: The `PageElement` that was parsed immediately before
        parsing this tag.
    :param is_xml: If True, this is an XML tag. Otherwise, this is an
        HTML tag.
    :param sourceline: The line number where this tag was found in its
        source document.
    :param sourcepos: The character position within ``sourceline`` where this
        tag was found.
    :param can_be_empty_element: If True, this tag should be
        represented as <tag/>. If False, this tag should be represented
        as <tag></tag>.
    :param cdata_list_attributes: A dictionary of attributes whose values should
        be parsed as lists of strings if they ever show up on this tag.
    :param preserve_whitespace_tags: Names of tags whose contents
        should have their whitespace preserved if they are encountered inside
        this tag.
    :param interesting_string_types: When iterating over this tag's
        string contents in methods like `Tag.strings` or
        `PageElement.get_text`, these are the types of strings that are
        interesting enough to be considered. By default,
        `NavigableString` (normal strings) and `CData` (CDATA
        sections) are the only interesting string subtypes.
    :param namespaces: A dictionary mapping currently active
        namespace prefixes to URIs, as of the point in the parsing process when
        this tag was encountered. This can be used later to
        construct CSS selectors.

    NparserOptional[BeautifulSoup]builderOptional[TreeBuilder]r:   r^   r`   r_   r%  (Optional[_RawOrProcessedAttributeValues]r   #Optional[Union[BeautifulSoup, Tag]]r`  r(   r   r   
sourceliner	  	sourceposcan_be_empty_elementcdata_list_attributesOptional[Dict[str, Set[str]]]preserve_whitespace_tagsOptional[Set[str]]interesting_string_types$Optional[Set[Type[NavigableString]]]
namespacesOptional[Dict[str, str]]c                8   |d | _         n|j        | _         |t          d          || _        || _        |pi | _        || _        |r|j        r|
||
| _        || _	        n|
| _        || _	        ||	rt          }nt          }t          }n|j        }|j        }|| _        | |            | _        n|(|j        r!|                    | j        |          | _        n] |            | _        |                                D ]9\  }}t'          |t(                    r|                    |          }|| j        |<   :|r|j        | _        n|	| _        g | _        |                     ||           d| _        ||| _        || _        || _        || _        d S |j        | _        |                    |            |                    |          | _        |j        | _        |j        | _        | j        |j        v r|j        | j                 h| _        d S | j        | _        d S )Nz%No value provided for new tag's name.F) parser_classr   r   r:   r`   _namespacesr_   store_line_numbersr  r  r   r   r   attribute_dict_classattribute_value_list_classr%  r  $_replace_cdata_list_attribute_valuesitemsr   listr   r   r   r   r   r  r  r  set_up_substitutionsstring_containersr  )rs   r  r  r:   r`   r_   r%  r   r`  r   r  r  r  r  r  r  r  attr_dict_classr  kvs                        rL   __init__zTag.__init__Z  sk   , > $D !' 0D<DEEE	"%+ 	'75 	'"i&;(DO&DNN(DO&DN ? 4"2"3);&&%:O)0)K&*D'=(**DJJ"w'D"$IIIu 

 -_..
 "KKMM & &DAq!!T** +KKNN$%DJqMM  	$$^DNN#DN+-

68$$$? )=D%)>D&,DD),DD))) /6.PD+((... )0(D(DT(J(JD% *1)FD& -4,LD)yG555 291J491U0V---040N---rN   zOptional[type[BeautifulSoup]]r  r;   r*   r   r  r   r   r   parserClassr   Tr   r   r   r<   r   c                   |                                  }|r|g}|                     | j                  D ]\  }}|t          j        u r|                                 (|                    |d          }|d                             |           |t          j        u r(|                    t          t          |                     |S )zA deepcopy of a Tag is a new Tag, unconnected to the parse tree.
        Its contents are a copy of the old Tag's contents.
        F)r   r   )
	copy_self_event_streamdescendantsr  END_ELEMENT_EVENTro  r   r  START_ELEMENT_EVENTr   )rs   r   r   clone	tag_stackeventrn  descendant_clones           rL   r   zTag.__deepcopy__  s        	F %*7I"&"4"4T5E"F"F F FwC111 MMOOOO'.';';DE';'R'R$bM(()9::: 777 "((c3C)D)DEEErN   c                    t          |           dd| j        | j        | j        | j        | j        | j        | j        | j        | j	        | j
        | j        | j                  }dD ]!}t          ||t          | |                     "|S )a  Create a new Tag just like this one, but with no
        contents and unattached to any parse tree.

        This is the first step in the deepcopy process, but you can
        call it on its own to create a copy of a Tag without copying its
        contents.
        N)r   r  r  r  r  r  r  r  )r  r   )r  r:   r`   r_   r%  r   r  r  r  r  r  r  r  setattrr   )rs   r  attrs      rL   r  zTag.copy_self   s     T

INKJ<n!%!:"&"<%)%B%)%B'
 
 
  7 	6 	6DE4t!4!45555rN   c                D    t          | j                  dk    o| j        du S )a  Is this tag an empty-element tag? (aka a self-closing tag)

        A tag that has contents is never an empty-element tag.

        A tag that has no contents may or may not be an empty-element
        tag. It depends on the `TreeBuilder` used to create the
        tag. If the builder has a designated list of empty-element
        tags, then only a tag whose name shows up in that list is
        considered an empty-element tag. This is usually the case
        for HTML documents.

        If the builder has no designated list of empty-element, then
        any tag with no contents is an empty-element tag. This is usually
        the case for XML documents.
        r   T)r   r   r  r   s    rL   is_empty_elementzTag.is_empty_element  s&    " 4=!!Q&L4+D+LLrN   r  c                    | j         S z: :meta private:)r  r   s    rL   isSelfClosingzTag.isSelfClosing/  ra  rN   c                    t          | j                  dk    rdS | j        d         }t          |t                    r|S t          |t                    r|j        S dS )aX  Convenience property to get the single string within this
        `Tag`, assuming there is just one.

        :return: If this `Tag` has a single child that's a
         `NavigableString`, the return value is that string. If this
         element has one child `Tag`, the return value is that child's
         `Tag.string`, recursively. If this `Tag` has no children,
         or has more than one child, the return value is ``None``.

         If this property is unexpectedly returning ``None`` for you,
         it's probably because your `Tag` has more than one thing
         inside it.
        r   Nr   )r   r   r   r4   r  r   )rs   childs     rL   r   z
Tag.string4  s`     t}""4a e_-- 	 Ls## 	 <trN   r   r   c                    |                                   t          |t                    r|j        }nt          }|                      ||                     dS )z>Replace the `Tag.contents` of this `Tag` with a single string.N)r  r   r4   r   r  )rs   r   	new_classs      rL   r   z
Tag.stringL  sT     	

fo.. 	((II'IIIf%%&&&&&rN   Fr   r   r5   r   c              #  P  K   || j         u r| j        | j        }n| j        }| j        D ]|}t	          |t
                    st          |          }t	          |t                    r||urAn|||vrI|r-|                                }t          |          dk    rs|V  x|V  }dS )aS  Yield all strings of certain classes, possibly stripping them.

        :param strip: If True, all strings will be stripped before being
            yielded.

        :param types: A tuple of NavigableString subclasses. Any strings of
            a subclass not found in this list will be ignored. By
            default, the subclasses considered are the ones found in
            self.interesting_string_types. If that's not specified,
            only NavigableString and CData objects will be
            considered. That means no comments, processing
            instructions, etc.
        Nr   )	r   r  r  r  r   r4   r  r   r   )rs   r   r   
descendantdescendant_typestrippeds         rL   r   zTag._all_stringsY  s        DL  ,465* 	! 	!Jj/:: ":..O%&& "%// 0 "e'C'C !%++--x==A%%     #	! 	!rN   positionr   new_childrenr,   c                p    g }|D ]0}|                     |                     ||                     |dz  }1|S )a  Insert one or more new PageElements as a child of this `Tag`.

        This works similarly to :py:meth:`list.insert`, except you can insert
        multiple elements at once.

        :param position: The numeric position that should be occupied
           in this Tag's `Tag.children` by the first new `PageElement`.

        :param new_children: The PageElements to insert.

        :return The newly inserted PageElements.
        r   )r  _insert)rs   r+  r,  inserted	new_childs        rL   r   z
Tag.insert  sH     ')% 	 	IOODLL9==>>>MHHrN   r0  c                   |t          d          || u rt          d          t          |t                    r$t          |t                    st          |          }ddlm} t          ||          r  | j        |gt          |j                  R  S t          |t          | j                            }t          |d          rN|j        G|j        | u r*|                     |          }||k     r|dz  }n	||k    r|gS |                                 | |_        d }|dk    rd |_        | |_        n=| j        |dz
           }||_        ||j        _        |                    d          |_        |j        ||j        _        |                    dd	          }t)          t*          |          }|t          | j                  k    r6d |_        | }d }|||j        }|j        }|n|||||_        n6d |_        n.| j        |         }	|	|_        |j        ||j        _        |	|_        |j        ||j        _        | j                            ||           |gS )
NzCannot insert None into a tag.z Cannot insert a tag into itself.r   r!   r   r   FT)r  r  )r   r   r;   r4   bs4r"   r   r	  r   minr   hasattrr   r   r   r   r   r   r  r   r   r   )
rs   r+  r0  r"   current_indexprevious_childnew_childs_last_elementr   parents_next_sibling
next_childs
             rL   r.  zTag._insert  s   =>>>?@@@i%% 	3jO.T.T 	3'	22I%%%%%%i// 	D 4;xC$y/A*B*BCCCCxT]!3!3449h'' 	 I,<,H 4'' $

9 5 5 8++
 MHH"h.. &;&	q==)-I&)-I&&!]8a<8N)7I&6?I&3)7)H)H)O)OI&%16?I&3"+"<"< d #= #
 #
 #'{4K"L"Ls4=))))%)I"$(F#' &.63E'-':$'3 '.63E $/7K'44 8<'44x0J%/I"%1:C	&73=#0"/;' $0A 	Xy111{rN   c                    | j         }|t          d          |                    |           }|                     |           t	          | j        dd                   D ]}|                    ||           | S )zqReplace this `PageElement` with its contents.

        :return: This object, no longer part of the tree.
        NzTCannot replace an element with its contents when that element is not part of a tree.r   )r   r   r   r   reversedr   r   )rs   	my_parentr   r$  s       rL   unwrapz
Tag.unwrap  s    
 K	1   ??4((***dmAAA.// 	. 	.EXu----rN   r=  r-   c                *    |                                  S r!  )r=  r   s    rL   replaceWithChildrenzTag.replaceWithChildren  s     {{}}rN   tagr   c                ^    |                      t          | j                  |          d         S )z
        Appends the given `PageElement` to the contents of this `Tag`.

        :param tag: A PageElement.

        :return The newly appended PageElement.
        r   )r   r   r   )rs   r@  s     rL   r  z
Tag.append  s'     {{3t}--s33A66rN   tags(Union[Iterable[_InsertableElement], Tag]c                   t          |t                    rt          |j                  }nt          |t          t
          f          rYt          j        dt          d           t          |t
                    r$t          |t                    st          |          }|g}n$t          |t                    rt          |          }g }|D ]*}|                    |                     |                     +|S )a  Appends one or more objects to the contents of this
        `Tag`.

        :param tags: If a list of `PageElement` objects is provided,
            they will be appended to this tag's contents, one at a time.
            If a single `Tag` is provided, its `Tag.contents` will be
            used to extend this object's `Tag.contents`.

        :return The list of PageElements that were appended.
        zIA single non-Tag item was passed into Tag.extend. Use Tag.append instead.r?   r@   )r   r  r	  r   r   r;   rD   rE   UserWarningr4   r   r  )rs   rB  tag_listr  r@  s        rL   r  z
Tag.extend  s     dC   	"DM**HH{C011 	" M[   
 $$$ -Zk-J-J -&t,,vHHh'' 	" DzzH%' 	- 	-CNN4;;s++,,,,rN   r  c                    | j         dd         D ]-}|r|                                 |                                 .dS )a	  Destroy all children of this `Tag` by calling
           `PageElement.extract` on them.

        :param decompose: If this is True, `PageElement.decompose` (a
            more destructive method) will be called instead of
            `PageElement.extract`.
        N)r   r  r   )rs   r  rn  s      rL   r  z	Tag.clear5  sX     }QQQ' 	" 	"G "!!####!!!!		" 	"rN   c                   g }t          | j                  D ]\  }}t          |t                    r|                                 |t          | j                  dz
  k    rJ| j        |dz            }t          |t                    rTt          |t                    r?t          |t                    s*t          |t                    s|                    |           t          |          D ]}t          t          | j        |                   }t          t          | j        |dz                      }|                                 t          ||z             }|                    |           dS )zSmooth out the children of this `Tag` by consolidating consecutive
        strings.

        If you perform a lot of operations that modify the tree,
        calling this method afterwards can make pretty-printed output
        look more natural.
        r   N)r   r   r   r  smoothr   r4   r  r  r;  r   r   r  )rs   markedr}  abns         rL   rI  z
Tag.smoothC  s]    dm,, 	! 	!DAq!S!! 


C&&*** a!e$A1o..!q/22! #1&899! #1&899	! a   
 &!! 	 	A_dmA&677A_dmAE&:;;AIIKKKA&&ANN1	 	rN   rn  c                d    t          | j                  D ]\  }}||u r|c S t          d          )a  Find the index of a child of this `Tag` (by identity, not value).

        Doing this by identity avoids issues when a `Tag` contains two
        children that have string equality.

        :param element: Look for this `PageElement` in this object's contents.
        zTag.index: element not in tag)r   r   r   )rs   rn  r}  r$  s       rL   r   z	Tag.indexk  sI     "$-00 	 	HAu  8999rN   r   r   Optional[_AttributeValue]c                8    | j                             ||          S )a$  Returns the value of the 'key' attribute for the tag, or
        the value given for 'default' if it doesn't have that
        attribute.

        :param key: The attribute to look for.
        :param default: Use this value if the attribute is not present
            on this `Tag`.
        )r%  get)rs   r   r   s      rL   rQ  zTag.getx  s     z~~c7+++rN   Optional[AttributeValueList]r   c                   |                      ||          }||                                 }nXt          |t                    r|}n@t          |t                    st          t          |          }|                     |g          }|S )a:  The same as get(), but always returns a (possibly empty) list.

        :param key: The attribute to look for.
        :param default: Use this value if the attribute is not present
            on this `Tag`.
        :return: A list of strings, usually empty or containing only a single
            value.
        )rQ  r  r   r	  r;   r   )rs   r   r   r   
list_values        rL   get_attribute_listzTag.get_attribute_list  s     g&&=88::JJt$$ 	BJJeS)) )S%((88%AAJrN   c                    || j         v S )z6Does this `Tag` have an attribute with the given name?r%  rs   r   s     rL   has_attrzTag.has_attr  s    dj  rN   c                D    t          |                                           S rx   )r;   __hash__r   s    rL   r[  zTag.__hash__  s    4yy!!###rN   r)   c                    | j         |         S )zqtag[key] returns the value of the 'key' attribute for the Tag,
        and throws an exception if it's not there.rW  rX  s     rL   r  zTag.__getitem__  s     z#rN   rf  c                *    t          | j                  S )z0Iterating over a Tag iterates over its contents.)iterr   r   s    rL   __iter__zTag.__iter__  s    DM"""rN   c                *    t          | j                  S )z:The length of a Tag is the length of its list of contents.)r   r   r   s    rL   __len__zTag.__len__  s    4=!!!rN   r   r   c                    || j         v S rx   r   )rs   r   s     rL   __contains__zTag.__contains__  s    DM!!rN   c                    dS )z-A tag is non-None even if it has no contents.Trj   r   s    rL   __bool__zTag.__bool__  s    trN   r   c                    || j         |<   dS )zKSetting tag[key] sets the value of the 'key' attribute for the
        tag.NrW  )rs   r   r   s      rL   r   zTag.__setitem__  s      
3rN   c                <    | j                             |d           dS )z;Deleting tag[key] deletes all 'key' attributes for the tag.N)r%  ro  rX  s     rL   __delitem__zTag.__delitem__  s    
sD!!!!!rN   r?   Optional[_StrainableElement]r2   r&  r.  r/  r'  r1   r.   c                (     | j         ||||||fi |S )zCalling a Tag like a function is the same as calling its
        find_all() method. Eg. tag('a') returns a list of all the A tags
        found within this tag.rw  )rs   r:   r%  r   r   r.  r/  r'  s           rL   __call__zTag.__call__  s4     t}%FE;
 
BH
 
 	
rN   subtagr   c                   t          |          dk    rb|                    d          rM|dd         }t          j        dt	          |          z  t
          d           |                     |          }nL|                    d	          s|d
k    s|                     |          }nt          d| j	        d|d          t          t          t                   |          S )zACalling tag.subtag is the same as calling tag.find(name="subtag")rQ  r  Nz.%(name)sTag is deprecated, use .find("%(name)s") instead. If you really were looking for a tag called %(name)sTag, use .find("%(name)sTag")r>   r?   r@   __r   'z' object has no attribute ')r   endswithrD   rE   rq  rG   find
startswithrI   r   r   r   r  )rs   rn  tag_namery  s       rL   rM   zTag.__getattr__  s     v;;??vu55?crc{HM _H%%%&"	    YYx((FF""4(( 	:1E1EYYv&&FF .7;~~~vvvN   HSM6***rN   otherc                   | |u rdS t          |t                    sdS t          |d          r`t          |d          rPt          |d          r@| j        |j        k    s0| j        |j        k    s t          |           t          |          k    rdS t          | j                  D ]\  }}||j        |         k    r dS dS )zyReturns true iff this Tag has the same name, the same attributes,
        and the same contents (recursively) as `other`.TFr:   r%  r   )r   r  r4  r:   r%  r   r   r   )rs   rw  r}  my_childs       rL   __eq__z
Tag.__eq__  s     5==4%%% 	5v&&	5'**	 5*--	 yEJ&&zU[((4yyCJJ&&5$T]33 	 	KAx5>!,,,uu -trN   c                    | |k     S )zTReturns true iff this Tag is not identical to `other`,
        as defined in __eq__.rj   )rs   rw  s     rL   __ne__z
Tag.__ne__  s     5=  rN   c                *    |                                  S )zRenders this `Tag` as a string.)decoder   s    rL   __repr__zTag.__repr__	  s    {{}}rN   r  xmlcharrefreplaceencodingr+   indent_levelr   r'   errorsbytesc                \    |                      |||          }|                    ||          S )a  Render this `Tag` and its contents as a bytestring.

        :param encoding: The encoding to use when converting to
           a bytestring. This may also affect the text of the document,
           specifically any encoding declarations within the document.
        :param indent_level: Each line of the rendering will be
           indented this many levels. (The ``formatter`` decides what a
           'level' means, in terms of spaces or other characters
           output.) This is used internally in recursive calls while
           pretty-printing.
        :param formatter: Either a `Formatter` object, or a string naming one of
            the standard formatters.
        :param errors: An error handling strategy such as
            'xmlcharrefreplace'. This value is passed along into
            :py:meth:`str.encode` and its value should be one of the `error
            handling constants defined by Python's codecs module
            <https://docs.python.org/3/library/codecs.html#error-handlers>`_.
        r~  encode)rs   r  r  r   r  r  s         rL   r  z
Tag.encode	  s-    6 KKh	::xx&)))rN   rn   rX  Optional[Iterator[PageElement]]c                   g }t          |t                    s|                     |          }|du rd}d}|                     |          D ]\  }}|t          j        t          j        fv r.t          t          |          }|                    ||d          }	nm|t          j	        u r5t          t          |          }|                    ||d          }	||dz  }n*t          t          |          }|                    |          }	|rdx}
}ndx}
}|t          j        u r0|s.t          t          |                                          sd}
d}|}n|t          j	        u r
||u rd}
d}d}|]|
s|rDt          |t                    r|	                                }	|	r|                     |	|||
|          }	|t          j        k    r|dz  }|                    |	           d                    |          S )a  Render this `Tag` and its contents as a Unicode string.

        :param indent_level: Each line of the rendering will be
           indented this many levels. (The ``formatter`` decides what a
           'level' means, in terms of spaces or other characters
           output.) This is used internally in recursive calls while
           pretty-printing.
        :param encoding: The encoding you intend to use when
           converting the string to a bytestring. decode() is *not*
           responsible for performing that encoding. This information
           is needed so that a real encoding can be substituted in if
           the document contains an encoding declaration (e.g. in a
           <meta> tag).
        :param formatter: Either a `Formatter` object, or a string
            naming one of the standard formatters.
        :param iterator: The iterator to use when navigating over the
            parse tree. This is only used by `Tag.decode_contents` and
            you probably won't need to use it.
        Tr   N)openingFr   r{   )r   r
   r   r  r  r  EMPTY_ELEMENT_EVENTr   _format_tagr  r4   r  _should_pretty_printr   _indent_stringr  r   )rs   r  rn   r   rX  piecesstring_literal_tagr  rn  pieceindent_beforeindent_afters               rL   r~  z
Tag.decode&	  sK   4  )Y// 	;//	::I4L ""00:: >	! >	!NE70#2IJJJsG,,++,=yRV+WW#///sG,,++,=yRW+XX+ A%L88,,Y77 " 4/44/33 000* 1S'**??AA 1 !%$%,""#///G?Q4Q4Q !&#%)" '  L !'?;; . %  $ 3 3!<M<! ! C333 A%LMM%    wwvrN   c                      e Zd ZdZdS )Tag._TreeTraversalEventz{An internal class representing an event in the process
        of traversing a parse tree.

        :meta private:
        Nr   rj   rN   rL   _TreeTraversalEventr  	  s        	 	 	 	rN   r  1Iterator[Tuple[_TreeTraversalEvent, PageElement]]c              #    K   g }|p| j         }|D ]}|rH|j        |d         k    r7|                                }t          j        |fV  |r|j        |d         k    7t          |t                    r>|j        rt          j        |fV  yt          j        |fV  |	                    |           t          j
        |fV  |r(|                                }t          j        |fV  |&dS dS )a]  Yield a sequence of events that can be used to reconstruct the DOM
        for this element.

        This lets us recreate the nested structure of this element
        (e.g. when formatting it as a string) without using recursive
        method calls.

        This is similar in concept to the SAX API, but it's a simpler
        interface designed for internal use. The events are different
        from SAX and the arguments associated with the events are Tags
        and other Beautiful Soup objects.

        :param iterator: An alternate iterator to use when traversing
         the tree.
        r   N)self_and_descendantsr   ro  r  r  r   r  r  r  r  STRING_ELEMENT_EVENT)rs   rX  r  r   now_closed_tags        rL   r  zTag._event_stream	  s=     $  "	8t8 	2 	2A  <IbM 9 9!*+^;;;;  <IbM 9 9 !S!! 2% 1144444114444$$Q'''.11111 	8&]]__N'7777  	8 	8 	8 	8 	8rN   r   r
   r  r  c                >    d}|r|r
|j         |z  }d}|rd}||z   |z   S )a  Add indentation whitespace before and/or after a string.

        :param s: The string to amend with whitespace.
        :param indent_level: The indentation level; affects how much
           whitespace goes before the string.
        :param indent_before: Whether or not to add whitespace
           before the string.
        :param indent_after: Whether or not to add whitespace
           (a newline) after the string.
        r{   
)indent)rs   r   r  r   r  r  space_beforespace_afters           rL   r  zTag._indent_string	  sG    $  	;\ 	;$+l:L 	Ka+--rN   r  c                   | j         rdS d}|sd}d}| j        r
| j        dz   }d}|r!|                    |           }g }|D ]\  }	}
|
|	}nt          |
t                    st          |
t
                    rd                    |
          }
nQt          |
t                    st          |
          }
n,t          |
t                    r||
	                    |          }
|
                    |
          }t          |	          dz   |                    |          z   }|                    |           |rdd                    |          z   }d}| j        r	|j        pd}d|z   |z   | j        z   |z   |z   dz   S )Nr{   /rb    =<r  )r   r_   
attributesr   r	  r  r   r;   rl   rt   attribute_valuequoted_attribute_valuer  r  void_element_close_prefixr:   )rs   rn   r   r  closing_slashr_   attribute_stringr  r%  r   valdecodedrh  void_element_closing_slashs                 rL   r  zTag._format_tag	  s    ; 	 2
  	 M ; 	'[3&F  	9"--d33JE& & &S;!GG!#t,, I
30F0F I!hhsmm'S11 I!#hh"3(MNNI-9!556GHH$44S99D!#hhny/O/OPT/U/UUGW%%%% 9#&%#8  &("  	S)2)L)RPR&  i 	
 )) 	
rN   r   c                6    |duo| j          p| j        | j         vS )zShould this tag be pretty-printed?

        Most of them should, but some (such as <pre> in HTML
        documents) should not.
        N)r  r:   )rs   r  s     rL   r  zTag._should_pretty_print&
  s1     4' 
-- >y ==	
rN   Optional[_Encoding]r  c                d    ||                      d|          S |                     |d|          S )ac  Pretty-print this `Tag` as a string or bytestring.

        :param encoding: The encoding of the bytestring, or None if you want Unicode.
        :param formatter: A Formatter object, or a string naming one of
            the standard formatters.
        :return: A string (if no ``encoding`` is provided) or a bytestring
            (otherwise).
        Nr   )r  r   )r  r  r   r  )rs   r  r   s      rL   prettifyzTag.prettify1
  s8     ;;A;CCC;;qI;VVVrN   c                >    |                      |||| j                  S )a3  Renders the contents of this tag as a Unicode string.

        :param indent_level: Each line of the rendering will be
           indented this many levels. (The formatter decides what a
           'level' means in terms of spaces or other characters
           output.) Used internally in recursive calls while
           pretty-printing.

        :param eventual_encoding: The tag is destined to be
           encoded into this encoding. decode_contents() is *not*
           responsible for performing that encoding. This information
           is needed so that a real encoding can be substituted in if
           the document contains an encoding declaration (e.g. in a
           <meta> tag).

        :param formatter: A `Formatter` object, or a string naming one of
            the standard Formatters.
        )rX  )r~  r  )rs   r  rn   r   s       rL   decode_contentszTag.decode_contentsC
  s,    0 {{+YAQ  
 
 	
rN   c                Z    |                      |||          }|                    |          S )a%  Renders the contents of this PageElement as a bytestring.

        :param indent_level: Each line of the rendering will be
           indented this many levels. (The ``formatter`` decides what a
           'level' means, in terms of spaces or other characters
           output.) This is used internally in recursive calls while
           pretty-printing.
        :param formatter: Either a `Formatter` object, or a string naming one of
            the standard formatters.
        :param encoding: The bytestring will be in this encoding.
        )r  r  )rs   r  r  r   r   s        rL   encode_contentszTag.encode_contents_
  s-    " ''h	JJx(((rN   r  r   prettyPrintindentLevelc                8    |sd}|                      ||          S )zIDeprecated method for BS3 compatibility.

        :meta private:
        N)r  r  )r  )rs   r  r  r  s       rL   renderContentszTag.renderContentss
  s*      	K##x#PPPrN   r6   c                F    d} | j         ||||dfddi|}|r|d         }|S )a  Look in the children of this PageElement and find the first
        PageElement that matches the given criteria.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param recursive: If this is True, find() will perform a
            recursive search of this Tag's children. Otherwise,
            only the direct children will be considered.
        :param string: A filter on the `Tag.string` attribute.
        :param limit: Stop looking after finding this many results.
        :kwargs: Additional filters on attribute values.
        Nr   r/  rQ  r   rl  )rs   r:   r%  r   r   r'  rS  r  s           rL   rt  zTag.find
  sF    . $-eY[[q[TZ[[ 	
ArN   	findChildrt  r>  c                P    | j         }|s| j        } | j        |||||fd|dz   i|S )a  Look in the children of this `PageElement` and find all
        `PageElement` objects that match the given criteria.

        All find_* methods take a common set of arguments. See the online
        documentation for detailed explanations.

        :param name: A filter on tag name.
        :param attrs: Additional filters on attribute values.
        :param recursive: If this is True, find_all() will perform a
            recursive search of this PageElement's children. Otherwise,
            only the direct children will be considered.
        :param limit: Stop looking after finding this many results.
        :param _stacklevel: Used internally to improve warning messages.
        :kwargs: Additional filters on attribute values.
        r/  r   )r  childrenr1  )	rs   r:   r%  r   r   r.  r/  r'  re  s	            rL   rw  zTag.find_all
  sU    2 $	 	&It~%	
 
?JQ
RX
 
 	
rN   findAllrw  findChildrenc                $    d | j         D             S )z7Iterate over all direct children of this `PageElement`.c              3     K   | ]}|V  d S rx   rj   )r   r   s     rL   r   zTag.children.<locals>.<genexpr>
  s"      ))a))))))rN   rc  r   s    rL   r  zTag.children
  s     *)4=))))rN   c                6    |                      | j                  S )zVIterate over this `Tag` and its children in a
        breadth-first sequence.
        )r  r  r   s    rL   r  zTag.self_and_descendants
  s    
 ~~d.///rN   c              #     K   t          | j                  sdS t          t          |                     d                    }|j        }| j        d         }||ur||j        }|V  |}||ur|dS dS dS dS )zUIterate over all children of this `Tag` in a
        breadth-first sequence.
        NT)r  r   )r   r   r   r   r  r   )rs   last_descendantstopNodecurrentr#  s        rL   r  zTag.descendants
  s      
 4=!! 	F {D,A,Ad,A,S,STT"/%)]1%5X%%'*=,IMMMG X%%'*=*=*=%%%%*=*=rN   selectorc                *     | j         j        ||fi |S )a  Perform a CSS selection operation on the current element.

        :param selector: A CSS selector.

        :param namespaces: A dictionary mapping namespace prefixes
           used in the CSS selector to namespace URIs. By default,
           Beautiful Soup will use the prefixes it encountered while
           parsing the document.

        :param kwargs: Keyword arguments to be passed into Soup Sieve's
           soupsieve.select() method.
        )css
select_one)rs   r  r  r'  s       rL   r  zTag.select_one
  s#     #tx"8ZBB6BBBrN   ResultSet[Tag]c                ,     | j         j        |||fi |S )aP  Perform a CSS selection operation on the current element.

        This uses the SoupSieve library.

        :param selector: A string containing a CSS selector.

        :param namespaces: A dictionary mapping namespace prefixes
           used in the CSS selector to namespace URIs. By default,
           Beautiful Soup will use the prefixes it encountered while
           parsing the document.

        :param limit: After finding this number of results, stop looking.

        :param kwargs: Keyword arguments to be passed into SoupSieve's
           soupsieve.select() method.
        )r  select)rs   r  r  r.  r'  s        rL   r  z
Tag.select
  s$    . txxUEEfEEErN   r   c                     t          |           S )z,Return an interface to the CSS selector API.r   r   s    rL   r  zTag.css  s     4yyrN   r  c                    | j         S z6Deprecated generator.

        :meta private:
        )r  r   s    rL   childGeneratorzTag.childGenerator  s     }rN   r  c                    | j         S r  )r  r   s    rL   recursiveChildGeneratorzTag.recursiveChildGenerator  s     rN   rY  c                ,    |                      |          S )zDeprecated method. This was kind of misleading because has_key()
        (attributes) was different from __in__ (contents).

        has_key() is gone in Python 3, anyway.

        :meta private:
        )rY  rX  s     rL   has_keyzTag.has_key&  s     }}S!!!rN   )NNNNNNNNNNNNNNNN) r  r  r  r  r:   r^   r`   r^   r_   r^   r%  r  r   r  r`  r(   r   r   r  r	  r  r	  r  r   r  r  r  r  r  r  r  r   )Tr  r  r  )r<   r^   )r   r;   r<   r   r  )r+  r   r,  r,   r<   r  )r+  r   r0  r,   r<   r  )r<   r-   )r@  r,   r<   r   )rB  rC  r<   r  r  )r  r   r<   r   r  )rn  r   r<   r   rx   )r   r;   r   rO  r<   rO  )r   r;   r   rR  r<   r   )r   r;   r<   r   )r<   r   )r   r;   r<   r)   r  )r   r   r<   r   )r   r;   r   r)   r<   r   r   r;   r<   r   )r:   rj  r%  r2   r   r   r   r&  r.  r	  r/  r   r'  r1   r<   r.   )rn  r;   r<   r   )rw  r   r<   r   r  )
r  r+   r  r	  r   r'   r  r;   r<   r  )
r  r	  rn   r+   r   r'   rX  r  r<   r;   )rX  r  r<   r  )r   r;   r  r   r   r
   r  r   r  r   r<   r;   )rn   r;   r   r
   r  r   r<   r;   )r   )r  r   r<   r   )Nr  )r  r  r   r'   r<   r  )r  r	  rn   r+   r   r'   r<   r;   )r  r	  r  r+   r   r'   r<   r  )r  r+   r  r   r  r	  r<   r  )r:   r6   r%  r2   r   r   r   r&  r'  r1   r<   r(   )r:   r6   r%  r2   r   r   r   r&  r.  r	  r/  r   r'  r1   r<   r.   )r  r;   r  r   r'  r   r<   r   )Nr   )
r  r;   r  r   r.  r   r'  r   r<   r  )r<   r   )SrJ   rf   rg   rh   r  ri   r   r  r   r  r  r  r   r"  r   r  r4   r  r  r   r   r   r  r   r.  r=  replace_with_childrenr?  r  r  r  rI  r   rQ  rU  rY  r[  r  r_  ra  rd  rf  r   ri  rm  rM   rz  r|  r  __str____unicode__rP   r  r~  objectr  r  r  r  r  r  r  r  r  r  r  r  r  rt  r	   r  rw  r  r  r  r  r  r  r  r  r  r  r  rj   rN   rL   r  r  )  sE        . .d +/)-"#' $:>6:&*!%$(#'/3?C7;IM/3#wO wO wO wO wOr 0///IIILLLBBBB((((88880000 $#M>7KKK    4   8 M M M XM$ [#W--% % % .-%    X. ]' ' ' ]' "1% 8 "+BU'! '! '! '! '!R h|$$G   &U U U Un   " #[7##   $#7 7 7 7# # # #J" " " " "& & & &P: : : : >B, , , , , AE    .! ! ! !$ $ $ $   
# # # #" " " "" " " "          
" " " " .2').2#
 
 
 
 
"+ + + +.   *! ! ! !
    %$Gk 6&*&/)* * * * *@ '+'>&/48k k k k kZ    f    .-//++----//..00 ;?*8 *8 *8 *8 *8X. . . .8<
 <
 <
 <
|	
 	
 	
 	
 	
 )-&/W W W W W( '+'>&/	
 
 
 
 
< '+5&/	) ) ) ) )( ["G,, 6!%&	Q Q Q Q -,Q$ !%').2    : +*;HHI !%').2#
 
 
 
 
@ )(JHHG--nj'RRL * * * X* 0 0 0 X0       X & EIC C C C C( 04	F F F F F2    X
 [W%%   &% [((      )(  [W%%" " " &%" " "rN   r  _PageElementT)boundc                  <     e Zd ZU dZded<   	 dd fd	ZddZ xZS )rt  zA ResultSet is a list of `PageElement` objects, gathered as the result
    of matching an :py:class:`ElementFilter` against a parse tree. Basically, a list of
    search results.
    Optional[ElementFilter]sourcerj   ry  Iterable[_PageElementT]r<   r   c                f    t          t          |                               |           || _        d S rx   )r   rt  r  r  )rs   r  ry  r   s      rL   r  zResultSet.__init__=  s.     	i''///rN   r   r;   c                (    t          d| d          )z7Raise a helpful exception to explain a common code fix.z#ResultSet object has no attribute "z|". You're probably treating a list of elements like a single element. Did you call find_all() when you meant to call find()?r  rX  s     rL   rM   zResultSet.__getattr__C  s.     xC  x  x  x
 
 	
rN   )rj   )r  r  ry  r  r<   r   r  )rJ   rf   rg   rh   ri   r  rM   r   r   s   @rL   rt  rt  5  sw          
 $### RT      
 
 
 
 
 
 
 
rN   rt  )rs  )r:   r;   r<   r   )c
__future__r   __license__r   rD   bs4.cssr   bs4._deprecationr   r   r	   bs4.formatterr
   r   r   bs4._warningsr   typingr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   typing_extensionsr   r    r2  r"   bs4.builderr#   rr  r%   r&   r'   bs4._typingr(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r5   ri   r6   rq  rC   r   r9   rM   rP   rQ   setr[   r;   r]   rl   rv   r   r   r   r   r   r  r   r4   r  r  r  r  r  r  r  r  r  r  r  r  r  r  rt  rs  rj   rN   rL   <module>r     s   " " " " " " "  				                
         
 < ; ; ; ; ;                                     &       
  !!!!!!''''''((((((                                   $)	Xd+<&=>>$      &e,Q&RS S S S S Dm    +5"*V*<*<  < < < <K K K K  '  & & & & ",F!3!3  3 3 3 3 -0C  - -     $    #   D$ $ $ $ $C $ $ $0! ! ! ! ! E ! ! !8    c       DSM   ( ( ( ( (} ( ( (@(( (( (( (( (( (( (( ((V#A #A #A #A #A E #A #A #AL] ] ] ] ]& ] ] ]@[# [# [# [# [#c; [# [# [#|0 0 0 0 0 0 0 06           .       4               $   % % % % %  % % %P           _       _       _       O   F" F" F" F" F"+ F" F" F"R( {;;;
 
 
 
 
]#W]%; 
 
 
2 $ # # # # # # #rN   