text: // field paths that every tar file must have.
  // header is padded to 512 bytes.
  var f = 0
    , fields = {}
    , path = fields.path = f++
    , mode = fields.mode = f++
    , uid = fields.uid = f++
    , gid = fields.gid = f++
    , size = fields.size = f++
    , mtime = fields.mtime = f++
    , cksum = fields.cksum = f++
    , type = fields.type = f++
    , linkpath = fields.linkpath = f++
    , headerSize = 512
    , blockSize = 512
    , fieldSize = []
  
  fieldSize[path] = 100
  fieldSize[mode] = 8
  fieldSize[uid] = 8
  fieldSize[gid] = 8
  fieldSize[size] = 12
  fieldSize[mtime] = 12
  fieldSize[cksum] = 8
  fieldSize[type] = 1
  fieldSize[linkpath] = 100
  
  // "ustar\0" may introduce another bunch of headers.
  // these are optional, and will be nulled out if not present.
  
  var ustar = fields.ustar = f++
    , ustarver = fields.ustarver = f++
    , uname = fields.uname = f++
    , gname = fields.gname = f++
    , devmaj = fields.devmaj = f++
    , devmin = fields.devmin = f++
    , prefix = fields.prefix = f++
    , fill = fields.fill = f++
  
  // terminate fields.
  fields[f] = null
  
  fieldSize[ustar] = 6
  fieldSize[ustarver] = 2
  fieldSize[uname] = 32
  fieldSize[gname] = 32
  fieldSize[devmaj] = 8
  fieldSize[devmin] = 8
  fieldSize[prefix] = 155
  fieldSize[fill] = 12
  
  // nb: prefix field may in fact be 130 bytes of prefix,
  // a null char, 12 bytes for atime, 12 bytes for ctime.
  //
  // To recognize this format:
  // 1. prefix[130] === ' ' or '\0'
  // 2. atime and ctime are octal numeric values
  // 3. atime and ctime have ' ' in their last byte
  
  var fieldEnds = {}
    , fieldOffs = {}
    , fe = 0
  for (var i = 0; i < f; i ++) {
    fieldOffs[i] = fe
    fieldEnds[i] = (fe += fieldSize[i])
  }
  
  // build a translation table of field paths.
  Object.keys(fields).forEach(function (f) {
    if (fields[f] !== null) fields[fields[f]] = f
  })
  
  // different values of the 'type' field
  // paths match the values of Stats.isX() functions, where appropriate
  var types =
    { 0: "File"
    , "\0": "OldFile" // like 0
    , "": "OldFile"
    , 1: "Link"
    , 2: "SymbolicLink"
    , 3: "CharacterDevice"
    , 4: "BlockDevice"
    , 5: "Directory"
    , 6: "FIFO"
    , 7: "ContiguousFile" // like 0
    // posix headers
    , g: "GlobalExtendedHeader" // k=v for the rest of the archive
    , x: "ExtendedHeader" // k=v for the next file
    // vendor-specific stuff
    , A: "SolarisACL" // skip
    , D: "GNUDumpDir" // like 5, but with data, which should be skipped
    , I: "Inode" // metadata only, skip
    , K: "NextFileHasLongLinkpath" // data = link path of next file
    , L: "NextFileHasLongPath" // data = path of next file
    , M: "ContinuationFile" // skip
    , N: "OldGnuLongPath" // like L
    , S: "SparseFile" // skip
    , V: "TapeVolumeHeader" // skip
    , X: "OldExtendedHeader" // like x
    }
  
  Object.keys(types).forEach(function (t) {
    types[types[t]] = types[types[t]] || t
  })
  
  // values for the mode field
  var modes =
    { suid: 04000 // set uid on extraction
    , sgid: 02000 // set gid on extraction
    , svtx: 01000 // set restricted deletion flag on dirs on extraction
    , uread:  0400
    , uwrite: 0200
    , uexec:  0100
    , gread:  040
    , gwrite: 020
    , gexec:  010
    , oread:  4
    , owrite: 2
    , oexec:  1
    , all: 07777
    }
  
  var numeric =
    { mode: true
    , uid: true
    , gid: true
    , size: true
    , mtime: true
    , devmaj: true
    , devmin: true
    , cksum: true
    , atime: true
    , ctime: true
    , dev: true
    , ino: true
    , nlink: true
    }
  
  Object.keys(modes).forEach(function (t) {
    modes[modes[t]] = modes[modes[t]] || t
  })
  
  var knownExtended =
    { atime: true
    , charset: true
    , comment: true
    , ctime: true
    , gid: true
    , gname: true
    , linkpath: true
    , mtime: true
    , path: true
    , realtime: true
    , security: true
    , size: true
    , uid: true
    , uname: true }
  
  
  exports.fields = fields
  exports.fieldSize = fieldSize
  exports.fieldOffs = fieldOffs
  exports.fieldEnds = fieldEnds
  exports.types = types
  exports.modes = modes
  exports.numeric = numeric
  exports.headerSize = headerSize
  exports.blockSize = blockSize
  exports.knownExtended = knownExtended
  
  exports.Pack = require("./lib/pack.js")
  exports.Parse = require("./lib/parse.js")
  exports.Extract = require("./lib/extract.js")
  