a aB@sdZddlmZgdZddlZddlZddlZddlmZzddl m Z m Z Wn"e yrddl m Z m Z Yn0ddlmZd d lmZd d lmZzdd lmZWne ydd lmZYn0zeWneyeZYn0zeWney eefZYn0d dZdZejddeidZejddeidZejddeidZ edZ!edZ"edZ#e$dej%j&Z'e$dj&Z(ejddeidZ)e$dZ*e$dej%j+Z,ddZ-dd Z.d!d"Z/Gd#d$d$e Z0Gd%d&d&e1Z2Gd'd(d(e1Z3e3d)d*d+Z4e3d,d*d+Z5e3d-d.d+Z6e3d/d.d+Z7e3d0d*d+Z8e3d1d.d+Z9Gd2d3d3ej:e2Z;Gd4d5d5eje2Z?Gd8d9d9ej@e2ZAGd:d;d;ejBZCe$ed<ej%jDZEe$dd?ZHdd@dAZIddBdCZJddDdEZKddFdGZLdHdIZMdJdKZNGdLdMdMe=ZOeOeCjPdN<ddOdPZQdQdRZRGdSdTdTe ZSGdUdVdVe1ZTGdWdXdXe1ZUGdYdZdZeUe=ZVeVeCjPd[<Gd\d]d]eUe=ZWeWeCjPd^<Gd_d`d`eZXGdadbdbeYZZGdcddddeYZ[GdedfdfeZ\GdgdhdheUe=Z]e]eCjPdi<Gdjdkdke=Z^e^eCjPdl<dmdnZ_dodpZ`e$dqjaZbe$dqFdrjaZcddtduZdeedjed_ddvdwZeGdxdydyejfZfGdzd{d{ejgZhd|d}ZiefZjehZkdS)z.The ``lxml.html`` tool set for HTML handling. )absolute_import)document_fromstringfragment_fromstringfragments_fromstring fromstringtostringElementdefsopen_in_browser submit_formfind_rel_links find_classmake_links_absoluteresolve_base_href iterlinks rewrite_linksparseN)partial)MutableMapping MutableSet)etree)r )SetMixinurljoincCsB|s|Stjddkr(tdtjj}ntdtjj}|d|S)Nrz^(\s*)u'z^(\s*)b'z\1')sys version_inforecompileMsub)sr"r$8/usr/lib64/python3.9/site-packages/lxml/html/__init__.py__fix_docstringKs r&zhttp://www.w3.org/1999/xhtmlz9descendant-or-self::a[@rel]|descendant-or-self::x:a[@rel]xZ namespacesz7descendant-or-self::option|descendant-or-self::x:optionz3descendant-or-self::form|descendant-or-self::x:formztdescendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), concat(' ', $class_name, ' '))]zdescendant-or-self::*[@id=$id]zstring()z&url\((["][^"]*["]|['][^']*[']|[^)]*)\)z@import "(.*?)"z%//label[@for=$id]|//x:label[@for=$id]z[^ ]+z%[^;=]*;\s*(?:url\s*=\s*)?(?P.*)$cCs`|dddkr |dddks@|dddkrT|dddkrT|dd|dfS||fSdS)Nr"'r$)r#posr$r$r%_unquote_matchjs@r-cCs4t|trt|ddSt|tr,t|ddS|SdS)z1Convert the result back into the input type. zutf-8)encodingunicodeN) issubclassbytesrr/)typresultr$r$r%_transform_resultqs     r4cCs@t|tr<|ddkr<|dttdtkr<|ddS|S)Nr{r}r*) isinstance basestringlenXHTML_NAMESPACEsplit)tagr$r$r%_nons|s $r=cs`eZdZdZddZddZddZfdd Zd d Zd d Z ddZ ddZ ddZ Z S)Classesa*Provides access to an element's class attribute as a set-like collection. Usage:: >>> el = fromstring('') >>> classes = el.classes # or: classes = Classes(el.attrib) >>> classes |= ['block', 'paragraph'] >>> el.get('class') 'hidden large block paragraph' >>> classes.toggle('hidden') False >>> el.get('class') 'large block paragraph' >>> classes -= ('some', 'classes', 'block') >>> el.get('class') 'large paragraph' cCs||_t|jdd|_dS)Nclass) _attributesrget_get_class_value)selfZ attributesr$r$r%__init__szClasses.__init__cCsR|rtd|rtd||}||vr4dS||d||jd<dS)z[ Add a class. This has no effect if the class is already present. \sInvalid class name: %rN r?)rsearch ValueErrorrCr;appendjoinrArDvalueclassesr$r$r%adds   z Classes.addcsbrtdrtdfdd|D}|rLd||jd<nd|jvr^|jd=dS)zn Remove a class if it is currently present. If the class is not present, do nothing. rFrGcsg|]}|kr|qSr$r$).0namerNr$r% sz#Classes.discard..rHr?N)rrIrJrCr;rLrArMr$rSr%discards  zClasses.discardcs0|rtd|rtd|tt||dS)zw Remove a class; it must currently be present. If the class is not present, raise a KeyError. rFrGN)rrIrJsuperr>removerDrN __class__r$r%rWs zClasses.removecCs|}||vo||vSN)rCr;)rDrRrOr$r$r% __contains__szClasses.__contains__cCst|Sr[)iterrCr;rDr$r$r%__iter__szClasses.__iter__cCst|Sr[)r9rCr;r^r$r$r%__len__szClasses.__len__cCsH|}d}|D]}||vr||d}q|rDd||jd<dS)z. Add all names from 'values'. FTrHr?N)rCr;rKrLrA)rDvaluesrOZextendedrNr$r$r%updates  zClasses.updatecCs~|rtd|rtd||}z||d}Wn tyZ||d}Yn0|rrd||jd<n|jd=|S)z Add a class name if it isn't there yet, or remove it if it exists. Returns true if the class was added (and is now enabled) and false if it was removed (and is now disabled). rFrGFTrHr?) rrIrJrCr;rWrKrLrA)rDrNrOZenabledr$r$r%toggles      zClasses.toggle)__name__ __module__ __qualname____doc__rErPrUrWr\r_r`rbrc __classcell__r$r$rYr%r>s  r>cseZdZd+fdd ZeddZejddZeddZed d Zed d Z ed dZ eddZ e jddZ e j ddZ ddZ ddZddZddZddZddZd,d d!Zd-d#d$Zd.d%d&Zd'd(Zd/d)d*ZZS)0 HtmlMixinNcstt|||dS)zset(self, key, value=None) Sets an element attribute. If no value is provided, or if the value is None, creates a 'boolean' attribute without value, e.g. "
" for ``form.set('novalidate')``. N)rV HtmlElementset)rDkeyrNrYr$r%rksz HtmlMixin.setcCs t|jS)zB A set-like wrapper around the 'class' attribute. )r>attribr^r$r$r%rOszHtmlMixin.classescCsBt|tsJ|}|r(|d|n|ddur>|jd=dS)Nr?)r7r>rCrkrBrm)rDrOrNr$r$r%rOs cCs |jjS)z Returns the base URL, given when the page was parsed. Use with ``urlparse.urljoin(el.base_url, href)`` to get absolute URLs. )Z getroottreedocinfoZURLr^r$r$r%base_url szHtmlMixin.base_urlcCst|S)z0 Return a list of all the forms ) _forms_xpathr^r$r$r%formsszHtmlMixin.formscCs|jddtiddS)zt Return the element. Can be called from a child element to get the document's head. z//body|//x:bodyr'r(rxpathr:r^r$r$r%bodyszHtmlMixin.bodycCs|jddtiddS)zu Returns the element. Can be called from a child element to get the document's head. z//head|//x:headr'r(rrrr^r$r$r%head#szHtmlMixin.headcCs2|d}|sdSt||d}|s&dS|dSdS)zN Get or set any