o b @sUdZddlZddlZddlZddlmZmZddlmZm Z m Z ddl m Z ddl mZddlmZmZmZmZmZmZmZmZmZmZmZmZddlmZmZdd lm Z m!Z!m"Z"m#Z#m$Z$m%Z%dd l&m'Z(m)Z*m+Z,dd l-m.Z.m/Z/dd l0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;mZ>dd l?m@Z@ddlAmBZBmCZCddlDmEZEddlFmGZGmHZIerddlJmKZKddlAmLZLeGMrddlNmOZOndZOee3GdddZPee<GdddZQee<GdddZRedefZSeeSeeTdfeeUeTffZVedeeUeSeeTdfeeUeTffZWGdddZXee7e8GdddZYed eeUeWfZZeedefeeTdfeeUeTffZ[ee6e:e>Gd!d"d"eYZ\eGMrZee\e9ee2Gd#d$d$eZ]Gd%d&d&e j^Z_Gd'd(d(Z`gZaeeUebd)<dS)*z8 Very basic functionality for a Reactor implementation. N)ABCabstractmethod)heapifyheappopheappush) format_stack) FrameType) TYPE_CHECKINGAnyCallableDictListNewTypeOptionalSequenceSetTupleUnioncast)classImplements implementer)abstractdefererrorfdescmainthreads)ComplexResolverSimplifier GAIResolverSimpleResolverComplexifier)Deferred DeferredList)IAddress IConnector IDelayedCallIHostnameResolver IProtocol IReactorCoreIReactorPluggableNameResolverIReactorPluggableResolverIReactorThreads IReactorTimeIReadDescriptorIResolverSimpleIWriteDescriptor_ISupportsExitSignalCapturing) ClientFactory)logreflect)Failure)platformseconds)Client) threadable) ThreadPoolc@seZdZUdZdZeeed<efde de de fde e deee fd e dgdfd e dgdfd e ge fd dfd dZd e fddZd$ddZde d dfddZde d dfddZd$ddZd efddZde d efddZde d efd d!Zd efd"d#ZdS)% DelayedCallFN_reprtimefunc.argskwcancelresetr5returncCs^||||f\|_|_|_|_||_||_||_d|_|_d|_ |j r-t dd|_ dSdS)aR @param time: Seconds from the epoch at which to call C{func}. @param func: The callable to call. @param args: The positional arguments to pass to the callable. @param kw: The keyword arguments to pass to the callable. @param cancel: A callable which will be called with this DelayedCall before cancellation. @param reset: A callable which will be called with this DelayedCall after changing this DelayedCall's scheduled execution time. The callable should adjust any necessary scheduling details to ensure this DelayedCall is invoked at the new appropriate time. @param seconds: If provided, a no-argument callable which will be used to determine the current time any time that information is needed. rN) r;r<r=r>resetter cancellerr5 cancelledcalled delayed_timedebugrcreator)selfr;r<r=r>r?r@r5rL7/usr/lib/python3/dist-packages/twisted/internet/base.py__init__Ss zDelayedCall.__init__cCs |j|jS)z Return the time at which this call will fire @return: The number of seconds after the epoch at which this call is scheduled to be made. r;rHrKrLrLrMgetTimevs zDelayedCall.getTimecCsH|jrtj|jr tj||d|_|jrt||_|` |` |` dS)z Unschedule this call @raise AlreadyCancelled: Raised if this call has already been unscheduled. @raise AlreadyCalled: Raised if this call has already been made. N) rFrAlreadyCancelledrG AlreadyCalledrErIreprr:r<r=r>rPrLrLrMr?s   zDelayedCall.cancelsecondsFromNowcCsX|jrtj|jr tj||}||jkr$d|_||_||dS||j|_dS)aY Reschedule this call for a different time @param secondsFromNow: The number of seconds from the time of the C{reset} call at which this call will be scheduled. @raise AlreadyCancelled: Raised if this call has been cancelled. @raise AlreadyCalled: Raised if this call has already been made. rBN) rFrrSrGrTr5r;rHrD)rKrVnewTimerLrLrMr@s   zDelayedCall.reset secondsLatercCsJ|jrtj|jr tj|j|7_|jdkr#|||dSdS)aQ Reschedule this call for a later time @param secondsLater: The number of seconds after the originally scheduled time for which to reschedule this call. @raise AlreadyCancelled: Raised if this call has been cancelled. @raise AlreadyCalled: Raised if this call has already been made. rBN)rFrrSrGrTrHactivate_delayrD)rKrXrLrLrMdelays  zDelayedCall.delaycCs|j|j7_d|_dS)NrBrOrPrLrLrMrYs zDelayedCall.activate_delaycCs|jp|j S)zDetermine whether this call is still pending @return: True if this call has not yet been made or cancelled, False otherwise. )rFrGrPrLrLrMactiveszDelayedCall.activeothercCst|tr |j|jkStS)z Implement C{<=} operator between two L{DelayedCall} instances. Comparison is based on the C{time} attribute (unadjusted by the delayed time).  isinstancer9r;NotImplementedrKr\rLrLrM__le__  zDelayedCall.__le__cCst|tr |j|jkStS)z Implement C{<} operator between two L{DelayedCall} instances. Comparison is based on the C{time} attribute (unadjusted by the delayed time). r]r`rLrLrM__lt__rbzDelayedCall.__lt__cCsV|jdur|jSt|dr@t|jdd}|dur5t|jdd}|dur5t|jdd}|dur5|d|}|dur?t|j}nd}|}dt||j||j |j fg}|dur| d|d f|j r{| d d d |j D|jr{| d |jr| d d d |jD| d|jr| dd|j| dd|S)z Implement C{repr()} for L{DelayedCall} instances. @returns: String containing details of the L{DelayedCall}. Nr< __qualname____name__im_class.z.sz(DelayedCall.__repr__..cSs$g|]\}}|dt|qS)=rj)rlkvrLrLrMrns$)z traceback at creation: %sz >)r:hasattrgetattrr<r2rkr5idr;rGrFextendr=appendjoinr>itemsrIrJ)rKr<imClassnowLrLrLrM__repr__sH       zDelayedCall.__repr__rAN)re __module__rdrIr:rstr__annotations__runtimeSecondsfloatr r robjectr rNrQr?r@rZrYboolr[rarcrrLrLrLrMr9Ks<        #    r9c@seZdZdZdddZded edefd d Zded eeddfd dZ deded eeddfddZ ddede e deefddZ dS)ThreadedResolvera L{ThreadedResolver} uses a reactor, a threadpool, and L{socket.gethostbyname} to perform name lookups without blocking the reactor thread. It also supports timeouts indepedently from whatever timeout logic L{socket.gethostbyname} might have. @ivar reactor: The reactor the threadpool of which will be used to call L{socket.gethostbyname} and the I/O thread of which the result will be delivered. reactor ReactorBaserANcCs||_i|_dSN)r_runningQueries)rKrrLrLrMrN szThreadedResolver.__init__nameerrcCstd|d|}t|S)Naddress z not found: )rDNSLookupErrorr3)rKrr lookupErrorrLrLrM_fail&szThreadedResolver._faillookupDeferredcCs,|j|\}}|j|=|||ddS)Nz timeout error)rerrbackr)rKrr userDeferred cancelCallrLrLrM_cleanup*szThreadedResolver._cleanupresultcCsjz |j|\}}Wn tyYdSw|j|=|t|tr.||||dS||dSr) rKeyErrorr?r^r3rrgetErrorMessagecallback)rKrrrrrrLrLrM _checkTimeout/s  zThreadedResolver._checkTimeoutrR -timeoutcCst|rt|}nd}t}t|jtt|jtj |}tt |j ||j ||}||f|j |<||j|||S)a1 See L{twisted.internet.interfaces.IResolverSimple.getHostByName}. Note that the elements of C{timeout} are summed and the result is used as a timeout for the lookup. Any intermediate timeout or retry logic is left up to the platform via L{socket.gethostbyname}. <)sumr rdeferToThreadPoolrrr* getThreadPoolsocket gethostbynamer+ callLaterrraddBothr)rKrr timeoutDelayrrrrLrLrM getHostByName?s    zThreadedResolver.getHostByName)rrrANr)rerrd__doc__rNrr3rr rrrintrrLrLrLrMrs,  rc@s.eZdZ ddedeedeefddZdS) BlockingResolverrrrrAcCsLzt|}Wnty d|d}t|}t|YSwt|S)Nrz not found)rrOSErrorrrrfailsucceed)rKrraddressmsgrrLrLrMr^s    zBlockingResolver.getHostByNameNr)rerrdrrrr rrLrLrLrMr\sr._ThreePhaseEventTriggerHandlec @seZdZdZdddZdededed edef d d Z d eddfd dZ d eddfddZ d eddfddZ dddZ deddfddZdS)_ThreePhaseEventa Collection of callables (with arguments) which can be invoked as a group in a particular order. This provides the underlying implementation for the reactor's system event triggers. An instance of this class tracks triggers for all phases of a single type of event. @ivar before: A list of the before-phase triggers containing three-tuples of a callable, a tuple of positional arguments, and a dict of keyword arguments @ivar finishedBefore: A list of the before-phase triggers which have already been executed. This is only populated in the C{'BEFORE'} state. @ivar during: A list of the during-phase triggers containing three-tuples of a callable, a tuple of positional arguments, and a dict of keyword arguments @ivar after: A list of the after-phase triggers containing three-tuples of a callable, a tuple of positional arguments, and a dict of keyword arguments @ivar state: A string indicating what is currently going on with this object. One of C{'BASE'} (for when nothing in particular is happening; this is the initial value), C{'BEFORE'} (when the before-phase triggers are in the process of being executed). rANcCsg|_g|_g|_d|_dS)NBASE)beforeduringafterstaterPrLrLrMrNs z_ThreePhaseEvent.__init__phasecallabler=kwargscOs6|dvrtdt|||||ft||||fS)a Add a trigger to the indicate phase. @param phase: One of C{'before'}, C{'during'}, or C{'after'}. @param callable: An object to be called when this event is triggered. @param args: Positional arguments to pass to C{callable}. @param kwargs: Keyword arguments to pass to C{callable}. @return: An opaque handle which may be passed to L{removeTrigger} to reverse the effects of calling this method. rrr invalid phase)rrvryr)rKrrr=rrLrLrM addTriggersz_ThreePhaseEvent.addTriggerhandlecCst|d|j|dS)aS Remove a previously added trigger callable. @param handle: An object previously returned by L{addTrigger}. The trigger added by that call will be removed. @raise ValueError: If the trigger associated with C{handle} has already been removed or if C{handle} is not a valid handle. removeTrigger_N)rvr)rKrrLrLrM removeTriggers z_ThreePhaseEvent.removeTriggerc CsVz|\}}}}Wn ttfytdw|dvrtdt|||||fdS)zN Just try to remove the trigger. @see: removeTrigger zinvalid trigger handlerrN) TypeError ValueErrorrrvremoverKrrrr=rrLrLrMremoveTrigger_BASEsz#_ThreePhaseEvent.removeTrigger_BASEcCsP|\}}}}|dkr||S|||f|jvr!tjdtdddS||dS)z Remove the trigger if it has yet to be executed, otherwise emit a warning that in the future an exception will be raised when removing an already-executed trigger. @see: removeTrigger rzdRemoving already-fired system event triggers will raise an exception in a future version of Twisted.r)category stacklevelN)rfinishedBeforewarningswarnDeprecationWarningrrLrLrMremoveTrigger_BEFOREs   z%_ThreePhaseEvent.removeTrigger_BEFOREcCsd|_g|_g}|jrA|jd\}}}|j|||fz ||i|}Wn ty3tYn wt|t r>|||js t | |j dS)z8 Call the triggers added to this event. BEFORErN) rrrpopry BaseExceptionr1rr^r r! addCallback_continueFiring)rK beforeResultsrr=rrrLrLrM fireEvents     z_ThreePhaseEvent.fireEventignoredc Cshd|_g|_|j|jfD]%}|r1|d\}}}z ||i|Wn ty.tYnw|sq dS)zJ Call the during and after phase triggers for this event. rrN)rrrrrrr1r)rKrrrr=rrLrLrMrs  z _ThreePhaseEvent._continueFiringr)rerrdrrNr_ThreePhaseEventTriggerCallablerrrrrrrrrLrLrLrMrus&    rc@sfeZdZUdZeZeed<eeZ e ed<dedefddZ de de fddZ e de fd d Zd S) PluggableResolverMixinz A mixin which implements the pluggable resolver reactor interfaces. @ivar resolver: The installed L{IResolverSimple}. @ivar _nameResolver: The installed L{IHostnameResolver}. resolver _nameResolverrAcCs(t|sJ|j}||_t||_|S)z See L{IReactorPluggableResolver}. @param resolver: see L{IReactorPluggableResolver}. @return: see L{IReactorPluggableResolver}. )r- providedByr_SimpleResolverComplexifierr)rKr oldResolverrLrLrMinstallResolvers  z&PluggableResolverMixin.installResolvercCs|j}||_t||_|S)z See L{IReactorPluggableNameResolver}. @param resolver: See L{IReactorPluggableNameResolver}. @return: see L{IReactorPluggableNameResolver}. )r_ComplexResolverSimplifierr)rKrpreviousNameResolverrLrLrMinstallNameResolvers z*PluggableResolverMixin.installNameResolvercCs|jS)zd Implementation of read-only L{IReactorPluggableNameResolver.nameResolver}. )rrPrLrLrM nameResolver,sz#PluggableResolverMixin.nameResolverN)rerrdrrrr-rrrr%rrpropertyrrLrLrLrMrs  r_SystemEventIDc seZdZdZdZdZdZdZdZdZdofdd Z dZ dod d Z dod d Z d e eddfddZdeddfddZdeddfddZdeddfddZdeddfddZdeeeeffddZdeefddZdeefddZ dpd!ed"eedeefd#d$Zdod%d&Z dod'd(Z!dqd)ed*e e"ddfd+d,Z#dqd)ed*e e"ddfd-d.Z$dqd)ed*e e"ddfd/d0Z%dod1d2Z&drd eddfd4d5Z'd6eddfd7d8Z(d9ed6ed:e)d;e*fdd?Z-d@e,ddfdAdBZ.d:e)d;e*fde?@reAdusaJdZBdZCdZDdod[d\ZEd]e)d;e*fdc Osbt|s J|d|dksJ|dt||||||j|j|jd}|j||S)zI See twisted.internet.interfaces.IReactorTime.callLater. r-rz* is not greater than or equal to 0 seconds)r5)r.rr9r5_cancelCallLater_moveCallLaterSoonerrry)rKrZrr=r> delayedCallrLrLrMr^s  zReactorBase.callLaterr:cCsv|j}z-||}||}|dkr*|dd}|||krn ||||<|}|dks|||<WdSty:YdSw)NrrR)rindexr)rKr:heapposeltparentrLrLrMr9rs     z ReactorBase._moveCallLaterSoonercCs|jd7_dSNrR)r)rKr:rLrLrMr8szReactorBase._cancelCallLatercCsdd|j|jDS)zQ See L{twisted.internet.interfaces.IReactorTime.getDelayedCalls} cSg|]}|js|qSrLrFrlxrLrLrMrns z/ReactorBase.getDelayedCalls..)rrrPrLrLrMgetDelayedCallss zReactorBase.getDelayedCallscCs@|jD]}|jr|jd8_q|t|j|qg|_dSrA)rrFrrYrr)rKcallrLrLrM_insertNewDelayedCallss  z"ReactorBase._insertNewDelayedCallscCs:||js dS|jdj|}d}tdt||S)z Determine the longest time the reactor may sleep (waiting on I/O notification, perhaps) before it must wake up to service a time-related event. @return: The maximum number of seconds the reactor may sleep. Nri )rHrr;r5maxmin)rKrZlongestrLrLrMrs  zReactorBase.timeoutc Cs|jrAd}t|j}|jD]&\}}}z ||i|Wn ty(tYnw|d7}||kr3nq |jd|=|jrA|||}|jr|jdj |krt |j}|j rd|j d8_ qI|j dkrt|t|j|qIzd|_|j|ji|jWn3tytt|drd}|d7}|d7}|d |jdd 7}|d7}t|Ynw|jr|jdj |ksT|j d kr|j t|jd?krd|_ d d |jD|_t|j|jrd|_|ddSdS)z. Run all pending timed calls. rrRNrBrJ z? C: previous exception occurred in a DelayedCall created here: z C:rtz C:2cSrBrLrCrDrLrLrMrns z/ReactorBase.runUntilCurrent..Fr)rlenrr1rrrHr5rr;rrFrrHrYrrGr<r=r>deferrrurzrJrstripreplacerrrr,) rKcounttotalfar>r}rGrmrLrLrMr'sn            zReactorBase.runUntilCurrentcCs|t||jd|_dS)NT)r _GAIResolverr usingThreadsrPrLrLrMrs zReactorBase._initThreadsrTcOs4t|s J|d|j|||f|dS)zl See L{twisted.internet.interfaces.IReactorFromThreads.callFromThread}. r-N)rrryrrKrTr=rrLrLrMr s zReactorBase.callFromThreadcCs4tddd|_||jj|_|dd|j|_dS)zO Create the threadpool accessible with callFromThread. r rrrN)r8 threadpoolr1start_threadpoolStartupIDr_stopThreadPoolthreadpoolShutdownIDrPrLrLrM_initThreadPools  zReactorBase._initThreadPoolcCdSrrLrPrLrLrM_uninstallHandler$szReactorBase._uninstallHandlerc Csj|j|jg}td|D]}z||Wq tyYq wd|_d|_|jdus+J|jd|_dS)a4 Stop the reactor threadpool. This method is only valid if there is currently a threadpool (created by L{_initThreadPool}). It is not intended to be called directly; instead, it will be called by a shutdown trigger created in L{_initThreadPool}. N)r\r^filterr0rrZr)rKtriggerstriggerrLrLrMr]'s    zReactorBase._stopThreadPoolcCs&|jdur||jdusJ|jS)z[ See L{twisted.internet.interfaces.IReactorThreads.getThreadPool}. N)rZr_rPrLrLrMr:s zReactorBase.getThreadPool _callablecOs |j|g|Ri|dS)z\ See L{twisted.internet.interfaces.IReactorInThreads.callInThread}. N)r callInThread)rKrer=rrLrLrMrfFs zReactorBase.callInThreadsizecCs|j|ddS)zc See L{twisted.internet.interfaces.IReactorThreads.suggestThreadPoolSize}. ) maxthreadsN)radjustPoolsize)rKrgrLrLrMsuggestThreadPoolSizeNsz!ReactorBase.suggestThreadPoolSizecOs,t|s J|d|j|||fdS)Nr-)rrryrXrLrLrMrVsrrr)rB)Nrerrdrr4r installedrWrrN_lockrrrrrr,r r.r rrr rrrrrrrr rrrrrr!r"rr(r,r r rrrr0r1r6rr7 staticmethodrr5r9rr9r8r$rFrHrr'r4rr8rZr\r^rrr_rar]rrfrj __classcell__rLrLrrMr9s                  D       rc@seZdZdZdZdZdedededdfdd Z d!d d Z e d"d dZ d!ddZ d!ddZd!ddZdedeefddZdeddfddZdeddfddZdefddZdefdd ZdS)# BaseConnectorzm Basic implementation of L{IConnector}. State can be: "connecting", "connected", "disconnected" NrfactoryrrrAcCsd|_||_||_||_dS)N disconnected)rrrpr)rKrprrrLrLrMrNms zBaseConnector.__init__cCs@|jdkr |dS|jdkr|jdusJ|jdSdS)z!Disconnect whatever our state is. connecting connectedN)rstopConnecting transportloseConnectionrPrLrLrM disconnectus   zBaseConnector.disconnectr6cCr`rrLrPrLrLrM_makeTransport}szBaseConnector._makeTransportcCsn|jdkr tdd|_|js|jd|_||_|jdur/|j |j|jj t |_ |j|dS)z"Start connection to remote server.rqzcan't connect in this staterrrRN)r RuntimeErrorfactoryStartedrpdoStartrxrurrrfailIfNotConnectedr TimeoutError timeoutIDstartedConnectingrPrLrLrMconnects    zBaseConnector.connectcCs@|jdkr td|jdusJd|_|jt|`dS)zStop attempting to connect.rrzwe're not trying to connectNrq)rrNotConnectingErrorrur| UserErrorrPrLrLrMrts  zBaseConnector.stopConnectingcCs8|jdurz|jWn tyYnw|`dSdSr)r~r?rrPrLrLrM cancelTimeouts  zBaseConnector.cancelTimeoutaddrcCsd|_||j|S)Nrs)rrrp buildProtocol)rKrrLrLrMrs zBaseConnector.buildProtocolreasoncCsD|d|_d|_|j|||jdkr |jd|_dSdSNrqr)rrurrpclientConnectionFaileddoStoprzrKrrLrLrMconnectionFaileds   zBaseConnector.connectionFailedcCs6d|_|j|||jdkr|jd|_dSdSr)rrpclientConnectionLostrrzrrLrLrMr$s    zBaseConnector.connectionLostcCr)Nz! did not implement getDestinationrrPrLrLrMgetDestinationrzBaseConnector.getDestinationcCs"dt|jt||j|S)Nz<{} instance at 0x{:x} {} {}>)formatr2rrrwrrrPrLrLrMrs  zBaseConnector.__repr__r)rAr6)rerrdrr~rzr0rrrNrwrrxrrtrr"rr&rr3rr$rrrrLrLrLrMrobs0      roc@sPeZdZUdZdZejed<dZej ed<dejfddZ de e fdd Z dS) BasePortziBasic implementation of a ListeningPort. Note: This does not actually implement IListeningPort. N addressFamily socketTyperAcCs,t|j|j}|dt||S)NF)rrr setblockingr_setCloseOnExecfileno)rKsrLrLrMcreateInternetSockets zBasePort.createInternetSocketcCstdt|j)zRaises a RuntimeErrorzdoWrite called on a %s)ryr2rrrPrLrLrMdoWriteszBasePort.doWrite)rerrdrrr AddressFamilyrr SocketKindrrr3rrLrLrLrMrs rc@sZeZdZdZdZdddZddeddfd d Zdd d Zddeddfd dZ dddZ dS)_SignalReactorMixina! Private mixin to manage signals: it installs signal handlers at start time, and define run method. It can only be used mixed in with L{ReactorBase}, and has to be defined first in the inheritance (so that method resolution order finds startRunning first). @ivar _installSignalHandlers: A flag which indicates whether any signal handlers will be installed during startup. This includes handlers for SIGCHLD to monitor child processes, and SIGINT, SIGTERM, and SIGBREAK to stop the reactor. FrANcCszddl}WntytdYdSwtt|}||j|jkr,||j|j ||j |j t |dd}|durG|||j dSdS)zI Install the signal handlers for the Twisted event loop. rNzEWarning: signal module unavailable -- not installing signal handlers.SIGBREAK)signal ImportErrorr1rrr getsignalSIGINTdefault_int_handlerrSIGTERMr"rvr!)rKrreactorBaseSelfrrLrLrM_handleSignalss     z"_SignalReactorMixin._handleSignalsTinstallSignalHandlerscCs||_ttt|dS)aB Extend the base implementation in order to remember whether signal handlers should be installed later. @param installSignalHandlers: A flag which, if set, indicates that handlers for a number of (implementation-defined) signals should be installed during startup. N)_installSignalHandlersrr6rrKrrLrLrMr6s z _SignalReactorMixin.startRunningcCs&ttt||jr|dSdS)z Extend the base implementation by also installing signal handlers, if C{self._installSignalHandlers} is true. N)rrrrrrPrLrLrMrs z'_SignalReactorMixin._reallyStartRunningcCs|j|d|dS)N)r)r6mainLooprrLrLrMr7!s  z_SignalReactorMixin.runcCstt|}|jr?z|jr!||}|jo|}|||js Wnty4t dt Ynwt d|jsdSdS)NzUnexpected error in main loop.zMain loop terminated.) rrrr'rrrrr1rr)rKrt2trLrLrMr%s       z_SignalReactorMixin.mainLoopr)T) rerrdrrrrr6rr7rrLrLrLrMrs  r__all__)crr.rrabcrrheapqrrr tracebackrtypesrtypingr r r r r rrrrrrrzope.interfacerrtwisted.internetrrrrrrtwisted.internet._resolverrrrrVrrtwisted.internet.deferr r!twisted.internet.interfacesr"r#r$r%r&r'r(r)r*r+r,r-r.r/twisted.internet.protocolr0twisted.pythonr1r2twisted.python.failurer3twisted.python.runtimer4r5rtwisted.internet.tcpr6r7rtwisted.python.threadpoolr8r9rrrrr_ThreePhaseEventTriggerrrrr _ThreadCallrroFileDescriptorrrrrrLrLrLrMst  8 @    HH 1&  ( e\