{"version":3,"sources":["jsdelivr-header.js","/npm/node_modules/.pnpm/buffer-crc32@0.2.13/node_modules/buffer-crc32/index.js","/npm/node_modules/.pnpm/yazl@2.5.1/node_modules/yazl/index.js","/npm/@xmcl/installer@6.1.2/index.ts","/npm/@xmcl/installer@6.1.2/fabric.ts","/npm/@xmcl/installer@6.1.2/utils.ts","/npm/@xmcl/installer@6.1.2/liteloader.ts","/npm/@xmcl/installer@6.1.2/forge.ts","/npm/@xmcl/installer@6.1.2/downloadTask.ts","/npm/@xmcl/installer@6.1.2/minecraft.ts","/npm/@xmcl/installer@6.1.2/zipValdiator.ts","/npm/@xmcl/installer@6.1.2/profile.ts","/npm/@xmcl/installer@6.1.2/manifest.ts","/npm/@xmcl/installer@6.1.2/neoForged.ts","/npm/@xmcl/installer@6.1.2/optifine.ts","/npm/@xmcl/installer@6.1.2/java.ts","/npm/@xmcl/installer@6.1.2/java-runtime.ts","/npm/@xmcl/installer@6.1.2/diagnose.ts","/npm/@xmcl/installer@6.1.2/quilt.ts","/npm/@xmcl/installer@6.1.2/unzip.ts","/npm/@xmcl/installer@6.1.2/labymod.ts"],"names":[],"mappings":"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","file":"/npm/@xmcl/installer@6.1.2/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@xmcl/installer@6.1.2/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","var Buffer = require('buffer').Buffer;\n\nvar CRC_TABLE = [\n  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,\n  0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,\n  0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,\n  0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,\n  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,\n  0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,\n  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,\n  0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,\n  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,\n  0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,\n  0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,\n  0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,\n  0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,\n  0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,\n  0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,\n  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,\n  0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,\n  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,\n  0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,\n  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,\n  0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,\n  0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,\n  0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,\n  0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,\n  0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,\n  0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,\n  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,\n  0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,\n  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,\n  0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,\n  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,\n  0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,\n  0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,\n  0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,\n  0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,\n  0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,\n  0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,\n  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,\n  0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,\n  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,\n  0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,\n  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,\n  0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,\n  0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,\n  0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,\n  0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,\n  0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,\n  0x2d02ef8d\n];\n\nif (typeof Int32Array !== 'undefined') {\n  CRC_TABLE = new Int32Array(CRC_TABLE);\n}\n\nfunction ensureBuffer(input) {\n  if (Buffer.isBuffer(input)) {\n    return input;\n  }\n\n  var hasNewBufferAPI =\n      typeof Buffer.alloc === \"function\" &&\n      typeof Buffer.from === \"function\";\n\n  if (typeof input === \"number\") {\n    return hasNewBufferAPI ? Buffer.alloc(input) : new Buffer(input);\n  }\n  else if (typeof input === \"string\") {\n    return hasNewBufferAPI ? Buffer.from(input) : new Buffer(input);\n  }\n  else {\n    throw new Error(\"input must be buffer, number, or string, received \" +\n                    typeof input);\n  }\n}\n\nfunction bufferizeInt(num) {\n  var tmp = ensureBuffer(4);\n  tmp.writeInt32BE(num, 0);\n  return tmp;\n}\n\nfunction _crc32(buf, previous) {\n  buf = ensureBuffer(buf);\n  if (Buffer.isBuffer(previous)) {\n    previous = previous.readUInt32BE(0);\n  }\n  var crc = ~~previous ^ -1;\n  for (var n = 0; n < buf.length; n++) {\n    crc = CRC_TABLE[(crc ^ buf[n]) & 0xff] ^ (crc >>> 8);\n  }\n  return (crc ^ -1);\n}\n\nfunction crc32() {\n  return bufferizeInt(_crc32.apply(null, arguments));\n}\ncrc32.signed = function () {\n  return _crc32.apply(null, arguments);\n};\ncrc32.unsigned = function () {\n  return _crc32.apply(null, arguments) >>> 0;\n};\n\nmodule.exports = crc32;\n","var fs = require(\"fs\");\nvar Transform = require(\"stream\").Transform;\nvar PassThrough = require(\"stream\").PassThrough;\nvar zlib = require(\"zlib\");\nvar util = require(\"util\");\nvar EventEmitter = require(\"events\").EventEmitter;\nvar crc32 = require(\"buffer-crc32\");\n\nexports.ZipFile = ZipFile;\nexports.dateToDosDateTime = dateToDosDateTime;\n\nutil.inherits(ZipFile, EventEmitter);\nfunction ZipFile() {\n  this.outputStream = new PassThrough();\n  this.entries = [];\n  this.outputStreamCursor = 0;\n  this.ended = false; // .end() sets this\n  this.allDone = false; // set when we've written the last bytes\n  this.forceZip64Eocd = false; // configurable in .end()\n}\n\nZipFile.prototype.addFile = function(realPath, metadataPath, options) {\n  var self = this;\n  metadataPath = validateMetadataPath(metadataPath, false);\n  if (options == null) options = {};\n\n  var entry = new Entry(metadataPath, false, options);\n  self.entries.push(entry);\n  fs.stat(realPath, function(err, stats) {\n    if (err) return self.emit(\"error\", err);\n    if (!stats.isFile()) return self.emit(\"error\", new Error(\"not a file: \" + realPath));\n    entry.uncompressedSize = stats.size;\n    if (options.mtime == null) entry.setLastModDate(stats.mtime);\n    if (options.mode == null) entry.setFileAttributesMode(stats.mode);\n    entry.setFileDataPumpFunction(function() {\n      var readStream = fs.createReadStream(realPath);\n      entry.state = Entry.FILE_DATA_IN_PROGRESS;\n      readStream.on(\"error\", function(err) {\n        self.emit(\"error\", err);\n      });\n      pumpFileDataReadStream(self, entry, readStream);\n    });\n    pumpEntries(self);\n  });\n};\n\nZipFile.prototype.addReadStream = function(readStream, metadataPath, options) {\n  var self = this;\n  metadataPath = validateMetadataPath(metadataPath, false);\n  if (options == null) options = {};\n  var entry = new Entry(metadataPath, false, options);\n  self.entries.push(entry);\n  entry.setFileDataPumpFunction(function() {\n    entry.state = Entry.FILE_DATA_IN_PROGRESS;\n    pumpFileDataReadStream(self, entry, readStream);\n  });\n  pumpEntries(self);\n};\n\nZipFile.prototype.addBuffer = function(buffer, metadataPath, options) {\n  var self = this;\n  metadataPath = validateMetadataPath(metadataPath, false);\n  if (buffer.length > 0x3fffffff) throw new Error(\"buffer too large: \" + buffer.length + \" > \" + 0x3fffffff);\n  if (options == null) options = {};\n  if (options.size != null) throw new Error(\"options.size not allowed\");\n  var entry = new Entry(metadataPath, false, options);\n  entry.uncompressedSize = buffer.length;\n  entry.crc32 = crc32.unsigned(buffer);\n  entry.crcAndFileSizeKnown = true;\n  self.entries.push(entry);\n  if (!entry.compress) {\n    setCompressedBuffer(buffer);\n  } else {\n    zlib.deflateRaw(buffer, function(err, compressedBuffer) {\n      setCompressedBuffer(compressedBuffer);\n    });\n  }\n  function setCompressedBuffer(compressedBuffer) {\n    entry.compressedSize = compressedBuffer.length;\n    entry.setFileDataPumpFunction(function() {\n      writeToOutputStream(self, compressedBuffer);\n      writeToOutputStream(self, entry.getDataDescriptor());\n      entry.state = Entry.FILE_DATA_DONE;\n\n      // don't call pumpEntries() recursively.\n      // (also, don't call process.nextTick recursively.)\n      setImmediate(function() {\n        pumpEntries(self);\n      });\n    });\n    pumpEntries(self);\n  }\n};\n\nZipFile.prototype.addEmptyDirectory = function(metadataPath, options) {\n  var self = this;\n  metadataPath = validateMetadataPath(metadataPath, true);\n  if (options == null) options = {};\n  if (options.size != null) throw new Error(\"options.size not allowed\");\n  if (options.compress != null) throw new Error(\"options.compress not allowed\");\n  var entry = new Entry(metadataPath, true, options);\n  self.entries.push(entry);\n  entry.setFileDataPumpFunction(function() {\n    writeToOutputStream(self, entry.getDataDescriptor());\n    entry.state = Entry.FILE_DATA_DONE;\n    pumpEntries(self);\n  });\n  pumpEntries(self);\n};\n\nvar eocdrSignatureBuffer = bufferFrom([0x50, 0x4b, 0x05, 0x06]);\n\nZipFile.prototype.end = function(options, finalSizeCallback) {\n  if (typeof options === \"function\") {\n    finalSizeCallback = options;\n    options = null;\n  }\n  if (options == null) options = {};\n  if (this.ended) return;\n  this.ended = true;\n  this.finalSizeCallback = finalSizeCallback;\n  this.forceZip64Eocd = !!options.forceZip64Format;\n  if (options.comment) {\n    if (typeof options.comment === \"string\") {\n      this.comment = encodeCp437(options.comment);\n    } else {\n      // It should be a Buffer\n      this.comment = options.comment;\n    }\n    if (this.comment.length > 0xffff) throw new Error(\"comment is too large\");\n    // gotta check for this, because the zipfile format is actually ambiguous.\n    if (bufferIncludes(this.comment, eocdrSignatureBuffer)) throw new Error(\"comment contains end of central directory record signature\");\n  } else {\n    // no comment.\n    this.comment = EMPTY_BUFFER;\n  }\n  pumpEntries(this);\n};\n\nfunction writeToOutputStream(self, buffer) {\n  self.outputStream.write(buffer);\n  self.outputStreamCursor += buffer.length;\n}\n\nfunction pumpFileDataReadStream(self, entry, readStream) {\n  var crc32Watcher = new Crc32Watcher();\n  var uncompressedSizeCounter = new ByteCounter();\n  var compressor = entry.compress ? new zlib.DeflateRaw() : new PassThrough();\n  var compressedSizeCounter = new ByteCounter();\n  readStream.pipe(crc32Watcher)\n            .pipe(uncompressedSizeCounter)\n            .pipe(compressor)\n            .pipe(compressedSizeCounter)\n            .pipe(self.outputStream, {end: false});\n  compressedSizeCounter.on(\"end\", function() {\n    entry.crc32 = crc32Watcher.crc32;\n    if (entry.uncompressedSize == null) {\n      entry.uncompressedSize = uncompressedSizeCounter.byteCount;\n    } else {\n      if (entry.uncompressedSize !== uncompressedSizeCounter.byteCount) return self.emit(\"error\", new Error(\"file data stream has unexpected number of bytes\"));\n    }\n    entry.compressedSize = compressedSizeCounter.byteCount;\n    self.outputStreamCursor += entry.compressedSize;\n    writeToOutputStream(self, entry.getDataDescriptor());\n    entry.state = Entry.FILE_DATA_DONE;\n    pumpEntries(self);\n  });\n}\n\nfunction pumpEntries(self) {\n  if (self.allDone) return;\n  // first check if finalSize is finally known\n  if (self.ended && self.finalSizeCallback != null) {\n    var finalSize = calculateFinalSize(self);\n    if (finalSize != null) {\n      // we have an answer\n      self.finalSizeCallback(finalSize);\n      self.finalSizeCallback = null;\n    }\n  }\n\n  // pump entries\n  var entry = getFirstNotDoneEntry();\n  function getFirstNotDoneEntry() {\n    for (var i = 0; i < self.entries.length; i++) {\n      var entry = self.entries[i];\n      if (entry.state < Entry.FILE_DATA_DONE) return entry;\n    }\n    return null;\n  }\n  if (entry != null) {\n    // this entry is not done yet\n    if (entry.state < Entry.READY_TO_PUMP_FILE_DATA) return; // input file not open yet\n    if (entry.state === Entry.FILE_DATA_IN_PROGRESS) return; // we'll get there\n    // start with local file header\n    entry.relativeOffsetOfLocalHeader = self.outputStreamCursor;\n    var localFileHeader = entry.getLocalFileHeader();\n    writeToOutputStream(self, localFileHeader);\n    entry.doFileDataPump();\n  } else {\n    // all cought up on writing entries\n    if (self.ended) {\n      // head for the exit\n      self.offsetOfStartOfCentralDirectory = self.outputStreamCursor;\n      self.entries.forEach(function(entry) {\n        var centralDirectoryRecord = entry.getCentralDirectoryRecord();\n        writeToOutputStream(self, centralDirectoryRecord);\n      });\n      writeToOutputStream(self, getEndOfCentralDirectoryRecord(self));\n      self.outputStream.end();\n      self.allDone = true;\n    }\n  }\n}\n\nfunction calculateFinalSize(self) {\n  var pretendOutputCursor = 0;\n  var centralDirectorySize = 0;\n  for (var i = 0; i < self.entries.length; i++) {\n    var entry = self.entries[i];\n    // compression is too hard to predict\n    if (entry.compress) return -1;\n    if (entry.state >= Entry.READY_TO_PUMP_FILE_DATA) {\n      // if addReadStream was called without providing the size, we can't predict the final size\n      if (entry.uncompressedSize == null) return -1;\n    } else {\n      // if we're still waiting for fs.stat, we might learn the size someday\n      if (entry.uncompressedSize == null) return null;\n    }\n    // we know this for sure, and this is important to know if we need ZIP64 format.\n    entry.relativeOffsetOfLocalHeader = pretendOutputCursor;\n    var useZip64Format = entry.useZip64Format();\n\n    pretendOutputCursor += LOCAL_FILE_HEADER_FIXED_SIZE + entry.utf8FileName.length;\n    pretendOutputCursor += entry.uncompressedSize;\n    if (!entry.crcAndFileSizeKnown) {\n      // use a data descriptor\n      if (useZip64Format) {\n        pretendOutputCursor += ZIP64_DATA_DESCRIPTOR_SIZE;\n      } else {\n        pretendOutputCursor += DATA_DESCRIPTOR_SIZE;\n      }\n    }\n\n    centralDirectorySize += CENTRAL_DIRECTORY_RECORD_FIXED_SIZE + entry.utf8FileName.length + entry.fileComment.length;\n    if (useZip64Format) {\n      centralDirectorySize += ZIP64_EXTENDED_INFORMATION_EXTRA_FIELD_SIZE;\n    }\n  }\n\n  var endOfCentralDirectorySize = 0;\n  if (self.forceZip64Eocd ||\n      self.entries.length >= 0xffff ||\n      centralDirectorySize >= 0xffff ||\n      pretendOutputCursor >= 0xffffffff) {\n    // use zip64 end of central directory stuff\n    endOfCentralDirectorySize += ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIZE + ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIZE;\n  }\n  endOfCentralDirectorySize += END_OF_CENTRAL_DIRECTORY_RECORD_SIZE + self.comment.length;\n  return pretendOutputCursor + centralDirectorySize + endOfCentralDirectorySize;\n}\n\nvar ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIZE = 56;\nvar ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIZE = 20;\nvar END_OF_CENTRAL_DIRECTORY_RECORD_SIZE = 22;\nfunction getEndOfCentralDirectoryRecord(self, actuallyJustTellMeHowLongItWouldBe) {\n  var needZip64Format = false;\n  var normalEntriesLength = self.entries.length;\n  if (self.forceZip64Eocd || self.entries.length >= 0xffff) {\n    normalEntriesLength = 0xffff;\n    needZip64Format = true;\n  }\n  var sizeOfCentralDirectory = self.outputStreamCursor - self.offsetOfStartOfCentralDirectory;\n  var normalSizeOfCentralDirectory = sizeOfCentralDirectory;\n  if (self.forceZip64Eocd || sizeOfCentralDirectory >= 0xffffffff) {\n    normalSizeOfCentralDirectory = 0xffffffff;\n    needZip64Format = true;\n  }\n  var normalOffsetOfStartOfCentralDirectory = self.offsetOfStartOfCentralDirectory;\n  if (self.forceZip64Eocd || self.offsetOfStartOfCentralDirectory >= 0xffffffff) {\n    normalOffsetOfStartOfCentralDirectory = 0xffffffff;\n    needZip64Format = true;\n  }\n  if (actuallyJustTellMeHowLongItWouldBe) {\n    if (needZip64Format) {\n      return (\n        ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIZE +\n        ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIZE +\n        END_OF_CENTRAL_DIRECTORY_RECORD_SIZE\n      );\n    } else {\n      return END_OF_CENTRAL_DIRECTORY_RECORD_SIZE;\n    }\n  }\n\n  var eocdrBuffer = bufferAlloc(END_OF_CENTRAL_DIRECTORY_RECORD_SIZE + self.comment.length);\n  // end of central dir signature                       4 bytes  (0x06054b50)\n  eocdrBuffer.writeUInt32LE(0x06054b50, 0);\n  // number of this disk                                2 bytes\n  eocdrBuffer.writeUInt16LE(0, 4);\n  // number of the disk with the start of the central directory  2 bytes\n  eocdrBuffer.writeUInt16LE(0, 6);\n  // total number of entries in the central directory on this disk  2 bytes\n  eocdrBuffer.writeUInt16LE(normalEntriesLength, 8);\n  // total number of entries in the central directory   2 bytes\n  eocdrBuffer.writeUInt16LE(normalEntriesLength, 10);\n  // size of the central directory                      4 bytes\n  eocdrBuffer.writeUInt32LE(normalSizeOfCentralDirectory, 12);\n  // offset of start of central directory with respect to the starting disk number  4 bytes\n  eocdrBuffer.writeUInt32LE(normalOffsetOfStartOfCentralDirectory, 16);\n  // .ZIP file comment length                           2 bytes\n  eocdrBuffer.writeUInt16LE(self.comment.length, 20);\n  // .ZIP file comment                                  (variable size)\n  self.comment.copy(eocdrBuffer, 22);\n\n  if (!needZip64Format) return eocdrBuffer;\n\n  // ZIP64 format\n  // ZIP64 End of Central Directory Record\n  var zip64EocdrBuffer = bufferAlloc(ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIZE);\n  // zip64 end of central dir signature                                             4 bytes  (0x06064b50)\n  zip64EocdrBuffer.writeUInt32LE(0x06064b50, 0);\n  // size of zip64 end of central directory record                                  8 bytes\n  writeUInt64LE(zip64EocdrBuffer, ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIZE - 12, 4);\n  // version made by                                                                2 bytes\n  zip64EocdrBuffer.writeUInt16LE(VERSION_MADE_BY, 12);\n  // version needed to extract                                                      2 bytes\n  zip64EocdrBuffer.writeUInt16LE(VERSION_NEEDED_TO_EXTRACT_ZIP64, 14);\n  // number of this disk                                                            4 bytes\n  zip64EocdrBuffer.writeUInt32LE(0, 16);\n  // number of the disk with the start of the central directory                     4 bytes\n  zip64EocdrBuffer.writeUInt32LE(0, 20);\n  // total number of entries in the central directory on this disk                  8 bytes\n  writeUInt64LE(zip64EocdrBuffer, self.entries.length, 24);\n  // total number of entries in the central directory                               8 bytes\n  writeUInt64LE(zip64EocdrBuffer, self.entries.length, 32);\n  // size of the central directory                                                  8 bytes\n  writeUInt64LE(zip64EocdrBuffer, sizeOfCentralDirectory, 40);\n  // offset of start of central directory with respect to the starting disk number  8 bytes\n  writeUInt64LE(zip64EocdrBuffer, self.offsetOfStartOfCentralDirectory, 48);\n  // zip64 extensible data sector                                                   (variable size)\n  // nothing in the zip64 extensible data sector\n\n\n  // ZIP64 End of Central Directory Locator\n  var zip64EocdlBuffer = bufferAlloc(ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIZE);\n  // zip64 end of central dir locator signature                               4 bytes  (0x07064b50)\n  zip64EocdlBuffer.writeUInt32LE(0x07064b50, 0);\n  // number of the disk with the start of the zip64 end of central directory  4 bytes\n  zip64EocdlBuffer.writeUInt32LE(0, 4);\n  // relative offset of the zip64 end of central directory record             8 bytes\n  writeUInt64LE(zip64EocdlBuffer, self.outputStreamCursor, 8);\n  // total number of disks                                                    4 bytes\n  zip64EocdlBuffer.writeUInt32LE(1, 16);\n\n\n  return Buffer.concat([\n    zip64EocdrBuffer,\n    zip64EocdlBuffer,\n    eocdrBuffer,\n  ]);\n}\n\nfunction validateMetadataPath(metadataPath, isDirectory) {\n  if (metadataPath === \"\") throw new Error(\"empty metadataPath\");\n  metadataPath = metadataPath.replace(/\\\\/g, \"/\");\n  if (/^[a-zA-Z]:/.test(metadataPath) || /^\\//.test(metadataPath)) throw new Error(\"absolute path: \" + metadataPath);\n  if (metadataPath.split(\"/\").indexOf(\"..\") !== -1) throw new Error(\"invalid relative path: \" + metadataPath);\n  var looksLikeDirectory = /\\/$/.test(metadataPath);\n  if (isDirectory) {\n    // append a trailing '/' if necessary.\n    if (!looksLikeDirectory) metadataPath += \"/\";\n  } else {\n    if (looksLikeDirectory) throw new Error(\"file path cannot end with '/': \" + metadataPath);\n  }\n  return metadataPath;\n}\n\nvar EMPTY_BUFFER = bufferAlloc(0);\n\n// this class is not part of the public API\nfunction Entry(metadataPath, isDirectory, options) {\n  this.utf8FileName = bufferFrom(metadataPath);\n  if (this.utf8FileName.length > 0xffff) throw new Error(\"utf8 file name too long. \" + utf8FileName.length + \" > \" + 0xffff);\n  this.isDirectory = isDirectory;\n  this.state = Entry.WAITING_FOR_METADATA;\n  this.setLastModDate(options.mtime != null ? options.mtime : new Date());\n  if (options.mode != null) {\n    this.setFileAttributesMode(options.mode);\n  } else {\n    this.setFileAttributesMode(isDirectory ? 0o40775 : 0o100664);\n  }\n  if (isDirectory) {\n    this.crcAndFileSizeKnown = true;\n    this.crc32 = 0;\n    this.uncompressedSize = 0;\n    this.compressedSize = 0;\n  } else {\n    // unknown so far\n    this.crcAndFileSizeKnown = false;\n    this.crc32 = null;\n    this.uncompressedSize = null;\n    this.compressedSize = null;\n    if (options.size != null) this.uncompressedSize = options.size;\n  }\n  if (isDirectory) {\n    this.compress = false;\n  } else {\n    this.compress = true; // default\n    if (options.compress != null) this.compress = !!options.compress;\n  }\n  this.forceZip64Format = !!options.forceZip64Format;\n  if (options.fileComment) {\n    if (typeof options.fileComment === \"string\") {\n      this.fileComment = bufferFrom(options.fileComment, \"utf-8\");\n    } else {\n      // It should be a Buffer\n      this.fileComment = options.fileComment;\n    }\n    if (this.fileComment.length > 0xffff) throw new Error(\"fileComment is too large\");\n  } else {\n    // no comment.\n    this.fileComment = EMPTY_BUFFER;\n  }\n}\nEntry.WAITING_FOR_METADATA = 0;\nEntry.READY_TO_PUMP_FILE_DATA = 1;\nEntry.FILE_DATA_IN_PROGRESS = 2;\nEntry.FILE_DATA_DONE = 3;\nEntry.prototype.setLastModDate = function(date) {\n  var dosDateTime = dateToDosDateTime(date);\n  this.lastModFileTime = dosDateTime.time;\n  this.lastModFileDate = dosDateTime.date;\n};\nEntry.prototype.setFileAttributesMode = function(mode) {\n  if ((mode & 0xffff) !== mode) throw new Error(\"invalid mode. expected: 0 <= \" + mode + \" <= \" + 0xffff);\n  // http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute/14727#14727\n  this.externalFileAttributes = (mode << 16) >>> 0;\n};\n// doFileDataPump() should not call pumpEntries() directly. see issue #9.\nEntry.prototype.setFileDataPumpFunction = function(doFileDataPump) {\n  this.doFileDataPump = doFileDataPump;\n  this.state = Entry.READY_TO_PUMP_FILE_DATA;\n};\nEntry.prototype.useZip64Format = function() {\n  return (\n    (this.forceZip64Format) ||\n    (this.uncompressedSize != null && this.uncompressedSize > 0xfffffffe) ||\n    (this.compressedSize != null && this.compressedSize > 0xfffffffe) ||\n    (this.relativeOffsetOfLocalHeader != null && this.relativeOffsetOfLocalHeader > 0xfffffffe)\n  );\n}\nvar LOCAL_FILE_HEADER_FIXED_SIZE = 30;\nvar VERSION_NEEDED_TO_EXTRACT_UTF8 = 20;\nvar VERSION_NEEDED_TO_EXTRACT_ZIP64 = 45;\n// 3 = unix. 63 = spec version 6.3\nvar VERSION_MADE_BY = (3 << 8) | 63;\nvar FILE_NAME_IS_UTF8 = 1 << 11;\nvar UNKNOWN_CRC32_AND_FILE_SIZES = 1 << 3;\nEntry.prototype.getLocalFileHeader = function() {\n  var crc32 = 0;\n  var compressedSize = 0;\n  var uncompressedSize = 0;\n  if (this.crcAndFileSizeKnown) {\n    crc32 = this.crc32;\n    compressedSize = this.compressedSize;\n    uncompressedSize = this.uncompressedSize;\n  }\n\n  var fixedSizeStuff = bufferAlloc(LOCAL_FILE_HEADER_FIXED_SIZE);\n  var generalPurposeBitFlag = FILE_NAME_IS_UTF8;\n  if (!this.crcAndFileSizeKnown) generalPurposeBitFlag |= UNKNOWN_CRC32_AND_FILE_SIZES;\n\n  // local file header signature     4 bytes  (0x04034b50)\n  fixedSizeStuff.writeUInt32LE(0x04034b50, 0);\n  // version needed to extract       2 bytes\n  fixedSizeStuff.writeUInt16LE(VERSION_NEEDED_TO_EXTRACT_UTF8, 4);\n  // general purpose bit flag        2 bytes\n  fixedSizeStuff.writeUInt16LE(generalPurposeBitFlag, 6);\n  // compression method              2 bytes\n  fixedSizeStuff.writeUInt16LE(this.getCompressionMethod(), 8);\n  // last mod file time              2 bytes\n  fixedSizeStuff.writeUInt16LE(this.lastModFileTime, 10);\n  // last mod file date              2 bytes\n  fixedSizeStuff.writeUInt16LE(this.lastModFileDate, 12);\n  // crc-32                          4 bytes\n  fixedSizeStuff.writeUInt32LE(crc32, 14);\n  // compressed size                 4 bytes\n  fixedSizeStuff.writeUInt32LE(compressedSize, 18);\n  // uncompressed size               4 bytes\n  fixedSizeStuff.writeUInt32LE(uncompressedSize, 22);\n  // file name length                2 bytes\n  fixedSizeStuff.writeUInt16LE(this.utf8FileName.length, 26);\n  // extra field length              2 bytes\n  fixedSizeStuff.writeUInt16LE(0, 28);\n  return Buffer.concat([\n    fixedSizeStuff,\n    // file name (variable size)\n    this.utf8FileName,\n    // extra field (variable size)\n    // no extra fields\n  ]);\n};\nvar DATA_DESCRIPTOR_SIZE = 16;\nvar ZIP64_DATA_DESCRIPTOR_SIZE = 24;\nEntry.prototype.getDataDescriptor = function() {\n  if (this.crcAndFileSizeKnown) {\n    // the Mac Archive Utility requires this not be present unless we set general purpose bit 3\n    return EMPTY_BUFFER;\n  }\n  if (!this.useZip64Format()) {\n    var buffer = bufferAlloc(DATA_DESCRIPTOR_SIZE);\n    // optional signature (required according to Archive Utility)\n    buffer.writeUInt32LE(0x08074b50, 0);\n    // crc-32                          4 bytes\n    buffer.writeUInt32LE(this.crc32, 4);\n    // compressed size                 4 bytes\n    buffer.writeUInt32LE(this.compressedSize, 8);\n    // uncompressed size               4 bytes\n    buffer.writeUInt32LE(this.uncompressedSize, 12);\n    return buffer;\n  } else {\n    // ZIP64 format\n    var buffer = bufferAlloc(ZIP64_DATA_DESCRIPTOR_SIZE);\n    // optional signature (unknown if anyone cares about this)\n    buffer.writeUInt32LE(0x08074b50, 0);\n    // crc-32                          4 bytes\n    buffer.writeUInt32LE(this.crc32, 4);\n    // compressed size                 8 bytes\n    writeUInt64LE(buffer, this.compressedSize, 8);\n    // uncompressed size               8 bytes\n    writeUInt64LE(buffer, this.uncompressedSize, 16);\n    return buffer;\n  }\n};\nvar CENTRAL_DIRECTORY_RECORD_FIXED_SIZE = 46;\nvar ZIP64_EXTENDED_INFORMATION_EXTRA_FIELD_SIZE = 28;\nEntry.prototype.getCentralDirectoryRecord = function() {\n  var fixedSizeStuff = bufferAlloc(CENTRAL_DIRECTORY_RECORD_FIXED_SIZE);\n  var generalPurposeBitFlag = FILE_NAME_IS_UTF8;\n  if (!this.crcAndFileSizeKnown) generalPurposeBitFlag |= UNKNOWN_CRC32_AND_FILE_SIZES;\n\n  var normalCompressedSize = this.compressedSize;\n  var normalUncompressedSize = this.uncompressedSize;\n  var normalRelativeOffsetOfLocalHeader = this.relativeOffsetOfLocalHeader;\n  var versionNeededToExtract;\n  var zeiefBuffer;\n  if (this.useZip64Format()) {\n    normalCompressedSize = 0xffffffff;\n    normalUncompressedSize = 0xffffffff;\n    normalRelativeOffsetOfLocalHeader = 0xffffffff;\n    versionNeededToExtract = VERSION_NEEDED_TO_EXTRACT_ZIP64;\n\n    // ZIP64 extended information extra field\n    zeiefBuffer = bufferAlloc(ZIP64_EXTENDED_INFORMATION_EXTRA_FIELD_SIZE);\n    // 0x0001                  2 bytes    Tag for this \"extra\" block type\n    zeiefBuffer.writeUInt16LE(0x0001, 0);\n    // Size                    2 bytes    Size of this \"extra\" block\n    zeiefBuffer.writeUInt16LE(ZIP64_EXTENDED_INFORMATION_EXTRA_FIELD_SIZE - 4, 2);\n    // Original Size           8 bytes    Original uncompressed file size\n    writeUInt64LE(zeiefBuffer, this.uncompressedSize, 4);\n    // Compressed Size         8 bytes    Size of compressed data\n    writeUInt64LE(zeiefBuffer, this.compressedSize, 12);\n    // Relative Header Offset  8 bytes    Offset of local header record\n    writeUInt64LE(zeiefBuffer, this.relativeOffsetOfLocalHeader, 20);\n    // Disk Start Number       4 bytes    Number of the disk on which this file starts\n    // (omit)\n  } else {\n    versionNeededToExtract = VERSION_NEEDED_TO_EXTRACT_UTF8;\n    zeiefBuffer = EMPTY_BUFFER;\n  }\n\n  // central file header signature   4 bytes  (0x02014b50)\n  fixedSizeStuff.writeUInt32LE(0x02014b50, 0);\n  // version made by                 2 bytes\n  fixedSizeStuff.writeUInt16LE(VERSION_MADE_BY, 4);\n  // version needed to extract       2 bytes\n  fixedSizeStuff.writeUInt16LE(versionNeededToExtract, 6);\n  // general purpose bit flag        2 bytes\n  fixedSizeStuff.writeUInt16LE(generalPurposeBitFlag, 8);\n  // compression method              2 bytes\n  fixedSizeStuff.writeUInt16LE(this.getCompressionMethod(), 10);\n  // last mod file time              2 bytes\n  fixedSizeStuff.writeUInt16LE(this.lastModFileTime, 12);\n  // last mod file date              2 bytes\n  fixedSizeStuff.writeUInt16LE(this.lastModFileDate, 14);\n  // crc-32                          4 bytes\n  fixedSizeStuff.writeUInt32LE(this.crc32, 16);\n  // compressed size                 4 bytes\n  fixedSizeStuff.writeUInt32LE(normalCompressedSize, 20);\n  // uncompressed size               4 bytes\n  fixedSizeStuff.writeUInt32LE(normalUncompressedSize, 24);\n  // file name length                2 bytes\n  fixedSizeStuff.writeUInt16LE(this.utf8FileName.length, 28);\n  // extra field length              2 bytes\n  fixedSizeStuff.writeUInt16LE(zeiefBuffer.length, 30);\n  // file comment length             2 bytes\n  fixedSizeStuff.writeUInt16LE(this.fileComment.length, 32);\n  // disk number start               2 bytes\n  fixedSizeStuff.writeUInt16LE(0, 34);\n  // internal file attributes        2 bytes\n  fixedSizeStuff.writeUInt16LE(0, 36);\n  // external file attributes        4 bytes\n  fixedSizeStuff.writeUInt32LE(this.externalFileAttributes, 38);\n  // relative offset of local header 4 bytes\n  fixedSizeStuff.writeUInt32LE(normalRelativeOffsetOfLocalHeader, 42);\n\n  return Buffer.concat([\n    fixedSizeStuff,\n    // file name (variable size)\n    this.utf8FileName,\n    // extra field (variable size)\n    zeiefBuffer,\n    // file comment (variable size)\n    this.fileComment,\n  ]);\n};\nEntry.prototype.getCompressionMethod = function() {\n  var NO_COMPRESSION = 0;\n  var DEFLATE_COMPRESSION = 8;\n  return this.compress ? DEFLATE_COMPRESSION : NO_COMPRESSION;\n};\n\nfunction dateToDosDateTime(jsDate) {\n  var date = 0;\n  date |= jsDate.getDate() & 0x1f; // 1-31\n  date |= ((jsDate.getMonth() + 1) & 0xf) << 5; // 0-11, 1-12\n  date |= ((jsDate.getFullYear() - 1980) & 0x7f) << 9; // 0-128, 1980-2108\n\n  var time = 0;\n  time |= Math.floor(jsDate.getSeconds() / 2); // 0-59, 0-29 (lose odd numbers)\n  time |= (jsDate.getMinutes() & 0x3f) << 5; // 0-59\n  time |= (jsDate.getHours() & 0x1f) << 11; // 0-23\n\n  return {date: date, time: time};\n}\n\nfunction writeUInt64LE(buffer, n, offset) {\n  // can't use bitshift here, because JavaScript only allows bitshifting on 32-bit integers.\n  var high = Math.floor(n / 0x100000000);\n  var low = n % 0x100000000;\n  buffer.writeUInt32LE(low, offset);\n  buffer.writeUInt32LE(high, offset + 4);\n}\n\nfunction defaultCallback(err) {\n  if (err) throw err;\n}\n\nutil.inherits(ByteCounter, Transform);\nfunction ByteCounter(options) {\n  Transform.call(this, options);\n  this.byteCount = 0;\n}\nByteCounter.prototype._transform = function(chunk, encoding, cb) {\n  this.byteCount += chunk.length;\n  cb(null, chunk);\n};\n\nutil.inherits(Crc32Watcher, Transform);\nfunction Crc32Watcher(options) {\n  Transform.call(this, options);\n  this.crc32 = 0;\n}\nCrc32Watcher.prototype._transform = function(chunk, encoding, cb) {\n  this.crc32 = crc32.unsigned(chunk, this.crc32);\n  cb(null, chunk);\n};\n\nvar cp437 = '\\u0000☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñÑªº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ';\nif (cp437.length !== 256) throw new Error(\"assertion failure\");\nvar reverseCp437 = null;\n\nfunction encodeCp437(string) {\n  if (/^[\\x20-\\x7e]*$/.test(string)) {\n    // CP437, ASCII, and UTF-8 overlap in this range.\n    return bufferFrom(string, \"utf-8\");\n  }\n\n  // This is the slow path.\n  if (reverseCp437 == null) {\n    // cache this once\n    reverseCp437 = {};\n    for (var i = 0; i < cp437.length; i++) {\n      reverseCp437[cp437[i]] = i;\n    }\n  }\n\n  var result = bufferAlloc(string.length);\n  for (var i = 0; i < string.length; i++) {\n    var b = reverseCp437[string[i]];\n    if (b == null) throw new Error(\"character not encodable in CP437: \" + JSON.stringify(string[i]));\n    result[i] = b;\n  }\n\n  return result;\n}\n\nfunction bufferAlloc(size) {\n  bufferAlloc = modern;\n  try {\n    return bufferAlloc(size);\n  } catch (e) {\n    bufferAlloc = legacy;\n    return bufferAlloc(size);\n  }\n  function modern(size) {\n    return Buffer.allocUnsafe(size);\n  }\n  function legacy(size) {\n    return new Buffer(size);\n  }\n}\nfunction bufferFrom(something, encoding) {\n  bufferFrom = modern;\n  try {\n    return bufferFrom(something, encoding);\n  } catch (e) {\n    bufferFrom = legacy;\n    return bufferFrom(something, encoding);\n  }\n  function modern(something, encoding) {\n    return Buffer.from(something, encoding);\n  }\n  function legacy(something, encoding) {\n    return new Buffer(something, encoding);\n  }\n}\nfunction bufferIncludes(buffer, content) {\n  bufferIncludes = modern;\n  try {\n    return bufferIncludes(buffer, content);\n  } catch (e) {\n    bufferIncludes = legacy;\n    return bufferIncludes(buffer, content);\n  }\n  function modern(buffer, content) {\n    return buffer.includes(content);\n  }\n  function legacy(buffer, content) {\n    for (var i = 0; i <= buffer.length - content.length; i++) {\n      for (var j = 0;; j++) {\n        if (j === content.length) return true;\n        if (buffer[i + j] !== content[j]) break;\n      }\n    }\n    return false;\n  }\n}\n","/**\n * The installer module provides commonly used installation functions for Minecraft.\n * @packageDocumentation\n * @module @xmcl/installer\n */\n\nexport * from './fabric'\nexport * from './liteloader'\nexport * from './forge'\nexport * from './neoForged'\nexport * from './minecraft'\nexport * from './profile'\nexport * from './optifine'\nexport * from './java'\nexport * from './java-runtime'\nexport * from './diagnose'\nexport * from './quilt'\nexport { InstallOptions } from './utils'\nexport * from './downloadTask'\nexport * from './unzip'\nexport * from './labymod'\n","import { MinecraftFolder, MinecraftLocation } from '@xmcl/core'\nimport type { Version } from '@xmcl/core'\nimport { writeFile } from 'fs/promises'\nimport { FetchOptions, InstallOptions, doFetch, ensureFile } from './utils'\n\nexport interface FabricArtifactVersion {\n  gameVersion?: string // \"20w10a\",\n  separator?: string\n  build?: number\n  maven: string // \"net.fabricmc:yarn:20w10a+build.7\",\n  version: string // \"20w10a+build.7\",\n  stable: boolean\n}\n\nexport interface FabricArtifacts {\n  mappings: FabricArtifactVersion[]\n  loader: FabricArtifactVersion[]\n}\n\nexport interface FabricLoaderArtifact {\n  loader: FabricArtifactVersion\n  intermediary: FabricArtifactVersion\n  launcherMeta: {\n    version: number\n    libraries: {\n      client: { name: string; url: string }[]\n      common: { name: string; url: string }[]\n      server: { name: string; url: string }[]\n    }\n    mainClass: {\n      client: string\n      server: string\n    }\n  }\n}\n\n/**\n * Get supported fabric game versions\n */\nexport async function getFabricGames(options?: FetchOptions): Promise<string[]> {\n  const response = await doFetch(options, `${DEFAULT_META_URL_FABRIC}/v2/game`)\n  const body = await response.json() as Array<{ version: string }>\n  return body.map((g) => g.version)\n}\n\n/**\n * Get fabric-loader artifact list\n */\nexport async function getFabricLoaders(options?: FetchOptions): Promise<FabricArtifactVersion[]> {\n  const response = await doFetch(options, `${DEFAULT_META_URL_FABRIC}/v2/versions/loader`)\n  const body = response.json()\n  return body\n}\n\n/**\n * Get fabric-loader artifact list by Minecraft version\n * @param minecraft The minecraft version\n */\nexport async function getLoaderArtifactListFor(minecraft: string, options?: FetchOptions): Promise<FabricLoaderArtifact[]> {\n  const response = await doFetch(options, `${DEFAULT_META_URL_FABRIC}/v2/versions/loader/` + minecraft)\n  const body = response.json()\n  return body\n}\n/**\n * Get fabric-loader artifact list by Minecraft version\n * @param minecraft The minecraft version\n * @param loader The yarn-loader version\n */\nexport async function getFabricLoaderArtifact(minecraft: string, loader: string, options?: FetchOptions): Promise<FabricLoaderArtifact> {\n  const response = await doFetch(options, `${DEFAULT_META_URL_FABRIC}/v2/versions/loader/` + minecraft + '/' + loader)\n  const body = response.json()\n  return body\n}\n\nexport interface FabricInstallOptions extends InstallOptions {\n  side?: 'client' | 'server'\n}\n\n/**\n * Generate fabric version json from loader artifact.\n * @param loader The fabric loader artifact\n * @param side The side of the fabric\n * @param options\n * @returns The generated version json\n */\nexport function getVersionJsonFromLoaderArtifact(loader: FabricLoaderArtifact, side: 'client' | 'server', options: FabricInstallOptions = {}) {\n  const mcversion = loader.intermediary.version\n  const id = options.versionId || `${mcversion}-fabric${loader.loader.version}`\n  const libraries = [\n    { name: loader.loader.maven, url: 'https://maven.fabricmc.net/' },\n    { name: loader.intermediary.maven, url: 'https://maven.fabricmc.net/' },\n    ...loader.launcherMeta.libraries.common,\n    ...loader.launcherMeta.libraries[side],\n  ]\n  const mainClass = loader.launcherMeta.mainClass[side]\n  const inheritsFrom = options.inheritsFrom || mcversion\n\n  return {\n    id,\n    inheritsFrom,\n    mainClass,\n    libraries,\n    arguments: {\n      game: [],\n      jvm: [],\n    },\n    releaseTime: new Date().toJSON(),\n    time: new Date().toJSON(),\n  }\n}\n\n/**\n * Install fabric version json.\n *\n * If side is `server`, it requires the Minecraft version json to be installed.\n *\n * @returns The installed version id\n */\nexport async function installFabricByLoaderArtifact(loader: FabricLoaderArtifact, minecraft: MinecraftLocation, options: FabricInstallOptions = {}) {\n  const folder = MinecraftFolder.from(minecraft)\n\n  const side = options.side || 'client'\n  const version = getVersionJsonFromLoaderArtifact(loader, side, options)\n\n  const jsonFile = side === 'client' ? folder.getVersionJson(version.id) : folder.getVersionServerJson(version.id)\n  await ensureFile(jsonFile)\n  await writeFile(jsonFile, JSON.stringify(version, null, 4))\n\n  return version.id\n}\n\nexport interface InstallFabricVersionOptions extends FetchOptions {\n  minecraftVersion: string\n  version: string\n  minecraft: MinecraftLocation\n  side?: 'client' | 'server'\n}\n\nexport const DEFAULT_META_URL_FABRIC = 'https://meta.fabricmc.net'\n\nexport async function installFabric(options: InstallFabricVersionOptions) {\n  const side = options.side ?? 'client'\n  const url = side === 'client'\n    ? `${DEFAULT_META_URL_FABRIC}/v2/versions/loader/${options.minecraftVersion}/${options.version}/profile/json`\n    : `${DEFAULT_META_URL_FABRIC}/v2/versions/loader/${options.minecraftVersion}/${options.version}/server/json`\n  const response = await doFetch(options, url)\n  const content: Version = await response.json() as any\n\n  const minecraft = MinecraftFolder.from(options.minecraft)\n  const versionName = `${options.minecraftVersion}-fabric${options.version}`\n  content.id = versionName\n\n  const jsonPath = side === 'client' ? minecraft.getVersionJson(versionName) : minecraft.getVersionServerJson(versionName)\n\n  await ensureFile(jsonPath)\n  await writeFile(jsonPath, JSON.stringify(content))\n\n  return versionName\n}\n","/* eslint-disable n/no-unsupported-features/node-builtins */\nimport { ChildProcess, ExecOptions, spawn, SpawnOptions } from 'child_process'\nimport { Abortable } from 'events'\nimport { access, mkdir, stat } from 'fs/promises'\nimport { dirname } from 'path'\n\nexport { checksum } from '@xmcl/core'\n\nexport function missing(target: string) {\n  return access(target).then(() => false, () => true)\n}\n\nexport async function ensureDir(target: string) {\n  try {\n    await mkdir(target)\n  } catch (err) {\n    const e: any = err\n    if (await stat(target).then((s) => s.isDirectory()).catch(() => false)) { return }\n    if (e.code === 'EEXIST') { return }\n    if (e.code === 'ENOENT') {\n      if (dirname(target) === target) {\n        throw e\n      }\n      try {\n        await ensureDir(dirname(target))\n        await mkdir(target)\n      } catch {\n        if (await stat(target).then((s) => s.isDirectory()).catch((e) => false)) { return }\n        throw e\n      }\n      return\n    }\n    throw e\n  }\n}\n\nexport interface SpawnJavaOptions {\n  /**\n   * The java exectable path. It will use `java` by default.\n   *\n   * @defaults \"java\"\n   */\n  java?: string\n\n  /**\n   * The spawn process function. Used for spawn the java process at the end.\n   *\n   * By default, it will be the spawn function from \"child_process\" module. You can use this option to change the 3rd party spawn like [cross-spawn](https://www.npmjs.com/package/cross-spawn)\n   */\n  spawn?: (command: string, args?: ReadonlyArray<string>, options?: SpawnOptions) => ChildProcess\n}\n\nexport function ensureFile(target: string) {\n  return ensureDir(dirname(target))\n}\nexport function normalizeArray<T>(arr: T | T[] = []): T[] {\n  return arr instanceof Array ? arr : [arr]\n}\nexport function spawnProcess(spawnJavaOptions: SpawnJavaOptions, args: string[], options?: ExecOptions) {\n  const process = (spawnJavaOptions?.spawn ?? spawn)(spawnJavaOptions.java ?? 'java', args, options)\n  return waitProcess(process)\n}\n\nexport function waitProcess(process: ChildProcess) {\n  return new Promise<void>((resolve, reject) => {\n    const errorMsg: string[] = []\n    process.on('error', (err) => {\n      reject(err)\n    })\n    process.on('close', (code) => {\n      if (code !== 0) { reject(new Error(errorMsg.join(''))) } else { resolve() }\n    })\n    process.on('exit', (code) => {\n      if (code !== 0) { reject(new Error(errorMsg.join(''))) } else { resolve() }\n    })\n    process.stdout?.setEncoding('utf-8')\n    process.stdout?.on('data', (buf) => { })\n    process.stderr?.setEncoding('utf-8')\n    process.stderr?.on('data', (buf) => { errorMsg.push(buf.toString()) })\n  })\n}\n\n/**\n * Join two urls\n */\nexport function joinUrl(a: string, b: string) {\n  if (a.endsWith('/') && b.startsWith('/')) {\n    return a + b.substring(1)\n  }\n  if (!a.endsWith('/') && !b.startsWith('/')) {\n    return a + '/' + b\n  }\n  return a + b\n}\n\nexport interface ParallelTaskOptions {\n  throwErrorImmediately?: boolean\n}\n/**\n * Shared install options\n */\nexport interface InstallOptions {\n  /**\n     * When you want to install a version over another one.\n     *\n     * Like, you want to install liteloader over a forge version.\n     * You should fill this with that forge version id.\n     */\n  inheritsFrom?: string\n\n  /**\n     * Override the newly installed version id.\n     *\n     * If this is absent, the installed version id will be either generated or provided by installer.\n     */\n  versionId?: string\n}\n\nexport function errorToString(e: any) {\n  if (e instanceof Error) {\n    return e.stack ? e.stack : e.message\n  }\n  return e.toString()\n}\n\nexport interface FetchOptions extends Abortable {\n  fetch?: (url: string, init?: RequestInit) => Promise<Response>\n}\n\nexport function doFetch(o: FetchOptions | undefined, url: string, init?: RequestInit) {\n  if (init) {\n    init.signal = o?.signal\n  } else {\n    init = { signal: o?.signal }\n  }\n  return o?.fetch ? o.fetch(url, init) : fetch(url, init)\n}\n","import { MinecraftFolder, MinecraftLocation } from '@xmcl/core'\nimport { Task, task } from '@xmcl/task'\nimport { readFile, writeFile } from 'fs/promises'\nimport { join } from 'path'\nimport { Dispatcher, request } from 'undici'\nimport { ensureDir, InstallOptions, missing } from './utils'\n\nexport const DEFAULT_VERSION_MANIFEST = 'http://dl.liteloader.com/versions/versions.json'\n/**\n * The liteloader version list. Containing the minecraft version -> liteloader version info mapping.\n */\nexport interface LiteloaderVersionList {\n  meta: {\n    description: string\n    authors: string\n    url: string\n    updated: string\n    updatedTime: number\n  }\n  versions: { [version: string]: { snapshot?: LiteloaderVersion; release?: LiteloaderVersion } }\n}\nfunction processLibraries(lib: { name: string; url?: string }) {\n  if (Object.keys(lib).length === 1 && lib.name) {\n    if (lib.name.startsWith('org.ow2.asm')) {\n      lib.url = 'https://files.minecraftforge.net/maven/'\n    }\n  }\n  return lib\n}\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace LiteloaderVersionList {\n  export function parse(content: string) {\n    const result = JSON.parse(content)\n    const metalist = { meta: result.meta, versions: {} }\n    for (const mcversion in result.versions) {\n      const versions: { release?: LiteloaderVersion; snapshot?: LiteloaderVersion } =\n                (metalist.versions as any)[mcversion] = {}\n      const snapshots = result.versions[mcversion].snapshots\n      const artifacts = result.versions[mcversion].artefacts // that's right, artefact\n      const url = result.versions[mcversion].repo.url\n      if (snapshots) {\n        const { stream, file, version, md5, timestamp, tweakClass, libraries } = snapshots['com.mumfrey:liteloader'].latest\n        const type = (stream === 'RELEASE' ? 'RELEASE' : 'SNAPSHOT')\n        versions.snapshot = {\n          url,\n          type,\n          file,\n          version,\n          md5,\n          timestamp,\n          mcversion,\n          tweakClass,\n          libraries: libraries.map(processLibraries),\n        }\n      }\n      if (artifacts) {\n        const { stream, file, version, md5, timestamp, tweakClass, libraries } = artifacts['com.mumfrey:liteloader'].latest\n        const type = (stream === 'RELEASE' ? 'RELEASE' : 'SNAPSHOT')\n        versions.release = {\n          url,\n          type,\n          file,\n          version,\n          md5,\n          timestamp,\n          mcversion,\n          tweakClass,\n          libraries: libraries.map(processLibraries),\n        }\n      }\n    }\n    return metalist\n  }\n}\n\n/**\n * A liteloader remote version information\n */\nexport interface LiteloaderVersion {\n  version: string\n  url: string\n  file: string\n  mcversion: string\n  type: 'RELEASE' | 'SNAPSHOT'\n  md5: string\n  timestamp: string\n  libraries: Array<{ name: string; url?: string }>\n  tweakClass: string\n}\n\nconst snapshotRoot = 'http://dl.liteloader.com/versions/'\nconst releaseRoot = 'http://repo.mumfrey.com/content/repositories/liteloader/'\n\n/**\n * This error is only thrown from liteloader install currently.\n */\nexport class MissingVersionJsonError extends Error {\n  constructor(public version: string,\n    /**\n         * The path of version json\n         */\n    public path: string) {\n    super()\n    this.name = 'MissingVersionJson'\n  }\n}\n/**\n * Get or update the LiteLoader version list.\n *\n * This will request liteloader offical json by default. You can replace the request by assigning the remote option.\n */\nexport async function getLiteloaderVersionList(options: {\n  /**\n     * The request dispatcher\n     */\n  dispatcher?: Dispatcher\n} = {}): Promise<LiteloaderVersionList> {\n  const response = await request(DEFAULT_VERSION_MANIFEST, { dispatcher: options.dispatcher, throwOnError: true })\n  const body = await response.body.text()\n  return LiteloaderVersionList.parse(body)\n}\n\n/**\n * Install the liteloader to specific minecraft location.\n *\n * This will install the liteloader amount on the corresponded Minecraft version by default.\n * If you want to install over the forge. You should first install forge and pass the installed forge version id to the third param,\n * like `1.12-forge-xxxx`\n *\n * @param versionMeta The liteloader version metadata.\n * @param location The minecraft location you want to install\n * @param version The real existed version id (under the the provided minecraft location) you want to installed liteloader inherit\n * @throws {@link MissingVersionJsonError}\n */\nexport function installLiteloader(versionMeta: LiteloaderVersion, location: MinecraftLocation, options?: InstallOptions) {\n  return installLiteloaderTask(versionMeta, location, options).startAndWait()\n}\n\nfunction buildVersionInfo(versionMeta: LiteloaderVersion, mountedJSON: any) {\n  const id = `${mountedJSON.id}-Liteloader${versionMeta.mcversion}-${versionMeta.version}`\n  const time = new Date(Number.parseInt(versionMeta.timestamp, 10) * 1000).toISOString()\n  const releaseTime = time\n  const type = versionMeta.type\n  const libraries = [\n    {\n      name: `com.mumfrey:liteloader:${versionMeta.version}`,\n      url: type === 'SNAPSHOT' ? snapshotRoot : releaseRoot,\n    },\n    ...versionMeta.libraries.map(processLibraries),\n  ]\n  const mainClass = 'net.minecraft.launchwrapper.Launch'\n  const inheritsFrom = mountedJSON.id\n  const jar = mountedJSON.jar || mountedJSON.id\n  const info: any = {\n    id, time, releaseTime, type, libraries, mainClass, inheritsFrom, jar,\n  }\n  if (mountedJSON.arguments) {\n    // liteloader not supported for version > 1.12...\n    // just write this for exception\n    info.arguments = {\n      game: ['--tweakClass', versionMeta.tweakClass],\n      jvm: [],\n    }\n  } else {\n    info.minecraftArguments = `--tweakClass ${versionMeta.tweakClass} ` + mountedJSON.minecraftArguments\n  }\n  return info\n}\n\n/**\n * Install the liteloader to specific minecraft location.\n *\n * This will install the liteloader amount on the corresponded Minecraft version by default.\n * If you want to install over the forge. You should first install forge and pass the installed forge version id to the third param,\n * like `1.12-forge-xxxx`\n *\n * @tasks installLiteloader, installLiteloader.resolveVersionJson installLiteloader.generateLiteloaderJson\n *\n * @param versionMeta The liteloader version metadata.\n * @param location The minecraft location you want to install\n * @param version The real existed version id (under the the provided minecraft location) you want to installed liteloader inherit\n */\nexport function installLiteloaderTask(versionMeta: LiteloaderVersion, location: MinecraftLocation, options: InstallOptions = {}): Task<string> {\n  return task('installLiteloader', async function installLiteloader() {\n    const mc: MinecraftFolder = MinecraftFolder.from(location)\n\n    const mountVersion = options.inheritsFrom || versionMeta.mcversion\n\n    const mountedJSON: any = await this.yield(task('resolveVersionJson', async function resolveVersionJson() {\n      if (await missing(mc.getVersionJson(mountVersion))) {\n        throw new MissingVersionJsonError(mountVersion, mc.getVersionJson(mountVersion))\n      }\n      return readFile(mc.getVersionJson(mountVersion)).then((b) => b.toString()).then(JSON.parse)\n    }))\n\n    const versionInf = await this.yield(task('generateLiteloaderJson', async function generateLiteloaderJson() {\n      const inf = buildVersionInfo(versionMeta, mountedJSON)\n\n      inf.id = options.versionId || inf.id\n      inf.inheritsFrom = options.inheritsFrom || inf.inheritsFrom\n\n      const versionPath = mc.getVersionRoot(inf.id)\n\n      await ensureDir(versionPath)\n      await writeFile(join(versionPath, inf.id + '.json'), JSON.stringify(inf, undefined, 4))\n\n      return inf\n    }))\n    return versionInf.id as string\n  })\n}\n","import { LibraryInfo, MinecraftFolder, MinecraftLocation, Version as VersionJson } from '@xmcl/core'\nimport { getDownloadBaseOptions } from '@xmcl/file-transfer'\nimport { parse as parseForge } from '@xmcl/forge-site-parser'\nimport { Task, task } from '@xmcl/task'\nimport { filterEntries, open, openEntryReadStream, readAllEntries, readEntry } from '@xmcl/unzip'\nimport { createWriteStream } from 'fs'\nimport { writeFile } from 'fs/promises'\nimport { basename, dirname, join, relative, sep } from 'path'\nimport { pipeline } from 'stream/promises'\nimport { Dispatcher, request } from 'undici'\nimport { Entry, ZipFile } from 'yauzl'\nimport { ZipFile as WriteableZipFile } from 'yazl'\nimport { DownloadTask } from './downloadTask'\nimport { LibraryOptions, resolveLibraryDownloadUrls } from './minecraft'\nimport { InstallProfile, InstallProfileOption, installByProfileTask } from './profile'\nimport { InstallOptions as InstallOptionsBase, ensureDir, ensureFile, joinUrl, normalizeArray } from './utils'\nimport { ZipValidator } from './zipValdiator'\n\nexport interface ForgeVersionList {\n  mcversion: string\n  versions: ForgeVersion[]\n}\n/**\n * The forge version metadata to download a forge\n */\nexport interface ForgeVersion {\n  /**\n     * The installer info\n     */\n  installer: {\n    md5: string\n    sha1: string\n    /**\n         * The url path to concat with forge maven\n         */\n    path: string\n  }\n  universal: {\n    md5: string\n    sha1: string\n    /**\n         * The url path to concat with forge maven\n         */\n    path: string\n  }\n  /**\n     * The minecraft version\n     */\n  mcversion: string\n  /**\n     * The forge version (without minecraft version)\n     */\n  version: string\n\n  type: 'buggy' | 'recommended' | 'common' | 'latest'\n}\n\n/**\n * All the useful entries in forge installer jar\n */\nexport interface ForgeInstallerEntries {\n  /**\n     *  maven/net/minecraftforge/forge/${forgeVersion}/forge-${forgeVersion}.jar\n     */\n  forgeJar?: Entry\n  /**\n     *  maven/net/minecraftforge/forge/${forgeVersion}/forge-${forgeVersion}-universal.jar\n     */\n  forgeUniversalJar?: Entry\n  /**\n     * data/client.lzma\n     */\n  clientLzma?: Entry\n  /**\n     * data/server.lzma\n     */\n  serverLzma?: Entry\n  /**\n     * install_profile.json\n     */\n  installProfileJson?: Entry\n  /**\n     * version.json\n     */\n  versionJson?: Entry\n  /**\n   * forge-${forgeVersion}-universal.jar\n   */\n  legacyUniversalJar?: Entry\n  /**\n   * data/run.sh\n   */\n  runSh?: Entry\n  /**\n   * data/run.bat\n   */\n  runBat?: Entry\n  /**\n     * data/unix_args.txt\n     */\n  unixArgs?: Entry\n  /**\n   * data/user_jvm_args.txt\n   */\n  userJvmArgs?: Entry\n  /**\n   * data/win_args.txt\n   */\n  winArgs?: Entry\n}\n\nexport type ForgeInstallerEntriesPattern = ForgeInstallerEntries & Required<Pick<ForgeInstallerEntries, 'versionJson' | 'installProfileJson'>>\nexport type ForgeLegacyInstallerEntriesPattern = Required<Pick<ForgeInstallerEntries, 'installProfileJson' | 'legacyUniversalJar'>>\n\ntype RequiredVersion = {\n  /**\n     * The installer info.\n     *\n     * If this is not presented, it will genreate from mcversion and forge version.\n     */\n  installer?: {\n    sha1?: string\n    /**\n     * The url path to concat with forge maven\n     */\n    path: string\n  }\n  /**\n   * The minecraft version\n   */\n  mcversion: string\n  /**\n   * The forge version (without minecraft version)\n   */\n  version: string\n}\n\nexport const DEFAULT_FORGE_MAVEN = 'http://files.minecraftforge.net/maven'\n\n/**\n * The options to install forge.\n */\nexport interface InstallForgeOptions extends LibraryOptions, InstallOptionsBase, InstallProfileOption {\n  side?: 'client' | 'server'\n}\n\nexport class DownloadForgeInstallerTask extends DownloadTask {\n  readonly installJarPath: string\n\n  constructor(forgeVersion: string, installer: RequiredVersion['installer'], minecraft: MinecraftFolder, options: InstallForgeOptions, legacy?: boolean) {\n    const classifier = legacy ? 'universal' : 'installer'\n    const ext = legacy ? 'zip' : 'jar'\n    const path = installer\n      ? installer.path\n      : `net/minecraftforge/forge/${forgeVersion}/forge-${forgeVersion}-${classifier}.${ext}`\n    let url: string\n    if (installer) {\n      try {\n        const parsedUrl = new URL(path)\n        url = parsedUrl.toString()\n      } catch (e) {\n        const forgeMavenPath = path.replace('/maven', '').replace('maven', '')\n        url = joinUrl(DEFAULT_FORGE_MAVEN, forgeMavenPath)\n      }\n    } else {\n      const forgeMavenPath = path.replace('/maven', '').replace('maven', '')\n      url = joinUrl(DEFAULT_FORGE_MAVEN, forgeMavenPath)\n    }\n\n    const library = VersionJson.resolveLibrary({\n      name: `net.minecraftforge:forge:${forgeVersion}:${classifier}`,\n      downloads: {\n        artifact: {\n          url,\n          path: `net/minecraftforge/forge/${forgeVersion}/forge-${forgeVersion}-${classifier}.${ext}`,\n          size: -1,\n          sha1: installer?.sha1 || '',\n        },\n      },\n    })!\n    const mavenHost = options.mavenHost ? normalizeArray(options.mavenHost) : []\n\n    if (mavenHost.indexOf(DEFAULT_FORGE_MAVEN) === -1) {\n      mavenHost.push(DEFAULT_FORGE_MAVEN)\n    }\n\n    const urls = resolveLibraryDownloadUrls(library, { ...options, mavenHost })\n\n    const installJarPath = minecraft.getLibraryByPath(library.path)\n\n    super({\n      url: urls,\n      destination: installJarPath,\n      validator: installer?.sha1\n        ? options.checksumValidatorResolver?.({ algorithm: 'sha1', hash: installer?.sha1 }) || { algorithm: 'sha1', hash: installer?.sha1 }\n        : new ZipValidator(),\n      ...getDownloadBaseOptions(options),\n    })\n\n    this.installJarPath = installJarPath\n    this.name = 'downloadInstaller'\n    this.param = { version: forgeVersion }\n  }\n}\n\nfunction getLibraryPathWithoutMaven(mc: MinecraftFolder, name: string) {\n  // remove the maven/ prefix\n  return mc.getLibraryByPath(name.substring(name.indexOf('/') + 1))\n}\nfunction extractEntryTo(zip: ZipFile, e: Entry, dest: string) {\n  return openEntryReadStream(zip, e).then((stream) => pipeline(stream, createWriteStream(dest)))\n}\n\nasync function installLegacyForgeFromUniversalZip(forgeZip: ZipFile, mc: MinecraftFolder, forgeVersion: string, mcVersion: string) {\n  const minecraftZip = await open(mc.getVersionJar(mcVersion), { lazyEntries: true, autoClose: false })\n  const forgeEntries = await readAllEntries(forgeZip)\n  const mcEntries = await readAllEntries(minecraftZip)\n  const finalZipEntries: Record<string, [Entry, ZipFile]> = {}\n  // forge entries overwrite mc entries\n  for (const e of mcEntries) {\n    if (e.fileName.startsWith('META-INF')) continue\n    finalZipEntries[e.fileName] = [e, minecraftZip]\n  }\n  for (const e of forgeEntries) {\n    if (e.fileName.startsWith('META-INF')) continue\n    finalZipEntries[e.fileName] = [e, forgeZip]\n  }\n  const finalZip = new WriteableZipFile()\n  for (const [k, [e, zip]] of Object.entries(finalZipEntries)) {\n    finalZip.addReadStream(await openEntryReadStream(zip, e), e.fileName)\n  }\n  finalZip.end()\n  const dest = mc.getLibraryByPath(`net/minecraftforge/forge/${forgeVersion}/forge-${forgeVersion}.jar`)\n  await ensureDir(dirname(dest))\n  await pipeline(finalZip.outputStream, createWriteStream(dest))\n  const versionId = `${mcVersion}-forge-${forgeVersion}`\n  await ensureDir(mc.getVersionRoot(versionId))\n  const versionJson: VersionJson = {\n    id: versionId,\n    inheritsFrom: mcVersion,\n    time: new Date().toUTCString(),\n    type: 'release',\n    releaseTime: new Date().toUTCString(),\n    minimumLauncherVersion: 4,\n    arguments: {\n      game: [\n      ],\n      // eslint-disable-next-line no-template-curly-in-string\n      jvm: ['-Dminecraft.applet.TargetDirectory=${game_directory}'],\n    },\n    mainClass: 'net.minecraft.launchwrapper.Launch',\n    libraries: [\n      { name: `net.minecraftforge:forge:${forgeVersion}` },\n      {\n        downloads: {\n          artifact: {\n            path: 'guava-12.0.1.jar',\n            sha1: 'b8e78b9af7bf45900e14c6f958486b6ca682195f',\n            size: -1,\n            url: 'https://files.minecraftforge.net/maven/com/google/guava/guava/12.0.1/guava-12.0.1.jar',\n          },\n        },\n        name: 'com.google.guava:guava:12.0.1',\n      },\n      {\n        downloads: {\n          artifact: {\n            path: 'argo-2.25.jar',\n            sha1: 'bb672829fde76cb163004752b86b0484bd0a7f4b',\n            size: -1,\n            url: 'https://files.minecraftforge.net/maven/net/sourceforge/argo/argo/2.25/argo-2.25.jar',\n          },\n        },\n        name: 'net.sourceforge.argo:argo:2.25',\n      },\n      {\n        downloads: {\n          artifact: {\n            path: 'asm-all-4.0.jar',\n            sha1: '98308890597acb64047f7e896638e0d98753ae82',\n            size: -1,\n            url: 'https://files.multimc.org/fmllibs/asm-all-4.0.jar',\n          },\n        },\n        name: 'org.ow2.asm:asm-all:4.0',\n      },\n      {\n        downloads: {\n          artifact: {\n            path: 'bcprov-jdk15on-147.jar',\n            sha1: 'b6f5d9926b0afbde9f4dbe3db88c5247be7794bb',\n            size: -1,\n            url: 'https://files.multimc.org/fmllibs/bcprov-jdk15on-147.jar',\n          },\n        },\n        name: 'org.bouncycastle:bcprov-jdk15on:1.47',\n      },\n    ],\n  }\n  await writeFile(mc.getVersionJson(versionId), JSON.stringify(versionJson, null, 4))\n  return versionId\n}\n\nasync function installLegacyForgeFromZip(zip: ZipFile, entries: ForgeLegacyInstallerEntriesPattern, profile: InstallProfile, mc: MinecraftFolder, jarFilePath: string, options: InstallForgeOptions) {\n  const versionJson = profile.versionInfo\n  if (!versionJson) {\n    throw new Error(`Malform legacy installer json ${profile.version}`)\n  }\n\n  // apply override for inheritsFrom\n  versionJson.id = options.versionId || versionJson.id\n  versionJson.inheritsFrom = options.inheritsFrom || versionJson.inheritsFrom\n\n  const rootPath = mc.getVersionRoot(versionJson.id)\n  const versionJsonPath = join(rootPath, `${versionJson.id}.json`)\n  await ensureFile(versionJsonPath)\n\n  const forgeLib = versionJson.libraries.find((l) => l.name.startsWith('net.minecraftforge:forge') || l.name.startsWith('net.minecraftforge:minecraftforge'))\n  if (!forgeLib) {\n    throw new BadForgeInstallerJarError(jarFilePath)\n  }\n  const library = LibraryInfo.resolve(forgeLib)\n  const jarPath = mc.getLibraryByPath(library.path)\n  await ensureFile(jarPath)\n\n  await Promise.all([\n    writeFile(versionJsonPath, JSON.stringify(versionJson, undefined, 4)),\n    extractEntryTo(zip, entries.legacyUniversalJar, jarPath),\n  ])\n\n  return versionJson.id\n}\n\n/**\n * Unpack forge installer jar file content to the version library artifact directory.\n * @param zip The forge jar file\n * @param entries The entries\n * @param profile The forge install profile\n * @param mc The minecraft location\n * @returns The installed version id\n */\nexport async function unpackForgeInstaller(zip: ZipFile, entries: ForgeInstallerEntriesPattern, profile: InstallProfile, mc: MinecraftFolder, jarPath: string, options: InstallForgeOptions) {\n  const versionJson: VersionJson = await readEntry(zip, entries.versionJson).then((b) => b.toString()).then(JSON.parse)\n\n  // apply override for inheritsFrom\n  versionJson.id = options.versionId || versionJson.id\n  versionJson.inheritsFrom = options.inheritsFrom || versionJson.inheritsFrom\n\n  // resolve all the required paths\n  const rootPath = mc.getVersionRoot(versionJson.id)\n\n  const versionJsonPath = join(rootPath, `${versionJson.id}.json`)\n  const installJsonPath = join(rootPath, 'install_profile.json')\n\n  const mavenLibVersionPath = dirname(jarPath)\n\n  const unpackData = (entry: Entry) => {\n    promises.push(extractEntryTo(zip, entry, join(mavenLibVersionPath, entry.fileName.substring('data/'.length))))\n  }\n\n  await ensureFile(versionJsonPath)\n\n  const promises: Promise<void>[] = []\n  if (entries.forgeUniversalJar) {\n    promises.push(extractEntryTo(zip, entries.forgeUniversalJar, getLibraryPathWithoutMaven(mc, entries.forgeUniversalJar.fileName)))\n  }\n\n  if (!profile.data) {\n    profile.data = {}\n  }\n\n  const mavenPaths = relative(mc.libraries, mavenLibVersionPath).split(sep)\n  const mavenVersion = mavenPaths.pop()\n  const mavenArtifact = mavenPaths.pop()\n  const mavenGroup = mavenPaths.join('.')\n  const mavenPath = `${mavenGroup}:${mavenArtifact}:${mavenVersion}`\n\n  const installerMaven = `${mavenPath}:installer`\n  profile.data.INSTALLER = {\n    client: `[${installerMaven}]`,\n    server: `[${installerMaven}]`,\n  }\n\n  if (entries.serverLzma) {\n    // forge version and mavens, compatible with twitch api\n    const serverMaven = `${mavenPath}:serverdata@lzma`\n    // override forge bin patch location\n    profile.data.BINPATCH.server = `[${serverMaven}]`\n\n    const serverBinPath = mc.getLibraryByPath(LibraryInfo.resolve(serverMaven).path)\n    await ensureFile(serverBinPath)\n    promises.push(extractEntryTo(zip, entries.serverLzma, serverBinPath))\n  }\n\n  if (entries.clientLzma) {\n    // forge version and mavens, compatible with twitch api\n    const clientMaven = `${mavenPath}:clientdata@lzma`\n    // override forge bin patch location\n    profile.data.BINPATCH.client = `[${clientMaven}]`\n\n    const clientBinPath = mc.getLibraryByPath(LibraryInfo.resolve(clientMaven).path)\n    await ensureFile(clientBinPath)\n    promises.push(extractEntryTo(zip, entries.clientLzma, clientBinPath))\n  }\n\n  if (entries.forgeJar) {\n    promises.push(extractEntryTo(zip, entries.forgeJar, getLibraryPathWithoutMaven(mc, entries.forgeJar.fileName)))\n  }\n  if (entries.runBat) { unpackData(entries.runBat) }\n  if (entries.runSh) { unpackData(entries.runSh) }\n  if (entries.winArgs) { unpackData(entries.winArgs) }\n  if (entries.unixArgs) { unpackData(entries.unixArgs) }\n  if (entries.userJvmArgs) { unpackData(entries.userJvmArgs) }\n\n  promises.push(\n    writeFile(installJsonPath, JSON.stringify(profile)),\n    writeFile(versionJsonPath, JSON.stringify(versionJson)),\n  )\n\n  await Promise.all(promises)\n\n  return versionJson.id\n}\n\nexport function isLegacyForgeInstallerEntries(entries: ForgeInstallerEntries): entries is ForgeLegacyInstallerEntriesPattern {\n  return !!entries.legacyUniversalJar && !!entries.installProfileJson\n}\n\nexport function isForgeInstallerEntries(entries: ForgeInstallerEntries): entries is ForgeInstallerEntriesPattern {\n  return !!entries.installProfileJson && !!entries.versionJson\n}\n\n/**\n * Walk the forge installer file to find key entries\n * @param zip THe forge instal\n * @param forgeVersion Forge version to install\n */\nexport async function walkForgeInstallerEntries(zip: ZipFile, forgeVersion: string): Promise<ForgeInstallerEntries> {\n  const [forgeJar, forgeUniversalJar, clientLzma, serverLzma, installProfileJson, versionJson, legacyUniversalJar, runSh, runBat, unixArgs, userJvmArgs, winArgs] = await filterEntries(zip, [\n    `maven/net/minecraftforge/forge/${forgeVersion}/forge-${forgeVersion}.jar`,\n    `maven/net/minecraftforge/forge/${forgeVersion}/forge-${forgeVersion}-universal.jar`,\n    'data/client.lzma',\n    'data/server.lzma',\n    'install_profile.json',\n    'version.json',\n    (e) => e.fileName === `forge-${forgeVersion}-universal.jar` || (e.fileName.startsWith('forge-') && e.fileName.endsWith('-universal.jar')) || (e.fileName.startsWith('minecraftforge-universal-')), // legacy installer format\n    'data/run.sh',\n    'data/run.bat',\n    'data/unix_args.txt',\n    'data/user_jvm_args.txt',\n    'data/win_args.txt',\n  ])\n  return {\n    forgeJar,\n    forgeUniversalJar,\n    clientLzma,\n    serverLzma,\n    installProfileJson,\n    versionJson,\n    legacyUniversalJar,\n    runSh,\n    runBat,\n    unixArgs,\n    userJvmArgs,\n    winArgs,\n  }\n}\n\nexport class BadForgeInstallerJarError extends Error {\n  name = 'BadForgeInstallerJarError'\n\n  constructor(\n    public jarPath: string,\n    /**\n         * What entry in jar is missing\n         */\n    public entry?: string) {\n    super(entry ? `Missing entry ${entry} in forge installer jar: ${jarPath}` : `Bad forge installer: ${jarPath}`)\n  }\n}\n\nexport function installByInstallerTask(version: RequiredVersion, minecraft: MinecraftLocation, options: InstallForgeOptions) {\n  return task('installForge', async function () {\n    function getForgeArtifactVersion() {\n      const [_, minor] = version.mcversion.split('.')\n      const minorVersion = Number.parseInt(minor)\n      if (minorVersion >= 7 && minorVersion <= 8) {\n        return `${version.mcversion}-${version.version}-${version.mcversion}`\n      }\n      if (version.version.startsWith(version.mcversion)) {\n        return version.version\n      }\n      return `${version.mcversion}-${version.version}`\n    }\n    const forgeVersion = getForgeArtifactVersion()\n    const isLegacy = version.mcversion.startsWith('1.4.')\n    const mc = MinecraftFolder.from(minecraft)\n    const jarPath: string = await this.yield(new DownloadForgeInstallerTask(forgeVersion, version.installer, mc, options, isLegacy)\n      .map(function () { return this.installJarPath }))\n\n    if (isLegacy) {\n      const forgeZip = await open(jarPath, { lazyEntries: true, autoClose: false })\n      const versionId = await installLegacyForgeFromUniversalZip(forgeZip, mc, forgeVersion, version.mcversion)\n      return versionId\n    }\n\n    const zip = await open(jarPath, { lazyEntries: true, autoClose: false })\n    const entries = await walkForgeInstallerEntries(zip, forgeVersion)\n\n    if (!entries.installProfileJson) {\n      throw new BadForgeInstallerJarError(jarPath, 'install_profile.json')\n    }\n    const profile: InstallProfile = await readEntry(zip, entries.installProfileJson).then((b) => b.toString()).then(JSON.parse)\n    if (isForgeInstallerEntries(entries)) {\n      // new forge\n      const versionId = await unpackForgeInstaller(zip, entries, profile, mc, jarPath, options)\n      await this.concat(installByProfileTask(profile, minecraft, options))\n      return versionId\n    } else if (isLegacyForgeInstallerEntries(entries)) {\n      // legacy forge\n      return installLegacyForgeFromZip(zip, entries, profile, mc, jarPath, options)\n    } else {\n      // bad forge\n      throw new BadForgeInstallerJarError(jarPath)\n    }\n  })\n}\n\n/**\n * Install forge to target location.\n * Installation task for forge with mcversion >= 1.13 requires java installed on your pc.\n * @param version The forge version meta\n * @returns The installed version name.\n * @throws {@link BadForgeInstallerJarError}\n */\nexport function installForge(version: RequiredVersion, minecraft: MinecraftLocation, options?: InstallForgeOptions) {\n  return installForgeTask(version, minecraft, options).startAndWait()\n}\n\n/**\n * Install forge to target location.\n * Installation task for forge with mcversion >= 1.13 requires java installed on your pc.\n * @param version The forge version meta\n * @returns The task to install the forge\n * @throws {@link BadForgeInstallerJarError}\n */\nexport function installForgeTask(version: RequiredVersion, minecraft: MinecraftLocation, options: InstallForgeOptions = {}): Task<string> {\n  return installByInstallerTask(version, minecraft, options)\n}\n\n/**\n * Query the webpage content from files.minecraftforge.net.\n *\n * You can put the last query result to the fallback option. It will check if your old result is up-to-date.\n * It will request a new page only when the fallback option is outdated.\n *\n * @param option The option can control querying minecraft version, and page caching.\n */\nexport async function getForgeVersionList(options: {\n  /**\n     * The minecraft version you are requesting\n     */\n  minecraft?: string\n  dispatcher?: Dispatcher\n} = {}): Promise<ForgeVersionList> {\n  const mcversion = options.minecraft || ''\n  const url = mcversion === '' ? 'http://files.minecraftforge.net/maven/net/minecraftforge/forge/index.html' : `http://files.minecraftforge.net/maven/net/minecraftforge/forge/index_${mcversion}.html`\n  const response = await request(url, {\n    dispatcher: options.dispatcher,\n    maxRedirections: 3,\n  })\n  const body = parseForge(await response.body.text())\n  return body as any\n}\n","import { download, DownloadOptions } from '@xmcl/file-transfer'\nimport { AbortableTask } from '@xmcl/task'\nimport { errors } from 'undici'\n\nexport class DownloadTask extends AbortableTask<void> {\n  protected controller: AbortController | undefined\n\n  constructor(protected options: DownloadOptions) {\n    super()\n    this._from = options.url instanceof Array ? options.url[0] : options.url\n    this._to = options.destination\n  }\n\n  protected abort(): void {\n    if (this.controller) {\n      this.controller.abort()\n    }\n  }\n\n  protected process(): Promise<void> {\n    this.controller = new AbortController()\n    const signal = this.controller.signal\n    return download({\n      ...this.options,\n      progressController: (url, chunkSize, progress, total) => {\n        this._progress = progress\n        this._total = total\n        this._from = url.toString()\n        this.update(chunkSize)\n      },\n      abortSignal: signal,\n    })\n  }\n\n  protected isAbortedError(e: any): boolean {\n    if (e instanceof errors.RequestAbortedError || e.code === 'UND_ERR_ABORTED') {\n      return true\n    }\n    return false\n  }\n}\n\nexport class DownloadMultipleTask extends AbortableTask<void> {\n  protected controller: AbortController | undefined\n  protected progresses: number[] = []\n  protected totals: number[] = []\n\n  constructor(protected options: DownloadOptions[]) {\n    super()\n    this._progress = -1\n    this._total = -1\n  }\n\n  get total(): number {\n    if (this._total === -1) {\n      this._total = this.totals.reduce((a, b) => a + b, 0)\n    }\n    return this._total\n  }\n\n  get progress(): number {\n    if (this._progress === -1) {\n      this._progress = this.progresses.reduce((a, b) => a + b, 0)\n    }\n    return this._progress\n  }\n\n  protected onFinished?: (index: number) => void\n\n  protected async process(): Promise<void> {\n    this.progresses = this.options.map(() => 0)\n    this.totals = this.options.map(() => 0)\n    this.controller = new AbortController()\n    const results = await Promise.allSettled(this.options.map(async (options, i) => {\n      await download({\n        ...options,\n        progressController: (url, chunkSize, written, total) => {\n          this.progresses[i] = written\n          this.totals[i] = total\n\n          this._total = -1\n          this._progress = -1\n\n          this.update(chunkSize)\n          this._from = url.toString()\n        },\n        abortSignal: this.controller?.signal,\n      })\n      this.progresses[i] = this.totals[i]\n      this.update(0)\n      this.onFinished?.(i)\n    }))\n    const rejecteds = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected')\n    if (rejecteds.length > 0) {\n      if (this.isAbortedError(rejecteds[0].reason)) {\n        throw rejecteds[0].reason\n      }\n      throw new AggregateError(rejecteds.map((r) => r.reason).flatMap(r => r instanceof AggregateError ? r.errors : r))\n    }\n  }\n\n  protected abort(isCancelled: boolean): void {\n    if (this.controller) {\n      this.controller.abort()\n    }\n  }\n\n  protected isAbortedError(e: any): boolean {\n    if (e instanceof errors.RequestAbortedError || e.code === 'UND_ERR_ABORTED') {\n      return true\n    }\n    return false\n  }\n}\n","/* eslint-disable n/no-unsupported-features/node-builtins */\nimport { MinecraftFolder, MinecraftLocation, ResolvedLibrary, ResolvedVersion, Version, Version as VersionJson } from '@xmcl/core'\nimport { ChecksumNotMatchError, ChecksumValidatorOptions, DownloadBaseOptions, JsonValidator, Validator, getDownloadBaseOptions } from '@xmcl/file-transfer'\nimport { Task, task } from '@xmcl/task'\nimport { link } from 'fs'\nimport { readFile, stat, writeFile } from 'fs/promises'\nimport { join, relative, sep } from 'path'\nimport { promisify } from 'util'\nimport { DownloadMultipleTask, DownloadTask } from './downloadTask'\nimport { ParallelTaskOptions, ensureDir, joinUrl, normalizeArray } from './utils'\nimport { ZipValidator } from './zipValdiator'\n\n/**\n * The function to swap library host.\n */\nexport type LibraryHost = (library: ResolvedLibrary) => string | string[] | undefined\n\nexport interface MinecraftVersionBaseInfo {\n  /**\n     * The version id, like 1.14.4\n     */\n  id: string\n  /**\n     * The version json download url\n     */\n  url: string\n}\n\n/**\n * The version metadata containing the version information, like download url\n */\nexport interface MinecraftVersion extends MinecraftVersionBaseInfo {\n  /**\n     * The version id, like 1.14.4\n     */\n  id: string\n  type: string\n  time: string\n  releaseTime: string\n  /**\n     * The version json download url\n     */\n  url: string\n}\n\nexport interface AssetInfo {\n  name: string\n  hash: string\n  size: number\n}\n\n/**\n * Minecraft version metadata list\n */\nexport interface MinecraftVersionList {\n  latest: {\n    /**\n         * Snapshot version id of the Minecraft\n         */\n    snapshot: string\n    /**\n         * Release version id of the Minecraft, like 1.14.2\n         */\n    release: string\n  }\n  /**\n     * All the vesrsion list\n     */\n  versions: MinecraftVersion[]\n}\n\n/**\n * Default minecraft version manifest url.\n */\nexport const DEFAULT_VERSION_MANIFEST_URL = 'https://launchermeta.mojang.com/mc/game/version_manifest.json'\n/**\n * Default resource/assets url root\n */\nexport const DEFAULT_RESOURCE_ROOT_URL = 'https://resources.download.minecraft.net'\n\n/**\n * Get and update the version list.\n * This try to send http GET request to offical Minecraft metadata endpoint by default.\n * You can swap the endpoint by passing url on `remote` in option.\n *\n * @returns The new list if there is\n */\nexport async function getVersionList(options: {\n  /**\n   * Request dispatcher\n   */\n  fetch?: typeof fetch,\n  remote?: string\n} = {}): Promise<MinecraftVersionList> {\n  const response = await (options.fetch ?? fetch)(options.remote ?? DEFAULT_VERSION_MANIFEST_URL);\n  return await response.json() as any\n}\n\n/**\n * Change the library host url\n */\nexport interface LibraryOptions extends DownloadBaseOptions, ParallelTaskOptions {\n  /**\n   * A more flexiable way to control library download url.\n   * @see mavenHost\n   */\n  libraryHost?: LibraryHost\n  /**\n   * The alterative maven host to download library. It will try to use these host from the `[0]` to the `[maven.length - 1]`\n   */\n  mavenHost?: string | string[]\n  /**\n   * Control how many libraries download task should run at the same time.\n   * It will override the `maxConcurrencyOption` if this is presented.\n   *\n   * This will be ignored if you have your own downloader assigned.\n   */\n  librariesDownloadConcurrency?: number\n\n  checksumValidatorResolver?: (checksum: ChecksumValidatorOptions) => Validator\n}\n/**\n * Change the host url of assets download\n */\nexport interface AssetsOptions extends DownloadBaseOptions, ParallelTaskOptions {\n  /**\n   * The alternative assets host to download asset. It will try to use these host from the `[0]` to the `[assetsHost.length - 1]`\n   */\n  assetsHost?: string | string[]\n  /**\n   * Control how many assets download task should run at the same time.\n   * It will override the `maxConcurrencyOption` if this is presented.\n   *\n   * This will be ignored if you have your own downloader assigned.\n   */\n  assetsDownloadConcurrency?: number\n  /**\n   * Use hash as the assets index file name. Default is `false`\n   */\n  useHashForAssetsIndex?: boolean\n  /**\n   * The assets index download or url replacement\n   */\n  assetsIndexUrl?: string | string[] | ((version: ResolvedVersion) => string | string[])\n\n  fetch?: typeof fetch\n\n  checksumValidatorResolver?: (checksum: ChecksumValidatorOptions) => Validator\n  /**\n   * Only precheck the size of the assets. Do not check the hash.\n   */\n  prevalidSizeOnly?: boolean\n}\n\nexport type InstallLibraryVersion = Pick<ResolvedVersion, 'libraries' | 'minecraftDirectory'>\n\nfunction resolveDownloadUrls<T>(original: string, version: T, option?: string | string[] | ((version: T) => string | string[])) {\n  const result = [] as string[]\n  if (typeof option === 'function') {\n    result.unshift(...normalizeArray(option(version)))\n  } else {\n    result.unshift(...normalizeArray(option))\n  }\n  if (result.indexOf(original) === -1) {\n    result.push(original)\n  }\n  return result\n}\n/**\n * Replace the minecraft client or server jar download\n */\nexport interface JarOption extends DownloadBaseOptions, ParallelTaskOptions, InstallSideOption {\n  /**\n   * The version json url replacement\n   */\n  json?: string | string[] | ((version: MinecraftVersionBaseInfo) => string | string[])\n  /**\n   * The client jar url replacement\n   */\n  client?: string | string[] | ((version: ResolvedVersion) => string | string[])\n  /**\n   * The server jar url replacement\n   */\n  server?: string | string[] | ((version: ResolvedVersion) => string | string[])\n\n  checksumValidatorResolver?: (checksum: ChecksumValidatorOptions) => Validator\n}\n\nexport interface InstallSideOption {\n  /**\n     * The installation side\n     */\n  side?: 'client' | 'server'\n}\n\nexport type Options = DownloadBaseOptions & ParallelTaskOptions & AssetsOptions & JarOption & LibraryOptions & InstallSideOption\n\n/**\n * Install the Minecraft game to a location by version metadata.\n *\n * This will install version json, version jar, and all dependencies (assets, libraries)\n *\n * @param versionMeta The version metadata\n * @param minecraft The Minecraft location\n * @param option\n */\nexport async function install(versionMeta: MinecraftVersionBaseInfo, minecraft: MinecraftLocation, option: Options = {}): Promise<ResolvedVersion> {\n  return installTask(versionMeta, minecraft, option).startAndWait()\n}\n\n/**\n * Only install the json/jar. Do not install dependencies.\n *\n * @param versionMeta the version metadata; get from updateVersionMeta\n * @param minecraft minecraft location\n */\nexport function installVersion(versionMeta: MinecraftVersionBaseInfo, minecraft: MinecraftLocation, options: JarOption = {}): Promise<ResolvedVersion> {\n  return installVersionTask(versionMeta, minecraft, options).startAndWait()\n}\n\n/**\n * Install the completeness of the Minecraft game assets and libraries on a existed version.\n *\n * @param version The resolved version produced by Version.parse\n * @param minecraft The minecraft location\n */\nexport function installDependencies(version: ResolvedVersion, options?: Options): Promise<ResolvedVersion> {\n  return installDependenciesTask(version, options).startAndWait()\n}\n\n/**\n * Install or check the assets to resolved version\n *\n * @param version The target version\n * @param options The option to replace assets host url\n */\nexport function installAssets(version: ResolvedVersion, options: AssetsOptions = {}): Promise<ResolvedVersion> {\n  return installAssetsTask(version, options).startAndWait()\n}\n\n/**\n * Install all the libraries of providing version\n * @param version The target version\n * @param options The library host swap option\n */\nexport function installLibraries(version: ResolvedVersion, options: LibraryOptions = {}): Promise<void> {\n  return installLibrariesTask(version, options).startAndWait()\n}\n\n/**\n * Only install several resolved libraries\n * @param libraries The resolved libraries\n * @param minecraft The minecraft location\n * @param option The install option\n */\nexport async function installResolvedLibraries(libraries: ResolvedLibrary[], minecraft: MinecraftLocation, option?: LibraryOptions): Promise<void> {\n  await installLibrariesTask({ libraries, minecraftDirectory: typeof minecraft === 'string' ? minecraft : minecraft.root }, option).startAndWait()\n}\n\n/**\n * Install the Minecraft game to a location by version metadata.\n *\n * This will install version json, version jar, and all dependencies (assets, libraries)\n *\n * @param type The type of game, client or server\n * @param versionMeta The version metadata\n * @param minecraft The Minecraft location\n * @param options\n */\nexport function installTask(versionMeta: MinecraftVersionBaseInfo, minecraft: MinecraftLocation, options: Options = {}): Task<ResolvedVersion> {\n  return task('install', async function () {\n    const version = await this.yield(installVersionTask(versionMeta, minecraft, options))\n    if (options.side !== 'server') {\n      await this.yield(installDependenciesTask(version, options))\n    }\n    return version\n  })\n}\n/**\n * Only install the json/jar. Do not install dependencies.\n *\n * @param type client or server\n * @param versionMeta the version metadata; get from updateVersionMeta\n * @param minecraft minecraft location\n */\nexport function installVersionTask(versionMeta: MinecraftVersionBaseInfo, minecraft: MinecraftLocation, options: JarOption = {}): Task<ResolvedVersion> {\n  return task('version', async function () {\n    const folder = MinecraftFolder.from(minecraft)\n    await this.yield(new InstallJsonTask(versionMeta, folder, options))\n    const version = await VersionJson.parse(folder, versionMeta.id)\n    const side = options.side ?? 'client'\n    if (version.downloads[side]) {\n      await this.yield(new InstallJarTask(version as any, folder, options))\n    }\n    if (side === 'server') {\n      const jarPath = folder.getVersionJar(versionMeta.id, 'server')\n      const server: Version = {\n        id: versionMeta.id,\n        type: 'release',\n        time: version.time,\n        releaseTime: version.releaseTime,\n        jar: relative(folder.libraries, jarPath).replaceAll(sep, '/'),\n        arguments: {\n          game: [],\n          jvm: [],\n        },\n        mainClass: '',\n        minimumLauncherVersion: 13,\n        libraries: [],\n      }\n      await writeFile(join(folder.getVersionRoot(versionMeta.id), 'server.json'), JSON.stringify(server, null, 2))\n    }\n    return version\n  }, versionMeta)\n}\n\n/**\n * Install the completeness of the Minecraft game assets and libraries on a existed version.\n *\n * @param version The resolved version produced by Version.parse\n * @param minecraft The minecraft location\n */\nexport function installDependenciesTask(version: ResolvedVersion, options: Options = {}): Task<ResolvedVersion> {\n  return task('dependencies', async function () {\n    await Promise.all([\n      this.yield(installAssetsTask(version, options)),\n      this.yield(installLibrariesTask(version, options)),\n    ])\n    return version\n  })\n}\n\n/**\n * Install or check the assets to resolved version\n *\n * @param version The target version\n * @param options The option to replace assets host url\n */\nexport function installAssetsTask(version: ResolvedVersion, options: AssetsOptions = {}): Task<ResolvedVersion> {\n  return task('assets', async function () {\n    const folder = MinecraftFolder.from(version.minecraftDirectory)\n    if (version.logging?.client?.file) {\n      const file = version.logging.client.file\n\n      await this.yield(new DownloadTask({\n        url: file.url,\n        validator: {\n          algorithm: 'sha1',\n          hash: file.sha1,\n        },\n        destination: folder.getLogConfig(file.id),\n        ...getDownloadBaseOptions(options),\n      }).setName('asset', { name: file.id, hash: file.sha1, size: file.size }))\n    }\n    const jsonPath = folder.getPath('assets', 'indexes', (version.assetIndex?.sha1 ?? version.assets) + '.json')\n\n    if (version.assetIndex) {\n      await this.yield(new InstallAssetIndexTask(version as any, options))\n      await promisify(link)(\n        folder.getPath('assets', 'indexes', version.assetIndex.sha1 + '.json'),\n        folder.getPath('assets', 'indexes', version.assets + '.json'),\n      ).catch(() => { })\n    }\n\n    await ensureDir(folder.getPath('assets', 'objects'))\n    interface AssetIndex {\n      objects: {\n        [key: string]: {\n          hash: string\n          size: number\n        }\n      }\n    }\n\n    const getAssetIndexFallback = async () => {\n      const urls = resolveDownloadUrls(version.assetIndex!.url, version, options.assetsIndexUrl)\n      for (const url of urls) {\n        try {\n          const response = await (options.fetch || fetch)(url, { })\n          const json = await response.json() as any\n          await writeFile(jsonPath, JSON.stringify(json))\n          return json\n        } catch {\n          // ignore\n        }\n      }\n    }\n\n    let objectArray: any[]\n    try {\n      const { objects } = JSON.parse(await readFile(jsonPath).then((b) => b.toString())) as AssetIndex\n      objectArray = Object.keys(objects).map((k) => ({ name: k, ...objects[k] }))\n    } catch (e) {\n      const { objects } = await getAssetIndexFallback()\n      objectArray = Object.keys(objects).map((k) => ({ name: k, ...objects[k] }))\n    }\n    await this.yield(new InstallAssetTask(objectArray, folder, options))\n\n    return version\n  })\n}\n\n/**\n * Install all the libraries of providing version\n * @param version The target version\n * @param options The library host swap option\n */\nexport function installLibrariesTask(version: InstallLibraryVersion, options: LibraryOptions = {}): Task<void> {\n  return new InstallLibraryTask(version.libraries, MinecraftFolder.from(version.minecraftDirectory), options)\n    .setName('libraries', { count: version.libraries.length })\n}\n\n/**\n * Only install several resolved libraries\n * @param libraries The resolved libraries\n * @param minecraft The minecraft location\n * @param option The install option\n */\nexport function installResolvedLibrariesTask(libraries: ResolvedLibrary[], minecraft: MinecraftLocation, option?: LibraryOptions) {\n  return installLibrariesTask({ libraries, minecraftDirectory: typeof minecraft === 'string' ? minecraft : minecraft.root }, option)\n}\n\n/**\n * Only install several resolved assets.\n * @param assets The assets to install\n * @param folder The minecraft folder\n * @param options The asset option\n */\nexport function installResolvedAssetsTask(assets: AssetInfo[], folder: MinecraftFolder, options: AssetsOptions = {}) {\n  return task('assets', async function () {\n    await ensureDir(folder.getPath('assets', 'objects'))\n\n    await this.yield(new InstallAssetTask(assets, folder, options))\n  })\n}\n\nexport class InstallJsonTask extends DownloadTask {\n  constructor(version: MinecraftVersionBaseInfo, minecraft: MinecraftLocation, options: Options) {\n    const folder = MinecraftFolder.from(minecraft)\n    const destination = folder.getVersionJson(version.id)\n    const expectSha1 = version.url.split('/')[5]\n    const urls = resolveDownloadUrls(version.url, version, options.json)\n\n    super({\n      url: urls,\n      validator: expectSha1 ? options.checksumValidatorResolver?.({ algorithm: 'sha1', hash: expectSha1 }) || { algorithm: 'sha1', hash: expectSha1 } : new JsonValidator(),\n      destination,\n      ...getDownloadBaseOptions(options),\n    })\n\n    this.name = 'json'\n    this.param = version\n  }\n}\n\nexport class InstallJarTask extends DownloadTask {\n  constructor(version: ResolvedVersion & { downloads: Required<ResolvedVersion>['downloads'] }, minecraft: MinecraftLocation, options: Options) {\n    const folder = MinecraftFolder.from(minecraft)\n    const type = options.side ?? 'client'\n    const destination = folder.getVersionJar(version.id, type)\n    const download = version.downloads[type]\n    if (!download) {\n      throw new Error(`Cannot find downloadable jar in ${type}`)\n    }\n    const urls = resolveDownloadUrls(download.url, version, options[type])\n    const expectSha1 = download.sha1\n\n    super({\n      url: urls,\n      validator: options.checksumValidatorResolver?.({ algorithm: 'sha1', hash: expectSha1 }) || { algorithm: 'sha1', hash: expectSha1 },\n      destination,\n      ...getDownloadBaseOptions(options),\n    })\n\n    this.name = 'jar'\n    this.param = version\n  }\n}\n\nexport class InstallAssetIndexTask extends DownloadTask {\n  constructor(version: ResolvedVersion & { assetIndex: Version.AssetIndex }, options: AssetsOptions = {}) {\n    const folder = MinecraftFolder.from(version.minecraftDirectory)\n    const expectSha1 = version.assetIndex.sha1\n    const jsonPath = folder.getPath('assets', 'indexes', (options.useHashForAssetsIndex ? expectSha1 : version.assets) + '.json')\n\n    super({\n      url: resolveDownloadUrls(version.assetIndex.url, version, options.assetsIndexUrl),\n      destination: jsonPath,\n      validator: options.checksumValidatorResolver?.({ algorithm: 'sha1', hash: expectSha1 }) || { algorithm: 'sha1', hash: expectSha1 },\n      ...getDownloadBaseOptions(options),\n    })\n\n    this.name = 'assetIndex'\n    this.param = version\n  }\n}\n\nexport class InstallLibraryTask extends DownloadMultipleTask {\n  constructor(libs: ResolvedLibrary[], folder: MinecraftFolder, options: LibraryOptions) {\n    super(libs.map(lib => {\n      const libraryPath = lib.download.path\n      const destination = join(folder.libraries, libraryPath)\n      const urls: string[] = resolveLibraryDownloadUrls(lib, options)\n      const expectSha1 = lib.download.sha1\n      return {\n        url: urls,\n        validator: lib.download.sha1 === ''\n          ? new ZipValidator()\n          : options.checksumValidatorResolver?.({ algorithm: 'sha1', hash: expectSha1 }) || { algorithm: 'sha1', hash: expectSha1 },\n        destination,\n        ...getDownloadBaseOptions(options),\n        skipHead: lib.download.size < 2 * 1024 * 1024,\n      }\n    }))\n\n    this.name = 'library'\n    this._total = libs.reduce((a, b) => a + (b.download?.size ?? 0), 0)\n    this.param = { count: libs.length }\n  }\n}\n\nexport class InstallAssetTask extends DownloadMultipleTask {\n  #total = 0\n\n  constructor(assets: AssetInfo[], folder: MinecraftFolder, options: AssetsOptions) {\n    const assetsHosts = normalizeArray(options.assetsHost || [])\n\n    if (assetsHosts.indexOf(DEFAULT_RESOURCE_ROOT_URL) === -1) {\n      assetsHosts.push(DEFAULT_RESOURCE_ROOT_URL)\n    }\n\n    super(assets.map((asset) => {\n      const { hash, size, name } = asset\n      const head = hash.substring(0, 2)\n      const dir = folder.getPath('assets', 'objects', head)\n      const file = join(dir, hash)\n      const urls = assetsHosts.map((h) => `${h}/${head}/${hash}`)\n      return {\n        url: urls,\n        destination: file,\n        validator: options.prevalidSizeOnly\n          ? {\n            async validate(destination, url) {\n              const fstat = await stat(destination).catch(() => ({ size: -1 }))\n              if (fstat.size !== size) {\n                throw new ChecksumNotMatchError('size', size.toString(), fstat.size.toString(), destination, url)\n              }\n            },\n          }\n          : options.checksumValidatorResolver?.({ algorithm: 'sha1', hash }) || { algorithm: 'sha1', hash },\n        ...getDownloadBaseOptions(options),\n        skipHead: asset.size < 2 * 1024 * 1024,\n      }\n    }))\n\n    this.#total = assets.reduce((a, b) => a + b.size, 0)\n    this.name = 'asset'\n    this.param = { count: assets.length }\n  }\n\n  get total(): number {\n    return this.#total\n  }\n}\n\nconst DEFAULT_MAVENS = ['https://repo1.maven.org/maven2/']\n\n/**\n * Resolve a library download urls with fallback.\n *\n * @param library The resolved library\n * @param libraryOptions The library install options\n */\nexport function resolveLibraryDownloadUrls(library: ResolvedLibrary, libraryOptions: LibraryOptions): string[] {\n  const urls = libraryOptions.libraryHost?.(library) ?? [\n    ...normalizeArray(libraryOptions.mavenHost).map((m) => joinUrl(m, library.download.path)),\n    library.download.url,\n    ...DEFAULT_MAVENS.map((m) => joinUrl(m, library.download.path)),\n  ]\n\n  return [...new Set(normalizeArray(urls))]\n}\n","import { ValidationError, Validator } from '@xmcl/file-transfer'\nimport { open } from '@xmcl/unzip'\n\nexport class ZipValidator implements Validator {\n  async validate(destination: string, url: string): Promise<void> {\n    try {\n      const file = await open(destination, { autoClose: false, lazyEntries: true })\n      file.close()\n    } catch (e) {\n      throw new ValidationError('InvalidZipError', (e as any).message)\n    }\n  }\n}\n","import { LibraryInfo, MinecraftFolder, MinecraftLocation, Version, Version as VersionJson } from '@xmcl/core'\nimport { AbortableTask, CancelledError, Task, task } from '@xmcl/task'\nimport { filterEntries, open, readEntry, walkEntriesGenerator } from '@xmcl/unzip'\nimport { spawn } from 'child_process'\nimport { readFile, writeFile } from 'fs/promises'\nimport { delimiter, dirname, join, relative, sep } from 'path'\nimport { ZipFile } from 'yauzl'\nimport { convertClasspathToMaven, parseManifest } from './manifest'\nimport { InstallLibraryTask, InstallSideOption, LibraryOptions } from './minecraft'\nimport { SpawnJavaOptions, checksum, missing, waitProcess } from './utils'\n\nexport interface PostProcessor {\n  /**\n   * The executable jar path\n   */\n  jar: string\n  /**\n   * The classpath to run\n   */\n  classpath: string[]\n  args: string[]\n  outputs?: { [key: string]: string }\n  sides?: Array<'client' | 'server'>\n}\n\nexport interface InstallProfile {\n  spec?: number\n  /**\n   * The type of this installation, like \"forge\"\n   */\n  profile: string\n  /**\n   * The version of this installation\n   */\n  version: string\n  /**\n   * The version json path\n   */\n  json: string\n  /**\n   * The maven artifact name: `<org>:<artifact-id>:<version>`\n   */\n  path: string\n  /**\n   * The minecraft version\n   */\n  minecraft: string\n  /**\n   * The processor shared variables. The key is the name of variable to replace.\n   *\n   * The value of client/server is the value of the variable.\n   */\n  data?: { [key: string]: { client: string; server: string } }\n  /**\n   * The post processor. Which require java to run.\n   */\n  processors?: Array<PostProcessor>\n  /**\n   * The required install profile libraries\n   */\n  libraries: VersionJson.NormalLibrary[]\n  /**\n   * Legacy format\n   */\n  versionInfo?: VersionJson\n}\n\nexport interface PostProcessOptions extends SpawnJavaOptions {\n  /**\n   * Custom handlers to handle the post processor\n   */\n  handler?: (postProcessor: PostProcessor) => Promise<boolean>\n  onPostProcessFailed?: (proc: PostProcessor, jar: string, classPaths: string, mainClass: string, args: string[], error: unknown) => void\n  onPostProcessSuccess?: (proc: PostProcessor, jar: string, classPaths: string, mainClass: string, args: string[]) => void\n  customPostProcessTask?: (processor: PostProcessor[], minecraftFolder: MinecraftFolder, options: PostProcessOptions, originalTask: () => Task<void>) => Task<void>\n}\n\nexport interface InstallProfileOption extends LibraryOptions, InstallSideOption, PostProcessOptions {\n  /**\n   * New forge (>=1.13) require java to install. Can be a executor or java executable path.\n   */\n  java?: string\n}\n\n/**\n * Resolve processors in install profile\n */\nexport function resolveProcessors(side: 'client' | 'server', installProfile: InstallProfile, minecraft: MinecraftFolder) {\n  function normalizePath(val: string) {\n    if (val && val.match(/^\\[.+\\]$/g)) { // match sth like [net.minecraft:client:1.15.2:slim]\n      const name = val.substring(1, val.length - 1)\n      return minecraft.getLibraryByPath(LibraryInfo.resolve(name).path)\n    }\n    return val\n  }\n\n  const normalizeVariable = (val: string) => {\n    if (!val) return val\n    // replace \"{A}/{B}, which the value of A and B are from varaiables\n    // for example, variables = { A: \"a\", B: \"b\" }\n    // \"{A}/{B}\" => \"a/b\"\n    // The key variable name can be any alphabet characters and number other special characters\n    // Another example, \"{A}\" => \"a\"\n    return val.replace(/{([A-Za-z0-9_-]+)}/g, (_, key) => variables[key]?.[side] ?? '')\n  }\n\n  // store the mapping of {VARIABLE_NAME} -> real path in disk\n  const variables: Record<string, { client: string; server: string }> = {\n    SIDE: {\n      client: 'client',\n      server: 'server',\n    },\n    MINECRAFT_JAR: {\n      client: minecraft.getVersionJar(installProfile.minecraft),\n      server: minecraft.getVersionJar(installProfile.minecraft, 'server'),\n    },\n    ROOT: {\n      client: minecraft.root,\n      server: minecraft.root,\n    },\n    MINECRAFT_VERSION: {\n      client: installProfile.minecraft,\n      server: installProfile.minecraft,\n    },\n    LIBRARY_DIR: {\n      client: minecraft.libraries,\n      server: minecraft.libraries,\n    },\n  }\n  if (installProfile.data) {\n    for (const key in installProfile.data) {\n      const { client, server } = installProfile.data[key]\n      variables[key] = {\n        client: normalizePath(client),\n        server: normalizePath(server),\n      }\n    }\n  }\n\n  const resolveOutputs = (proc: PostProcessor, args: string[]) => {\n    const original = proc.outputs\n      ? Object.entries(proc.outputs).map(([k, v]) => ({ [normalizeVariable(k)]: normalizeVariable(v) })).reduce((a, b) => Object.assign(a, b), {})\n      : {}\n    for (const [key, val] of Object.entries(original)) {\n      original[key] = val.replace(/'/g, '')\n    }\n    const outputIndex = args.indexOf('--output') === -1 ? args.indexOf('--out-jar') : args.indexOf('--output')\n    const outputFile = outputIndex !== -1 ? args[outputIndex + 1] : undefined\n    if (outputFile && !original[outputFile]) {\n      original[outputFile] = ''\n    }\n    return original\n  }\n  const processors = (installProfile.processors || []).map((proc) => {\n    const args = proc.args.map(normalizePath).map(normalizeVariable)\n    return {\n      ...proc,\n      args,\n      outputs: resolveOutputs(proc, args),\n    }\n  }).filter((proc) => proc.sides ? proc.sides.indexOf(side) !== -1 : true)\n  return processors\n}\n\n/**\n * Post process the post processors from `InstallProfile`.\n *\n * @param processors The processor info\n * @param minecraft The minecraft location\n * @param java The java executable path\n * @throws {@link PostProcessError}\n */\nexport function postProcess(processors: PostProcessor[], minecraft: MinecraftFolder, options: PostProcessOptions) {\n  return new PostProcessingTask(processors, minecraft, options).startAndWait()\n}\n\n/**\n * Install by install profile. The install profile usually contains some preprocess should run before installing dependencies.\n *\n * @param installProfile The install profile\n * @param minecraft The minecraft location\n * @param options The options to install\n * @throws {@link PostProcessError}\n */\nexport function installByProfile(installProfile: InstallProfile, minecraft: MinecraftLocation, options: InstallProfileOption = {}) {\n  return installByProfileTask(installProfile, minecraft, options).startAndWait()\n}\n\nfunction parseArgumentsFromArgsFile(content: string, parentDir: string, serverProfile: Version) {\n  const args = content.split('\\n').map(v => v.trim().split(' ')).flatMap(v => v).filter(v => v)\n  // find the Main class or -jar\n  let mainClass: string = ''\n  let jar: string | undefined\n  let found = false\n  for (let i = 0; i < args.length; i++) {\n    if (args[i].startsWith('-')) {\n      if (args[i] === '-jar') {\n        jar = join(parentDir, args[i + 1])\n        found = true\n        i++\n        continue\n      }\n    } else if (!mainClass) {\n      mainClass = args[i]\n      found = true\n      continue\n    }\n    if (!found) {\n      if (!args[i].startsWith('-D')) {\n        serverProfile.arguments!.jvm.push(args[i], args[i + 1])\n        i++\n      } else {\n        serverProfile.arguments!.jvm.push(args[i])\n      }\n    } else {\n      serverProfile.arguments!.game.push(args[i])\n    }\n  }\n\n  serverProfile.mainClass = mainClass\n\n  return jar\n}\n\nasync function parseJar(minecraftFolder: MinecraftFolder, jar: string, installProfile: InstallProfile, serverVersion: Version) {\n  let zip: ZipFile | undefined\n  try {\n    const jsonContent: Version = JSON.parse(await readFile(minecraftFolder.getVersionJson(installProfile.version), 'utf-8'))\n    zip = await open(jar, { lazyEntries: true, autoClose: false })\n    const [entry] = await filterEntries(zip, ['META-INF/MANIFEST.MF'])\n    if (entry) {\n      const manifestContent = await readEntry(zip, entry).then((b) => b.toString())\n      const result = parseManifest(manifestContent)\n      serverVersion.mainClass = result.mainClass\n      const cp = [...result.classPath, relative(minecraftFolder.libraries, jar).replaceAll(sep, '/')]\n      serverVersion.libraries.push(...jsonContent.libraries.filter(l => !l.name.endsWith(':client')))\n      const mavenPaths = convertClasspathToMaven(cp)\n      for (const name of mavenPaths) {\n        if (serverVersion.libraries.find(l => l.name === name)) continue\n        if (name.startsWith(':')) continue\n        serverVersion.libraries.push({ name })\n      }\n    }\n  } catch (e) {\n    throw new PostProcessBadJarError(jar, e as any)\n  } finally {\n    zip?.close()\n  }\n}\n\n/**\n * Install by install profile. The install profile usually contains some preprocess should run before installing dependencies.\n *\n * @param installProfile The install profile\n * @param minecraft The minecraft location\n * @param options The options to install\n */\nexport function installByProfileTask(installProfile: InstallProfile, minecraft: MinecraftLocation, options: InstallProfileOption = {}) {\n  return task('installByProfile', async function () {\n    const minecraftFolder = MinecraftFolder.from(minecraft)\n\n    const side = options.side === 'server' ? 'server' : 'client'\n\n    const processor = resolveProcessors(side, installProfile, minecraftFolder)\n\n    const installRequiredLibs = VersionJson.resolveLibraries(installProfile.libraries)\n\n    await this.yield(new InstallLibraryTask(installRequiredLibs, minecraftFolder, options))\n\n    if (options.customPostProcessTask) {\n      await this.yield(options.customPostProcessTask(processor, minecraftFolder, options, () => new PostProcessingTask(processor, minecraftFolder, options)))\n    } else {\n      await this.yield(new PostProcessingTask(processor, minecraftFolder, options))\n    }\n\n    if (side === 'client') {\n      const versionJson: VersionJson = await readFile(minecraftFolder.getVersionJson(installProfile.version)).then((b) => b.toString()).then(JSON.parse)\n      const libraries = VersionJson.resolveLibraries(versionJson.libraries)\n      await this.yield(new InstallLibraryTask(libraries, minecraftFolder, options))\n    } else {\n      const argsText = process.platform === 'win32' ? 'win_args.txt' : 'unix_args.txt'\n\n      if (!installProfile.processors) { return }\n\n      let txtPath: string | undefined\n      for (const p of installProfile.processors) {\n        txtPath = p.args.find(a => a.startsWith('{ROOT}') && a.endsWith(argsText))\n        if (txtPath) {\n          txtPath = txtPath.replace('{ROOT}', minecraftFolder.root)\n          if (await missing(txtPath)) {\n            throw new Error(`No ${argsText} found in the forge jar`)\n          }\n          break\n        }\n      }\n      const serverProfile: Version = {\n        id: installProfile.version,\n        libraries: [],\n        type: 'release',\n        arguments: {\n          game: [],\n          jvm: [],\n        },\n        releaseTime: new Date().toJSON(),\n        time: new Date().toJSON(),\n        minimumLauncherVersion: 13,\n        mainClass: '',\n        inheritsFrom: installProfile.minecraft,\n      }\n\n      let jar: string | undefined\n\n      if (!txtPath) {\n        // legacy\n        const info = LibraryInfo.resolve(installProfile.path)\n        const libPath = minecraftFolder.getLibraryByPath(info.path)\n        jar = libPath\n      } else {\n        const content = await readFile(txtPath, 'utf-8')\n        jar = parseArgumentsFromArgsFile(content, dirname(txtPath), serverProfile)\n      }\n\n      if (jar) {\n        await parseJar(minecraftFolder, jar, installProfile, serverProfile)\n      }\n\n      if (!serverProfile.mainClass) {\n        throw new PostProcessNoMainClassError(jar!)\n      }\n\n      await writeFile(join(minecraftFolder.getVersionRoot(serverProfile.id), 'server.json'), JSON.stringify(serverProfile, null, 4))\n\n      const resolvedLibraries = VersionJson.resolveLibraries(serverProfile.libraries)\n      await this.yield(new InstallLibraryTask(resolvedLibraries, minecraftFolder, options))\n    }\n  })\n}\n\nexport class PostProcessBadJarError extends Error {\n  constructor(public jarPath: string, public causeBy: Error) {\n    super(`Fail to post process bad jar: ${jarPath}`)\n  }\n\n  name = 'PostProcessBadJarError'\n}\n\nexport class PostProcessNoMainClassError extends Error {\n  constructor(public jarPath: string) {\n    super(`Fail to post process bad jar without main class: ${jarPath}`)\n  }\n\n  name = 'PostProcessNoMainClassError'\n}\n\nexport class PostProcessFailedError extends Error {\n  constructor(public jarPath: string, public commands: string[], message: string) {\n    super(message)\n  }\n\n  name = 'PostProcessFailedError'\n}\n\nexport class PostProcessValidationFailedError extends PostProcessFailedError {\n  constructor(jarPath: string, commands: string[], message: string, readonly file: string, readonly expect: string, readonly actual: string) {\n    super(jarPath, commands, message)\n  }\n\n  name = 'PostProcessValidationFailedError'\n}\n\nconst PAUSEED = Symbol('PAUSED')\n/**\n * Post process the post processors from `InstallProfile`.\n *\n * @param processors The processor info\n * @param minecraft The minecraft location\n * @param java The java executable path\n * @throws {@link PostProcessError}\n */\nexport class PostProcessingTask extends AbortableTask<void> {\n  readonly name: string = 'postProcessing'\n\n  private pointer = 0\n\n  private _abort = () => { }\n\n  constructor(private processors: PostProcessor[], private minecraft: MinecraftFolder, private options: PostProcessOptions) {\n    super()\n    this.param = processors\n    this._total = processors.length\n  }\n\n  protected async findMainClass(lib: string) {\n    let zip: ZipFile | undefined\n    let mainClass: string | undefined\n    try {\n      zip = await open(lib, { lazyEntries: true })\n      for await (const entry of walkEntriesGenerator(zip)) {\n        if (entry.fileName === 'META-INF/MANIFEST.MF') {\n          const content = await readEntry(zip, entry).then((b) => b.toString())\n          mainClass = content.split('\\n')\n            .map((l) => l.split(': '))\n            .find((arr) => arr[0] === 'Main-Class')?.[1].trim()\n          break\n        }\n      }\n    } catch (e) {\n      throw new PostProcessBadJarError(lib, e as any)\n    } finally {\n      zip?.close()\n    }\n    if (!mainClass) {\n      throw new PostProcessNoMainClassError(lib)\n    }\n    return mainClass\n  }\n\n  protected async isInvalid(outputs: Required<PostProcessor>['outputs']) {\n    for (const [file, expect] of Object.entries(outputs)) {\n      if (!expect) {\n        return false\n      }\n      const sha1 = await checksum(file, 'sha1').catch((e) => '') as string\n      const expected = expect.replace(/'/g, '')\n      if (!sha1) return [file, expected, sha1] as const // if file not exist, the file is not generated\n      if (!expect) return false // if expect is empty, we just need file exists\n      if (expected !== sha1) {\n        return [file, expected, sha1] as const\n      }\n    }\n    return false\n  }\n\n  protected async postProcess(mc: MinecraftFolder, proc: PostProcessor, options: PostProcessOptions) {\n    if (await options.handler?.(proc).catch(() => false)) {\n      return\n    }\n    const jarRealPath = mc.getLibraryByPath(LibraryInfo.resolve(proc.jar).path)\n    const mainClass = await this.findMainClass(jarRealPath)\n    this._to = proc.jar\n    const cp = [...proc.classpath, proc.jar].map(LibraryInfo.resolve).map((p) => mc.getLibraryByPath(p.path)).join(delimiter)\n    const cmd = ['-cp', cp, mainClass, ...proc.args]\n    try {\n      await new Promise((resolve, reject) => {\n        const process = (options?.spawn ?? spawn)(options.java ?? 'java', cmd)\n        waitProcess(process).then(resolve, reject)\n        this._abort = () => {\n          reject(PAUSEED)\n          process.kill(1)\n        }\n      })\n      options.onPostProcessSuccess?.(proc, jarRealPath, cp, mainClass, proc.args)\n    } catch (e) {\n      if (e !== PAUSEED) {\n        options.onPostProcessFailed?.(proc, jarRealPath, cp, mainClass, proc.args, e)\n      }\n      if (e instanceof Error && e.name === 'Error') {\n        throw new PostProcessFailedError(proc.jar, [options.java ?? 'java', ...cmd], e.message)\n      }\n      throw e\n    }\n    // if (proc.outputs) {\n    //   const invalidation = await this.isInvalid(proc.outputs)\n    //   if (invalidation) {\n    //     const [file, expect, actual] = invalidation\n    //     throw new PostProcessValidationFailedError(proc.jar, [options.java ?? 'java', ...cmd], 'Validate the output of process failed!', file, expect, actual)\n    //   }\n    // }\n  }\n\n  protected async process(): Promise<void> {\n    for (; this.pointer < this.processors.length; this.pointer++) {\n      const proc = this.processors[this.pointer]\n      if (this.isCancelled) {\n        throw new CancelledError()\n      }\n      if (this.isPaused) {\n        throw PAUSEED\n      }\n      await this.postProcess(this.minecraft, proc, this.options)\n      if (this.isCancelled) {\n        throw new CancelledError()\n      }\n      if (this.isPaused) {\n        throw PAUSEED\n      }\n      this._progress = this.pointer\n      this.update(1)\n    }\n  }\n\n  protected async abort(isCancelled: boolean): Promise<void> {\n    this._abort()\n  }\n\n  protected isAbortedError(e: any): boolean {\n    return e === PAUSEED\n  }\n}\n","export function convertClasspathToMaven(paths: string[]): string[] {\n  return paths.map(path => {\n    const trimmedPath = path.replace(/^libraries\\//, '')\n\n    const parts = trimmedPath.split('/')\n\n    let jarName = parts.pop()\n    const version = parts.pop()\n    const artifactId = parts.pop()\n    const groupIdParts = parts\n\n    const groupId = groupIdParts.join('.')\n\n    let classifier = ''\n\n    if (jarName) {\n      jarName = jarName.replace(/\\.jar$/, '')\n      const jarParts = jarName?.substring(`${artifactId}-${version}`.length + 1).split('-')\n      if (jarParts && jarParts.length > 0) {\n        classifier = jarParts[0]\n      }\n    }\n\n    let mavenCoordinate = `${groupId}:${artifactId}:${version}`\n    if (classifier) {\n      mavenCoordinate += `:${classifier}`\n    }\n\n    return mavenCoordinate\n  })\n}\n\nexport function parseManifest(manifestContent: string): { mainClass: string; classPath: string[] } {\n  const lines = manifestContent.split('\\r\\n')\n  let mainClass = ''\n  let classPath = [] as string[]\n\n  for (let i = 0; i < lines.length; i++) {\n    const line = lines[i].trim()\n    if (line.startsWith('Main-Class:')) {\n      mainClass = line.substring('Main-Class:'.length).trim()\n    } else if (line.startsWith('Class-Path:')) {\n      let classPathLine = line.substring('Class-Path:'.length).trim()\n      while (i + 1 < lines.length && lines[i + 1].startsWith(' ')) {\n        i++\n        classPathLine += lines[i].slice(1)\n      }\n      classPath = classPathLine.split(' ').filter(path => path.length > 0)\n    }\n  }\n\n  return {\n    mainClass,\n    classPath,\n  }\n}\n","import { MinecraftFolder, MinecraftLocation, Version as VersionJson } from '@xmcl/core'\nimport { getDownloadBaseOptions } from '@xmcl/file-transfer'\nimport { Task, task } from '@xmcl/task'\nimport { open, readEntry } from '@xmcl/unzip'\nimport { DownloadTask } from './downloadTask'\nimport { BadForgeInstallerJarError, InstallForgeOptions, isForgeInstallerEntries, unpackForgeInstaller, walkForgeInstallerEntries } from './forge'\nimport { resolveLibraryDownloadUrls } from './minecraft'\nimport { InstallProfile, installByProfileTask } from './profile'\nimport { normalizeArray } from './utils'\nimport { ZipValidator } from './zipValdiator'\n\nexport class DownloadNeoForgedInstallerTask extends DownloadTask {\n  readonly installJarPath: string\n\n  constructor(project: 'forge' | 'neoforge', version: string, minecraft: MinecraftFolder, options: InstallForgeOptions) {\n    const url = `https://maven.neoforged.net/releases/net/neoforged/${project}/${version}/${project}-${version}-installer.jar`\n\n    const library = VersionJson.resolveLibrary({\n      name: `net.neoforged:${project}:${version}:installer`,\n      downloads: {\n        artifact: {\n          url,\n          path: `net/neoforged/${project}/${version}/${project}-${version}-installer.jar`,\n          size: -1,\n          sha1: '',\n        },\n      },\n    })!\n    const mavenHost = options.mavenHost ? normalizeArray(options.mavenHost) : []\n\n    const urls = resolveLibraryDownloadUrls(library, { ...options, mavenHost })\n\n    const installJarPath = minecraft.getLibraryByPath(library.path)\n\n    super({\n      url: urls,\n      destination: installJarPath,\n      validator: new ZipValidator(),\n      ...getDownloadBaseOptions(options),\n    })\n\n    this.installJarPath = installJarPath\n    this.name = 'downloadInstaller'\n    this.param = { version }\n  }\n}\n\nexport async function installNeoForged(project: 'forge' | 'neoforge', version: string, minecraft: MinecraftLocation, options: InstallForgeOptions): Promise<string> {\n  return installNeoForgedTask(project, version, minecraft, options).startAndWait()\n}\n\nexport function installNeoForgedTask(project: 'forge' | 'neoforge', version: string, minecraft: MinecraftLocation, options: InstallForgeOptions): Task<string> {\n  return task('installForge', async function () {\n    const [_, forgeVersion = version] = version.split('-')\n    const mc = MinecraftFolder.from(minecraft)\n    const jarPath = await this.yield(new DownloadNeoForgedInstallerTask(project, version, mc, options)\n      .map(function () { return this.installJarPath }))\n\n    const zip = await open(jarPath, { lazyEntries: true, autoClose: false })\n    const entries = await walkForgeInstallerEntries(zip, forgeVersion)\n\n    if (!entries.installProfileJson) {\n      throw new BadForgeInstallerJarError(jarPath, 'install_profile.json')\n    }\n    const profile: InstallProfile = await readEntry(zip, entries.installProfileJson).then((b) => b.toString()).then(JSON.parse)\n    if (isForgeInstallerEntries(entries)) {\n      // new forge\n      const versionId = await unpackForgeInstaller(zip, entries, profile, mc, jarPath, options)\n      await this.concat(installByProfileTask(profile, minecraft, options))\n      return versionId\n    } else {\n      // bad forge\n      throw new BadForgeInstallerJarError(jarPath)\n    }\n  })\n}\n","import { ClassReader, ClassVisitor, Opcodes } from '@xmcl/asm'\nimport { MinecraftFolder, MinecraftLocation, Version } from '@xmcl/core'\nimport { task } from '@xmcl/task'\nimport { getEntriesRecord, open, readAllEntries, readEntry } from '@xmcl/unzip'\nimport { writeFile } from 'fs/promises'\nimport { ensureFile, InstallOptions, SpawnJavaOptions, spawnProcess } from './utils'\n\nexport interface InstallOptifineOptions extends InstallOptions, SpawnJavaOptions {\n  /**\n   * Use \"optifine.OptiFineForgeTweaker\" instead of \"optifine.OptiFineTweaker\" for tweakClass.\n   *\n   * If you want to install upon forge, you should use this.\n   */\n  useForgeTweaker?: boolean\n}\n\n/**\n * Generate the optifine version json from provided info.\n * @param editionRelease The edition + release with _\n * @param minecraftVersion The minecraft version\n * @param launchWrapperVersion The launch wrapper version\n * @param options The install options\n * @beta Might be changed and don't break the major version\n */\nexport function generateOptifineVersion(editionRelease: string, minecraftVersion: string, launchWrapperVersion?: string, options: InstallOptifineOptions = {}): Version {\n  const id = options.versionId ?? `${minecraftVersion}-Optifine_${editionRelease}`\n  const inheritsFrom = options.inheritsFrom ?? minecraftVersion\n  const mainClass = 'net.minecraft.launchwrapper.Launch'\n  const libraries = [{ name: `optifine:Optifine:${minecraftVersion}_${editionRelease}` }]\n  if (launchWrapperVersion) {\n    libraries.unshift({ name: `optifine:launchwrapper-of:${launchWrapperVersion}` })\n  } else {\n    libraries.unshift({ name: 'net.minecraft:launchwrapper:1.12' })\n  }\n  return {\n    id,\n    inheritsFrom,\n    arguments: {\n      game: ['--tweakClass', options.useForgeTweaker ? 'optifine.OptiFineForgeTweaker' : 'optifine.OptiFineTweaker'],\n      jvm: [],\n    },\n    releaseTime: new Date().toJSON(),\n    time: new Date().toJSON(),\n    type: 'release',\n    libraries,\n    mainClass,\n    minimumLauncherVersion: 21,\n  }\n}\n\n/**\n * Install optifine by optifine installer\n *\n * @param installer The installer jar file path\n * @param minecraft The minecraft location\n * @param options The option to install\n * @beta Might be changed and don't break the major version\n * @throws {@link BadOptifineJarError}\n */\nexport function installOptifine(installer: string, minecraft: MinecraftLocation, options?: InstallOptifineOptions) {\n  return installOptifineTask(installer, minecraft, options).startAndWait()\n}\n\nexport class BadOptifineJarError extends Error {\n  constructor(\n    public optifine: string,\n    /**\n         * What entry in jar is missing\n         */\n    public entry: string,\n  ) {\n    super(`Missing entry ${entry} in optifine installer: ${optifine}`)\n  }\n\n  error = 'BadOptifineJarError'\n}\n\n/**\n * Install optifine by optifine installer task\n *\n * @param installer The installer jar file path\n * @param minecraft The minecraft location\n * @param options The option to install\n * @beta Might be changed and don't break the major version\n * @throws {@link BadOptifineJarError}\n */\nexport function installOptifineTask(installer: string, minecraft: MinecraftLocation, options: InstallOptifineOptions = {}) {\n  return task('installOptifine', async function () {\n    const mc = MinecraftFolder.from(minecraft)\n\n    // context.update(0, 100);\n\n    const zip = await open(installer)\n    const entries = await readAllEntries(zip)\n    const record = getEntriesRecord(entries)\n    // context.update(10, 100);\n\n    const entry = record['net/optifine/Config.class'] ?? record['Config.class'] ?? record['notch/net/optifine/Config.class']\n    if (!entry) {\n      throw new BadOptifineJarError(installer, 'net/optifine/Config.class')\n    }\n\n    const launchWrapperVersionEntry = record['launchwrapper-of.txt']\n    const launchWrapperVersion = launchWrapperVersionEntry\n      ? await readEntry(zip, launchWrapperVersionEntry).then((b) => b.toString())\n      : undefined\n    // context.update(15, 100);\n\n    const buf = await readEntry(zip, entry)\n    const reader = new ClassReader(buf)\n    class OptifineVisitor extends ClassVisitor {\n      fields: Record<string, any> = {}\n      visitField(access: number, name: string, desc: string, signature: string, value: any) {\n        this.fields[name] = value\n        return null\n      }\n    }\n    const visitor = new OptifineVisitor(Opcodes.ASM5)\n    reader.accept(visitor)\n    const mcversion: string = visitor.fields.MC_VERSION // 1.14.4\n    const edition: string = visitor.fields.OF_EDITION // HD_U\n    const release: string = visitor.fields.OF_RELEASE // F5\n    const editionRelease = edition + '_' + release\n\n    const versionJSON = generateOptifineVersion(editionRelease, mcversion, launchWrapperVersion, options)\n    const versionJSONPath = mc.getVersionJson(versionJSON.id)\n\n    // context.update(20, 100);\n    // write version json\n    await this.yield(task('json', async () => {\n      await ensureFile(versionJSONPath)\n      await writeFile(versionJSONPath, JSON.stringify(versionJSON, null, 4))\n    }))\n\n    const launchWrapperEntry = record[`launchwrapper-of-${launchWrapperVersion}.jar`]\n    // write launch wrapper\n    if (launchWrapperEntry) {\n      await this.yield(task('library', async () => {\n        const wrapperDest = mc.getLibraryByPath(`optifine/launchwrapper-of/${launchWrapperVersion}/launchwrapper-of-${launchWrapperVersion}.jar`)\n        await ensureFile(wrapperDest)\n        await writeFile(wrapperDest, await readEntry(zip, launchWrapperEntry))\n      }))\n    }\n\n    // write the optifine\n    await this.yield(task('jar', async () => {\n      const dest = mc.getLibraryByPath(`optifine/Optifine/${mcversion}_${editionRelease}/Optifine-${mcversion}_${editionRelease}.jar`)\n      const mcJar = mc.getVersionJar(mcversion)\n\n      await ensureFile(dest)\n      await spawnProcess(options, ['-cp', installer, 'optifine.Patcher', mcJar, installer, dest]).catch((e) => {\n        e.name = 'OptifinePatchError'\n        throw e\n      })\n    }))\n\n    return versionJSON.id\n  })\n}\n","import { getPlatform, Platform } from '@xmcl/core'\nimport { DownloadBaseOptions, getDownloadBaseOptions } from '@xmcl/file-transfer'\nimport { Task, task } from '@xmcl/task'\nimport { exec } from 'child_process'\nimport { stat, unlink } from 'fs/promises'\nimport { EOL, platform, tmpdir } from 'os'\nimport { basename, join, resolve } from 'path'\nimport { Dispatcher, request } from 'undici'\nimport { DownloadTask } from './downloadTask'\nimport { ensureDir, missing } from './utils'\n\nexport interface JavaInfo {\n  /**\n     * Full java executable path\n     */\n  path: string\n  /**\n     * Java version string\n     */\n  version: string\n  /**\n     * Major version of java\n     */\n  majorVersion: number\n}\n\nexport interface InstallJavaOptions extends DownloadBaseOptions {\n  /**\n     * The destination of this installation\n     */\n  destination: string\n  /**\n     * The cached directory which compressed java lzma will be download to.\n     * @default os.tempdir()\n     */\n  cacheDir?: string\n  /**\n     * The platform to install. It will be auto-resolved by default.\n     * @default currentPlatform\n     */\n  platform?: Platform\n  /**\n     * Unpack lzma function. It must present, else it will not be able to unpack mojang provided LZMA.\n     */\n  unpackLZMA: UnpackLZMAFunction\n  /**\n     * The dispatcher for API\n     */\n  dispatcher?: Dispatcher\n}\n\nexport type UnpackLZMAFunction =\n    ((src: string, dest: string) => Promise<void>) |\n    ((src: string, dest: string) => Task<void>)\n\nexport class DownloadJRETask extends DownloadTask {\n  constructor(jre: DownloadInfo, dir: string, options: InstallJavaOptions) {\n    const { sha1, url } = jre\n    const filename = basename(url)\n    const downloadDestination = resolve(dir, filename)\n\n    super({\n      url,\n      destination: downloadDestination,\n      validator: {\n        algorithm: 'sha1',\n        hash: sha1,\n      },\n      ...getDownloadBaseOptions(options),\n    })\n\n    this.name = 'downloadJre'\n    this.param = jre\n  }\n}\n\ninterface DownloadInfo { sha1: string; url: string; version: string }\n\n/**\n * Install JRE from Mojang offical resource. It should install jdk 8.\n * @param options The install options\n */\nexport function installJreFromMojangTask(options: InstallJavaOptions) {\n  const {\n    destination,\n    unpackLZMA,\n    cacheDir = tmpdir(),\n    platform = getPlatform(),\n  } = options\n  return task('installJreFromMojang', async function () {\n    const info: { [system: string]: { [arch: string]: { jre: DownloadInfo } } } =\n            await this.yield(task('fetchInfo', async () => {\n              const response = await request('https://launchermeta.mojang.com/mc/launcher.json', { dispatcher: options.dispatcher, throwOnError: true })\n              return response.body.json() as any\n            }))\n    const system = platform.name\n    function resolveArch() {\n      switch (platform.arch) {\n        case 'x86':\n        case 'x32': return '32'\n        case 'x64': return '64'\n        default: return '32'\n      }\n    }\n    const currentArch = resolveArch()\n\n    if (!info[system] || !info[system][currentArch] || !info[system][currentArch].jre) {\n      throw new Error('No Java package available for your platform')\n    }\n    const lzmaPath = await this.yield(new DownloadJRETask(info[system][currentArch].jre, cacheDir, options).map(function () { return this.to! }))\n    const result = unpackLZMA(lzmaPath, destination)\n    await ensureDir(destination)\n    if (result instanceof Promise) {\n      await this.yield(task('decompress', () => result))\n    } else {\n      await this.yield(result)\n    }\n    await this.yield(task('cleanup', () => unlink(lzmaPath)))\n  })\n}\n\n/**\n * Install JRE from Mojang offical resource. It should install jdk 8.\n * @param options The install options\n */\nexport function installJreFromMojang(options: InstallJavaOptions) {\n  return installJreFromMojangTask(options).startAndWait()\n}\n\n/**\n * Try to resolve a java info at this path. This will call `java -version`\n * @param path The java exectuable path.\n */\nexport async function resolveJava(path: string): Promise<JavaInfo | undefined> {\n  if (await missing(path)) { return undefined }\n\n  return new Promise((resolve) => {\n    exec(`\"${path}\" -version`, (_err, _sout, serr) => {\n      if (serr) {\n        const ver = parseJavaVersion(serr)\n        if (ver) {\n          resolve({ path, ...ver })\n        } else {\n          resolve(undefined)\n        }\n      } else {\n        resolve(undefined)\n      }\n    })\n  })\n}\n\nexport class ParseJavaVersionError extends Error {\n  name = 'ParseJavaVersionError'\n\n  constructor(message: string) { super(message) }\n}\n\n/**\n * Parse version string and major version number from stderr of java process.\n *\n * @param versionText The stderr for `java -version`\n */\nexport function parseJavaVersion(versionText: string): { version: string; majorVersion: number; patch: number } | undefined {\n  const getVersion = (str?: string) => {\n    if (!str) { return undefined }\n    const match = /(\\d+)\\.(\\d)+\\.(\\d+)(_\\d+)?/.exec(str)\n    if (match === null) {\n      const openjdkMatch = /openjdk version \"(\\d+)\"/.exec(str)\n      if (openjdkMatch) {\n        return {\n          version: openjdkMatch[1],\n          majorVersion: Number.parseInt(openjdkMatch[1]),\n          patch: -1,\n        }\n      }\n      return undefined\n    }\n    if (match[1] === '1') {\n      return {\n        version: match[0],\n        majorVersion: Number.parseInt(match[2]),\n        patch: Number.parseInt(match[4]?.substring(1) ?? '-1'),\n      }\n    }\n    return {\n      version: match[0],\n      majorVersion: Number.parseInt(match[1]),\n      patch: Number.parseInt(match[3]),\n    }\n  }\n  try {\n    const javaVersion = getVersion(versionText)\n    if (!javaVersion) { return undefined }\n    return javaVersion\n  } catch (e) {\n    throw new ParseJavaVersionError(`Fail to parse java version [${versionText}]: ${(e as any).message}`)\n  }\n}\n\n/**\n * Get all potential java locations for Minecraft.\n *\n * On mac/linux, it will perform `which java`. On win32, it will perform `where java`\n *\n * @returns The absolute java locations path\n */\nexport async function getPotentialJavaLocations(): Promise<string[]> {\n  const unchecked = new Set<string>()\n  const currentPlatform = platform()\n  const javaFile = currentPlatform === 'win32' ? 'java.exe' : 'java'\n\n  if (process.env.JAVA_HOME) {\n    unchecked.add(join(process.env.JAVA_HOME, 'bin', javaFile))\n  }\n\n  const which = () => new Promise<string>((resolve) => {\n    exec('which java', (_error, stdout) => {\n      if (!_error) resolve(stdout.replace('\\n', ''))\n      else resolve('')\n    }).once('error', () => resolve(''))\n  })\n  const where = () => new Promise<string[]>((resolve) => {\n    exec('where java', (_error, stdout) => {\n      if (!_error) resolve(stdout.split('\\r\\n'))\n      else resolve([])\n    }).once('error', () => resolve([]))\n  })\n\n  if (currentPlatform === 'win32') {\n    const out = await new Promise<string[]>((resolve) => {\n      exec('REG QUERY HKEY_LOCAL_MACHINE\\\\Software\\\\JavaSoft\\\\ /s /v JavaHome', (_error, stdout) => {\n        if (!stdout) { resolve([]) }\n        resolve(stdout.split(EOL).map((item) => item.replace(/[\\r\\n]/g, ''))\n          .filter((item) => item !== null && item !== undefined)\n          .filter((item) => item[0] === ' ')\n          .map((item) => `${item.split('    ')[3]}\\\\bin\\\\java.exe`))\n      })\n    })\n    for (const o of [...out, ...await where()]) {\n      unchecked.add(o)\n    }\n  } else if (currentPlatform === 'darwin') {\n    unchecked.add('/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java')\n    unchecked.add(await which())\n  } else {\n    unchecked.add(await which())\n  }\n\n  const checkingList = Array.from(unchecked).filter((jPath) => typeof jPath === 'string').filter((p) => p !== '')\n\n  return checkingList\n}\n\nasync function dedupJreExecutables(files: Iterable<string>) {\n  // some file might shared same ino\n  const inos = new Set<number>()\n  const result: string[] = []\n  for (const file of files) {\n    const fstat = await stat(file).catch(() => ({ ino: -1 }))\n    if (inos.has(fstat.ino)) {\n      continue\n    }\n    inos.add(fstat.ino)\n    result.push(file)\n  }\n  return result\n}\n\n/**\n * Scan local java version on the disk.\n *\n * It will check if the passed `locations` are the home of java.\n * Notice that the locations should not be the executable, but the path of java installation, like JAVA_HOME.\n *\n * This will call `getPotentialJavaLocations` and then `resolveJava`\n *\n * @param locations The location (like java_home) want to check.\n * @returns All validate java info\n */\nexport async function scanLocalJava(locations: string[]): Promise<JavaInfo[]> {\n  const unchecked = new Set(locations)\n  const potential = await getPotentialJavaLocations()\n  potential.forEach((p) => unchecked.add(p))\n\n  const checkingList = await dedupJreExecutables([...unchecked].filter((jPath) => typeof jPath === 'string').filter((p) => p !== ''))\n\n  const javas = await Promise.all(checkingList.map((jPath) => resolveJava(jPath)))\n  return javas.filter(((j) => j !== undefined) as (j?: JavaInfo) => j is JavaInfo)\n}\n","import { getPlatform, Platform } from '@xmcl/core'\nimport { ChecksumValidatorOptions, DownloadBaseOptions, DownloadOptions, getDownloadBaseOptions, Validator } from '@xmcl/file-transfer'\nimport { Task, task, TaskRoutine } from '@xmcl/task'\nimport { link, readFile } from 'fs/promises'\nimport { dirname, join } from 'path'\nimport { Dispatcher, request } from 'undici'\nimport { DownloadMultipleTask, DownloadTask } from './downloadTask'\nimport { ensureDir, ParallelTaskOptions } from './utils'\n/**\n * Contain all java runtimes basic info\n */\nexport interface JavaRuntimes {\n  linux: JavaRuntimeTargets\n  'linux-i386': JavaRuntimeTargets\n  'mac-os': JavaRuntimeTargets\n  'mac-os-arm64': JavaRuntimeTargets\n  'windows-x64': JavaRuntimeTargets\n  'windows-x86': JavaRuntimeTargets\n  'windows-arm64': JavaRuntimeTargets\n}\n\nexport interface JavaRuntimeTargets {\n  'java-runtime-alpha': JavaRuntimeTarget[]\n  'java-runtime-beta': JavaRuntimeTarget[]\n  'jre-legacy': JavaRuntimeTarget[]\n  'minecraft-java-exe': JavaRuntimeTarget[]\n  [key: string]: JavaRuntimeTarget[]\n}\n\nexport enum JavaRuntimeTargetType {\n  /**\n   * The legacy java version\n   */\n  Legacy = 'jre-legacy',\n  /**\n   * The new java environment, which is the java 16\n   */\n  Alpha = 'java-runtime-alpha',\n  Beta = 'java-runtime-beta',\n  Delta = 'java-runtime-delta',\n  Gamma = 'java-runtime-gamma',\n  JavaExe = 'minecraft-java-exe',\n}\n\n/**\n * Represent a java runtime\n */\nexport interface JavaRuntimeTarget {\n  /**\n     * Guessing this is the flight of this java runtime\n     */\n  availability: {\n    group: number\n    progress: number\n  }\n  /**\n   * The manifest detail of the resource\n   */\n  manifest: DownloadInfo\n  /**\n   * The basic version info of the manifest\n   */\n  version: {\n    /**\n     * The name of the version. e.g. `8u51`, `12`, `16.0.1.9.1`\n     */\n    name: string\n    /**\n     * The date string (UTC)\n     */\n    released: string\n  }\n}\n\nexport interface Entry {\n  type: 'file' | 'link' | 'directory'\n}\n\nexport interface LinkEntry extends Entry {\n  type: 'link'\n  /**\n   * The link target\n   */\n  target: string\n}\n\nexport interface DirectoryEntry extends Entry {\n  type: 'directory'\n}\n\nexport interface DownloadInfo {\n  /**\n   * The sha info of the resource\n   */\n  sha1: string\n  /**\n   * The size of the resource\n   */\n  size: number\n  /**\n   * The url to download resource\n   */\n  url: string\n}\n\nexport interface FileEntry extends Entry {\n  type: 'file'\n  executable: boolean\n  downloads: {\n    /**\n     * The raw format of the file\n     */\n    raw: DownloadInfo\n    /**\n     * The lzma format of the file\n     */\n    lzma?: DownloadInfo\n  }\n}\n\nexport type AnyEntry = FileEntry | DirectoryEntry | LinkEntry\n\n/**\n * Contains info about every files in this java runtime\n */\nexport interface JavaRuntimeManifest {\n  target: JavaRuntimeTargetType | string\n  /**\n   * The files of the java runtime\n   */\n  files: Record<string, AnyEntry>\n\n  version: JavaRuntimeTarget['version']\n}\n\nexport const DEFAULT_RUNTIME_ALL_URL = 'https://launchermeta.mojang.com/v1/products/java-runtime/2ec0cc96c44e5a76b9c8b7c39df7210883d12871/all.json'\n\nfunction normalizeUrls(url: string, fileHost?: string | string[]): string[] {\n  if (!fileHost) {\n    return [url]\n  }\n  if (typeof fileHost === 'string') {\n    const u = new URL(url)\n    u.hostname = fileHost\n    const result = u.toString()\n    if (result !== url) {\n      return [result, url]\n    }\n    return [result]\n  }\n  const result = fileHost.map((host) => {\n    const u = new URL(url)\n    u.hostname = host\n    return u.toString()\n  })\n\n  if (result.indexOf(url) === -1) {\n    result.push(url)\n  }\n\n  return result\n}\n\nexport interface FetchJavaRuntimeManifestOptions extends DownloadBaseOptions {\n  /**\n   * The alternative download host for the file\n   */\n  apiHost?: string | string[]\n  /**\n   * The url of the all runtime json\n   */\n  url?: string\n  /**\n   * The platform to install. It will be auto-resolved by default.\n   * @default getPlatform()\n   */\n  platform?: Platform\n  /**\n   * The install java runtime type\n   * @default InstallJavaRuntimeTarget.Next\n   */\n  target?: JavaRuntimeTargetType | string\n  /**\n   * The index manifest of the java runtime. If this is not presented, it will fetch by platform and all platform url.\n   */\n  manifestIndex?: JavaRuntimes\n  /**\n   * The dispatcher to request API\n   */\n  dispatcher?: Dispatcher\n}\n\n/**\n * Fetch java runtime manifest. It should be able to resolve to your platform, or you can assign the platform.\n *\n * Also, you should assign the target to download, or it will use the latest java 16.\n * @param options The options of fetch runtime manifest\n */\nexport async function fetchJavaRuntimeManifest(options: FetchJavaRuntimeManifestOptions = {}): Promise<JavaRuntimeManifest> {\n  let manifestIndex = options.manifestIndex\n  if (!manifestIndex) {\n    const response = await request(normalizeUrls(options.url ?? DEFAULT_RUNTIME_ALL_URL, options.apiHost)[0], { dispatcher: options.dispatcher, throwOnError: true })\n    manifestIndex = await response.body.json() as JavaRuntimes\n  }\n  const manifest = manifestIndex\n  const platform = options.platform ?? getPlatform()\n  const runtimeTarget = options.target ?? JavaRuntimeTargetType.Beta\n  const resolveTarget = () => {\n    if (platform.name === 'windows') {\n      if (platform.arch === 'x64') {\n        return manifest['windows-x64']\n      }\n      if (platform.arch === 'x86' || platform.arch === 'x32') {\n        return manifest['windows-x86']\n      }\n      if (platform.arch === 'arm64') {\n        return manifest['windows-arm64']\n      }\n      return manifest['windows-x64']\n    }\n    if (platform.name === 'osx') {\n      if (platform.arch === 'arm64') {\n        return manifest['mac-os-arm64']\n      }\n      return manifest['mac-os']\n    }\n    if (platform.name === 'linux') {\n      if (platform.arch === 'x86' || platform.arch === 'x32') {\n        return manifest['linux-i386']\n      }\n      if (platform.arch === 'x64') {\n        return manifest.linux\n      }\n      return manifest.linux\n    }\n    throw new Error('Cannot resolve platform')\n  }\n  const targets = resolveTarget()[runtimeTarget]\n  if (targets && targets.length > 0) {\n    const target = targets[0]\n    const manifestUrl = normalizeUrls(target.manifest.url, options.apiHost)[0]\n    const response = await request(manifestUrl, { dispatcher: options.dispatcher, throwOnError: true })\n    const manifest: JavaRuntimeManifest = await response.body.json() as any\n    const result: JavaRuntimeManifest = {\n      files: manifest.files,\n      target: runtimeTarget,\n      version: target.version,\n    }\n    return result\n  } else {\n    throw new Error()\n  }\n}\n\n\nasync function downloadFiles(this: TaskRoutine<any>, destination: string, options: InstallJavaRuntimeWithJsonOptions | InstallJavaRuntimeOptions, manifest: JavaRuntimeManifest) {\n  const downloadLzma = false\n  await this.yield(new DownloadMultipleTask(Object.entries(manifest.files)\n    .filter(([file, entry]) => entry.type === 'file')\n    .map(([file, entry]) => {\n      const fEntry = entry as FileEntry\n      const downloadInfo = (downloadLzma && fEntry.downloads.lzma) ? fEntry.downloads.lzma : fEntry.downloads.raw\n      const isLzma = downloadInfo === fEntry.downloads.lzma\n      const dest = isLzma ? (join(destination, file) + '.lzma') : join(destination, file)\n      const urls = normalizeUrls(downloadInfo.url, options.apiHost)\n      const hash = downloadInfo.sha1\n      const downloadOptions: DownloadOptions = {\n        url: urls,\n        validator: options.checksumValidatorResolver?.({ algorithm: 'sha1', hash }) || { algorithm: 'sha1', hash },\n        destination: dest,\n        ...getDownloadBaseOptions(options),\n      }\n      return downloadOptions\n    })\n  ).setName('download'))\n  await Promise.all(Object.entries(manifest.files)\n    .filter(([file, entry]) => entry.type !== 'file')\n    .map(async ([file, entry]) => {\n      const dest = join(destination, file)\n      if (entry.type === 'directory') {\n        await ensureDir(dest)\n      } else if (entry.type === 'link') {\n        await link(dest, join(dirname(dest), entry.target)).catch(() => { })\n      }\n    }))\n}\n\nexport interface InstallJavaRuntimeOptions extends DownloadBaseOptions, ParallelTaskOptions {\n  /**\n     * The alternative download host for the file\n     */\n  apiHost?: string | string[]\n  /**\n     * The destination of this installation\n     */\n  destination: string\n  /**\n     * The actual manfiest to install.\n     */\n  manifest: JavaRuntimeManifest\n  /**\n     * Download lzma compressed version instead of raw version.\n     * - If `true`, it will just download lzma file version, you need to decompress by youself!\n     * - If `Function`, it will use that function to decompress the file!\n     */\n  lzma?: boolean | ((compressedFilePath: string, targetPath: string) => Promise<void>)\n\n  checksumValidatorResolver?: (checksum: ChecksumValidatorOptions) => Validator\n}\n\n/**\n * Install java runtime from java runtime manifest\n * @param options The options to install java runtime\n */\nexport function installJavaRuntimeTask(options: InstallJavaRuntimeOptions): Task<void> {\n  return task('installJavaRuntime', async function () {\n    const destination = options.destination\n    const manifest = options.manifest\n    await downloadFiles.call(this, destination, options, manifest)\n  })\n}\n\n\nexport interface InstallJavaRuntimeWithJsonOptions extends DownloadBaseOptions, ParallelTaskOptions {\n  /**\n   * The alternative download host for the file\n   */\n  apiHost?: string | string[]\n  /**\n   * The destination of this installation\n   */\n  destination: string\n  /**\n   * The actual manfiest metadata.\n   */\n  target: JavaRuntimeTarget\n  /**\n   * Download lzma compressed version instead of raw version.\n   * - If `true`, it will just download lzma file version, you need to decompress by youself!\n   * - If `Function`, it will use that function to decompress the file!\n   */\n  lzma?: boolean | ((compressedFilePath: string, targetPath: string) => Promise<void>)\n\n  checksumValidatorResolver?: (checksum: ChecksumValidatorOptions) => Validator\n}\n\n/**\n * Install java runtime from java runtime manifest\n * @param options The options to install java runtime\n */\nexport function installJavaRuntimeWithJsonTask(options: InstallJavaRuntimeWithJsonOptions): Task<void> {\n  return task('installJavaRuntime', async function () {\n    const destination = options.destination\n    const target = options.target\n    const downloadOptions = getDownloadBaseOptions(options)\n    const jsonPath = join(destination, 'manifest.json')\n    const manifestUrl = normalizeUrls(target.manifest.url, options.apiHost)\n    await this.yield(new DownloadTask({\n      destination: jsonPath,\n      url: manifestUrl,\n      validator: {\n        algorithm: 'sha1',\n        hash: target.manifest.sha1,\n      },\n      ...downloadOptions,\n    }).setName('json'))\n\n    const content = await readFile(jsonPath, 'utf-8')\n    const manifest: JavaRuntimeManifest = JSON.parse(content)\n\n    await downloadFiles.call(this, destination, options, manifest)\n  })\n}\n","import { diagnoseFile, Issue, LibraryIssue, MinecraftFolder, MinecraftLocation, Version } from '@xmcl/core'\nimport { InstallProfile, resolveProcessors, PostProcessor } from './profile'\n\nexport type InstallIssues = ProcessorIssue | LibraryIssue\n\n/**\n * The processor issue\n */\nexport interface ProcessorIssue extends Issue {\n  role: 'processor'\n\n  /**\n     * The processor\n     */\n  processor: PostProcessor\n}\n\nexport interface InstallProfileIssueReport {\n  minecraftLocation: MinecraftFolder\n  installProfile: InstallProfile\n  issues: InstallIssues[]\n}\n\n/**\n * Diagnose a install profile status. Check if it processor output correctly processed.\n *\n * This can be used for check if forge correctly installed when minecraft >= 1.13\n * @beta\n *\n * @param installProfile The install profile.\n * @param minecraftLocation The minecraft location\n */\nexport async function diagnoseInstall(installProfile: InstallProfile, minecraftLocation: MinecraftLocation, side: 'client' | 'server' = 'client'): Promise<InstallProfileIssueReport> {\n  const mc = MinecraftFolder.from(minecraftLocation)\n  const report: InstallProfileIssueReport = {\n    minecraftLocation: mc,\n    installProfile,\n    issues: [],\n  }\n  const issues = report.issues\n  const processors: PostProcessor[] = resolveProcessors(side, installProfile, mc)\n  await Promise.all(Version.resolveLibraries(installProfile.libraries).map(async (lib) => {\n    const libPath = mc.getLibraryByPath(lib.download.path)\n    const issue = await diagnoseFile({\n      role: 'library',\n      file: libPath,\n      expectedChecksum: lib.download.sha1,\n      hint: 'Problem on install_profile! Please consider to use Installer.installByProfile to fix.',\n    })\n    if (issue) {\n      issues.push(Object.assign(issue, { library: lib }))\n    }\n  }))\n  for (const proc of processors) {\n    if (proc.outputs) {\n      for (const [file, checksum] of Object.entries(proc.outputs)) {\n        const issue = await diagnoseFile({\n          role: 'processor',\n          file,\n          expectedChecksum: checksum.replace(/'/g, ''),\n          hint: 'Re-install this installer profile!',\n        })\n        if (issue) {\n          issues.push(Object.assign(issue, { processor: proc }))\n        }\n      }\n    }\n  }\n  return report\n}\n","import { MinecraftFolder, MinecraftLocation, Version } from '@xmcl/core'\nimport { writeFile } from 'fs/promises'\nimport { FetchOptions, doFetch, ensureFile } from './utils'\nimport { FabricArtifactVersion, FabricLoaderArtifact } from './fabric'\n\nexport const DEFAULT_META_URL_QUILT = 'https://meta.quiltmc.org'\n\nexport interface GetQuiltOptions extends FetchOptions {\n  minecraftVersion: string\n}\n\nexport interface QuiltLoaderArtifact extends FabricLoaderArtifact {\n  hashed: FabricLoaderArtifact['intermediary']\n}\n\n/**\n * Get supported fabric game versions\n */\nexport async function getQuiltGames(options?: FetchOptions): Promise<string[]> {\n  const response = await doFetch(options, `${DEFAULT_META_URL_QUILT}/v3/game`)\n  const body = await response.json() as Array<{ version: string }>\n  return body.map((g) => g.version)\n}\n\n/**\n * Get quilt-loader artifact list\n */\nexport async function getQuiltLoaders(options?: FetchOptions): Promise<FabricArtifactVersion[]> {\n  const response = await doFetch(options, `${DEFAULT_META_URL_QUILT}/v3/versions/loader`)\n  const body = response.json()\n  return body\n}\n\n/**\n * Get quilt loader versions list for a specific minecraft version\n */\nexport async function getQuiltLoaderVersionsByMinecraft(options: GetQuiltOptions): Promise<QuiltLoaderArtifact[]> {\n  const response = await doFetch(options, `${DEFAULT_META_URL_QUILT}/v3/versions/loader/${options.minecraftVersion}`)\n  const content: QuiltLoaderArtifact[] = await response.json()\n  return content\n}\n\nexport interface InstallQuiltVersionOptions extends FetchOptions {\n  minecraftVersion: string\n  version: string\n  minecraft: MinecraftLocation\n  side?: 'client' | 'server'\n}\n\n/**\n * Install quilt version via profile API\n */\nexport async function installQuiltVersion(options: InstallQuiltVersionOptions) {\n  const side = options.side ?? 'client'\n  const url = side === 'client'\n    ? `${DEFAULT_META_URL_QUILT}/v3/versions/loader/${options.minecraftVersion}/${options.version}/profile/json`\n    : `${DEFAULT_META_URL_QUILT}/v3/versions/loader/${options.minecraftVersion}/${options.version}/server/json`\n  const response = await doFetch(options, url)\n  const content: Version = await response.json() as any\n\n  const minecraft = MinecraftFolder.from(options.minecraft)\n  const versionName = `${options.minecraftVersion}-quilt${options.version}`\n  content.id = versionName\n\n  const jsonPath = side === 'client' ? minecraft.getVersionJson(versionName) : minecraft.getVersionServerJson(versionName)\n\n  await ensureFile(jsonPath)\n  await writeFile(jsonPath, JSON.stringify(content))\n\n  return versionName\n}\n","import { BaseTask, CancelledError, TaskState } from '@xmcl/task'\nimport { openEntryReadStream } from '@xmcl/unzip'\nimport { createWriteStream } from 'fs'\nimport { join } from 'path'\nimport { Readable, Writable } from 'stream'\nimport { pipeline } from 'stream/promises'\nimport { Entry, ZipFile } from 'yauzl'\nimport { ensureFile } from './utils'\n\nexport interface EntryResolver {\n  (entry: Entry): Promise<string> | string\n}\n\nexport function getDefaultEntryResolver(): EntryResolver {\n  return (e) => e.fileName\n}\n\nexport class UnzipTask extends BaseTask<void> {\n  private streams: [Readable, Writable][] = []\n  private _onCancelled = () => { }\n\n  constructor(readonly zipFile: ZipFile, readonly entries: Entry[], destination: string, readonly resolver: EntryResolver = getDefaultEntryResolver(), readonly interpreter: (input: Readable, file: string) => void = () => { }) {\n    super()\n    this._to = destination\n  }\n\n  protected async handleEntry(entry: Entry, relativePath: string) {\n    const file = join(this.to!, relativePath)\n    if (this._state === TaskState.Cancelled) {\n      throw new CancelledError()\n    }\n\n    const readStream = await openEntryReadStream(this.zipFile, entry)\n    if (this.isCancelled) {\n      throw new CancelledError()\n    }\n    if (this._state === TaskState.Paused) {\n      readStream.pause()\n    }\n\n    await ensureFile(file)\n    this.interpreter(readStream, file)\n    const writeStream = createWriteStream(file)\n    readStream.on('data', (buf: Buffer) => {\n      this._progress += buf.length\n      this.update(buf.length)\n    })\n    this.streams.push([readStream, writeStream])\n    await pipeline(readStream, writeStream)\n  }\n\n  protected async runTask(): Promise<void> {\n    const promises: Promise<void>[] = []\n\n    for (const e of this.entries) {\n      const path = await this.resolver(e)\n      if (this.isCancelled) {\n        throw new CancelledError()\n      }\n      this._total += e.uncompressedSize\n      promises.push(this.handleEntry(e, path))\n    }\n\n    this.update(0)\n\n    try {\n      await Promise.all(promises)\n    } catch (e) {\n      if (e instanceof CancelledError) {\n        this._onCancelled()\n      }\n      throw e\n    }\n  }\n\n  protected cancelTask(): Promise<void> {\n    for (const [read, write] of this.streams) {\n      read.unpipe()\n      read.destroy(new CancelledError())\n      this.zipFile.close()\n      write.destroy(new CancelledError())\n    }\n    return new Promise((resolve) => {\n      this._onCancelled = resolve\n    })\n  }\n\n  protected async pauseTask(): Promise<void> {\n    const promise = Promise.all(this.streams.map(([read]) => new Promise((resolve) =>\n      read.once('pause', resolve))))\n    for (const [read] of this.streams) {\n      read.pause()\n    }\n    await promise\n  }\n\n  protected async resumeTask(): Promise<void> {\n    const promise = Promise.all(this.streams.map(([read]) => new Promise((resolve) =>\n      read.once('readable', resolve))))\n    for (const [read] of this.streams) {\n      read.resume()\n    }\n    await promise\n  }\n}\n","/* eslint-disable n/no-unsupported-features/node-builtins */\nimport { LibraryInfo, MinecraftFolder, MinecraftLocation } from '@xmcl/core'\nimport { DownloadBaseOptions, getDownloadBaseOptions } from '@xmcl/file-transfer'\nimport { AbortableTask, CancelledError, Task, task } from '@xmcl/task'\nimport { writeFile } from 'fs/promises'\nimport { dirname } from 'path'\nimport { Dispatcher, request } from 'undici'\nimport { DownloadTask } from './downloadTask'\nimport { ensureDir } from './utils'\n\nexport interface LabyModManifest {\n  labyModVersion: string\n  commitReference: string\n  sha1: string\n  releaseTime: number\n  size: number\n\n  assets: {\n    shader: string\n    common: string\n    fonts: string\n    'vanilla-theme': string\n    'fancy-theme': string\n    i18n: string\n  }\n\n  minecraftVersions: MinecraftVersion[]\n}\n\ninterface MinecraftVersion {\n  tag: string\n  version: string\n  index: number\n  type: string\n  runtime: {\n    name: string\n    version: number\n  }\n  customManifestUrl: string\n}\n\nexport async function getLabyModManifest(env = 'production', options?: { dispatcher?: Dispatcher }): Promise<LabyModManifest> {\n  const url = `https://laby-releases.s3.de.io.cloud.ovh.net/api/v1/manifest/${env}/latest.json`\n  const res = await request(url, options)\n  return await res.body.json() as any\n}\n\nexport interface InstallLabyModOptions extends DownloadBaseOptions {\n  dispatcher?: Dispatcher\n  environment?: string\n  fetch?: typeof fetch\n}\n\nclass JsonTask extends AbortableTask<string> {\n  private controller = new AbortController()\n\n  constructor(private manifest: LabyModManifest, private tag: string, private folder: MinecraftFolder, private environment: string, private fetch?: typeof globalThis.fetch) {\n    super()\n    this.name = 'json'\n    this.param = { version: tag }\n  }\n\n  protected async process(): Promise<string> {\n    this.controller = new AbortController()\n    const librariesUrl = `https://laby-releases.s3.de.io.cloud.ovh.net/api/v1/libraries/${this.environment}.json`\n    const versionInfo = this.manifest.minecraftVersions.find((v) => v.tag === this.tag)!\n\n    if (!versionInfo) {\n      throw Object.assign(new Error(`Cannot find version info for ${this.tag}`), {\n        name: 'VersionInfoNotFoundError',\n      })\n    }\n\n    interface LibInfo {\n      name: string\n      url: string\n      minecraftVersion: string\n      sha1: string\n      size: number\n      natives: any[]\n      resolvedAt: number\n    }\n\n    const fetch = this.fetch ?? globalThis.fetch\n\n    const metadataResponse = await fetch(librariesUrl, { signal: this.controller.signal })\n\n    if (!metadataResponse.ok) {\n      throw Object.assign(new Error(`Failed to fetch libraries metadata: ${metadataResponse.statusText}: ${await metadataResponse.text()}`), {\n        name: 'FetchLabyModMetadataError',\n      })\n    }\n    // Get version json and merge with libraries\n    const libraries: LibInfo[] = await metadataResponse.json()\n      .then((res) => res.libraries as LibInfo[])\n      .then((libs) => libs.filter(lib => lib.minecraftVersion === 'all' || lib.minecraftVersion === this.tag))\n\n    const versionJsonResponse = await fetch(versionInfo.customManifestUrl, { signal: this.controller.signal })\n\n    if (!versionJsonResponse.ok) {\n      throw Object.assign(new Error(`Failed to fetch version json: ${versionJsonResponse.statusText}: ${await versionJsonResponse.text()}`), {\n        name: 'FetchLabyModVersionJsonError',\n      })\n    }\n    const versionJson = await versionJsonResponse.json()\n\n    versionJson.libraries.push(...libraries.map((l) => ({\n      name: l.name,\n      downloads: {\n        artifact: {\n          path: LibraryInfo.resolve(l.name).path,\n          sha1: l.sha1,\n          size: l.size,\n          url: l.url,\n        },\n      },\n    })), {\n      name: `net.labymod:LabyMod:${this.manifest.labyModVersion}`,\n      downloads: {\n        artifact: {\n          path: `net/labymod/LabyMod/${this.manifest.labyModVersion}/LabyMod-${this.manifest.labyModVersion}.jar`,\n          sha1: this.manifest.sha1,\n          size: this.manifest.size,\n          url: `https://laby-releases.s3.de.io.cloud.ovh.net/api/v1/download/labymod4/${this.environment}/${this.manifest.commitReference}.jar`,\n        },\n      },\n    })\n    versionJson.id = `LabyMod-4-${this.tag}-${this.manifest.commitReference}`\n\n    // write json to file\n    const versionPath = this.folder.getPath('versions', versionJson.id, `${versionJson.id}.json`)\n    await ensureDir(dirname(versionPath))\n    await writeFile(versionPath, JSON.stringify(versionJson, null, 4))\n\n    return versionJson.id\n  }\n\n  protected abort(isCancelled: boolean): void {\n    this.controller.abort(new CancelledError())\n  }\n\n  protected isAbortedError(e: any): boolean {\n    return e instanceof CancelledError\n  }\n}\n\nexport function installLabyMod4Task(manifest: LabyModManifest, tag: string, minecraft: MinecraftLocation, options?: InstallLabyModOptions): Task<string> {\n  return task('installLabyMod', async function () {\n    const folder = MinecraftFolder.from(minecraft)\n    const environment = options?.environment ?? 'production'\n\n    const versionId = await this.yield(new JsonTask(manifest, tag, folder, environment, options?.fetch))\n\n    // Download assets\n    for (const [name, hash] of Object.entries(manifest.assets)) {\n      const url = `https://laby-releases.s3.de.io.cloud.ovh.net/api/v1/download/assets/labymod4/${environment}/${manifest.commitReference}/${name}/${hash}.jar`\n      const destination = folder.getPath('labymod-neo', 'assets', `${name}.jar`)\n      await this.yield(new DownloadTask({\n        url,\n        destination,\n        validator: { algorithm: 'sha1', hash },\n        ...getDownloadBaseOptions(options),\n      }).setName('asset', { name }))\n    }\n\n    return versionId\n  })\n}\n\nexport function installLaby4Mod(manifest: LabyModManifest, tag: string, minecraft: MinecraftLocation, options?: InstallLabyModOptions): Promise<string> {\n  return installLabyMod4Task(manifest, tag, minecraft, options).startAndWait()\n}\n"]}