?@      !"#$%&'()*+,-./0123456789:;<=>? 2016 Mark Karpov BSD 3 clause(Mark Karpov <markkarpov@openmailbox.org> experimentalportableSafeF Decode a @ containing CP 437 encoded text.A)Decode single byte of CP437 encoded text.AA 2016 Mark Karpov BSD 3 clause(Mark Karpov <markkarpov@openmailbox.org> experimentalportableNone+F4Bad things that can happen when you use the library.9Thrown when you try to get contents of non-existing entry.Thrown when archive structure cannot be parsed%Information about archive as a whole.Comment of entire archive-Absolute offset of start of central directory Size of central directory record Supported compression methods. Store file uncompressed Deflate  Compressed using BZip2 algorithm This record represents all information about archive entry that can be stored in a .ZIP archive. It does not mirror local file header or central directory file header, but their binary representation can be built given this date structure and actual archive contents.Version made byVersion needed to extractCompression methodLast modification date and timeCRC32 check sumSize of compressed entrySize of uncompressed entry$Absolute offset of local file header Entry commentAll extra fields found9Exception describing various troubles you can have with .)Selector cannot be created from this path{This data type serves for naming and selection of archive entries. It can be created only with help of smart constructor \, and it's the only key  that can be used to select files in archive or to name new files.The abstraction is crucial for ensuring that created archives are portable across operating systems, file systems, and different platforms. Since on some operating systems, file paths are case-insensitive, this selector is also case-insensitive. It makes sure that only relative paths are used to name files inside archive, as it's recommended in the specification. It also guarantees that forward slashes are used when the path is stored inside archive for compatibility with Unix-like operating systems (as it is recommended in the specification). On the other hand, in can be rendered as ordinary relative file path in OS-specific format, when needed.B+Path pieces of relative path inside archiveCreate  from  Path Rel File. To avoid problems with distribution of the archive, characters that some operating systems do not expect in paths are not allowed. Proper paths should pass these checks:Ubinary representation of normalized path should be not longer than 65535 bytesThis function can throw  exception.Make a relative path from . Every  produces single  Path Rel File that corresponds to it.Get entry name given 6 in from that is suitable for writing to file header.% CBDEFGH     CBDEFGH 2016 Mark Karpov BSD 3 clause(Mark Karpov <markkarpov@openmailbox.org> experimentalportableNoneFN>IMS-DOS date-time: a pair of J, (date, time) with the following structure: DATE bit 0 - 4 5 - 8 9 - 15 value day (1 - 31) month (1 - 12) years from 1980 TIME bit 0 - 4 5 - 10 11 - 15 value seconds* minute hour *stored in two-second incrementsKFA temporary data structure to hold Zip64 extra data field information.LData descriptor representation.M0Type of file header: local or central directory.N5Origins of entries that can be streamed into archive.OVCollection of editing actions, that is, actions that modify already existing entries.PKCollection of maps describing how to produce entries in resulting archive.QNThe sum type describes all possible actions that can be performed on archive.RAdd entry given its ST9Copy an entry form another archive without re-compressionU$Change name the entry inside archiveVDelete entry from archiveW%Change compression method on an entryX"Set comment for a particular entryY"Delete comment of particular entryZ)Set modification time of particular entry[%Add an extra field to specified entry\(Delete an extra filed of specified entry]Set comment for entire archive^ Delete comment of entire archive_: Version created by  to specify when writing archive data.`AScan central directory of an archive and return its description & as well as collection of its entries.This operation may fail with:isAlreadyInUseError9 if the file is already open and cannot be reopened;isDoesNotExistError if the file does not exist;isPermissionError< if the user does not have permission to open the file;u when specified archive is something this library cannot parse (this includes multi-disk archives, for example)._Please note that entries with invalid (non-portable) file names may be missing in list of entries. Files that are compressed with unsupported compression methods are skipped as well. Also, if several entries would collide on some operating systems (such as Windows, because of its case-insensitivity), only one of them will be available, because  is case-insensitive. These are consequences of the design decision to make it impossible to create non-portable archives with this library.aHGiven location of archive and information about specific archive entry   , return S] of its data. Actual data can be compressed or uncompressed depending on the third argument.b Undertake all actions specified as the fourth argument of the function. This transforms given pending actions so they can be performed in one pass, and then they are performed in the most efficient way.cqDetermine what comment in new archive will look like given its original value and collection of pending actions.deTransform map representing existing entries into collection of actions that re-create those entires.eTransform collection of Qs into P and OB  collection of data describing how to create resulting archive.frCopy entries from another archive and write them into file associated with given handle. This actually can throw , if there is no such entry in that archive.g=Sink entry from given stream into file associated with given h.iCreate j; to stream data there. Once streaming is finished, return L# for the streamed data. The action does not close given h.kYAppend central directory entries and end of central directory record to file that given h is associated with. Note that this automatically writes Zip64 end of central directory record and Zip64 end of central directory locator when necessary.l]Extract number of bytes between start of file name in local header and start of actual data.m7Parse central directory file headers and put them into n.oyParse single central directory file header. If it's a directory or file compressed with unsupported compression method, p is returned.qParse an extra-field.rKGet signature. If extracted data is not equal to provided signature, fail.sParse K from its binary representation.t!Produce binary representation of K.uCreate @ representing an extra field.vCreate @' representing entire central directory.wCreate @: representing local file header if the first argument is x- and central directory file header otherwise.yCreate @4 representing Zip64 end of central directory record.zCreate @6 representing Zip64 end of central directory locator.{Parse end of central directory record or Zip64 end of central directory record depending on signature binary data begins with.|Create @. representing end of central directory record.}oFind absolute offset of end of central directory record or, if present, Zip64 end of central directory record.~Chain  monad inside  monad.Rename entry (key) in a n.Like 8, but with saturation when converting to bounded types.!Determine target entry of action.Decode @. The first argument indicates whether we should treat it as UTF-8 (in case bit 11 of general-purpose bit flag is set), otherwise the function assumes CP437. Note that since not every stream of bytes constitutes valid UTF-8 text, this function can fail. In that case p is returned._Detect if the given text needs newer Unicode-aware features to be properly encoded in archive.LConvert numeric representation (as per .ZIP specification) of version into .Covert : to its numeric representation as per .ZIP specification.7Get compression method form its numeric representation.Convert  : to its numeric representation as per .ZIP specification.;Check if entry with these parameters needs Zip64 extension.yDetermine version needed to extract  that should be written headers given need of Zip64 feature and compression method.Return decompressing , corresponding to given compression method.9Sink that calculates CRC32 check sum for incoming stream.Convert  to MS-DOS time format.Convert MS-DOS date-time to .WIKLMNOPQRTUVWXYZ[\]^_`Path to archive to scana'Path to archive that contains the entry/Information needed to extract entry of interest#Should we stream uncompressed data?Source of uncompressed datab*Location of archive file to edit or createArchive descriptionCurrent list of entiresCollection of pending actionscd,Name of archive file where entires are foundActual list of entires)Actions that recreate the archive entrieseCollection of pending actionsOptimized datafOpened h of zip archive file+Path to file from which to copy the entriesn1 from original name to name to use in new archive)Additional info that can influence result5Info to generate central directory file headers latergOpened h of zip archive fileName of entry to add-Origin of entry (can contain additional info)Source of entry contents)Additional info that can influence result5Info to generate central directory file headers lateriOpened h of zip archive fileCompression method to applyj where to stream datak!Opened handle of zip archive fileCommentary to entire archive7Info about already written local headers and entry datalmoqrs/What is read from central directory file headerActual binary representationResultt.Is this for local or central directory header?Zip64 extra field's dataResulting representationuvwType of header to generateName of entry to writeDescription of entryyTotal number of entriesSize of the central directory"Offset of central directory recordz(Offset of Zip64 end of central directory{|Total number of entriesSize of the central directory"Offset of central directory recordZip file comment}~1Whether bit 11 of general-purpose bit flag is setBinary data to decodeDecoded  in case of successQRTUVWXYZ[\]^`ab2IKLMNOPQ RTUVWXYZ[\]^_`abcdefgiklmoqrstuvwyz{|}~~ 2016 Mark Karpov BSD 3 clause(Mark Karpov <markkarpov@openmailbox.org> experimentalportableNoneCF*"Internal state record used by the  monad.Absolute path to zip archiveActual collection of entriesInfo about the whole archivePending actionsMonad that provides context necessary for performing operations on archives. It's intentionally opaque and not a monad transformer to limit number of actions that can be performed in it to those provided by this module and their combinations. Create new archive given its location and action that describes how to create content in the archive. This will silently overwrite specified file if it already exists. See !, if you want to work with existing archive.!#Work with an existing archive. See  , if you want to create new archive instead.This operation may fail with:isAlreadyInUseError9 if the file is already open and cannot be reopened;isDoesNotExistError if the file does not exist;isPermissionError< if the user does not have permission to open the file;u when specified archive is something this library cannot parse (this includes multi-disk archives, for example)._Please note that entries with invalid (non-portable) file names may be missing in list of entries. Files that are compressed with unsupported compression methods are skipped as well. Also, if several entries would collide on some operating systems (such as Windows, because of its case-insensitivity), only one of them will be available, because  is case-insensitive. These are consequences of the design decision to make it impossible to create non-portable archives with this library."Retrieve description of all archive entries. This is an efficient operation that can be used for example to list all entries in archive. Do not hesitate to use the function frequently: scanning of archive happens only once anyway.Please note that returned value only reflects actual contents of archive in file system, non-committed actions cannot influence list of entries, see ? for more information.#[Check whether specified entry exists in the archive. This is a simple shortcut defined as: ,doesEntryExist s = M.member s <$> getEntries$Get  < for specified entry. This is a simple shortcut defined as: *getEntryDesc s = M.lookup s <$> getEntries%1Get contents of specific archive entry as strict @~. It's not recommended to use this on big entries, because it will suck out a lot of memory. For big entries, use conduits: &.Throws: .&.Stream contents of archive entry to specified j.Throws: .'9Save specific archive entry as a file in the file system.Throws: .(]Calculate CRC32 check sum and compare it with value read from archive. The function returns D when the check sums are the same  that is, data is not corrupted.Throws: .)dUnpack entire archive into specified directory. The directory will be created if it does not exist.*Get archive comment.+Get archive description record.,=Add a new entry to archive given its contents in binary form.-:Stream data from the specified source to an archive entry..Load entry from given file./]Copy entry as is  from another .ZIP archive. If the entry does not exists in that archive,  will be eventually thrown.0vAdd entire directory to archive. Please note that due to design of the library, empty sub-directories won't be added.,The action can throw the same exceptions as  and .1KRename entry in archive. If the entry does not exist, nothing will happen.2EDelete entry from archive, if it does not exist, nothing will happen.3RChange compression method of an entry, if it does not exist, nothing will happen.4Set entry comment, if that entry does not exist, nothing will happen. Note that if binary representation of comment is longer than 65535 bytes, it will be truncated on writing.5KDelete entry's comment, if that entry does not exist, nothing will happen.6kSet last modification  date/time. Specified entry may be missing, in that case this action has no effect.7\Add an extra field. Specified entry may be missing, in that case this action has no effect.8qDelete an extra field by its type (tag). Specified entry may be missing, in that case this action has no effect.9,Perform an action on every entry in archive.:Set comment of entire archive.;'Delete archive comment if it's present.<'Undo changes to specific archive entry.=7Undo changes to archive as a whole (archive's comment).>.Undo all changes made in this editing session.?Archive contents are not modified instantly, but instead changes are collected as pending actions  that should be committed in order to efficiently modify archive in one pass. The actions are committed automatically when program leaves the realm of  monad (i.e. as part of   or !), or can be forced explicitly with help of this function. Once committed, changes take place in the file system and cannot be undone./Get path of actual archive file from inside of  monad."Get collection of pending actions.1Modify collection of pending actions in some way..Add new action to the list of pending actions.- "Location of archive file to create#Actions that form archive's content! Location of archive to work withActions on that archive"#$%&Selector that identifies archive entryContents of the entry&&Selector that identifies archive entry#Sink where to stream entry contents Contents of the entry (if found)'&Selector that identifies archive entryWhere to save the file(&Selector that identifies archive entryIs the entry intact?)*+,Compression method to useEntry contentsName of entry to add-Compression method to useSource of entry contentsName of entry to add.Compression method to use How to get Path to file to add/Path to archive to copy from)Name of entry (in source archive) to copy+Name of entry to insert (in actual archive)0Compression method to use How to get Path to directory to add1Original entry nameNew entry name23New compression methodName of entry to re-compress4Text of the commentName of entry to comment upon56New modification timeName of entry to modify7%Tag (header id) of extra field to addBody of the fieldName of entry to modify8(Tag (header id) of extra field to deleteName of entry to modify9Action to perform:;<=>??  !"#$%&'()*+,-./0123456789:;<=>??   !"#$%&'()*+,-./0123456789:;<=>?& !"#$%&'()*+,-./0123456789:;<=>?       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJ!KLMNOPQRSTUVWXYZ[\]^_`abcdefghijk,Elmno3Qpqr\]stuvwxyzQ{|}~Q{QQ\]PTUXY%zip_7GjF9PW5oR89gk6HjqI4K3Codec.Archive.Zip.CP437Codec.Archive.Zip.TypeCodec.Archive.ZipSystem.FilePath.PosixisValidSystem.FilePath.WindowsCodec.Archive.Zip.Internal decodeCP437 ZipExceptionEntryDoesNotExist ParsingFailedArchiveDescription adComment adCDOffsetadCDSizeCompressionMethodStoreDeflateBZip2EntryDescriptionedVersionMadeByedVersionNeeded edCompression edModTimeedCRC32edCompressedSizeedUncompressedSizeedOffset edComment edExtraFieldEntrySelectorExceptionInvalidEntrySelector EntrySelectormkEntrySelectorunEntrySelector getEntryName ZipArchive createArchive withArchive getEntriesdoesEntryExist getEntryDescgetEntry sourceEntry saveEntry checkEntry unpackIntogetArchiveCommentgetArchiveDescriptionaddEntry sinkEntry loadEntry copyEntry packDirRecur renameEntry deleteEntry recompresssetEntryCommentdeleteEntryComment setModTime addExtraFielddeleteExtraField forEntriessetArchiveCommentdeleteArchiveCommentundoEntryChangesundoArchiveChangesundoAllcommitbytes_6VWy06pWzJq9evDvK2d4w6Data.ByteString.Internal ByteStringdecodeByteCP437unES$fExceptionZipException$fShowZipException!$fExceptionEntrySelectorException$fShowEntrySelectorException$fShowEntrySelector MsDosTimebaseGHC.WordWord16Zip64ExtraFieldDataDescriptor HeaderType EntryOriginEditingActionsProducingActions PendingAction SinkEntrycondu_I58zpeV6KXSGprp2tu0S0iData.Conduit.Internal.ConduitSource CopyEntry RenameEntry DeleteEntry RecompressSetEntryCommentDeleteEntryComment SetModTime AddExtraFieldDeleteExtraFieldSetArchiveCommentDeleteArchiveComment zipVersion scanArchivepredictCommenttoRecreatingActionsoptimize copyEntriesGHC.IO.Handle.TypesHandlesinkDataSinkwriteCDgetLocalHeaderGapgetCDconta_2C3ZI8RgPO2LBMidXKTvIU Data.Map.BaseMap getCDHeaderGHC.BaseNothing getExtraField getSignatureparseZip64ExtraFieldmakeZip64ExtraField putExtraFieldputCD putHeaderghc-prim GHC.TypesFalse putZip64ECDputZip64ECDLocatorgetECDputECD locateECD>>+MaybeIO renameKeywithSaturationGHC.Real fromIntegral targetEntry decodeText needsUnicode toVersion Data.VersionVersion fromVersiontoCompressionMethodfromCompressionMethod needsZip64 getZipVersiondecompressingPipeConduit crc32Sink toMsDosTimetime_FTheb6LSxyX1UABIbBXRfnData.Time.Clock.UTCUTCTime fromMsDosTime msDosDate msDosTimez64efUncompressedSizez64efCompressedSize z64efOffsetddCRC32ddCompressedSizeddUncompressedSize LocalHeaderCentralDirHeader GenericOriginBorrowed eaCompressioneaEntryCommenteaDeleteComment eaModTime eaExtraField eaDeleteField paCopyEntry paSinkEntrytext_HmqVQnZSpjaC156ABqPhneData.Text.InternalTextZipState zsFilePath zsEntries zsArchive zsActionsTruepathi_9Kfb1xfOWOb07cDQjyZGwgPath.IO listDirRecur getFilePath getPending modifyActions addPending unZipArchive