qJc @sdZddkZddklZdddgZy eZWnej o eZnXde fdYZ de fdYZ dei fd YZyeZeZWnej oeZeZnXd efd YZd efd YZdefdYZdefdYZdefdYZdefdYZdZeidZde_eedd?gi-Z=d@Z>dAZ?ei%dBei&Z@dCZAdDefdEYZBdS(FsCSS Selectors based on XPath. This module supports selecting XML/HTML tags based on CSS selectors. See the `CSSSelector` class for details. iN(tetreetSelectorSyntaxErrortExpressionErrort CSSSelectorcBseZRS((t__name__t __module__(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRscBseZRS((RR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRscBs eZdZdZdZRS(sA CSS selector. Usage:: >>> from lxml import etree, cssselect >>> select = cssselect.CSSSelector("a tag > child") >>> root = etree.XML("TEXT") >>> [ el.tag for el in select(root) ] ['child'] cCs,t|}tii||||_dS(N(t css_to_xpathRtXPatht__init__tcss(tselfR tpath((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR$s cCs0d|iittt|d|ifS(Ns<%s %s for %r>i(t __class__RthextabstidR (R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt__repr__)s (RRt__doc__RR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs  t _UniTokencBseZdZdZRS(cCsti||}||_|S(N(t_unicodet__new__tpos(tclstcontentsRtobj((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR;s cCs#d|iiti||ifS(Ns %s(%s, %r)(R RRRR(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR@s  (RRRR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR:s tSymbolcBseZRS((RR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRFstStringcBseZRS((RR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRIstTokencBseZRS((RR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRLstClasscBs)eZdZdZdZdZRS(s( Represents selector.class_name cCs||_||_dS(N(tselectort class_name(R RR((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR[s cCsd|ii|i|ifS(Ns %s[%r.%s](R RRR(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR_s cCs5|ii}|idtd|id|S(Ns7contains(concat(' ', normalize-space(@class), ' '), %s)t (Rtxpatht add_conditiont xpath_literalR(R t sel_xpath((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR es(RRRRRR (((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRVs  tFunctioncBsweZdZddddgZdZdZdZeedZ d Z d Z d Z d Z d ZRS(s( Represents selector:name(expr) ttargettlangtenabledtdisabledcCs(||_||_||_||_dS(N(Rttypetnametexpr(R RR)R*R+((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRss   cCs)d|ii|i|i|i|ifS(Ns%s[%r%s%s(%r)](R RRR)R*R+(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRys cCs|ii}|i|ijotd|ind|iidd}t||ptd|int||}|||iS(Ns$The psuedo-class %r is not supportedt_xpath_t-t_sThe psuedo-class %r is unknown( RR R*t unsupportedRtreplacethasattrtgetattrR+(R tsel_pathtmethod((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR scCsut|\}}| o"| o| o|id|S|o|in|i|djo+|od|}n|id||S|o| }| }n|djot| }n d| }|djod||fg}ng}|djo|id|n*|djo|o|id |nd i|}|o|i|n|S( Nsfalse() and position() = 0is last() - %ssposition() = %ss+%sis(position() %s) mod %s = 0sposition() >= %ssposition() < (last() %s)s and (t parse_seriesR!t add_name_testtadd_star_prefixtstrtappendtjoin(R R R+tlastR6tatbtb_neg((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_nth_childs:        cCs|i||dtS(NR;(R?tTrue(R R R+((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_nth_last_childscCs6|idjotdn|i||dtS(Nt*s"*:nth-of-type() is not implementedR6(telementtNotImplementedErrorR?tFalse(R R R+((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_nth_of_types cCs|i||dtdtS(NR;R6(R?R@RE(R R R+((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_nth_last_of_typescCsAt|to|i}n|idt|i|S(Ns'contains(css:lower-case(string(.)), %s)(t isinstancetElementt_format_elementR!R"tlower(R R R+((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_containss  cCs*|i}|i}|id||S(Nsnot(%s)(R t conditionR!(R R R+tcond((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt _xpath_nots  (RRRR/RRR RER@R?RARFRGRLRO(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR$ks    *    cCs |iS(N(RK(tcontextts((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_make_lower_casesshttp://codespeak.net/lxml/css/R s lower-casetPseudoc BseZdZddddddddd d d g Zd Zd ZdZdZdZdZ dZ dZ dZ dZ dZdZRS(s# Represents selector:ident t indeterminates first-lines first-lettert selectiontbeforetaftertlinktvisitedtactivetfocusthovercCs||_||_||_dS(N(RCR)tident(R RCR)R]((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs  cCs#d|ii|i|i|ifS(Ns %s[%r%s%s](R RRCR)R](R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs cCs|ii}|i|ijotd|ind|iidd}t||ptd|int||}||}|S(Ns"The psuedo-class %r is unsupportedR,R-R.sThe psuedo-class %r is unknown(RCR R]R/RR0R1R2(R tel_xpathR4((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR s cCs|id|S(NsE(@selected or @checked) and (name(.) = 'input' or name(.) = 'option')(R!(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_checkeds cCs tdS(N(RD(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt _xpath_rootscCs%|i|i|id|S(Nsposition() = 1(R7R6R!(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_first_childs   cCs%|i|i|id|S(Nsposition() = last()(R7R6R!(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_last_child s   cCs;|idjotdn|i|id|S(NRBs"*:first-of-type is not implementedsposition() = 1(RCRDR7R!(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_first_of_types    cCs;|idjotdn|i|id|S(NRBs!*:last-of-type is not implementedsposition() = last()(RCRDR7R!(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_last_of_types    cCs%|i|i|id|S(Ns last() = 1(R6R7R!(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_only_child!s   cCs1|idjotdn|id|S(NRBs!*:only-of-type is not implementeds last() = 1(RCRDR!(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_only_of_type's   cCs|id|S(Ns!not(*) and not(normalize-space())(R!(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt _xpath_empty.s (RRRR/RRR R_R`RaRbRcRdReRfRg(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRSs            tAttribcBs;eZdZdZdZdZdZdZRS(s> Represents selector[namespace|attrib operator value] cCs1||_||_||_||_||_dS(N(Rt namespacetattribtoperatortvalue(R RRiRjRkRl((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR7s     cCsa|idjo!d|ii|i|ifSd|ii|i|i|i|ifSdS(Ntexistss %s[%r[%s]]s%s[%r[%s %s %r]](RkR RRt_format_attribRl(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR>s   cCs0|idjo|iSd|i|ifSdS(NRBs%s|%s(RiRj(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRnLscCs4|idjo d|iSd|i|ifSdS(NRBt@s@%s:%s(RiRj(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt _xpath_attribRs cCs|ii}|i}|i}|idjo|i|n|idjo!|id|t|fnz|idjoL|o$|id||t|fq|id|t|fn|idjo)|id|td |d fn|id jo1|id |t||t|d fn|id jo!|id|t|fns|idjo1|id||t|dt|fn2|idjo!|id|t|fn|S(NRmt=s%s = %ss!=snot(%s) or %s != %ss%s != %ss~=s3contains(concat(' ', normalize-space(%s), ' '), %s)Rs|=s%s = %s or starts-with(%s, %s)R-s^=sstarts-with(%s, %s)s$=s(substring(%s, string-length(%s)-%s) = %sis*=scontains(%s, %s)(RR RpRlRkR!R"tlen(R R RjRl((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR Ys<     )    ( (RRRRRRnRpR (((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRh2s     RIcBs2eZdZdZdZdZdZRS(s& Represents namespace|element cCs||_||_dS(N(RiRC(R RiRC((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs cCsd|ii|ifS(Ns%s[%s](R RRJ(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs cCs0|idjo|iSd|i|ifSdS(NRBs%s|%s(RiRC(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRJscCsF|idjo|ii}nd|i|if}td|S(NRBs%s:%sRC(RiRCRKt XPathExpr(R tel((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR s(RRRRRRJR (((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRIs    tHashcBs)eZdZdZdZdZRS(s Represents selector#id cCs||_||_dS(N(RR(R RR((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs cCsd|ii|i|ifS(Ns %s[%r#%s](R RRR(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs cCs-|ii}|idt|i|S(Ns@id = %s(RR R!R"R(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR s(RRRRRR (((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRus  tOrcBs#eZdZdZdZRS(cCs ||_dS(N(titems(R Rw((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRscCsd|ii|ifS(Ns%s(%r)(R RRw(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs cCs4g}|iD]}||iq~}t|S(N(RwR t XPathExprOr(R t_[1]titemtpaths((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR s*(RRRRR (((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRvs  tCombinedSelectorcBsieZhdd6dd6dd6dd6ZdZd Zd Zd Zd Zd ZdZ RS(t descendantRtchildt>tdirect_adjacentt+tindirect_adjacentt~cCs||_||_||_dS(N(Rt combinatort subselector(R RRR((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs  cCsC|idjo d}n |i}d|ii|i||ifS(NRs s %s[%r %s %r](RR RRR(R tcomb((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs   cCsl|i|ijotd|ind|i|i}t||}|ii}|||iS(NsUnknown combinator: %rR,(Rt_method_mappingRR2RR R(R R4R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR scCs|id|i|S(Ns /descendant::(R:R (R R tsub((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_descendantscCs|id|i|S(Nt/(R:R (R R R((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt _xpath_childscCs1|id|i|i|id|S(Ns/following-sibling::sposition() = 1(R:R R6R!(R R R((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_direct_adjacents  cCs|id|i|S(Ns/following-sibling::(R:R (R R R((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt_xpath_indirect_adjacents( RRRRRR RRRR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR|s     s^\w+\s*$s^(\w*)#(\w+)\s*$s^(\w*)\.(\w+)\s*$sdescendant-or-self::cCst|toti|}|dj od||idifSti|}|dj o+d||idpd|idfSti|}|dj o+d||idpd|idfSt |}n|i }|o|i |nt |S(Ns%s%sis%s%s[@id = '%s']iRBisA%s%s[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]( RHt _basestringt_el_retsearchtNonetgrouptstript_id_ret _class_retparseR t add_prefixR(tcss_exprtprefixtmatchR+((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs"  ( ( RscBsheZd d dd edZdZdZdZdZdZ dZ dZ d Z RS( RBcCs1||_||_||_||_||_dS(N(RR RCRMt star_prefix(R RR RCRMR((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs     cCsd}|idj o|t|i7}n|idj o|t|i7}n|t|i7}|io|d|i7}n|S(Nts[%s](RRRR RCRM(R R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt__str__s cCsd|ii|fS(Ns%s[%s](R R(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR(scCs1|iod|i|f|_n ||_dS(Ns %s and (%s)(RM(R RM((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR!,s cCs?|idjo|i|_n|i|i7_||_dS(N(R RRC(R tpart((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pytadd_path2scCs+|io||i|_n ||_dS(N(R(R R((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR9s cCs<|idjodS|idt|id|_dS(NRBs name() = %s(RCR!R"(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR6?scCs3|io|id7_n d|_t|_dS(s Adds a /* prefix if there is no prefix. This is when you need to keep context's constrained to a single parent. s*/N(R R@R(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR7Fs  cCst|}||7}|ipd|ipd}|io|djo d}n||_||_|i|_|i|_dS(NRs*/(RRR RRCRM(R tcombinertotherRR ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR:Qs      N( RRRRERRRR!RRR6R7R:(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRss        RxcBs#eZdZddZdZRS(s Represents |'d expressions. Note that unfortunately it isn't the union, it's the sum, so duplicate elements will appear. cCs'x|D]}qW||_||_dS(N(RwR(R RwRRz((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRds  cCsE|ipd}dig}|iD]}|d||fq$~S(NRs | s%s%s(RR:Rw(R RRyti((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRjsN(RRRRRR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRx^s s('+)cCst|to|i}n t|}d|jod|}nsd|jod|}nXddig}t|D]0}|o#|d|jodpd|q|q|~}|S(Nt's'%s't"s"%s"s concat(%s)t,(RHRIRJRR:tsplit_at_single_quotes(RQRyR((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR"ps    GcCstt|}||_yt|SWntj ozddk}|id}d||i|if}||_ |i djo ||_ nt |g|_ nXdS(Niis%s at %s -> %rii(ii(t TokenStreamttokenizetsourcetparse_selector_groupRtsystexc_infotusedtpeektmsgt version_infotmessagettupletargs(tstringtstreamRteR((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs    cCskg}x8|it||idjo|iq Pq t|djo |dSt|SdS(NRii(R9tparse_selectorRtnextRrRv(Rtresult((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs cCst|}x|i}|djp |djo|S|djo|i}nd}t|i}t|}|t|ijotd|int|||}q|S(NRRRRRsExpected selector, got '%s'(RRR(tparse_simple_selectorRRRRrRRR|(RRRRtconsumedt next_selector((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs    c CsC|i}|djot|t od}}n|i}|djo%t|t otd|n|idjoR|}|i|i}|djo%t|t otd|qn d}|}t||}t}x@|i}|djo8|oPn|it||i}t}qq|djo&|it ||i}qq|djoM|it ||}|i}|djptd|qqq|d jp |d jo)|i}|i}t|tptd|n|id jo|i|i}t|t o|i} n@t|to#t |ot |i} n t|} |i}|d jptd || fnt|||| }qt|||}qq|djo|inPq|S(NRBsExpected symbol, got '%s't|t#t.t[t]s] expected, got '%s't:s::t(t)sExpected ')', got '%s' and '%s'R(RRHRRRRIRERuR@Rt parse_attribRtis_inttintRR$RS( RRRCRiRRthas_hashR)R]R((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs                     cCs-yt|Wntj otSXtSdS(N(Rt ValueErrorRER@(tv((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs cCs|i}|idjo |}|i|i}nd}|idjot|||ddS|i}|djotd |n|i}t|ttfptd |nt|||||S(NRRBRRms^=s$=s*=Rqs~=s|=s!=sOperator expected, got '%s's#Expected string or symbol, got '%s'(s^=s$=s*=Rqs~=s|=s!=(RRRhRRRHRR(RRRjRitopRl((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs"     cCsat|to|i}n| p |djod St|to d|fS|djod S|djod S|djodSd|jodt|fS|idd\}}|p d}n;|djp |d jot|d }n t|}|p d}n;|djp |d jot|d }n t|}||fS(sJ Parses things like '1n+2', or 'an+b' generally, returning (a, b) RBitoddiiteventnR-Rt1(ii(ii(ii(ii(RHRIRJRtsplit(RQR<R=((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyR5s4         s\s+s /\*.*?\*/s[+-]?\d*n(?:[+-]\d+)?c csd}tid|}xti|d|}|o|}|i}nd}|t|jodSti|d|}|oG|idjo4|||i!}t||V|i}qn||}|||d!}|djot ||V|d7}qn|d joK|djo|djot d|Vnt ||V|d7}qn|djp |djo0|}t ||\}}t ||Vqn|}t ||\}}t||VqqdS(NiRRRis~=s|=s^=s$=s*=s::s!=s>+~,.*=[]()|:#s.#RiRR(s~=s|=s^=s$=s*=s::s!=( t _comment_reRt_whitespace_reRtendRrt _count_reRRRttokenize_escaped_stringRttokenize_symbol(RQRRtpreceding_whitespace_postsymtctc2told_pos((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRKsJ      s (\\(?:%s))Rs[A-Fa-f0-9]{1,6}(?: |\s)?s [^A-Fa-f0-9]cCsg}xt|D]}|pqnd|jo|ddjoKt|djo8|d}|ddjott|d}qqtd|idd|fn|i|qWdi|S(Ns\iit0123456789ABCDEFabcdefis'Invalid escape sequence %r in string %rR(tsplit_at_string_escapesRrt_unichrRRRR9R:(tliteralt substringst substring((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pytunescape_string_literalxs  $ !cCs||}|d}|}x|i||}|djotd|||fn|||!}|ido|d}qnd|jot|}n||dfSdS(Niis%Expected closing %s for string in: %rs\(tfindRtendswithR(RQRtquotetstartRR((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs       s[^\w\\-]cCs|}ti|d|}|p||t|fS|i|jon|p||}t|}n |||i!}|i}y|iddid}WnEtj o9ddk}|id}t d||fnX||fS(NRtASCIItbackslashreplacetunicode_escapeiisBad symbol %r: %s( t_illegal_symbolRRrRtencodetdecodetUnicodeDecodeErrorRRR(RQRRRRRR((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs&   RcBs/eZddZdZdZdZRS(cCsog|_t||_||_d|_t|_y|ii|_ Wn"t j o|ii |_ nXdS(N( RtiterttokensRRtpeekedREt_peekingRt next_tokentAttributeErrort__next__(R RR((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs    cCsm|io$t|_|ii|i|iSy$|i}|ii||SWntj odSXdS(N(RRERR9RRt StopIterationR(R R((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs   cCst|idS(N(RRR(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyt__iter__scCsH|ip7y|i|_Wntj odSXt|_n|iS(N(RRRRRR@(R ((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs  N(RRRRRRR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pyRs (CRtretlxmlRt__all__t basestringRt NameErrorR8t SyntaxErrorRt RuntimeErrorRRRtunicodeRtunichrRtchrRRRRtobjectRR$RRtFunctionNamespacetnsRRSRhRIRuRvR|tcompiletUNICODERRRRRsRxRRR"RRRRRRR5RtDOTALLRRRR:RRRRRR(((s4/usr/lib64/python2.6/site-packages/lxml/cssselect.pytsx        h   XP < K    L   ) )