xkdȐ<ddlmZddlZddlZddlZddlZddlmZmZm Z m Z m Z m Z m Z mZmZmZmZddlZddlmZmZddlZddlmZmZmZGddeZGdd eZGd d eZGd d eZ Gdde!Z"Gdde#Z$Gdde#Z%Gdde#Z&Gdde#Z'Gdde'Z(Gdde'Z)Gdde#Z*Gdde#Z+d Z,d!Z-d"Z.e/d#kr e.dSdS)$)print_functionN) AnyCallableDictIteratorListOptionalSetTupleUnioncastKeysView)PackageVersion)AcquireProgressInstallProgress OpProgressceZdZdZdS)FetchCancelledExceptionzAException that is thrown when the user cancels a fetch operation.N__name__ __module__ __qualname____doc__+/usr/lib/python3/dist-packages/apt/cache.pyrr2sKKKKrrceZdZdZdS)FetchFailedExceptionz-Exception that is thrown when fetching fails.Nrrrrrr6s7777rrceZdZdZdS)UntrustedExceptionz>Exception that is thrown when fetching fails for trust reasonsNrrrrr!r!:HHHHrr!ceZdZdZdS)LockFailedExceptionz,Exception that is thrown when locking fails.Nrrrrr$r$>s6666rr$ceZdZdZdS)CacheClosedExceptionz>Exception that is thrown when the cache is used after close().Nrrrrr&r&Br"rr&c$eZdZdZdZdZdZdS) _WrappedLockz`Wraps an apt_pkg.FileLock to raise LockFailedException. Initialized using a directory path.c||_tjtj|d|_dS)Nlock)_pathapt_pkgFileLockospathjoin_lock)selfr/s r__init__z_WrappedLock.__init__Ks/ %bgll4&@&@AA rc |jS#tj$r}t d|jd|d}~wwxYw)NzFailed to lock directory z: )r1 __enter__r,Errorr$r+)r2es rr5z_WrappedLock.__enter__Psa :'')) )}   %%7;zzz11E  sA AA c:|j|||SN)r1__exit__)r2typvalue tracebacks rr:z_WrappedLock.__exit__Ysz""3y999rN)rrrrr3r5r:rrrr(r(FsN++BBB :::::rr(ceZdZdZd1dZdZdZdZdZd2d Z d Z d Z d Z d Z dZd2dZdZdZdZdZdZdZdZdZd3dZedZedZedZdZ d2dZ d4dZdZ d5d!Z! d6d#Z"d$Z# d4d%Z$d&Z%d'Z&d(Z'd)Z(d*Z)d+Z*ed,Z+ed-Z,ed.Z-ed/Z.ed0Z/dS)7CacheaDictionary-like package cache. The APT cache file contains a hash table mapping names of binary packages to their metadata. A Cache object is the in-core representation of the same. It provides access to APTs idea of the list of available packages. The cache can be used like a mapping from package names to Package objects (although only getting items is supported). Keyword arguments: progress -- a OpProgress object, rootdir -- an alternative root directory. if that is given the system sources.list and system lists/files are not read, only file relative to the given rootdir, memonly -- build the cache in memory only. .. versionchanged:: 1.0 The cache now supports package names with special architecture qualifiers such as :all and :native. It does not export them in :meth:`keys()`, though, to keep :meth:`keys()` a unique set. NFc lttjd|_ttjd|_ttjd|_ttjd|_ i|_ i|_ tj |_tj|_d|_d|_|dd|dd|r tjdd|rRt,j|}t,j|dzr"tjtj|dzt,j|dzr"tjtj|dztjd |tjd |d ztjd t,j|d dd||tjtj d}tC||_"|#|dS)Ncache_post_open_inc_changes_countcache_post_changezDir::Cache::pkgcachez/etc/apt/apt.confz/etc/apt/apt.conf.dDirDir::State::status/var/lib/dpkg/statuszDir::bin::dpkgusrbindpkgDir::Cache::Archives)$r r,r?_cacheDepCache _depcachePackageRecords_records SourceList_list _callbacks _callbacks2weakrefWeakValueDictionary_weakrefWeakSet _weakversions_changes_count _sorted_setconnectconfigsetr.r/abspathexistsread_config_fileisdirread_config_dirr0_check_and_create_required_dirs init_systemfind_dirr( _archive_lockopen)r2progressrootdirmemonly archive_dirs rr3zCache.__init__xsQ7=$// g.55  "D   ',d33      ' ) ) %_..  &(<=== (*>???  ; N  5r : : :  "goog..Gw~~g(;;<< X(CV9VWWWw}}W'<<== Y'BW8WXXX N  ug . . . N  3W?U5U V V V N   "',,wuf"M"M     0 0 9 9 9   ! ! !n--.DEE )+66 (rc8|jdS)zFix broken packages.N)rO fix_brokenr2s rrozCache.fix_brokens !!#####rc&|xjdz c_dS)zIncrease the number of changesN)r[rps rrCzCache._inc_changes_counts q rc*ddg}gd}|D];}tj||zstj||z<|D]I}tj||zs%t ||zdJdS)zf check if the required apt directories/files are there and if not create them rHz/etc/apt/sources.list)z /var/lib/dpkgz /etc/apt/z/var/cache/apt/archives/partialz/var/lib/apt/lists/partialwN)r.r/ramakedirsriclose)r2rkfilesdirsdfs rrez%Cache._check_and_create_required_dirss # #      ) )A7>>'A+.. ) GaK((( / /A7>>'A+.. /Wq[#&&,,... / /rc||jvr5|j|D]'}|dkr||(||jvr |j|D]\}}}||g|Ri|dSdS)z!internal helper to run a callbackrCN)rTrCrUr2namecallbackargskwdss r_run_callbackszCache._run_callbackss 4? " " OD1  333++----HJJJJ 4# # #(,(8(> . .$$-------- $ # . .rc|#tjj}|||_|dtj||_ tj |j |_ tj |j |_ tj|_|jd|_|t'tjdk|_||ddS)zTOpen the package cache, after that it can be used like a dictionary Ncache_pre_openrrrB)aptrjbaserrv op_progressrr,r?rMrNrOrPrQrRrSread_main_listr\ _Cache__remaplenget_architectures_have_multi_archdone)r2rjs rriz Cache.opens  |(3355H # ,---mH--  )$+66.t{;; '))  !!###  #G$=$?$? @ @1 D  -.....rct|jD]b} |j|}n#t$rYwxYw |j|jj|jjf|_K#t$r |j|=Y_wxYwt|j D]}|j jj D]z}|j |j j krc|jdks%|j jdks|j|j jkr3|j|j jkr|j|j jkr ||_ n{|j |dS)zCalled after cache reopen() to relocate to new cache. Relocate objects like packages and versions from the old underlying cache to the new one. rN)listrXkeysKeyErrorrM_pkgr} architecture LookupErrorrZpackage version_listhash_candsize multi_archver_strremove)r2keypkgvervs r__remapz Cache.__remapsl **,,-- ' 'C mC(     ';sx}ch6K'KL ' ' 'M#&&& '*++ / /C[%2 / /Fcin,,1 !(;(;qv?W?W  (<<< SY%666 !CIE"))#... / /s! 8 AA (A22BBcH|`ttjd|_dS)zClose the package cacheN)rQr r,rPrps rrvz Cache.closes! MW3T:: rc|S)zEnter the with statementrrps rr5zCache.__enter__s  rc.|dS)zExit the with statementN)rv)r2exc_type exc_valuer=s rr:zCache.__exit__"s rc t|}|j|}n #t$rtd|zwxYw||std|z||}|S)z look like a dictionary (get key)z!The cache has no package named %r)strrMr_Cache__is_real_pkg_rawpkg_to_pkg)r2rrawpkgrs r __getitem__zCache.__getitem__'s Fc((C[%FF F F F>DEE E F!!&)) F>DEE E!!&)) s<c8 ||S#t$r|cYSwxYw)zaReturn *self*[*key*] or *default* if *key* not in *self*. .. versionadded:: 1.1 )r)r2rdefaults rgetz Cache.get8s5  9    NNN s  c|d}|j|t||S)zgReturns the apt.Package object for an apt_pkg.Package object. .. versionadded:: 1.0.0 Tpretty) get_fullnamerX setdefaultr)r2rfullnames rrzCache._rawpkg_to_pkgCs< &&d&33}'''$2G2GHHHrc#K|D]:}t||j|}|j||V;dSr9)rrrMrXrr2pkgnamers r__iter__zCache.__iter__Ms`yy{{ 9 9G$ G 455C-**7C88 8 8 8 8 9 9rc|jS)z8Check if the apt_pkg.Package provided is a real package.) has_versions)r2rs r __is_real_pkgzCache.__is_real_pkgXs ""rc ||vSr9rr2rs rhas_keyz Cache.has_key] d{rc ||jt|S#t$rYdSwxYwNF)rrMrrrs r __contains__zCache.__contains__asJ %%dk#c((&;<< <   55 s ,/ ==cDt|Sr9)rrrps r__len__z Cache.__len__hs499;;rcj*tfdjjD_t jS)Nc3nK|]/}||dV0dS)TrN)rr).0pr2s r zCache.keys..osY&&%%a((&d++&&&&&&r)r\sortedrMpackagesrrps`rrz Cache.keysls\   #%&&&&-&&&  D  D$%%%rcg}|jj}|jjD]5}||s(|||6|S)zGet the marked changes)rO marked_keeprMrappendr)r2changesrrs r get_changeszCache.get_changesvs_n0 k* < z&Cache._run_fetcher..sKKKd4?KTKKKrzUntrusted packages: %s c3$K|] }|jV dSr9)desc_uri)ris rrz%Cache._run_fetcher..s$5T5TQaj5T5T5T5T5T5TrrEzFailed to fetch  T)r,r^find_bitemsr!r0runstatus STAT_DONE STAT_IDLEr error_textRESULT_CANCELLEDrr)r2rallow_unauthenticated untrustedresfailederr_msgrs r _run_fetcherzCache._run_fetchers* ($+N$9$93U%% !LKgmKKK  2 $)DII5T5T)5T5T5T,T,TT  kkmmM  D{dn,,~  GDMMM4???S SGFF '* * *)'22 2  0&w// / rc|jtd|||j|jsdS|||S)zfetch the needed archivesNrF)rQr&rrSr)r2rrrs r_fetch_archiveszCache._fetch_archivessW = &'OPP Pw DMBB 5  *?@@@rc<||td|#tjj}|t j|}|j5||t j |j |cdddS#1swxYwYdS)aFetch the archives for all packages marked for install/upgrade. You can specify either an :class:`apt.progress.base.AcquireProgress()` object for the parameter *progress*, or specify an already existing :class:`apt_pkg.Acquire` object for the parameter *fetcher*. The return value of the function is undefined. If an error occurred, an exception of type :class:`FetchFailedException` or :class:`FetchCancelledException` is raised. The keyword-only parameter *allow_unauthenticated* specifies whether to allow unauthenticated downloads. If not specified, it defaults to the configuration option `APT::Get::AllowUnauthenticated`. .. versionadded:: 0.8.0 Nz'Takes a progress or a an Acquire object) ValueErrorrrjtextrr,rrhrrrO)r2rjrrs rfetch_archiveszCache.fetch_archivess.  G$7FGG G  |(88::H ?oh//G    ''/??AV                  s.BBBcx |j|}t|jo|j S#t$rYdSwxYw)z0Return whether the package is a virtual package.F)rMbool has_providesrrrs ris_virtual_packagezCache.is_virtual_packagesV C+g&C(A1A-ABB B   55 s + 99Tc|t}|jj} |j|}|jr|st |Sn#t $rt |cYSwxYw|jD]F\}}} | j} |r| || kr(| | | Gt |S)a)Return a list of all packages providing a package. Return a list of packages which provide the virtual package of the specified name. If 'candidate_only' is False, return all packages with at least one version providing the virtual package. Otherwise, return only those packages where the candidate version provides the virtual package. If 'include_nonvirtual' is True then it will search for all packages providing pkgname, even if pkgname is not itself a virtual pkg. ) r_rOrrMrrr provides_list parent_pkgrr) r2rcandidate_onlyinclude_nonvirtual providersrvpprovides providesverversionrs rget_providing_packageszCache.get_providing_packagess&EE  N< #W%B ''9 'I& # # # ?? " " " #/1.> ; ; *Hk7'F! ;g1B1B61J1J&J&J d11&99:::Is$AAArc,ttjd5|rtjd}tjd}tjd}tjdt j|tjddtjddtj }| n|j } |#tj j} |j|||} n!#t$$r} t'| d} ~ wwxYw| s|rt'| |r`tjd|tjd|tjd|cdddS#|ratjd|tjd|tjd|wwxYw#1swxYwYdS)aRun the equivalent of apt-get update. You probably want to call open() afterwards, in order to utilise the new cache. Otherwise, the old cache will be used which can lead to strange bugs. The first parameter *fetch_progress* may be set to an instance of apt.progress.FetchProgress, the default is apt.progress.FetchProgress() . sources_list -- Update a alternative sources.list than the default. Note that the sources.list.d directory is ignored in this case zDir::State::ListszDir::Etc::sourcelistzDir::Etc::sourcepartszAPT::List-Cleanupxxx0N)r(r,r^rgfindr_r.r/r`rRrrSrrjrrrMupdate SystemErrorr) r2fetch_progresspulse_intervalraise_on_error sources_listold_sources_listold_sources_list_d old_cleanupslistrr7s rrz Cache.update0s('.112EFF G G I I ##*>#6#67M#N#N %,^%8%89P%Q%Q"%n112EFF ""*BGOOL,I,I""#:EBBB""#6<<<*,,$$&&&&  I!)%(\%6%F%F%H%HN2+,,^UNSSCC"222.q1112~.000IN&&'=?OPPPN&&'>@RSSSN&&':KHHH= I I I I I I I I6 IN&&'=?OPPPN&&'>@RSSSN&&':KHHHHI7 I I I I I I I I I IsPD J ;%H!!E>=H!> FFFH!2A"J !A%JJ  J J c |n$#t$r|YnwxYwtj}|rtj ||}|rtjn#|rtjwwxYw |n$#t$r| YnwxYw|S)aY The first parameter *pm* refers to an object returned by apt_pkg.PackageManager(). The second parameter *install_progress* refers to an InstallProgress() object of the module apt.progress. This releases a system lock in newer versions, if there is any, and reestablishes it afterwards. ) startUpdateAttributeError start_updater,pkgsystem_is_lockedpkgsystem_unlock_innerrpkgsystem_lock_inner finishUpdate finish_update)r2rinstall_progress did_unlockrs rinstall_archiveszCache.install_archivesds ,  ( ( * * * * , , ,  ) ) + + + + + ,022  -  * , , , /"&&r**C /,... /,.... / -  ) ) + + + + - - -  * * , , , , , - s*88$BB'+CC! C!c|#tjj}|#tjj}|Jt j5t j|j}t j |}|j 5 | |||}| ||}||j krnM||jkrtd||jkrntd|z| dddn #1swxYwYdddn #1swxYwY||j kS)a!Apply the marked changes to the cache. The first parameter, *fetch_progress*, refers to a FetchProgress() object as found in apt.progress, the default being apt.progress.FetchProgress(). The second parameter, *install_progress*, is a apt.progress.InstallProgress() object. The keyword-only parameter *allow_unauthenticated* specifies whether to allow unauthenticated downloads. If not specified, it defaults to the configuration option `APT::Get::AllowUnauthenticated`. NTzinstallArchives() failedz>@@N  #"|0@@BB +++   ! ! ' ''77Bon55G# ' ''..wAB $$&&&%' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '.b)))s7"5EBD, E,D0 0E3D0 4EE Ec8|jdS)zUnmark all changesN)rOinitrps rclearz Cache.clears rc0|ddS)z>called internally if the cache has changed, emit a signal thenrDNrrps rrDzCache.cache_post_changes /00000rc0|ddS)zMcalled internally if the cache is about to change, emit a signal thenrNr?rps rrzCache.cache_pre_changes ./////rc|dkrtjdtd||jvr g|j|<|j||dS)zConnect to a signal. .. deprecated:: 1.0 Please use connect2() instead, as this function is very likely to cause a memory leak. rCzAconnect() likely causes a reference cycle, use connect2() insteadN)warningswarnRuntimeWarningrTr)r2r}r~s rr]z Cache.connectsi + + + MV    t & &$&DOD ! $$X.....rcr||jvr g|j|<|j||||fdS)a;Connect to a signal. The callback will be passed the cache as an argument, and any arguments passed to this function. Make sure that, if you pass a method of a class as your callback, your class does not contain a reference to the cache. Cyclic references to the cache can cause issues if the Cache object is replaced by a new one, because the cache keeps a lot of objects and tens of open file descriptors. currently only used for cache_{post,pre}_{changed,open}. .. versionadded:: 1.0 N)rUrr|s rconnect2zCache.connect2sH" t' ' '%'D T " %%xt&<=====rc4tj|jS)aReturn an `ActionGroup` object for the current cache. Action groups can be used to speedup actions. The action group is active as soon as it is created, and disabled when the object is deleted or when release() is called. You can use the action group as a context manager, this is the recommended way:: with cache.actiongroup(): for package in my_selected_packages: package.mark_install() This way, the action group is automatically released as soon as the with statement block is left. It also has the benefit of making it clear which parts of the code run with a action group and which don't. )r, ActionGrouprOrps r actiongroupzCache.actiongroups("4>222rctjtjd}tjtj|dD]}tj|drdSdS)zReturn True if the dpkg was interrupted All dpkg operations will fail until this is fixed, the action to fix the system if dpkg got interrupted is to run 'dpkg --configure -a' as root. rGupdatesz[0-9]*TF) r.r/dirnamer,r^ find_filelistdirr0fnmatch)r2dpkg_status_dirrzs rdpkg_journal_dirtyzCache.dpkg_journal_dirtys}'// N $ $%9 : :  BGLL)DDEE  Aq(++ tt urc|jjS)z7Return the number of packages with broken dependencies.)rO broken_countrps rrTzCache.broken_count"s~**rc|jjS)z2Return the number of packages marked for deletion.)rO del_countrps r delete_countzCache.delete_count(s~''rc|jjS)z6Return the number of packages marked for installation.)rO inst_countrps r install_countzCache.install_count.~((rc|jjS)z-Return the number of packages marked as keep.)rO keep_countrps rr]zCache.keep_count4r[r)NNFr9)F)NNN)TF)NrTN)0rrrrr3rorCrerrirrvr5r:rrrrrrrrrrrpropertyrrrrrr rrrr3r:r=rDrr]rGrJrRrTrWrZr]rrrr?r?^sv22222h$$$ !!! ///0 . . .////2///B;;;  "    III 9 9 9###    &&& ! ! ! !$$X$''X'   X    L# AAAA*" !!!!FCCC@E    H 2I2I2I2Ih   H" 9*9*9*9*v111 000 ///&>>>*333,X ++X+ ((X( ))X) ))X)))rr?c6eZdZdZdZdZdZdZdZdZ dS) ProblemResolverzuResolve problems due to dependencies and conflicts. The first argument 'cache' is an instance of apt.Cache. cPtj|j|_||_dSr9)r,r`rO _resolverrMr2caches rr3zProblemResolver.__init__As! 0AA rcD|j|jdS)z'Reset the package to the default state.N)rbr=rr2rs rr=zProblemResolver.clearFs" W\*****rcD|j|jdS)z)Protect a package so it won't be removed.N)rbprotectrrfs rrhzProblemResolver.protectKs" w|,,,,,rcD|j|jdS)zMark a package for removal.N)rbrrrfs rrzProblemResolver.removePs" gl+++++rc|j|j|jdS)z:Resolve dependencies, try to remove packages where needed.N)rMrrbresolverDrps rrkzProblemResolver.resolveUsF $$&&&     %%'''''rc|j|j|jdS)z4Resolve dependencies, do not try to remove packages.N)rMrrbresolve_by_keeprDrps rrmzProblemResolver.resolve_by_keep\sF $$&&& &&((( %%'''''rN) rrrrr3r=rhrrkrmrrrr`r`;sx  +++ --- ,,, ((((((((rr`ceZdZdZdZdS)FilterzFilter base classcdS)ziFilter function, return True if the package matchs a filter criteria and False otherwise Trr2rs rapplyz Filter.applyjs trNrrrrrrrrrrorogs)rroceZdZdZdZdS)MarkedChangesFilterz&Filter that returns all marked changesc4|js|js|jrdSdS)NTF)marked_install marked_deletemarked_upgraderqs rrrzMarkedChangesFilter.applyus+   !2 c6H 45rNrsrrrrururs)00rruceZdZdZdZdS)InstalledFilterzMFilter that returns all installed packages. .. versionadded:: 1.0.0 c|jSr9) is_installedrqs rrrzInstalledFilter.applys rNrsrrrr{r{}s-      rr{c*eZdZdZdZdZdZdZdS)_FilteredCacheHelperz:Helper class for FilteredCache to break a reference cycle.ci|_g|_|d|j|d|jdS)NrDrB) _filtered_filtersrGfilter_cache_post_changercs rr3z_FilteredCacheHelper.__init__sH  *D,IJJJ ($*GHHHHHrc~i|_|D]2}|jD](}||rd|j|j<n)3dS)zinternal helper to refilterTN)rrrrr})r2rdrrzs r_reapply_filterz$_FilteredCacheHelper._reapply_filters`  C]  773<</3DN38,E  rcHg|_|j|dSzSet the current active filter.N)rrr2filters r set_filterz_FilteredCacheHelper.set_filters'  V$$$$$rc0||dSz;Called internally if the cache changes, emit a signal then.N)rrcs rrz-_FilteredCacheHelper.filter_cache_post_changes U#####rN)rrrrr3rrrrrrrrsYDDIII   %%% $$$$$rrcPeZdZdZd dZdZdZdZdZdZ d Z d Z d Z d Z dS) FilteredCachez\A package cache that is filtered. Can work on a existing cache or create a new one Nct|t||_n||_t|j|_dSr9)r?rdr_helper)r2rdrjs rr3zFilteredCache.__init__s2 =xDJJDJ+DJ77 rc4t|jjSr9)rrrrps rrzFilteredCache.__len__s4<)***rc|j|Sr9rdrs rrzFilteredCache.__getitem__sz#rc#FK|jjD]}|j|VdSr9)rrrd)r2rs rrzFilteredCache.__iter__s:|- & &G*W% % % % % & &rc>|jjSr9)rrrrps rrzFilteredCache.keyss|%**,,,rc ||vSr9rrs rrzFilteredCache.has_keyrrcb |j|j|jjvS#t$rYdSwxYwr)rdr}rrrrs rrzFilteredCache.__contains__sB :c?'4<+AA A   55 s  ..cl|j||jdSr)rrrdrDrs rrzFilteredCache.set_filters4 ''' $$&&&&&rcD|j|jdSr)rrrdrps rrz&FilteredCache.filter_cache_post_changes" --dj99999rc,t|j|S)z)we try to look exactly like a real cache.)getattrrdrs r __getattr__zFilteredCache.__getattr__stz3'''r)NN)rrrrr3rrrrrrrrrrrrrrs 8888+++&&& ---''' ::: (((((rrc$tddS)Nzcache pre changedprintrs rcache_pre_changedrs rc$tddS)Nzcache post changedrrs rcache_post_changedrs rcFtdtjttjj}|dt|dttd|v|d}t|j tt|| D]}||j |ksJ||}tt||D] }|j sJ dD]5}t j|st!j|6tjddtj|j}tjtjj}|||dtd t7|}|jdt|jdt|j|t=tt|| D]}|||j ksJtt|td t7tjj }|jdt|jdt|j|t=tt|| D]}|||j ksJtt|dS) zInternal test code.zCache self testrrDaptitude) /tmp/pytestz/tmp/pytest/partialrLrNz.Testing filtered cache (argument is old cache)z$Testing filtered cache (no argument))rj) rr,r<r?rrjr rrGrrr}rrrrr.r/ramkdirr^r_rrOrrrrrdrrur)rdrrrrMrrfiltereds r_testrs  LNNN #,#..00 1 1E NN%'8999 NN&(:;;; :     C #(OOO #e**::<<..W~"g----- MMOOO!!G #g,,x:w~~g&&  HW    N-}===   0 0Bocl/??AABBG '2t,,, :;;;U##H N.0ABBB N/1CDDD N +--... #h--==??11(7+000000 #h-- 0111cl&7&B&B&D&DEEEH N.0ABBB N/1CDDD N +--... #h--==??11(7+000000 #h--r__main__)0 __future__rrPr.rCrVtypingrrrrrr r r r r rr, apt.packagerrapt.progress.textrapt.progress.baserrrIOErrorrrr!r$ Exceptionr&objectr(r?r`rorur{rrrrrrrrrrs,&%%%%%                           ((((((((JJJJJJJJJJLLLLLgLLL888887888IIIII-III77777'777IIIII9III:::::6:::0Z )Z )Z )Z )Z )FZ )Z )Z )z&(&(&(&(&(f&(&(&(XV&     f   !$!$!$!$!$6!$!$!$H9(9(9(9(9(F9(9(9(x    666r z EGGGGGr