h$      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                                                                                                                                                +None#$%&'(2359>? None#$%&'(2359>?hackage-securityCast from one type to anotherBy default (for language with type inference) we just compare the types returned by ; however, in languages in which terms can have more than one type this may not be the correct definition (indeed, for such languages we cannot give an instance of ).hackage-security&Embedded languages with type inferencehackage-security9Equality check that gives us a type-level equality proof.hackage-securityType equality proofsThis is a direct copy of "type-equality:Data.Type.Equality"; if we don't mind the dependency we can use that package directly. None#$%&'(2359>?55None#$%&'(2359>?fhackage-securityProduce a human-readable stringNone#$%&'(2359>?hackage-securityType f satisfies  SomeShow f if f a satisfies Show independent of ahackage-securityType f satisfies  SomeShow f if f a satisfies Show independent of ahackage-securityType f satisfies SomeEq f if f a satisfies Eq independent of a !"#$"# !$None#$%&'(2359>?3*hackage-security Abstract over a file system rootsee D,hackage-security?A file system root can be interpreted as an (absolute) FilePath-hackage-securityConvert a Path to an absolute FilePath (using native style directory separators).1hackage-security!Type-level tag for unrooted paths:Unrooted paths need a root before they can be interpreted.2hackage-securityPathsA 2 is simply a  with a type-level tag indicating where this path is rooted (relative to the current directory, absolute path, relative to a web domain, whatever). Most operations on 2? are just lifted versions of the operations on the underlying . The tag however allows us to give a lot of operations a more meaningful type. For instance, it does not make sense to append two absolute paths together; instead, we can only append an unrooted path to another path. It also means we avoid bugs where we use one kind of path where we expect another.4hackage-securityReinterpret the root of a pathThis literally just changes the type-level tag; use with caution!;hackage-securityReinterpret an unrooted pathThis is an alias for 4; see comments there.<hackage-securityForget a path's rootThis is an alias for 4; see comments there.=hackage-securityConvert a relative/unrooted Path to a FilePath (using POSIX style directory separators). See also ->hackage-securityConvert from a relative/unrooted FilePath (using POSIX style directory separators).?hackage-security5A path fragment (like a single directory or filename)Ghackage-securityWrapper around GHhackage-securityWrapper around (openBinaryTempFileWithDefaultPermissionsNOTE: The caller is responsible for cleaning up the temporary file.Vhackage-security,Return the immediate children of a directory Filters out "." and "..".Whackage-security(Recursive traverse a directory structureReturns a set of paths relative to the directory specified. The list is lazily constructed, so that directories are only read when required. (This is also essential to ensure that this function does not build the entire result in memory before returning, potentially running out of heap.)Xhackage-securityOldhackage-securityNew[hackage-security Path of the .tar filehackage-securityBase directoryhackage-security&Files to add, relative to the base dir  ()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_234567891:;<=>?@AB0/.,-*+CDEFGHIJKLMNOPQRSTUVWXY)Z[(\]^_  None#$%&'(2359>? hackage-securityMonomorphic traversalhackage-securityPolymorphic traversalhackage-securityMonomorphic lenshackage-securityPolymorphic lensNone#$%&'(2359>?$hackage-security?Attempt to create a filesystem lock in the specified directory.3This will use OS-specific file locking primitives: GHC.IO.Handle.Lock with #base-4.10" and later or a shim for base@ versions.&Blocks if the lock is already present.The logger callback passed as first argument is invoked before and after acquiring a lock, and after unlocking.May fallback to locking via creating a directory: Given a file pathto4, we do this by attempting to create the directory /pathto/hackage-security-lock, and deleting the directory again afterwards. Creating a directory that already exists will throw an exception on most OSs (certainly Linux, OSX and Windows) and is a reasonably common way to implement a lock file.None#$%&'(2359>?%hackage-securityMultiple exit points#We can simulate the imperative code if (cond1) return exp1; if (cond2) return exp2; if (cond3) return exp3; return exp4;as multipleExitPoints $ do when (cond1) $ exit exp1 when (cond2) $ exit exp2 when (cond3) $ exit exp3 return exp4hackage-securityFunction exit point (see )None#$%&'(2359>?(bkhackage-securityChecked exceptionsmhackage-securityThrow a checked exceptionnhackage-securityCatch a checked exceptionohackage-securityn with the arguments reversedphackage-securityLike try, but for checked exceptionsqhackage-security+Rethrow IO exceptions as checked exceptionsrhackage-securityThrow an unchecked exceptionThis is just an alias for throw, but makes it evident that this is a very intentional use of an unchecked exception.shackage-security Variation on r for internal errors klmnopqrs klmnopqrsNone#$%&'(2359>?+gxhackage-securityThe cache directoryyhackage-security/Paths relative to the root of the index tarballzhackage-securityThe root of the index tarball{hackage-security,Paths relative to the root of the repository|hackage-securityThe root of the repositoryRepository roots can be anchored at a remote URL or a local directory. Note that even for remote repos |" is (potentially) different from (& -- for a repository located at, say,  http://hackage.haskell.org4 they happen to coincide, but for one location at  $http://example.com/some/subdirectory they do not.hackage-security0Anchor a cache path to the location of the cache wxyz{|}~None#$%&'(2359>?. hackage-securityLayout of a repositoryhackage-securityTUF root metadatahackage-security TUF timestamphackage-security TUF snapshothackage-securityTUF mirrors listhackage-securityCompressed index tarballhackage-securityUncompressed index tarballhackage-securityPath to the package tarballhackage-securityThe layout used on Hackagehackage-security/Layout used by cabal for ("legacy") local reposObviously, such repos do not normally contain any of the TUF files, so their location is more or less arbitrary here. None#$%&'(2359>?2 hackage-security&Location of the various files we cacheAlthough the generic TUF algorithms do not care how we organize the cache, we nonetheless specity this here because as long as there are tools which access files in the cache directly we need to define the cache layout. See also comments for defaultCacheLayout.hackage-securityTUF root metadatahackage-security TUF timestamphackage-security TUF snapshothackage-securityTUF mirrors listhackage-securityUncompressed index tarballhackage-security'Index to the uncompressed index tarballhackage-securityCompressed index tarballWe cache both the compressed and the uncompressed tarballs, because incremental updates happen through the compressed tarball, but reads happen through the uncompressed one (with the help of the tarball index).hackage-security#The cache layout cabal-install usesWe cache the index as  cache /00-index.tar; this is important because `cabal-install` expects to find it there (and does not currently go through the hackage-security library to get files from the index). None#$%&'(2359>?91hackage-securityVerification monad%The verification monad is similar to  ResourceT in intent, in that we can register handlers to be run to release resources. Unlike  ResourceT, however, we maintain _two_ handlers: a cleanup handler which is run whether or not verification succeeds, and a finalisation handler which is run only if verification succeeds.&Cleanup handlers are registered using , and are guaranteed to run just before the computation terminates (after the finalisation handler).The finalisation handlers are run only when verification succeeds, and can be registered with . Finalisation can be used for instance to update the local cache (which should only happen if verification is successful).hackage-securityRun an action in the  monadhackage-securityAcquire a resource and register the corresponding cleanup handlerNOTE: Resource acquisition happens with exceptions masked. If it is important that the resource acquistion can be timed out (or receive other kinds of asynchronous exceptions), you will need to use an interruptible operation. See  ?http://www.well-typed.com/blog/2014/08/asynchronous-exceptions/ for details.hackage-security:Register an action to be run only if verification succeedshackage-security#Create a short-lived temporary fileCreates the directory where the temp file should live if it does not exist.hackage-securityTemp directoryhackage-securityTemplateNone#$%&'(2359>?<%hackage-securityHasFormat fs f is a proof that f is a key in fs.See  and  for typical usage.hackage-securityAvailable formatsRather than having a general list here, we enumerate all possibilities. This means we are very precise about what we expect, and we avoid any runtime errors about unexpect format definitions.NOTE: If we add additional cases here (for dealing with additional formats) all calls to error "inaccessible" need to be reevaluated.hackage-security:Format is a singleton type (reflection type to term level)=NOTE: In the future we might add further compression formats. .(c) Galois, Inc. 2007-2009, Duncan Coutts 2015None#$%&'(2359>?Cahackage-security54-bit integer values5JavaScript can only safely represent numbers between  -(2^53 - 1) and 2^53 - 1.TODO: Although we introduce the type here, we don't actually do any bounds checking and just inherit all type class instance from Int64. We should probably define  to do bounds checking, give different instances for type classes such as  and , etc.hackage-securityRender a JSON value in canonical form. This rendered form is canonical and so allows repeatable hashes.-For pretty printing, see prettyCanonicalJSON.NB: Canonical JSON's string escaping rules deviate from RFC 7159 JSON which requires"All Unicode characters may be placed within the quotation marks, except for the characters that must be escaped: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F)."Whereas the current specification of Canonical JSON explicitly requires to violate this by only escaping the quotation mark and the reverse solidus. This, however, contradicts Canonical JSON's statement that "Canonical JSON is parsable with any full JSON parser"Consequently, Canonical JSON is not a proper subset of RFC 7159.hackage-securityParse a canonical JSON format string as a JSON value. The input string does not have to be in canonical form, just in the "canonical JSON" format.Use  to convert into canonical form.hackage-securityRender a JSON value in a reasonable human-readable form. This rendered form is not the canonical form" used for repeatable hashes, use  for that.  None#$%&'(2359>?Dhackage-security+Monads in which we can report schema errorshackage-security Used in the  instance for hackage-security Used in the  instance for hackage-security"Extract a field from a JSON objectNone#$%&'(2359>?Ehackage-securitySimple wrapper around bytestring with ToJSON and FromJSON instances that use base64 encoding.None#$%&'(2359>?Ghackage-securityCompute the key ID of a keyhackage-securityThe key ID of a key, by definition, is the hexdigest of the SHA-256 hash of the canonical JSON form of the key where the private object key is excluded.NOTE: The FromJSON and ToJSON instances for KeyId are ntentially omitted. Use writeKeyAsId instead.hackage-security*Sign a bytestring and return the signatureTODO: It is unfortunate that we have to convert to a strict bytestring for ed25519 None#$%&'(2359>?Ihackage-securityA key environment is a mapping from key IDs to the corresponding keys.It should satisfy the invariant that these key IDs actually match the keys; see .   None#$%&'(2359>?Lhackage-security7MonadReader-like monad, specialized to key environmentshackage-securityMalformed JSON has syntax errors in the JSON itself (i.e., we cannot even parse it to a JSValue)hackage-security3Invalid JSON has valid syntax but invalid structure6The string gives a hint about what we expected insteadhackage-security1The JSON file contains a key ID of an unknown keyhackage-securitySome verification step failedhackage-securityWrong file type"Records actual and expected types.hackage-securityRender to canonical JSON formathackage-security Variation on - for files that don't require the repo layout;;None#$%&'(2359>?W hackage-security5A signature with a key ID (rather than an actual key)This corresponds precisely to the TUF representation of a signature.hackage-security"File with uninterpreted signaturesSometimes we want to be able to read a file without interpreting the signatures (that is, resolving the key IDs) or doing any kind of checks on them. One advantage of this is that this allows us to read many file types without any key environment at all, which is sometimes useful.hackage-securityA list of signaturesInvariant: each signature must be made with a different key. We enforce this invariant for incoming untrusted data (:) but not for lists of signatures that we create in code.hackage-security,Create a new document without any signatureshackage-securitySign a documenthackage-security Variation on " that doesn't need the repo layouthackage-security/Construct signatures for already rendered valuehackage-security.General FromJSON instance for signed datatypesWe don't give a general FromJSON instance for Signed because for some datatypes we need to do something special (datatypes where we need to read key environments); for instance, see the "Signed Root" instance.hackage-securitySignature verificationNOTES: 1. By definition, the signature must be verified against the canonical JSON format. This means we _must_ parse and then pretty print (as we do here) because the document as stored may or may not be in canonical format. 2. However, it is important that we NOT translate from the JSValue to whatever internal datatype we are using and then back to JSValue, because that may not roundtrip: we must allow for additional fields in the JSValue that we ignore (and would therefore lose when we attempt to roundtrip). 3. We verify that all signatures are valid, but we cannot verify (here) that these signatures are signed with the right key, or that we have a sufficient number of signatures. This will be the responsibility of the calling code.hackage-security&Convert a pre-signature to a signature9Verifies that the key type matches the advertised method.hackage-security"Convert signature to pre-signaturehackage-securityConvert a list of s to a list of sThis verifies the invariant that all signatures are made with different keys. We do this on the presignatures rather than the signatures so that we can do the check on key IDs, rather than keys (the latter don't have an Ord instance).hackage-security6Convert list of pre-signatures to a list of signatures None#$%&'(2359;>?^jhackage-security A delegation6A delegation is a pair of a pattern and a replacement.See match for an example.hackage-securityReplacement patterns%These constructors match the ones in : wildcards must be used in the same order as they appear in the pattern, but they don't all have to be used (that's why the base constructors are polymorphic in the stack tail).hackage-securityStructured patterns over pathsThe type argument indicates what kind of function we expect when the pattern matches. For example, we have the pattern  "*/*.txt": PathPatternDirAny (PathPatternFileExt ".txt") :: PathPattern (Directory :- BaseName :- ())TODOs (see README.md):Update this to work with Path rather than / Add different kinds of wildcardsAdd path rootsCurrently this is a proof of concept more than anything else; the right structure is here, but it needs updating. However, until we add author signing (or out-of-tarball targets) we don't actually use this yet.NOTE: Haddock lacks GADT support so constructors have only regular comments.hackage-security?The identity replacement replaces a matched pattern with itselfhackage-securityQuasi-quoter for delegations to make them easier to write in code#This allows to write delegations as 9$(qqd "targets/*/*/*.cabal" "targets/*/*/revisions.json")(The alternative syntax which actually uses a quasi-quoter doesn't work very well because the /** bits confuse CPP: "unterminated comment")!None#$%&'(2359>?bYhackage-security=Occassionally it is useful to read only a header from a file. HeaderOnly intentionally only has a  instance (no ).hackage-securityFile expiry dateA  value here means no expiry. That makes it possible to set some files to never expire. (Note that not having the Maybe in the type here still allows that, because you could set an expiry date 2000 years into the future. By having the Maybe here we avoid the _need_ for such encoding issues.)hackage-security File versionThe file version is a flat integer which must monotonically increase on every file update. and 1 instance are defined in terms of the underlying  (this is use for example by hackage during the backup process).hackage-securityFile expiry datehackage-security/File version (monotonically increasing counter)"None#$%&'(2359>?ehackage-securityFull versus partial mirrorsThe TUF spec explicitly allows for partial mirrors, with the mirrors file specifying (through patterns) what is available from partial mirrors.For now we only support full mirrors; if we wanted to add partial mirrors, we would add a second  MirrorPartial9 constructor here with arguments corresponding to TUF's  metacontent and targetscontent fields.hackage-securityDefinition of a mirrorNOTE: Unlike the TUF specification, we require that all mirrors must have the same format. That is, we omit metapath and  targetspath.hackage-security8Give a human-readable description of a particular mirror(for use in error messages) #None#$%&'(2359>?gqhackage-security File hashhackage-security Key thresholdThe key threshold is the minimum number of keys a document must be signed with. Key thresholds are specified in RoleSpec or DelegationsSpec.hackage-security File lengthHaving verified file length information means we can protect against endless data attacks and similar.$None#$%&'(2359>?lhackage-securityFile information$This intentionally does not have an  instance; see  and verifyFileInfo instead.NOTE: Throughout we compute file information always over the raw bytes. For example, when timestamp.json lists the hash of  snapshot.json), this hash is computed over the actual  snapshot.json file (as opposed to the canonical form of the embedded JSON). This brings it in line with the hash computed over target files, where that is the only choice available.hackage-securityCompute TODO: Currently this will load the entire input bytestring into memory. We need to make this incremental, by computing the length and all hashes in a single traversal over the input.hackage-securityCompute hackage-securityCompare the expected trusted file info against the actual file info of a target file."This should be used only when the 0 is already known. If we want to compare known  against a file on disk we should delay until we have confirmed that the file lengths match (see downloadedVerify).hackage-securityExtract SHA256 hash from  (if present)hackage-security!expected (from trusted TUF files)hackage-security actual (from  on target file) None#$%&'(2359>?ohackage-security7File got added or modified; we record the new file infohackage-securityFile got deletedhackage-security Entries in . either talk about the repository or the indexhackage-securityMapping from paths to file infoFile maps are used in target files; the paths are relative to the location of the target files containing the file map.hackage-securityOldhackage-securityNew  %None#$%&'(2359>?o{&None#$%&'(2359>?qhackage-securityDelegation specification"NOTE: This is a close analogue of RoleSpec.hackage-security DelegationsMuch like the Root datatype, this must have an invariant that ALL used keys (apart from the global keys, which are in the root key environment) must be listed in .hackage-securityTarget metadataMost target files do not need expiry dates because they are not subject to change (and hence attacks like freeze attacks are not a concern).'None#$%&'(2359>?u;hackage-security*Files that we might request from the indexThe type index tells us the type of the decoded file, if any. For files for which the library does not support decoding this will be ():. NOTE: Clients should NOT rely on this type index being (), or they might break if we add support for parsing additional file formats in the future.TODO: If we wanted to support legacy Hackage, we should also have a case for the global preferred-versions file. But supporting legacy Hackage will probably require more work anyway..hackage-security,Layout of the files within the index tarballhackage-security Translate an  to a pathhackage-security Parse an hackage-security0The layout of the index as maintained on Hackage (None#$%&'(2359>?w>hackage-securityFile info for the root metadataWe list this explicitly in the snapshot so that we can check if we need to update the root metadata without first having to download the entire index tarball.hackage-security!File info for the mirror metadatahackage-securityCompressed index tarballhackage-securityUncompressed index tarball.Repositories are not required to provide this.)None#$%&'(2359>?yhackage-securityRole specificationThe phantom type indicates what kind of type this role is meant to verify.hackage-securityThe root metadataNOTE: We must have the invariant that ALL keys (apart from delegation keys) must be listed in >. (Delegation keys satisfy a similar invariant, see Targets.)hackage-securityWe give an instance for Signed Root rather than Root because the key environment from the root data is necessary to resolve the explicit sharing in the signatures.*None#$%&'(2359>?ywxyz{|}~+None#$%&'(2359>?hackage-securitySome verification errors materialize as deserialization errorsFor example: if we try to deserialize a timestamp file but the timestamp key has been rolled over, deserialization of the file will fail with .hackage-securityThe spec stipulates that if a verification error occurs during the check for updates, we must download new root information and start over. However, we limit how often we attempt this.We record all verification errors that occurred before we gave up.hackage-securityTrusted values*Trusted values originate in only two ways:.Anything that is statically known is trusted ()If we have "dynamic" data we can trust it once we have verified the the signatures (trustSigned).9NOTE: Trusted is NOT a functor. If it was we could define trustAnything :: a -> Trusted a trustAnything a = fmap (const a) (trustStatic (static ()))Consequently, it is neither a monad nor a comonad. However, we _can_ apply trusted functions to trusted arguments ().The  constructor is exported, but any use of it should be verified.hackage-securityEquivalent of Trusted isn't quite applicative (no pure, not a functor), but it is somehow Applicative-like: we have the equivalent of hackage-security:Trust all elements of some trusted (traversable) containerIf we have, say, a trusted list of values, we should be able to get a list of trusted values out of it. (trustElems :: Trusted [a] -> [Trusted a]NOTE. It might appear that the more natural primitive to offer is a -like operator such as ;trustSeq :: Applicative f => Trusted (f a) -> f (Trusted a)5However, this is unsound. To see this, consider that ((->) a) is 4 (it's the reader monad); hence, we can instantiate trustSeq at .trustSeq :: Trusted (a -> a) -> a -> Trusted aand by passing trustStatic (static id) make  a functor, which we certainly don't want to do (see comments for ).$So why is it okay when we insist on  rather than ? To see this, it's instructive to consider how we might make a ((->) a) an instance of 0. If we define the domain of enumerable types as 3class Eq a => Enumerable a where enumerate :: [a]then we can make ((->) r) traversable by instance Enumerable r => Traversable ((->) r) where sequenceA f = rebuild <$> sequenceA ((\r -> (r,) <$> f r) <$> enumerate) where rebuild :: [(r, a)] -> r -> a rebuild fun arg = fromJust (lookup arg fun)The idea is that if the domain of a function is enumerable, we can apply the function to each possible input, collect the outputs, and construct a new function by pairing the inputs with the outputs. I.e., if we had something of type  a -> IO band a is enumerable, we just run the IO action on each possible a and collect all bs to get a pure function a -> b. Of course, you probably don't want to be doing that, but the point is that as far as the type system is concerned you could.In the context of , this means that we can derive *enumPure :: Enumerable a => a -> Trusted abut in a way this this makes sense anyway. If a domain is enumerable, it would not be unreasonable to change  Enumerable to =class Eq a => Enumerable a where enumerate :: [StaticPtr a]so we could define enumPure as enumPure :: Enumerable a => a -> Trusted a enumPure x = trustStatic $ fromJust (find ((== x) . deRefStaticPtr) enumerate)In other words, we just enumerate the entire domain as trusted values (because we defined them locally) and then return the one that matched the untrusted value.The conclusion from all of this is that the types of untrusted input (like the types of the TUF files we download from the server) should probably not be considered enumerable.hackage-securityRole verificationNOTE: We throw an error when the version number _decreases_, but allow it to be the same. This is sufficient: the file number is there so that attackers cannot replay old files. It cannot protect against freeze attacks (that's what the expiry date is for), so "replaying" the same file is not a problem. If an attacker changes the contents of the file but not the version number we have an inconsistent situation, but this is not something we need to worry about: in this case the attacker will need to resign the file or otherwise the signature won't match, and if the attacker has compromised the key then he might just as well increase the version number and resign.NOTE 2: We are not actually verifying the signatures _themselves_ here (we did that when we parsed the JSON). We are merely verifying the provenance of the keys.hackage-security Variation on  verifyRole# that uses key IDs rather than keys*This is used during the bootstrap process.See  3http://en.wikipedia.org/wiki/Public_key_fingerprint.hackage-securityFor signature validationhackage-security File source (for error messages)hackage-securityPrevious version (if available)hackage-securityTime now (if checking expiry)hackage-securityFor error messagesNone#$%&'(2359>?hackage-security-Apply a static function to a trusted argumenthackage-security Variation on  for  hackage-security Root datahackage-securitySource (for error messages)hackage-securityPrevious version (if available)hackage-securityTime now (if checking expiry)hackage-securityMirrors to verify None#$%&'(2359>?*-hackage-security#Is a particular remote file cached?hackage-securityRepository-specific exceptionsFor instance, for repositories using HTTP this might correspond to a 404; for local repositories this might correspond to file-not-found, etc.hackage-securityVerify a download filehackage-security,Read the file we just downloaded into memory)We never read binary data, only metadata.hackage-security)Copy a downloaded file to its destinationhackage-security>Records why we are downloading a file rather than updating it.hackage-security-Server does not support incremental downloadshackage-security0We don't have a local copy of the file to updatehackage-securityUpdate failed twiceIf we attempt an incremental update the first time, and it fails, we let it go round the loop, update local security information, and try again. But if an incremental update then fails _again_, we instead attempt a regular download.hackage-securityUpdate failed (for example: perhaps the local file got corrupted)hackage-security Log messages We use a  rather than a {# here because we might not have a { for the file that we were trying to download (that is, for example if the server does not provide an uncompressed tarball, it doesn't make much sense to list the path to that non-existing uncompressed tarball).hackage-securityRoot information was updatedThis message is issued when the root information is updated as part of the normal check for updates procedure. If the root information is updated because of a verification error WarningVerificationError is issued instead.hackage-securityA verification errorVerification errors can be temporary, and may be resolved later; hence these are just warnings. (Verification errors that cannot be resolved are thrown as exceptions.)hackage-security!Download a file from a repositoryhackage-security/Incrementally updating a file from a repositoryhackage-securitySelected a particular mirrorhackage-security;Updating a file failed (we will instead download it whole)hackage-securityWe got an exception with a particular mirror (we will try with a different mirror if any are available)hackage-securityThis log event is triggered before invoking a filesystem lock operation that may block for a significant amount of time; once the possibly blocking call completes successfully,  will be emitted.hackage-security7Denotes completion of the operation that advertised a  eventhackage-security>Denotes the filesystem lock previously acquired (signaled by ) has been released.hackage-securityAre we requesting this information because of a previous validation error?Clients can take advantage of this to tell caches to revalidate files.hackage-security RepositoryThis is an abstract representation of a repository. It simply provides a way to download metafiles and target files, without specifying how this is done. For instance, for a local repository this could just be doing a file read, whereas for remote repositories this could be using any kind of HTTP client.hackage-securityGet a file from the serverResponsibilies of :Download the file from the repository and make it available at a temporary locationUse the provided file length to protect against endless data attacks. (Repositories such as local repositories that are not suspectible to endless data attacks can safely ignore this argument.)Move the file from its temporary location to its permanent location if verification succeeds.NOTE: Calls to % should _always_ be in the scope of .hackage-security Get a cached file (if available)hackage-securityGet the cached rootThis is a separate method only because clients must ALWAYS have root information available.hackage-securityClear all cached dataIn particular, this should remove the snapshot and the timestamp. It would also be okay, but not required, to delete the index.hackage-securityOpen the tarball for reading%This function has this shape so that:We can read multiple files from the tarball without having to open and close the handle each time.We can close the handle immediately when done.hackage-securityRead the index indexhackage-securityLock the cache (during updates)hackage-securityMirror selectionThe purpose of ; is to scope mirror selection. The idea is that if we have )repWithMirror mirrorList $ someCallback5then the repository may pick a mirror before calling  someCallback, catch exceptions thrown by  someCallback, and potentially try the callback again with a different mirror.The list of mirrors may be Nothing if we haven't yet downloaded the list of mirrors from the repository, or when our cached list of mirrors is invalid. Of course, if we did download it, then the list of mirrors may still be empty. In this case the repository must fall back to its primary download mechanism.Mirrors as currently defined (in terms of a "base URL") are inherently a HTTP (or related) concept, so in repository implementations such as the local-repo repWithMirrors/ is probably just an identity operation (see  ignoreMirrors). Conversely, HTTP implementations of repositories may have other, out-of-band information (for example, coming from a cabal config file) that they may use to influence mirror selection.hackage-securityLogginghackage-securityLayout of this repositoryhackage-securityLayout of the indexSince the repository hosts the index, the layout of the index is not independent of the layout of the repository.hackage-security9Description of the repository (used in the show instance)hackage-security0Files that we might request from the local cachehackage-securityTimestamp metadata (timestamp.json)hackage-securityRoot metadata ( root.json)hackage-securitySnapshot metadata ( snapshot.json)hackage-securityMirrors list ( mirrors.json)hackage-security6Abstract definition of files we might have to download is parametrized by the type of the formats that we can accept from the remote repository, as well as with information on whether this file is metadata actual binary content.NOTE: Haddock lacks GADT support so constructors have only regular comments.hackage-security!Default format for each file typeFor most file types we don't have a choice; for the index the repository is only required to offer the GZip-compressed format so that is the default.hackage-securityDefault file info (see also )hackage-securityHelper function to implement repWithMirrors.hackage-security+Which remote files should we cache locally?None#$%&'(2359>?0hackage-securityAn IO action that represents an incoming response body coming from the server.The action gets a single chunk of data from the response body, or an empty bytestring if no more data is available.#This definition is copied from the  http-client package.hackage-securityProxy configurationAlthough actually setting the proxy is the purview of the initialization function for individual  implementations and therefore outside the scope of this module, we offer this ProxyConfiguration? type here as a way to uniformly configure proxies across all s.hackage-securityDon't use a proxyhackage-securityUse this specific proxyIndividual HTTP backends use their own types for specifying proxies.hackage-securityUse automatic proxy settings"What precisely automatic means is < specific, though typically it will involve looking at the  HTTP_PROXY1 environment variable or the (Windows) registry.hackage-securityResponse headersSince different libraries represent headers differently, here we just abstract over the few response headers that we might want to know about.hackage-security$Server accepts byte-range requests (Accept-Ranges: bytes)hackage-securityHTTP status codehackage-security200 OKhackage-security206 Partial Contenthackage-securityAdditional request headersSince different libraries represent headers differently, here we just abstract over the few request headers that we might want to sethackage-securitySet Cache-Control: max-age=0hackage-securitySet Cache-Control: no-transformhackage-securityAbstraction over HTTP clientsThis avoids insisting on a particular implementation (such as the HTTP package) and allows for other implementations (such as a conduit based one).5NOTE: Library-specific exceptions MUST be wrapped in .hackage-securityDownload a filehackage-securityDownload a byte range6Range is starting and (exclusive) end offset in bytes.HTTP servers are normally expected to respond to a range request with a "206 Partial Content" response. However, servers can respond with a "200 OK" response, sending the entire file instead (for instance, this may happen for servers that don't actually support range rqeuests, but for which we optimistically assumed they did). Implementations of + may accept such a response and inform the hackage-security library that the whole file is being returned; the security library can then decide to execute the  anyway (downloading the entire file) or abort the request and try something else. For this reason the security library must be informed whether the server returned the full file or the requested range.hackage-security Construct a Body reader from a lazy bytestringThis is appropriate if the lazy bytestring is constructed, say, by calling  hGetContents on a network socket, and the chunks of the bytestring correspond to the chunks as they are returned from the OS network layer.If the lazy bytestring needs to be re-chunked this function is NOT suitable.None#$%&'(2359>?hackage-security&Location and layout of the local cachehackage-security)Cache a previously downloaded remote filehackage-security Get a cached file (if available)hackage-security#Get the cached index (if available)hackage-securityGet the cached rootCalling  without root info available is a programmer error and will result in an unchecked exception. See requiresBootstrap.hackage-security*Delete a previously downloaded remote filehackage-securityLock the cacheThis avoids two concurrent processes updating the cache at the same time, provided they both take the lock.hackage-security Variant of  which emits s before and after a possibly blocking file-locking system call  None#$%&'(2359>?hackage-security,Repository options with a reasonable defaultClients should use defaultRepositoryOpts and override required settings.hackage-securityAllow additional mirrors?If this is set to True (default), in addition to the (out-of-band) specified mirrors we will also use mirrors reported by those out-of-band mirrors (that is,  mirrors.json).hackage-securityFor most files we download we know the exact size beforehand (because this information comes from the snapshot or delegated info)hackage-securityFor some files we might not know the size beforehand, but we might be able to provide an upper bound (timestamp, root info)hackage-securityDefault repository optionshackage-security?,hackage-securityLocation of the repositoryNote that we regard the local repository as immutable; we cache files just like we do for remote repositories.hackage-security?xwxyz{|}~|{}~zyxwNone#$%&'(2359>?hackage-securityVarious operations that we can perform on the index once its open Note that  contains a fields both for the raw file contents and the parsed file contents; clients can choose which to use.In principle these callbacks will do verification (once we have implemented author signing). Right now they don't need to do that, because the index as a whole will have been verified.hackage-securityLook up an entry by  Since these /s must come from somewhere (probably from the ), it is assumed that they are valid; if they are not, an (unchecked) exception will be thrown.This function also returns the  of the next file in the index (if any) for the benefit of clients who wish to walk through the entire index.hackage-securityLook up an entry by Returns  if the $ does not refer to an existing file.hackage-securityVariation if both the  and the  are known1You might use this when scanning the index using .hackage-security%Get (raw) cabal file (wrapper around )hackage-security(Lookup package metadata (wrapper around )0This will throw an (unchecked) exception if the  targets.json file could not be parsed.hackage-security/Get file info (including hash) (wrapper around )hackage-security2Get the SHA256 hash for a package (wrapper around indexLookupInfo)(In addition to the exceptions thrown by indexLookupInfo, this will also throw an exception if the SHA256 is not listed in the  (again, this will not happen with a well-formed Hackage index.)hackage-securityThe  for the indexWe provide this here because  will have read this anyway.hackage-security"Entry from the Hackage index; see .hackage-securityThe raw path in the tarfilehackage-securityThe parsed file (if recognised)hackage-securityThe raw contentsAlthough this is a lazy bytestring, this is actually read into memory strictly (i.e., it can safely be used outside the scope of withIndex and friends).hackage-securityThe parsed contentsThis field is lazily constructed; the parser is not unless you do a pattern match on this value.hackage-security%The time of the entry in the tarfile.hackage-securityEntry into the Hackage index.hackage-security/(Low-level) block number of the tar index entry0Exposed for the benefit of clients who read the .tar* file directly. For this reason also the  and  instances for & just print and parse the underlying TarEntryOffset.hackage-securityIndex directoryhackage-security!The first entry in the dictionaryhackage-security9The next available (i.e., one after last) directory entryhackage-security!Lookup an entry in the dictionaryThis is an efficient operation.hackage-securityAn enumeration of all entriesThis field is lazily constructed, so if you don't need it, it does not incur a performance overhead. Moreover, the 5 is also created lazily so if you only need the raw y there is no parsing overhead.The entries are ordered by : so that the entries can efficiently be read in sequence.NOTE: This means that there are two ways to enumerate all entries in the tar file, since when lookup an entry using  the  of the next entry is also returned. However, this involves reading through the entire tar! file. If you only need to read some files, it is significantly more efficient to enumerate the tar entries using  instead and only call  when required.hackage-security/Generic logic for checking if there are updatesThis implements the logic described in Section 5.1, "The client application", of the TUF spec. It checks which of the server metadata has changed, and downloads all changed metadata to the local cache. (Metadata here refers both to the TUF security metadata as well as the Hackage packge index.)You should pass Nothing for the UTCTime _only_ under exceptional circumstances (such as when the main server is down for longer than the expiry dates used in the timestamp files on mirrors).hackage-securityDownload a packagehackage-security Variation on  that takes a FilePath instead.hackage-security Read the Hackage index directoryShould only be called after .hackage-security$Look up entries in the Hackage index This is in G style so that clients can efficiently look up multiple files from the index.Should only be called after .hackage-security:Check if we need to bootstrap (i.e., if we have root info)hackage-securityBootstrap the chain of trustNew clients might need to obtain a copy of the root metadata. This however represents a chicken-and-egg problem: how can we verify the root metadata we downloaded? The only possibility is to be provided with a set of an out-of-band set of root keys and an appropriate threshold.Clients who provide a threshold of 0 can do an initial "unsafe" update of the root information, if they wish.The downloaded root information will _only_ be verified against the provided keys, and _not_ against previously downloaded root info (if any). It is the responsibility of the client to call * only when this is the desired behaviour.hackage-securityRe-throw all exceptions thrown by the client API as unchecked exceptionshackage-security(To check expiry times against (if using)hackage-security Repositoryhackage-securityPackage to downloadhackage-securityDestination (see also )hackage-security Repositoryhackage-securityPackage to downloadhackage-security Destinationwxyz{|}~|{}~zyxw,-.,/0,12,34,/5,/6,/7,18,19,1:,1;,<=,<>,<?,<@,AB,AC,AD,AE,AFGHIJKKLMNNOPQQRRSTUVWXYYZ[\]^_``abcdefghijklmnopqrstuvwxyz{|}~                                                                                                       !!!!!!!!!!!!!!!!"""""""""""""#######$$$$$$$$$$$$                       %%%%%&&&&&&&&&&&&&&&&''''''''''''(((((((()))))))))))))))))++++++++++++++++++++++                                                                               ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                     )+.hackage-security-0.6.1.0-6R2TFMyTGz3p5tEWZM6nOHackage.Security.TrustedHackage.Security.Util.PathHackage.Security.Client.VerifyHackage.Security.Util.PrettyHackage.Security.Util.SomeHackage.Security.Util.CheckedHackage.Security.ServerHackage.Security.Client.FormatsText.JSON.CanonicalHackage.Security.JSONHackage.Security.Key.EnvHackage.Security.TUF.FileMap"Hackage.Security.Client.Repository*Hackage.Security.Client.Repository.HttpLib(Hackage.Security.Client.Repository.Cache)Hackage.Security.Client.Repository.Remote(Hackage.Security.Client.Repository.LocalHackage.Security.ClientPrelude#Hackage.Security.Util.TypedEmbeddedHackage.Security.Util.StackHackage.Security.Util.LensHackage.Security.Util.IOHackage.Security.Util.ExitHackage.Security.TUF.Paths Hackage.Security.TUF.Layout.Repo!Hackage.Security.TUF.Layout.CacheHackage.Security.Util.JSONHackage.Security.Util.Base64Hackage.Security.KeyHackage.Security.TUF.SignedHackage.Security.TUF.PatternsHackage.Security.TUF.HeaderHackage.Security.TUF.MirrorsHackage.Security.TUF.CommonHackage.Security.TUF.FileInfoHackage.Security.TUF.TimestampHackage.Security.TUF.Targets!Hackage.Security.TUF.Layout.IndexHackage.Security.TUF.SnapshotHackage.Security.TUF.RootHackage.Security.TUFHackage.Security.Trusted.TCBbase GHC.StaticPtr StaticPtr GHC.IO.HandlehCloseGHC.IO.Handle.TypesHandleControl.Monad.IO.ClassliftIOhSeek hSetBuffering hFileSizeBlockBuffering LineBuffering NoBuffering BufferMode GHC.IO.Device SeekFromEnd RelativeSeek AbsoluteSeekSeekMode GHC.IO.IOMode ReadWriteMode AppendMode WriteModeReadModeIOModePrettypretty SomePretty somePretty DictPrettySomeShowsomeShowDictShowSomeEqsomeEqDictEqSome typecheckSome$fEqSome $fShowSome $fPrettySomeWebTarFsPathFsRoottoAbsoluteFilePathHomeDirAbsoluteRelativeUnrootedPathcastRoot takeDirectory takeFileName<.>splitExtension takeExtensionrootPath unrootPathtoUnrootedFilePathfromUnrootedFilePathfragment joinFragmentssplitFragmentsisPathPrefixOf toFilePath fromFilePath makeAbsolutefromAbsoluteFilePathwithFile openTempFile'readLazyByteStringreadStrictByteStringwriteLazyByteStringwriteStrictByteStringcopyFilecreateDirectorycreateDirectoryIfMissingremoveDirectory doesFileExistdoesDirectoryExistgetModificationTime removeFilegetTemporaryDirectorygetDirectoryContentsgetRecursiveContents renameFilegetCurrentDirectorytarIndexLookup tarAppend toURIPath fromURIPathuriPath modifyUriPath $fPrettyPath $fPrettyPath0 $fPrettyPath1 $fPrettyPath2$fFsRootHomeDir$fFsRootAbsolute$fFsRootRelative $fPrettyPath3 $fShowPath$fEqPath $fOrdPathThrowsunthrow throwChecked catchChecked handleChecked tryCheckedcheckIOthrowUnchecked internalError$fExceptionSyncException $fThrowsCatch$fShowSyncException CachePath CacheRoot IndexPath IndexRootRepoPathRepoRootanchorRepoPathLocallyanchorRepoPathRemotelyanchorCachePath RepoLayoutrepoLayoutRootrepoLayoutTimestamprepoLayoutSnapshotrepoLayoutMirrorsrepoLayoutIndexTarGzrepoLayoutIndexTarrepoLayoutPkgTarGzhackageRepoLayoutcabalLocalRepoLayout CacheLayoutcacheLayoutRootcacheLayoutTimestampcacheLayoutSnapshotcacheLayoutMirrorscacheLayoutIndexTarcacheLayoutIndexIdxcacheLayoutIndexTarGzcabalCacheLayoutVerify runVerifyacquire ifVerified openTempFile$fFunctorVerify$fApplicativeVerify $fMonadVerify$fMonadIOVerify HasFormatHFZHFSFormatsFsNoneFsUnFsGzFsUnGzFormatFUnFGzFormatGzFormatUnhasFormatAbsurd hasFormatGet formatsMap formatsMember formatsLookup $fUnifyFormat$fFunctorFormats$fShowHasFormat $fEqHasFormat $fShowFormats $fEqFormats $fEqFormat $fShowFormatInt54JSValueJSNullJSBoolJSNumJSStringJSArrayJSObjectrenderCanonicalJSONparseCanonicalJSONprettyCanonicalJSON $fReadInt54 $fShowInt54$fBoundedInt54 $fShowJSValue $fReadJSValue $fEqJSValue $fOrdJSValue $fEnumInt54 $fEqInt54$fIntegralInt54 $fDataInt54 $fNumInt54 $fOrdInt54 $fRealInt54 $fIxInt54$fFiniteBitsInt54 $fBitsInt54$fStorableInt54$fPrintfArgInt54GotExpectedReportSchemaErrorsexpected FromObjectKey fromObjectKey ToObjectKey toObjectKeyFromJSONfromJSONToJSONtoJSON expected' fromJSObject fromJSFieldfromJSOptFieldmkObjectHasKeyIdkeyIdKeyId keyIdStringKeyTypeKeyTypeEd25519 PrivateKeyPrivateKeyEd25519 PublicKeyPublicKeyEd25519Key KeyEd25519Ed25519 publicKey privateKey somePublicKeysomePublicKeyType someKeyId createKey createKey'signverifyKeyEnv keyEnvMapfromPublicKeysfromKeysemptynullinsertlookupunion$fFromJSONmKeyEnv$fToJSONmKeyEnv $fShowKeyEnv WriteJSONReadJSON_NoKeys_NoLayoutReadJSON_Keys_NoLayoutReadJSON_Keys_Layout MonadKeys localKeysaskKeysDeserializationErrorDeserializationErrorMalformedDeserializationErrorSchemaDeserializationErrorUnknownKeyDeserializationErrorValidationDeserializationErrorFileTypevalidate verifyType readKeyAsIdaddKeyswithKeys lookupKeyrunReadJSON_Keys_LayoutrunReadJSON_Keys_NoLayoutrunReadJSON_NoKeys_NoLayoutparseJSON_Keys_LayoutparseJSON_Keys_NoLayoutparseJSON_NoKeys_NoLayoutreadJSON_Keys_LayoutreadJSON_Keys_NoLayoutreadJSON_NoKeys_NoLayout runWriteJSON renderJSONrenderJSON_NoLayout writeJSONwriteJSON_NoLayout writeKeyAsId$fPrettyDeserializationError$fExceptionDeserializationError$fMonadKeysReadJSON_Keys_Layout+$fMonadReaderRepoLayoutReadJSON_Keys_Layout($fReportSchemaErrorsReadJSON_Keys_Layout!$fMonadKeysReadJSON_Keys_NoLayout*$fReportSchemaErrorsReadJSON_Keys_NoLayout,$fReportSchemaErrorsReadJSON_NoKeys_NoLayout$fFunctorWriteJSON$fApplicativeWriteJSON$fMonadWriteJSON $fMonadReaderRepoLayoutWriteJSON!$fFunctorReadJSON_NoKeys_NoLayout%$fApplicativeReadJSON_NoKeys_NoLayout$fMonadReadJSON_NoKeys_NoLayout8$fMonadErrorDeserializationErrorReadJSON_NoKeys_NoLayout$fFunctorReadJSON_Keys_NoLayout#$fApplicativeReadJSON_Keys_NoLayout$fMonadReadJSON_Keys_NoLayout6$fMonadErrorDeserializationErrorReadJSON_Keys_NoLayout$fFunctorReadJSON_Keys_Layout!$fApplicativeReadJSON_Keys_Layout$fMonadReadJSON_Keys_Layout4$fMonadErrorDeserializationErrorReadJSON_Keys_Layout$fShowDeserializationError PreSignature presignature presigMethod presigKeyIdUninterpretedSignaturesuninterpretedSigneduninterpretedSignatures Signature signature signatureKey SignaturesSignedsigned signaturesunsignedwithSignatureswithSignatures' signRenderedverifySignaturesignedFromJSONverifySignaturesfromPreSignaturetoPreSignaturefromPreSignaturestoPreSignatures DelegationHeader headerExpires headerVersion FileExpires FileVersion HasHeader fileExpires fileVersion expiresNever expiresInDays isExpiredversionInitialversionIncrementMirrorDescription MirrorContent MirrorFullMirror mirrorUrlBase mirrorContentMirrorsmirrorsVersionmirrorsExpiresmirrorsMirrorsdescribeMirrorHash KeyThreshold FileLength fileLengthFileInfofileInfoLengthfileInfoHashesHashFn HashFnSHA256 HashFnMD5fileInfocomputeFileInfocompareTrustedFileInfoknownFileInfoEqualfileInfoSHA256 FileChange FileChanged FileDeleted TargetPathTargetPathRepoTargetPathIndexFileMap!fromListfileMapChanges$fFromObjectKeymTargetPath$fToObjectKeymTargetPath$fPrettyTargetPath$fFromJSONmFileMap$fToJSONmFileMap$fShowFileChange $fShowFileMap$fShowTargetPath$fEqTargetPath$fOrdTargetPath TimestamptimestampVersiontimestampExpirestimestampInfoSnapshotDelegationSpecdelegationSpecKeysdelegationSpecThreshold delegation DelegationsdelegationsKeysdelegationsRolesTargetstargetsVersiontargetsExpirestargetsTargetstargetsDelegations targetsLookup IndexFileIndexPkgMetadata IndexPkgCabal IndexPkgPrefs IndexLayoutindexFileToPathindexFileFromPathhackageIndexLayoutindexLayoutPkgMetadataindexLayoutPkgCabalindexLayoutPkgPrefsSnapshotsnapshotVersionsnapshotExpiressnapshotInfoRootsnapshotInfoMirrorssnapshotInfoTarGzsnapshotInfoTarRoleSpec roleSpecKeysroleSpecThreshold RootRoles rootRolesRootrootRolesSnapshotrootRolesTargetsrootRolesTimestamprootRolesMirrorsRoot rootVersion rootExpiresrootKeys rootRolesVerificationHistory RootUpdatedVerificationErrorVerificationErrorSignaturesVerificationErrorExpiredVerificationErrorVersionVerificationErrorFileInfoVerificationErrorUnknownTargetVerificationErrorMissingSHA256 VerificationErrorDeserializationVerificationErrorLoopSignaturesVerifiedsignaturesVerifiedTrustedtrusted trustStatic trustVerified trustApply trustElems verifyRole'verifyFingerprints VerifyRole verifyRole<$$>trustedFileInfoEqual$fVerifyRoleMirrors$fVerifyRoleSnapshot$fVerifyRoleTimestamp$fVerifyRoleRootIsCachedCacheAs DontCache CacheIndexSomeRemoteErrorDownloadedFiledownloadedVerifydownloadedReaddownloadedCopyTo UpdateFailureUpdateImpossibleUnsupportedUpdateImpossibleNoLocalCopyUpdateFailedTwice UpdateFailed LogMessageLogRootUpdatedLogVerificationErrorLogDownloading LogUpdatingLogSelectedMirrorLogCannotUpdateLogMirrorFailed LogLockWaitLogLockWaitDone LogUnlock AttemptNr Repository repGetRemote repGetCachedrepGetCachedRoot repClearCache repWithIndexrepGetIndexIdx repLockCache repWithMirrorrepLog repLayoutrepIndexLayoutrepDescription CachedFileCachedTimestamp CachedRootCachedSnapshot CachedMirrors RemoteFileRemoteTimestamp RemoteRootRemoteSnapshot RemoteMirrors RemoteIndexRemotePkgTarGzBinaryMetadataremoteFileDefaultFormatremoteFileDefaultInfomirrorsUnsupportedremoteRepoPathremoteRepoPath' mustCache$fPrettyRemoteFile$fPrettyCachedFile$fPrettyUpdateFailure$fPrettyLogMessage$fPrettySomeRemoteError$fExceptionSomeRemoteError$fShowRepository $fEqAttemptNr$fOrdAttemptNr$fNumAttemptNr$fEqCachedFile$fOrdCachedFile$fShowCachedFile$fShowIsCached $fEqIsCached$fShowSomeRemoteError$fShowRemoteFile BodyReader ProxyConfigProxyConfigNoneProxyConfigUseProxyConfigAutoHttpResponseHeaderHttpResponseAcceptRangesBytes HttpStatusHttpStatus200OKHttpStatus206PartialContentHttpRequestHeaderHttpRequestMaxAge0HttpRequestNoTransformHttpLibhttpGet httpGetRangebodyReaderFromBS$fEqHttpResponseHeader$fOrdHttpResponseHeader$fShowHttpResponseHeader$fEqHttpRequestHeader$fOrdHttpRequestHeader$fShowHttpRequestHeaderCache cacheRoot cacheLayoutcacheRemoteFile getCachedgetCachedIndex getCachedRoot getIndexIdx withIndex clearCache lockCachelockCacheWithLogger RemoteTempRepoOptsrepoAllowAdditionalMirrorsFileSize FileSizeExact FileSizeBoundfileSizeWithinBoundsdefaultRepoOptswithRepository$fExceptionFileTooLarge$fPrettyFileTooLarge$fDownloadedFileRemoteTemp$fPrettyRemoteTemp$fShowFileSize$fShowFileTooLarge LocalFile LocalRepo$fDownloadedFileLocalFileInvalidFileInIndexinvalidFileInIndexinvalidFileInIndexRawinvalidFileInIndexErrorLocalFileCorruptedInvalidPackageExceptionIndexCallbacksindexLookupEntryindexLookupFileindexLookupFileEntryindexLookupCabalindexLookupMetadataindexLookupFileInfoindexLookupHashindexDirectory IndexEntryindexEntryPathindexEntryPathParsedindexEntryContentindexEntryContentParsedindexEntryTimeDirectoryEntrydirectoryEntryBlockNo DirectorydirectoryFirst directoryNextdirectoryLookupdirectoryEntries HasUpdates NoUpdatescheckForUpdatesdownloadPackagedownloadPackage' getDirectoryrequiresBootstrap bootstrapuncheckClientErrors$fReadDirectoryEntry$fShowDirectoryEntry$fPrettyInvalidPackageException"$fExceptionInvalidPackageException$fPrettyLocalFileCorrupted$fExceptionLocalFileCorrupted$fPrettyInvalidFileInIndex$fExceptionInvalidFileInIndex$fEqDirectoryEntry$fOrdDirectoryEntry$fShowHasUpdates$fEqHasUpdates$fOrdHasUpdates$fShowInvalidFileInIndex$fShowLocalFileCorrupted$fShowInvalidPackageExceptionGHC.Base++ghc-primGHC.PrimseqGHC.Listfilterzip System.IOprint Data.Tuplefstsnd otherwisemap$GHC.Real fromIntegral realToFracGHC.EnumBoundedmaxBoundminBoundEnumsuccpredtoEnumfromEnumenumFromThenTo enumFromToenumFrom enumFromThen GHC.ClassesEq==/= GHC.FloatFloatingpiexplogsqrt**logBasesincostanasinacosatansinhcoshtanhasinhatanhacosh Fractional/ fromRationalrecipIntegralquotremdivmodquotRem toIntegerdivModMonadreturn>>=>>Functorfmap<$GHC.NumNum+*abssignumnegate fromInteger-Ordminmax><=<>=compareGHC.ReadReadreadList readsPrecReal toRational RealFloat floatRadix floatDigits floatRange decodeFloat encodeFloatexponent significand scaleFloatisNaN isInfiniteisDenormalizedisNegativeZeroatan2isIEEERealFracproperFractiontruncateroundfloorceilingGHC.ShowShow showsPrecshowListshowControl.Monad.Fail MonadFailfail Applicative<**><*>pure Data.FoldableFoldablefoldl1foldr1foldMapfoldrfoldllengthelemmaximumminimumproductsumData.Traversable TraversablesequencemapM sequenceAtraverse Semigroup<>Monoidmconcatmemptymappend GHC.TypesBoolFalseTrueCharDoubleFloatIntinteger-wired-inGHC.Integer.TypeInteger GHC.MaybeMaybeNothingJustOrderingGTLTEQRationalIOWord Data.EitherEitherLeftRightnot||&&GHC.ErrerrorerrorWithoutStackTrace undefinedString=<<idconst.flip$!untilasTypeOfsubtractcurryuncurry Data.Functor<$> Data.Maybemaybescanlscanl1scanrscanr1iteraterepeat replicatecycle takeWhile dropWhiletakedropsplitAtspanbreakreverse!!zip3zipWithzipWith3unzipunzip3ShowSshowsshowChar showString showParenevenodd^^^gcdlcmText.ParserCombinators.ReadPReadS readParenlexeither Text.Readreads Data.OldListlinesunlineswordsunwords sequence_concat concatMapandoranyallnotElemGHC.IO.ExceptionIOError userErrorGHC.IOFilePathioErrorputCharputStrputStrLngetChargetLine getContentsinteractreadFile writeFile appendFilereadLnreadIOmapM_readinitlasttailheadAsTypetypeOfTypedUnify:=:asTypeunifyTypeOfRefl:- Traversal' TraversalLens'Lensgetoverset withDirLockWithDirLockEventWithDirLockEventPreWithDirLockEventPostWithDirLockEventUnlock getFileSizehandleDoesNotExisttimedIOmultipleExitPointsexit Data.Bits FiniteBitscontainers-0.6.2.1Data.Map.InternalMapBase64fromByteString toByteStringcheckKeyEnvInvariant ReplacementPatternidentityReplacementqqd RepFileConst RepFileExt RepFileAny RepDirConst RepDirAny PatFileConst PatFileExt PatFileAny PatDirConst PatDirAnyBaseName ExtensionFileNamematchDelegationparseDelegation$fFromJSONmSignedDeclareTrusted