"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js var require_ieee754 = __commonJS({ "node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js"(exports2) { exports2.read = function(buffer, offset, isLE, mLen, nBytes) { var e, m; var eLen = nBytes * 8 - mLen - 1; var eMax = (1 << eLen) - 1; var eBias = eMax >> 1; var nBits = -7; var i = isLE ? nBytes - 1 : 0; var d = isLE ? -1 : 1; var s = buffer[offset + i]; i += d; e = s & (1 << -nBits) - 1; s >>= -nBits; nBits += eLen; for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) { } m = e & (1 << -nBits) - 1; e >>= -nBits; nBits += mLen; for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) { } if (e === 0) { e = 1 - eBias; } else if (e === eMax) { return m ? NaN : (s ? -1 : 1) * Infinity; } else { m = m + Math.pow(2, mLen); e = e - eBias; } return (s ? -1 : 1) * m * Math.pow(2, e - mLen); }; exports2.write = function(buffer, value, offset, isLE, mLen, nBytes) { var e, m, c; var eLen = nBytes * 8 - mLen - 1; var eMax = (1 << eLen) - 1; var eBias = eMax >> 1; var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0; var i = isLE ? 0 : nBytes - 1; var d = isLE ? 1 : -1; var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0; value = Math.abs(value); if (isNaN(value) || value === Infinity) { m = isNaN(value) ? 1 : 0; e = eMax; } else { e = Math.floor(Math.log(value) / Math.LN2); if (value * (c = Math.pow(2, -e)) < 1) { e--; c *= 2; } if (e + eBias >= 1) { value += rt / c; } else { value += rt * Math.pow(2, 1 - eBias); } if (value * c >= 2) { e++; c /= 2; } if (e + eBias >= eMax) { m = 0; e = eMax; } else if (e + eBias >= 1) { m = (value * c - 1) * Math.pow(2, mLen); e = e + eBias; } else { m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); e = 0; } } for (; mLen >= 8; buffer[offset + i] = m & 255, i += d, m /= 256, mLen -= 8) { } e = e << mLen | m; eLen += mLen; for (; eLen > 0; buffer[offset + i] = e & 255, i += d, e /= 256, eLen -= 8) { } buffer[offset + i - d] |= s * 128; }; } }); // src/tray.ts var tray_exports = {}; __export(tray_exports, { createTrayIcon: () => createTrayIcon, destroyTrayIcon: () => destroyTrayIcon, updateTrayIconImage: () => updateTrayIconImage, updateTrayItem: () => updateTrayItem, updateTrayTooltip: () => updateTrayTooltip }); module.exports = __toCommonJS(tray_exports); // node_modules/.pnpm/file-type@19.6.0/node_modules/file-type/index.js var import_web = require("node:stream/web"); var import_node_stream = require("node:stream"); // node_modules/.pnpm/strtok3@9.0.1/node_modules/strtok3/lib/index.js var import_promises2 = require("node:fs/promises"); // node_modules/.pnpm/peek-readable@5.3.1/node_modules/peek-readable/lib/EndOfStreamError.js var defaultMessages = "End-Of-Stream"; var EndOfStreamError = class extends Error { constructor() { super(defaultMessages); } }; // node_modules/.pnpm/peek-readable@5.3.1/node_modules/peek-readable/lib/Deferred.js var Deferred = class { constructor() { this.resolve = () => null; this.reject = () => null; this.promise = new Promise((resolve, reject) => { this.reject = reject; this.resolve = resolve; }); } }; // node_modules/.pnpm/peek-readable@5.3.1/node_modules/peek-readable/lib/AbstractStreamReader.js var AbstractStreamReader = class { constructor() { this.maxStreamReadSize = 1 * 1024 * 1024; this.endOfStream = false; this.peekQueue = []; } async peek(uint8Array, offset, length) { const bytesRead = await this.read(uint8Array, offset, length); this.peekQueue.push(uint8Array.subarray(offset, offset + bytesRead)); return bytesRead; } async read(buffer, offset, length) { if (length === 0) { return 0; } let bytesRead = this.readFromPeekBuffer(buffer, offset, length); bytesRead += await this.readRemainderFromStream(buffer, offset + bytesRead, length - bytesRead); if (bytesRead === 0) { throw new EndOfStreamError(); } return bytesRead; } /** * Read chunk from stream * @param buffer - Target Uint8Array (or Buffer) to store data read from stream in * @param offset - Offset target * @param length - Number of bytes to read * @returns Number of bytes read */ readFromPeekBuffer(buffer, offset, length) { let remaining = length; let bytesRead = 0; while (this.peekQueue.length > 0 && remaining > 0) { const peekData = this.peekQueue.pop(); if (!peekData) throw new Error("peekData should be defined"); const lenCopy = Math.min(peekData.length, remaining); buffer.set(peekData.subarray(0, lenCopy), offset + bytesRead); bytesRead += lenCopy; remaining -= lenCopy; if (lenCopy < peekData.length) { this.peekQueue.push(peekData.subarray(lenCopy)); } } return bytesRead; } async readRemainderFromStream(buffer, offset, initialRemaining) { let remaining = initialRemaining; let bytesRead = 0; while (remaining > 0 && !this.endOfStream) { const reqLen = Math.min(remaining, this.maxStreamReadSize); const chunkLen = await this.readFromStream(buffer, offset + bytesRead, reqLen); if (chunkLen === 0) break; bytesRead += chunkLen; remaining -= chunkLen; } return bytesRead; } }; // node_modules/.pnpm/peek-readable@5.3.1/node_modules/peek-readable/lib/StreamReader.js var StreamReader = class extends AbstractStreamReader { constructor(s) { super(); this.s = s; this.deferred = null; if (!s.read || !s.once) { throw new Error("Expected an instance of stream.Readable"); } this.s.once("end", () => this.reject(new EndOfStreamError())); this.s.once("error", (err) => this.reject(err)); this.s.once("close", () => this.reject(new Error("Stream closed"))); } /** * Read chunk from stream * @param buffer Target Uint8Array (or Buffer) to store data read from stream in * @param offset Offset target * @param length Number of bytes to read * @returns Number of bytes read */ async readFromStream(buffer, offset, length) { if (this.endOfStream) { return 0; } const readBuffer = this.s.read(length); if (readBuffer) { buffer.set(readBuffer, offset); return readBuffer.length; } const request = { buffer, offset, length, deferred: new Deferred() }; this.deferred = request.deferred; this.s.once("readable", () => { this.readDeferred(request); }); return request.deferred.promise; } /** * Process deferred read request * @param request Deferred read request */ readDeferred(request) { const readBuffer = this.s.read(request.length); if (readBuffer) { request.buffer.set(readBuffer, request.offset); request.deferred.resolve(readBuffer.length); this.deferred = null; } else { this.s.once("readable", () => { this.readDeferred(request); }); } } reject(err) { this.endOfStream = true; if (this.deferred) { this.deferred.reject(err); this.deferred = null; } } async abort() { this.s.destroy(); } }; // node_modules/.pnpm/peek-readable@5.3.1/node_modules/peek-readable/lib/WebStreamReader.js var WebStreamReader = class extends AbstractStreamReader { constructor(stream) { super(); this.reader = stream.getReader({ mode: "byob" }); } async readFromStream(buffer, offset, length) { if (this.endOfStream) { throw new EndOfStreamError(); } const result = await this.reader.read(new Uint8Array(length)); if (result.done) { this.endOfStream = result.done; } if (result.value) { buffer.set(result.value, offset); return result.value.byteLength; } return 0; } async abort() { await this.reader.cancel(); this.reader.releaseLock(); } }; // node_modules/.pnpm/strtok3@9.0.1/node_modules/strtok3/lib/AbstractTokenizer.js var AbstractTokenizer = class { /** * Constructor * @param options Tokenizer options * @protected */ constructor(options) { this.position = 0; this.numBuffer = new Uint8Array(8); this.fileInfo = options?.fileInfo ?? {}; this.onClose = options?.onClose; if (options?.abortSignal) { options.abortSignal.addEventListener("abort", () => { this.abort(); }); } } /** * Read a token from the tokenizer-stream * @param token - The token to read * @param position - If provided, the desired position in the tokenizer-stream * @returns Promise with token data */ async readToken(token, position = this.position) { const uint8Array = new Uint8Array(token.len); const len = await this.readBuffer(uint8Array, { position }); if (len < token.len) throw new EndOfStreamError(); return token.get(uint8Array, 0); } /** * Peek a token from the tokenizer-stream. * @param token - Token to peek from the tokenizer-stream. * @param position - Offset where to begin reading within the file. If position is null, data will be read from the current file position. * @returns Promise with token data */ async peekToken(token, position = this.position) { const uint8Array = new Uint8Array(token.len); const len = await this.peekBuffer(uint8Array, { position }); if (len < token.len) throw new EndOfStreamError(); return token.get(uint8Array, 0); } /** * Read a numeric token from the stream * @param token - Numeric token * @returns Promise with number */ async readNumber(token) { const len = await this.readBuffer(this.numBuffer, { length: token.len }); if (len < token.len) throw new EndOfStreamError(); return token.get(this.numBuffer, 0); } /** * Read a numeric token from the stream * @param token - Numeric token * @returns Promise with number */ async peekNumber(token) { const len = await this.peekBuffer(this.numBuffer, { length: token.len }); if (len < token.len) throw new EndOfStreamError(); return token.get(this.numBuffer, 0); } /** * Ignore number of bytes, advances the pointer in under tokenizer-stream. * @param length - Number of bytes to ignore * @return resolves the number of bytes ignored, equals length if this available, otherwise the number of bytes available */ async ignore(length) { if (this.fileInfo.size !== void 0) { const bytesLeft = this.fileInfo.size - this.position; if (length > bytesLeft) { this.position += bytesLeft; return bytesLeft; } } this.position += length; return length; } async close() { await this.abort(); await this.onClose?.(); } normalizeOptions(uint8Array, options) { if (options && options.position !== void 0 && options.position < this.position) { throw new Error("`options.position` must be equal or greater than `tokenizer.position`"); } if (options) { return { mayBeLess: options.mayBeLess === true, offset: options.offset ? options.offset : 0, length: options.length ? options.length : uint8Array.length - (options.offset ? options.offset : 0), position: options.position ? options.position : this.position }; } return { mayBeLess: false, offset: 0, length: uint8Array.length, position: this.position }; } abort() { return Promise.resolve(); } }; // node_modules/.pnpm/strtok3@9.0.1/node_modules/strtok3/lib/ReadStreamTokenizer.js var maxBufferSize = 256e3; var ReadStreamTokenizer = class extends AbstractTokenizer { /** * Constructor * @param streamReader stream-reader to read from * @param options Tokenizer options */ constructor(streamReader, options) { super(options); this.streamReader = streamReader; } /** * Read buffer from tokenizer * @param uint8Array - Target Uint8Array to fill with data read from the tokenizer-stream * @param options - Read behaviour options * @returns Promise with number of bytes read */ async readBuffer(uint8Array, options) { const normOptions = this.normalizeOptions(uint8Array, options); const skipBytes = normOptions.position - this.position; if (skipBytes > 0) { await this.ignore(skipBytes); return this.readBuffer(uint8Array, options); } if (skipBytes < 0) { throw new Error("`options.position` must be equal or greater than `tokenizer.position`"); } if (normOptions.length === 0) { return 0; } const bytesRead = await this.streamReader.read(uint8Array, normOptions.offset, normOptions.length); this.position += bytesRead; if ((!options || !options.mayBeLess) && bytesRead < normOptions.length) { throw new EndOfStreamError(); } return bytesRead; } /** * Peek (read ahead) buffer from tokenizer * @param uint8Array - Uint8Array (or Buffer) to write data to * @param options - Read behaviour options * @returns Promise with number of bytes peeked */ async peekBuffer(uint8Array, options) { const normOptions = this.normalizeOptions(uint8Array, options); let bytesRead = 0; if (normOptions.position) { const skipBytes = normOptions.position - this.position; if (skipBytes > 0) { const skipBuffer = new Uint8Array(normOptions.length + skipBytes); bytesRead = await this.peekBuffer(skipBuffer, { mayBeLess: normOptions.mayBeLess }); uint8Array.set(skipBuffer.subarray(skipBytes), normOptions.offset); return bytesRead - skipBytes; } if (skipBytes < 0) { throw new Error("Cannot peek from a negative offset in a stream"); } } if (normOptions.length > 0) { try { bytesRead = await this.streamReader.peek(uint8Array, normOptions.offset, normOptions.length); } catch (err) { if (options?.mayBeLess && err instanceof EndOfStreamError) { return 0; } throw err; } if (!normOptions.mayBeLess && bytesRead < normOptions.length) { throw new EndOfStreamError(); } } return bytesRead; } async ignore(length) { const bufSize = Math.min(maxBufferSize, length); const buf = new Uint8Array(bufSize); let totBytesRead = 0; while (totBytesRead < length) { const remaining = length - totBytesRead; const bytesRead = await this.readBuffer(buf, { length: Math.min(bufSize, remaining) }); if (bytesRead < 0) { return bytesRead; } totBytesRead += bytesRead; } return totBytesRead; } abort() { return this.streamReader.abort(); } }; // node_modules/.pnpm/strtok3@9.0.1/node_modules/strtok3/lib/BufferTokenizer.js var BufferTokenizer = class extends AbstractTokenizer { /** * Construct BufferTokenizer * @param uint8Array - Uint8Array to tokenize * @param options Tokenizer options */ constructor(uint8Array, options) { super(options); this.uint8Array = uint8Array; this.fileInfo.size = this.fileInfo.size ? this.fileInfo.size : uint8Array.length; } /** * Read buffer from tokenizer * @param uint8Array - Uint8Array to tokenize * @param options - Read behaviour options * @returns {Promise} */ async readBuffer(uint8Array, options) { if (options?.position) { if (options.position < this.position) { throw new Error("`options.position` must be equal or greater than `tokenizer.position`"); } this.position = options.position; } const bytesRead = await this.peekBuffer(uint8Array, options); this.position += bytesRead; return bytesRead; } /** * Peek (read ahead) buffer from tokenizer * @param uint8Array * @param options - Read behaviour options * @returns {Promise} */ async peekBuffer(uint8Array, options) { const normOptions = this.normalizeOptions(uint8Array, options); const bytes2read = Math.min(this.uint8Array.length - normOptions.position, normOptions.length); if (!normOptions.mayBeLess && bytes2read < normOptions.length) { throw new EndOfStreamError(); } uint8Array.set(this.uint8Array.subarray(normOptions.position, normOptions.position + bytes2read), normOptions.offset); return bytes2read; } close() { return super.close(); } }; // node_modules/.pnpm/strtok3@9.0.1/node_modules/strtok3/lib/core.js function fromStream(stream, options) { return new ReadStreamTokenizer(new StreamReader(stream), options); } function fromWebStream(webStream, options) { return new ReadStreamTokenizer(new WebStreamReader(webStream), options); } function fromBuffer(uint8Array, options) { return new BufferTokenizer(uint8Array, options); } // node_modules/.pnpm/strtok3@9.0.1/node_modules/strtok3/lib/FileTokenizer.js var import_promises = require("node:fs/promises"); var FileTokenizer = class extends AbstractTokenizer { constructor(fileHandle, options) { super(options); this.fileHandle = fileHandle; } /** * Read buffer from file * @param uint8Array - Uint8Array to write result to * @param options - Read behaviour options * @returns Promise number of bytes read */ async readBuffer(uint8Array, options) { const normOptions = this.normalizeOptions(uint8Array, options); this.position = normOptions.position; if (normOptions.length === 0) return 0; const res = await this.fileHandle.read(uint8Array, normOptions.offset, normOptions.length, normOptions.position); this.position += res.bytesRead; if (res.bytesRead < normOptions.length && (!options || !options.mayBeLess)) { throw new EndOfStreamError(); } return res.bytesRead; } /** * Peek buffer from file * @param uint8Array - Uint8Array (or Buffer) to write data to * @param options - Read behaviour options * @returns Promise number of bytes read */ async peekBuffer(uint8Array, options) { const normOptions = this.normalizeOptions(uint8Array, options); const res = await this.fileHandle.read(uint8Array, normOptions.offset, normOptions.length, normOptions.position); if (!normOptions.mayBeLess && res.bytesRead < normOptions.length) { throw new EndOfStreamError(); } return res.bytesRead; } async close() { await this.fileHandle.close(); return super.close(); } }; async function fromFile(sourceFilePath) { const fileHandle = await (0, import_promises.open)(sourceFilePath, "r"); const stat = await fileHandle.stat(); return new FileTokenizer(fileHandle, { fileInfo: { path: sourceFilePath, size: stat.size } }); } // node_modules/.pnpm/strtok3@9.0.1/node_modules/strtok3/lib/index.js async function fromStream2(stream, options) { const augmentedOptions = options ?? {}; augmentedOptions.fileInfo = augmentedOptions.fileInfo ?? {}; if (stream.path) { const stat = await (0, import_promises2.stat)(stream.path); augmentedOptions.fileInfo.path = stream.path; augmentedOptions.fileInfo.size = stat.size; } return fromStream(stream, augmentedOptions); } // node_modules/.pnpm/token-types@6.0.0/node_modules/token-types/lib/index.js var ieee754 = __toESM(require_ieee754(), 1); function dv(array) { return new DataView(array.buffer, array.byteOffset); } var UINT8 = { len: 1, get(array, offset) { return dv(array).getUint8(offset); }, put(array, offset, value) { dv(array).setUint8(offset, value); return offset + 1; } }; var UINT16_LE = { len: 2, get(array, offset) { return dv(array).getUint16(offset, true); }, put(array, offset, value) { dv(array).setUint16(offset, value, true); return offset + 2; } }; var UINT16_BE = { len: 2, get(array, offset) { return dv(array).getUint16(offset); }, put(array, offset, value) { dv(array).setUint16(offset, value); return offset + 2; } }; var UINT32_LE = { len: 4, get(array, offset) { return dv(array).getUint32(offset, true); }, put(array, offset, value) { dv(array).setUint32(offset, value, true); return offset + 4; } }; var UINT32_BE = { len: 4, get(array, offset) { return dv(array).getUint32(offset); }, put(array, offset, value) { dv(array).setUint32(offset, value); return offset + 4; } }; var INT32_BE = { len: 4, get(array, offset) { return dv(array).getInt32(offset); }, put(array, offset, value) { dv(array).setInt32(offset, value); return offset + 4; } }; var UINT64_LE = { len: 8, get(array, offset) { return dv(array).getBigUint64(offset, true); }, put(array, offset, value) { dv(array).setBigUint64(offset, value, true); return offset + 8; } }; var StringType = class { constructor(len, encoding) { this.len = len; this.encoding = encoding; this.textDecoder = new TextDecoder(encoding); } get(uint8Array, offset) { return this.textDecoder.decode(uint8Array.subarray(offset, offset + this.len)); } }; // node_modules/.pnpm/uint8array-extras@1.4.0/node_modules/uint8array-extras/index.js var cachedDecoders = { utf8: new globalThis.TextDecoder("utf8") }; var cachedEncoder = new globalThis.TextEncoder(); var byteToHexLookupTable = Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0")); function getUintBE(view) { const { byteLength } = view; if (byteLength === 6) { return view.getUint16(0) * 2 ** 32 + view.getUint32(2); } if (byteLength === 5) { return view.getUint8(0) * 2 ** 32 + view.getUint32(1); } if (byteLength === 4) { return view.getUint32(0); } if (byteLength === 3) { return view.getUint8(0) * 2 ** 16 + view.getUint16(1); } if (byteLength === 2) { return view.getUint16(0); } if (byteLength === 1) { return view.getUint8(0); } } function indexOf(array, value) { const arrayLength = array.length; const valueLength = value.length; if (valueLength === 0) { return -1; } if (valueLength > arrayLength) { return -1; } const validOffsetLength = arrayLength - valueLength; for (let index = 0; index <= validOffsetLength; index++) { let isMatch = true; for (let index2 = 0; index2 < valueLength; index2++) { if (array[index + index2] !== value[index2]) { isMatch = false; break; } } if (isMatch) { return index; } } return -1; } function includes(array, value) { return indexOf(array, value) !== -1; } // node_modules/.pnpm/file-type@19.6.0/node_modules/file-type/util.js function stringToBytes(string) { return [...string].map((character) => character.charCodeAt(0)); } function tarHeaderChecksumMatches(arrayBuffer, offset = 0) { const readSum = Number.parseInt(new StringType(6).get(arrayBuffer, 148).replace(/\0.*$/, "").trim(), 8); if (Number.isNaN(readSum)) { return false; } let sum = 8 * 32; for (let index = offset; index < offset + 148; index++) { sum += arrayBuffer[index]; } for (let index = offset + 156; index < offset + 512; index++) { sum += arrayBuffer[index]; } return readSum === sum; } var uint32SyncSafeToken = { get: (buffer, offset) => buffer[offset + 3] & 127 | buffer[offset + 2] << 7 | buffer[offset + 1] << 14 | buffer[offset] << 21, len: 4 }; // node_modules/.pnpm/file-type@19.6.0/node_modules/file-type/supported.js var extensions = [ "jpg", "png", "apng", "gif", "webp", "flif", "xcf", "cr2", "cr3", "orf", "arw", "dng", "nef", "rw2", "raf", "tif", "bmp", "icns", "jxr", "psd", "indd", "zip", "tar", "rar", "gz", "bz2", "7z", "dmg", "mp4", "mid", "mkv", "webm", "mov", "avi", "mpg", "mp2", "mp3", "m4a", "oga", "ogg", "ogv", "opus", "flac", "wav", "spx", "amr", "pdf", "epub", "elf", "macho", "exe", "swf", "rtf", "wasm", "woff", "woff2", "eot", "ttf", "otf", "ico", "flv", "ps", "xz", "sqlite", "nes", "crx", "xpi", "cab", "deb", "ar", "rpm", "Z", "lz", "cfb", "mxf", "mts", "blend", "bpg", "docx", "pptx", "xlsx", "3gp", "3g2", "j2c", "jp2", "jpm", "jpx", "mj2", "aif", "qcp", "odt", "ods", "odp", "xml", "mobi", "heic", "cur", "ktx", "ape", "wv", "dcm", "ics", "glb", "pcap", "dsf", "lnk", "alias", "voc", "ac3", "m4v", "m4p", "m4b", "f4v", "f4p", "f4b", "f4a", "mie", "asf", "ogm", "ogx", "mpc", "arrow", "shp", "aac", "mp1", "it", "s3m", "xm", "ai", "skp", "avif", "eps", "lzh", "pgp", "asar", "stl", "chm", "3mf", "zst", "jxl", "vcf", "jls", "pst", "dwg", "parquet", "class", "arj", "cpio", "ace", "avro", "icc", "fbx", "vsdx", "vtt", "apk" ]; var mimeTypes = [ "image/jpeg", "image/png", "image/gif", "image/webp", "image/flif", "image/x-xcf", "image/x-canon-cr2", "image/x-canon-cr3", "image/tiff", "image/bmp", "image/vnd.ms-photo", "image/vnd.adobe.photoshop", "application/x-indesign", "application/epub+zip", "application/x-xpinstall", "application/vnd.oasis.opendocument.text", "application/vnd.oasis.opendocument.spreadsheet", "application/vnd.oasis.opendocument.presentation", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/zip", "application/x-tar", "application/x-rar-compressed", "application/gzip", "application/x-bzip2", "application/x-7z-compressed", "application/x-apple-diskimage", "application/x-apache-arrow", "video/mp4", "audio/midi", "video/x-matroska", "video/webm", "video/quicktime", "video/vnd.avi", "audio/wav", "audio/qcelp", "audio/x-ms-asf", "video/x-ms-asf", "application/vnd.ms-asf", "video/mpeg", "video/3gpp", "audio/mpeg", "audio/mp4", // RFC 4337 "video/ogg", "audio/ogg", "audio/ogg; codecs=opus", "application/ogg", "audio/x-flac", "audio/ape", "audio/wavpack", "audio/amr", "application/pdf", "application/x-elf", "application/x-mach-binary", "application/x-msdownload", "application/x-shockwave-flash", "application/rtf", "application/wasm", "font/woff", "font/woff2", "application/vnd.ms-fontobject", "font/ttf", "font/otf", "image/x-icon", "video/x-flv", "application/postscript", "application/eps", "application/x-xz", "application/x-sqlite3", "application/x-nintendo-nes-rom", "application/x-google-chrome-extension", "application/vnd.ms-cab-compressed", "application/x-deb", "application/x-unix-archive", "application/x-rpm", "application/x-compress", "application/x-lzip", "application/x-cfb", "application/x-mie", "application/mxf", "video/mp2t", "application/x-blender", "image/bpg", "image/j2c", "image/jp2", "image/jpx", "image/jpm", "image/mj2", "audio/aiff", "application/xml", "application/x-mobipocket-ebook", "image/heif", "image/heif-sequence", "image/heic", "image/heic-sequence", "image/icns", "image/ktx", "application/dicom", "audio/x-musepack", "text/calendar", "text/vcard", "text/vtt", "model/gltf-binary", "application/vnd.tcpdump.pcap", "audio/x-dsf", // Non-standard "application/x.ms.shortcut", // Invented by us "application/x.apple.alias", // Invented by us "audio/x-voc", "audio/vnd.dolby.dd-raw", "audio/x-m4a", "image/apng", "image/x-olympus-orf", "image/x-sony-arw", "image/x-adobe-dng", "image/x-nikon-nef", "image/x-panasonic-rw2", "image/x-fujifilm-raf", "video/x-m4v", "video/3gpp2", "application/x-esri-shape", "audio/aac", "audio/x-it", "audio/x-s3m", "audio/x-xm", "video/MP1S", "video/MP2P", "application/vnd.sketchup.skp", "image/avif", "application/x-lzh-compressed", "application/pgp-encrypted", "application/x-asar", "model/stl", "application/vnd.ms-htmlhelp", "model/3mf", "image/jxl", "application/zstd", "image/jls", "application/vnd.ms-outlook", "image/vnd.dwg", "application/x-parquet", "application/java-vm", "application/x-arj", "application/x-cpio", "application/x-ace-compressed", "application/avro", "application/vnd.iccprofile", "application/x.autodesk.fbx", // Invented by us "application/vnd.visio", "application/vnd.android.package-archive" ]; // node_modules/.pnpm/file-type@19.6.0/node_modules/file-type/core.js var reasonableDetectionSizeInBytes = 4100; function _check(buffer, headers, options) { options = { offset: 0, ...options }; for (const [index, header] of headers.entries()) { if (options.mask) { if (header !== (options.mask[index] & buffer[index + options.offset])) { return false; } } else if (header !== buffer[index + options.offset]) { return false; } } return true; } var FileTypeParser = class { constructor(options) { this.detectors = options?.customDetectors; this.tokenizerOptions = { abortSignal: options?.signal }; this.fromTokenizer = this.fromTokenizer.bind(this); this.fromBuffer = this.fromBuffer.bind(this); this.parse = this.parse.bind(this); } async fromTokenizer(tokenizer) { const initialPosition = tokenizer.position; for (const detector of this.detectors || []) { const fileType = await detector(tokenizer); if (fileType) { return fileType; } if (initialPosition !== tokenizer.position) { return void 0; } } return this.parse(tokenizer); } async fromBuffer(input) { if (!(input instanceof Uint8Array || input instanceof ArrayBuffer)) { throw new TypeError(`Expected the \`input\` argument to be of type \`Uint8Array\` or \`ArrayBuffer\`, got \`${typeof input}\``); } const buffer = input instanceof Uint8Array ? input : new Uint8Array(input); if (!(buffer?.length > 1)) { return; } return this.fromTokenizer(fromBuffer(buffer, this.tokenizerOptions)); } async fromBlob(blob) { return this.fromStream(blob.stream()); } async fromStream(stream) { const tokenizer = await fromWebStream(stream, this.tokenizerOptions); try { return await this.fromTokenizer(tokenizer); } finally { await tokenizer.close(); } } async toDetectionStream(stream, options) { const { sampleSize = reasonableDetectionSizeInBytes } = options; let detectedFileType; let firstChunk; const reader = stream.getReader({ mode: "byob" }); try { const { value: chunk, done } = await reader.read(new Uint8Array(sampleSize)); firstChunk = chunk; if (!done && chunk) { try { detectedFileType = await this.fromBuffer(chunk.slice(0, sampleSize)); } catch (error) { if (!(error instanceof EndOfStreamError)) { throw error; } detectedFileType = void 0; } } firstChunk = chunk; } finally { reader.releaseLock(); } const transformStream = new TransformStream({ async start(controller) { controller.enqueue(firstChunk); }, transform(chunk, controller) { controller.enqueue(chunk); } }); const newStream = stream.pipeThrough(transformStream); newStream.fileType = detectedFileType; return newStream; } check(header, options) { return _check(this.buffer, header, options); } checkString(header, options) { return this.check(stringToBytes(header), options); } async parse(tokenizer) { this.buffer = new Uint8Array(reasonableDetectionSizeInBytes); if (tokenizer.fileInfo.size === void 0) { tokenizer.fileInfo.size = Number.MAX_SAFE_INTEGER; } this.tokenizer = tokenizer; await tokenizer.peekBuffer(this.buffer, { length: 12, mayBeLess: true }); if (this.check([66, 77])) { return { ext: "bmp", mime: "image/bmp" }; } if (this.check([11, 119])) { return { ext: "ac3", mime: "audio/vnd.dolby.dd-raw" }; } if (this.check([120, 1])) { return { ext: "dmg", mime: "application/x-apple-diskimage" }; } if (this.check([77, 90])) { return { ext: "exe", mime: "application/x-msdownload" }; } if (this.check([37, 33])) { await tokenizer.peekBuffer(this.buffer, { length: 24, mayBeLess: true }); if (this.checkString("PS-Adobe-", { offset: 2 }) && this.checkString(" EPSF-", { offset: 14 })) { return { ext: "eps", mime: "application/eps" }; } return { ext: "ps", mime: "application/postscript" }; } if (this.check([31, 160]) || this.check([31, 157])) { return { ext: "Z", mime: "application/x-compress" }; } if (this.check([199, 113])) { return { ext: "cpio", mime: "application/x-cpio" }; } if (this.check([96, 234])) { return { ext: "arj", mime: "application/x-arj" }; } if (this.check([239, 187, 191])) { this.tokenizer.ignore(3); return this.parse(tokenizer); } if (this.check([71, 73, 70])) { return { ext: "gif", mime: "image/gif" }; } if (this.check([73, 73, 188])) { return { ext: "jxr", mime: "image/vnd.ms-photo" }; } if (this.check([31, 139, 8])) { return { ext: "gz", mime: "application/gzip" }; } if (this.check([66, 90, 104])) { return { ext: "bz2", mime: "application/x-bzip2" }; } if (this.checkString("ID3")) { await tokenizer.ignore(6); const id3HeaderLength = await tokenizer.readToken(uint32SyncSafeToken); if (tokenizer.position + id3HeaderLength > tokenizer.fileInfo.size) { return { ext: "mp3", mime: "audio/mpeg" }; } await tokenizer.ignore(id3HeaderLength); return this.fromTokenizer(tokenizer); } if (this.checkString("MP+")) { return { ext: "mpc", mime: "audio/x-musepack" }; } if ((this.buffer[0] === 67 || this.buffer[0] === 70) && this.check([87, 83], { offset: 1 })) { return { ext: "swf", mime: "application/x-shockwave-flash" }; } if (this.check([255, 216, 255])) { if (this.check([247], { offset: 3 })) { return { ext: "jls", mime: "image/jls" }; } return { ext: "jpg", mime: "image/jpeg" }; } if (this.check([79, 98, 106, 1])) { return { ext: "avro", mime: "application/avro" }; } if (this.checkString("FLIF")) { return { ext: "flif", mime: "image/flif" }; } if (this.checkString("8BPS")) { return { ext: "psd", mime: "image/vnd.adobe.photoshop" }; } if (this.checkString("WEBP", { offset: 8 })) { return { ext: "webp", mime: "image/webp" }; } if (this.checkString("MPCK")) { return { ext: "mpc", mime: "audio/x-musepack" }; } if (this.checkString("FORM")) { return { ext: "aif", mime: "audio/aiff" }; } if (this.checkString("icns", { offset: 0 })) { return { ext: "icns", mime: "image/icns" }; } if (this.check([80, 75, 3, 4])) { try { while (tokenizer.position + 30 < tokenizer.fileInfo.size) { await tokenizer.readBuffer(this.buffer, { length: 30 }); const view = new DataView(this.buffer.buffer); const zipHeader = { compressedSize: view.getUint32(18, true), uncompressedSize: view.getUint32(22, true), filenameLength: view.getUint16(26, true), extraFieldLength: view.getUint16(28, true) }; zipHeader.filename = await tokenizer.readToken(new StringType(zipHeader.filenameLength, "utf-8")); await tokenizer.ignore(zipHeader.extraFieldLength); if (/classes\d*\.dex/.test(zipHeader.filename)) { return { ext: "apk", mime: "application/vnd.android.package-archive" }; } if (zipHeader.filename === "META-INF/mozilla.rsa") { return { ext: "xpi", mime: "application/x-xpinstall" }; } if (zipHeader.filename.endsWith(".rels") || zipHeader.filename.endsWith(".xml")) { const type = zipHeader.filename.split("/")[0]; switch (type) { case "_rels": break; case "word": return { ext: "docx", mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }; case "ppt": return { ext: "pptx", mime: "application/vnd.openxmlformats-officedocument.presentationml.presentation" }; case "xl": return { ext: "xlsx", mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }; case "visio": return { ext: "vsdx", mime: "application/vnd.visio" }; default: break; } } if (zipHeader.filename.startsWith("xl/")) { return { ext: "xlsx", mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }; } if (zipHeader.filename.startsWith("3D/") && zipHeader.filename.endsWith(".model")) { return { ext: "3mf", mime: "model/3mf" }; } if (zipHeader.filename === "mimetype" && zipHeader.compressedSize === zipHeader.uncompressedSize) { let mimeType = await tokenizer.readToken(new StringType(zipHeader.compressedSize, "utf-8")); mimeType = mimeType.trim(); switch (mimeType) { case "application/epub+zip": return { ext: "epub", mime: "application/epub+zip" }; case "application/vnd.oasis.opendocument.text": return { ext: "odt", mime: "application/vnd.oasis.opendocument.text" }; case "application/vnd.oasis.opendocument.spreadsheet": return { ext: "ods", mime: "application/vnd.oasis.opendocument.spreadsheet" }; case "application/vnd.oasis.opendocument.presentation": return { ext: "odp", mime: "application/vnd.oasis.opendocument.presentation" }; default: } } if (zipHeader.compressedSize === 0) { let nextHeaderIndex = -1; while (nextHeaderIndex < 0 && tokenizer.position < tokenizer.fileInfo.size) { await tokenizer.peekBuffer(this.buffer, { mayBeLess: true }); nextHeaderIndex = indexOf(this.buffer, new Uint8Array([80, 75, 3, 4])); await tokenizer.ignore(nextHeaderIndex >= 0 ? nextHeaderIndex : this.buffer.length); } } else { await tokenizer.ignore(zipHeader.compressedSize); } } } catch (error) { if (!(error instanceof EndOfStreamError)) { throw error; } } return { ext: "zip", mime: "application/zip" }; } if (this.checkString("OggS")) { await tokenizer.ignore(28); const type = new Uint8Array(8); await tokenizer.readBuffer(type); if (_check(type, [79, 112, 117, 115, 72, 101, 97, 100])) { return { ext: "opus", mime: "audio/ogg; codecs=opus" }; } if (_check(type, [128, 116, 104, 101, 111, 114, 97])) { return { ext: "ogv", mime: "video/ogg" }; } if (_check(type, [1, 118, 105, 100, 101, 111, 0])) { return { ext: "ogm", mime: "video/ogg" }; } if (_check(type, [127, 70, 76, 65, 67])) { return { ext: "oga", mime: "audio/ogg" }; } if (_check(type, [83, 112, 101, 101, 120, 32, 32])) { return { ext: "spx", mime: "audio/ogg" }; } if (_check(type, [1, 118, 111, 114, 98, 105, 115])) { return { ext: "ogg", mime: "audio/ogg" }; } return { ext: "ogx", mime: "application/ogg" }; } if (this.check([80, 75]) && (this.buffer[2] === 3 || this.buffer[2] === 5 || this.buffer[2] === 7) && (this.buffer[3] === 4 || this.buffer[3] === 6 || this.buffer[3] === 8)) { return { ext: "zip", mime: "application/zip" }; } if (this.checkString("ftyp", { offset: 4 }) && (this.buffer[8] & 96) !== 0) { const brandMajor = new StringType(4, "latin1").get(this.buffer, 8).replace("\0", " ").trim(); switch (brandMajor) { case "avif": case "avis": return { ext: "avif", mime: "image/avif" }; case "mif1": return { ext: "heic", mime: "image/heif" }; case "msf1": return { ext: "heic", mime: "image/heif-sequence" }; case "heic": case "heix": return { ext: "heic", mime: "image/heic" }; case "hevc": case "hevx": return { ext: "heic", mime: "image/heic-sequence" }; case "qt": return { ext: "mov", mime: "video/quicktime" }; case "M4V": case "M4VH": case "M4VP": return { ext: "m4v", mime: "video/x-m4v" }; case "M4P": return { ext: "m4p", mime: "video/mp4" }; case "M4B": return { ext: "m4b", mime: "audio/mp4" }; case "M4A": return { ext: "m4a", mime: "audio/x-m4a" }; case "F4V": return { ext: "f4v", mime: "video/mp4" }; case "F4P": return { ext: "f4p", mime: "video/mp4" }; case "F4A": return { ext: "f4a", mime: "audio/mp4" }; case "F4B": return { ext: "f4b", mime: "audio/mp4" }; case "crx": return { ext: "cr3", mime: "image/x-canon-cr3" }; default: if (brandMajor.startsWith("3g")) { if (brandMajor.startsWith("3g2")) { return { ext: "3g2", mime: "video/3gpp2" }; } return { ext: "3gp", mime: "video/3gpp" }; } return { ext: "mp4", mime: "video/mp4" }; } } if (this.checkString("MThd")) { return { ext: "mid", mime: "audio/midi" }; } if (this.checkString("wOFF") && (this.check([0, 1, 0, 0], { offset: 4 }) || this.checkString("OTTO", { offset: 4 }))) { return { ext: "woff", mime: "font/woff" }; } if (this.checkString("wOF2") && (this.check([0, 1, 0, 0], { offset: 4 }) || this.checkString("OTTO", { offset: 4 }))) { return { ext: "woff2", mime: "font/woff2" }; } if (this.check([212, 195, 178, 161]) || this.check([161, 178, 195, 212])) { return { ext: "pcap", mime: "application/vnd.tcpdump.pcap" }; } if (this.checkString("DSD ")) { return { ext: "dsf", mime: "audio/x-dsf" // Non-standard }; } if (this.checkString("LZIP")) { return { ext: "lz", mime: "application/x-lzip" }; } if (this.checkString("fLaC")) { return { ext: "flac", mime: "audio/x-flac" }; } if (this.check([66, 80, 71, 251])) { return { ext: "bpg", mime: "image/bpg" }; } if (this.checkString("wvpk")) { return { ext: "wv", mime: "audio/wavpack" }; } if (this.checkString("%PDF")) { try { await tokenizer.ignore(1350); const maxBufferSize2 = 10 * 1024 * 1024; const buffer = new Uint8Array(Math.min(maxBufferSize2, tokenizer.fileInfo.size)); await tokenizer.readBuffer(buffer, { mayBeLess: true }); if (includes(buffer, new TextEncoder().encode("AIPrivateData"))) { return { ext: "ai", mime: "application/postscript" }; } } catch (error) { if (!(error instanceof EndOfStreamError)) { throw error; } } return { ext: "pdf", mime: "application/pdf" }; } if (this.check([0, 97, 115, 109])) { return { ext: "wasm", mime: "application/wasm" }; } if (this.check([73, 73])) { const fileType = await this.readTiffHeader(false); if (fileType) { return fileType; } } if (this.check([77, 77])) { const fileType = await this.readTiffHeader(true); if (fileType) { return fileType; } } if (this.checkString("MAC ")) { return { ext: "ape", mime: "audio/ape" }; } if (this.check([26, 69, 223, 163])) { async function readField() { const msb = await tokenizer.peekNumber(UINT8); let mask = 128; let ic = 0; while ((msb & mask) === 0 && mask !== 0) { ++ic; mask >>= 1; } const id = new Uint8Array(ic + 1); await tokenizer.readBuffer(id); return id; } async function readElement() { const idField = await readField(); const lengthField = await readField(); lengthField[0] ^= 128 >> lengthField.length - 1; const nrLength = Math.min(6, lengthField.length); const idView = new DataView(idField.buffer); const lengthView = new DataView(lengthField.buffer, lengthField.length - nrLength, nrLength); return { id: getUintBE(idView), len: getUintBE(lengthView) }; } async function readChildren(children) { while (children > 0) { const element = await readElement(); if (element.id === 17026) { const rawValue = await tokenizer.readToken(new StringType(element.len)); return rawValue.replaceAll(/\00.*$/g, ""); } await tokenizer.ignore(element.len); --children; } } const re = await readElement(); const docType = await readChildren(re.len); switch (docType) { case "webm": return { ext: "webm", mime: "video/webm" }; case "matroska": return { ext: "mkv", mime: "video/x-matroska" }; default: return; } } if (this.check([82, 73, 70, 70])) { if (this.check([65, 86, 73], { offset: 8 })) { return { ext: "avi", mime: "video/vnd.avi" }; } if (this.check([87, 65, 86, 69], { offset: 8 })) { return { ext: "wav", mime: "audio/wav" }; } if (this.check([81, 76, 67, 77], { offset: 8 })) { return { ext: "qcp", mime: "audio/qcelp" }; } } if (this.checkString("SQLi")) { return { ext: "sqlite", mime: "application/x-sqlite3" }; } if (this.check([78, 69, 83, 26])) { return { ext: "nes", mime: "application/x-nintendo-nes-rom" }; } if (this.checkString("Cr24")) { return { ext: "crx", mime: "application/x-google-chrome-extension" }; } if (this.checkString("MSCF") || this.checkString("ISc(")) { return { ext: "cab", mime: "application/vnd.ms-cab-compressed" }; } if (this.check([237, 171, 238, 219])) { return { ext: "rpm", mime: "application/x-rpm" }; } if (this.check([197, 208, 211, 198])) { return { ext: "eps", mime: "application/eps" }; } if (this.check([40, 181, 47, 253])) { return { ext: "zst", mime: "application/zstd" }; } if (this.check([127, 69, 76, 70])) { return { ext: "elf", mime: "application/x-elf" }; } if (this.check([33, 66, 68, 78])) { return { ext: "pst", mime: "application/vnd.ms-outlook" }; } if (this.checkString("PAR1")) { return { ext: "parquet", mime: "application/x-parquet" }; } if (this.check([207, 250, 237, 254])) { return { ext: "macho", mime: "application/x-mach-binary" }; } if (this.check([79, 84, 84, 79, 0])) { return { ext: "otf", mime: "font/otf" }; } if (this.checkString("#!AMR")) { return { ext: "amr", mime: "audio/amr" }; } if (this.checkString("{\\rtf")) { return { ext: "rtf", mime: "application/rtf" }; } if (this.check([70, 76, 86, 1])) { return { ext: "flv", mime: "video/x-flv" }; } if (this.checkString("IMPM")) { return { ext: "it", mime: "audio/x-it" }; } if (this.checkString("-lh0-", { offset: 2 }) || this.checkString("-lh1-", { offset: 2 }) || this.checkString("-lh2-", { offset: 2 }) || this.checkString("-lh3-", { offset: 2 }) || this.checkString("-lh4-", { offset: 2 }) || this.checkString("-lh5-", { offset: 2 }) || this.checkString("-lh6-", { offset: 2 }) || this.checkString("-lh7-", { offset: 2 }) || this.checkString("-lzs-", { offset: 2 }) || this.checkString("-lz4-", { offset: 2 }) || this.checkString("-lz5-", { offset: 2 }) || this.checkString("-lhd-", { offset: 2 })) { return { ext: "lzh", mime: "application/x-lzh-compressed" }; } if (this.check([0, 0, 1, 186])) { if (this.check([33], { offset: 4, mask: [241] })) { return { ext: "mpg", // May also be .ps, .mpeg mime: "video/MP1S" }; } if (this.check([68], { offset: 4, mask: [196] })) { return { ext: "mpg", // May also be .mpg, .m2p, .vob or .sub mime: "video/MP2P" }; } } if (this.checkString("ITSF")) { return { ext: "chm", mime: "application/vnd.ms-htmlhelp" }; } if (this.check([202, 254, 186, 190])) { return { ext: "class", mime: "application/java-vm" }; } if (this.check([253, 55, 122, 88, 90, 0])) { return { ext: "xz", mime: "application/x-xz" }; } if (this.checkString("= 1e3 && version <= 1050) { return { ext: "dwg", mime: "image/vnd.dwg" }; } } if (this.checkString("070707")) { return { ext: "cpio", mime: "application/x-cpio" }; } if (this.checkString("BLENDER")) { return { ext: "blend", mime: "application/x-blender" }; } if (this.checkString("!")) { await tokenizer.ignore(8); const string = await tokenizer.readToken(new StringType(13, "ascii")); if (string === "debian-binary") { return { ext: "deb", mime: "application/x-deb" }; } return { ext: "ar", mime: "application/x-unix-archive" }; } if (this.checkString("WEBVTT") && // One of LF, CR, tab, space, or end of file must follow "WEBVTT" per the spec (see `fixture/fixture-vtt-*.vtt` for examples). Note that `\0` is technically the null character (there is no such thing as an EOF character). However, checking for `\0` gives us the same result as checking for the end of the stream. ["\n", "\r", " ", " ", "\0"].some((char7) => this.checkString(char7, { offset: 6 }))) { return { ext: "vtt", mime: "text/vtt" }; } if (this.check([137, 80, 78, 71, 13, 10, 26, 10])) { await tokenizer.ignore(8); async function readChunkHeader() { return { length: await tokenizer.readToken(INT32_BE), type: await tokenizer.readToken(new StringType(4, "latin1")) }; } do { const chunk = await readChunkHeader(); if (chunk.length < 0) { return; } switch (chunk.type) { case "IDAT": return { ext: "png", mime: "image/png" }; case "acTL": return { ext: "apng", mime: "image/apng" }; default: await tokenizer.ignore(chunk.length + 4); } } while (tokenizer.position + 8 < tokenizer.fileInfo.size); return { ext: "png", mime: "image/png" }; } if (this.check([65, 82, 82, 79, 87, 49, 0, 0])) { return { ext: "arrow", mime: "application/x-apache-arrow" }; } if (this.check([103, 108, 84, 70, 2, 0, 0, 0])) { return { ext: "glb", mime: "model/gltf-binary" }; } if (this.check([102, 114, 101, 101], { offset: 4 }) || this.check([109, 100, 97, 116], { offset: 4 }) || this.check([109, 111, 111, 118], { offset: 4 }) || this.check([119, 105, 100, 101], { offset: 4 })) { return { ext: "mov", mime: "video/quicktime" }; } if (this.check([73, 73, 82, 79, 8, 0, 0, 0, 24])) { return { ext: "orf", mime: "image/x-olympus-orf" }; } if (this.checkString("gimp xcf ")) { return { ext: "xcf", mime: "image/x-xcf" }; } if (this.check([73, 73, 85, 0, 24, 0, 0, 0, 136, 231, 116, 216])) { return { ext: "rw2", mime: "image/x-panasonic-rw2" }; } if (this.check([48, 38, 178, 117, 142, 102, 207, 17, 166, 217])) { async function readHeader() { const guid = new Uint8Array(16); await tokenizer.readBuffer(guid); return { id: guid, size: Number(await tokenizer.readToken(UINT64_LE)) }; } await tokenizer.ignore(30); while (tokenizer.position + 24 < tokenizer.fileInfo.size) { const header = await readHeader(); let payload = header.size - 24; if (_check(header.id, [145, 7, 220, 183, 183, 169, 207, 17, 142, 230, 0, 192, 12, 32, 83, 101])) { const typeId = new Uint8Array(16); payload -= await tokenizer.readBuffer(typeId); if (_check(typeId, [64, 158, 105, 248, 77, 91, 207, 17, 168, 253, 0, 128, 95, 92, 68, 43])) { return { ext: "asf", mime: "audio/x-ms-asf" }; } if (_check(typeId, [192, 239, 25, 188, 77, 91, 207, 17, 168, 253, 0, 128, 95, 92, 68, 43])) { return { ext: "asf", mime: "video/x-ms-asf" }; } break; } await tokenizer.ignore(payload); } return { ext: "asf", mime: "application/vnd.ms-asf" }; } if (this.check([171, 75, 84, 88, 32, 49, 49, 187, 13, 10, 26, 10])) { return { ext: "ktx", mime: "image/ktx" }; } if ((this.check([126, 16, 4]) || this.check([126, 24, 4])) && this.check([48, 77, 73, 69], { offset: 4 })) { return { ext: "mie", mime: "application/x-mie" }; } if (this.check([39, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], { offset: 2 })) { return { ext: "shp", mime: "application/x-esri-shape" }; } if (this.check([255, 79, 255, 81])) { return { ext: "j2c", mime: "image/j2c" }; } if (this.check([0, 0, 0, 12, 106, 80, 32, 32, 13, 10, 135, 10])) { await tokenizer.ignore(20); const type = await tokenizer.readToken(new StringType(4, "ascii")); switch (type) { case "jp2 ": return { ext: "jp2", mime: "image/jp2" }; case "jpx ": return { ext: "jpx", mime: "image/jpx" }; case "jpm ": return { ext: "jpm", mime: "image/jpm" }; case "mjp2": return { ext: "mj2", mime: "image/mj2" }; default: return; } } if (this.check([255, 10]) || this.check([0, 0, 0, 12, 74, 88, 76, 32, 13, 10, 135, 10])) { return { ext: "jxl", mime: "image/jxl" }; } if (this.check([254, 255])) { if (this.check([0, 60, 0, 63, 0, 120, 0, 109, 0, 108], { offset: 2 })) { return { ext: "xml", mime: "application/xml" }; } return void 0; } if (this.check([0, 0, 1, 186]) || this.check([0, 0, 1, 179])) { return { ext: "mpg", mime: "video/mpeg" }; } if (this.check([0, 1, 0, 0, 0])) { return { ext: "ttf", mime: "font/ttf" }; } if (this.check([0, 0, 1, 0])) { return { ext: "ico", mime: "image/x-icon" }; } if (this.check([0, 0, 2, 0])) { return { ext: "cur", mime: "image/x-icon" }; } if (this.check([208, 207, 17, 224, 161, 177, 26, 225])) { return { ext: "cfb", mime: "application/x-cfb" }; } await tokenizer.peekBuffer(this.buffer, { length: Math.min(256, tokenizer.fileInfo.size), mayBeLess: true }); if (this.check([97, 99, 115, 112], { offset: 36 })) { return { ext: "icc", mime: "application/vnd.iccprofile" }; } if (this.checkString("**ACE", { offset: 7 }) && this.checkString("**", { offset: 12 })) { return { ext: "ace", mime: "application/x-ace-compressed" }; } if (this.checkString("BEGIN:")) { if (this.checkString("VCARD", { offset: 6 })) { return { ext: "vcf", mime: "text/vcard" }; } if (this.checkString("VCALENDAR", { offset: 6 })) { return { ext: "ics", mime: "text/calendar" }; } } if (this.checkString("FUJIFILMCCD-RAW")) { return { ext: "raf", mime: "image/x-fujifilm-raf" }; } if (this.checkString("Extended Module:")) { return { ext: "xm", mime: "audio/x-xm" }; } if (this.checkString("Creative Voice File")) { return { ext: "voc", mime: "audio/x-voc" }; } if (this.check([4, 0, 0, 0]) && this.buffer.length >= 16) { const jsonSize = new DataView(this.buffer.buffer).getUint32(12, true); if (jsonSize > 12 && this.buffer.length >= jsonSize + 16) { try { const header = new TextDecoder().decode(this.buffer.slice(16, jsonSize + 16)); const json = JSON.parse(header); if (json.files) { return { ext: "asar", mime: "application/x-asar" }; } } catch { } } } if (this.check([6, 14, 43, 52, 2, 5, 1, 1, 13, 1, 2, 1, 1, 2])) { return { ext: "mxf", mime: "application/mxf" }; } if (this.checkString("SCRM", { offset: 44 })) { return { ext: "s3m", mime: "audio/x-s3m" }; } if (this.check([71]) && this.check([71], { offset: 188 })) { return { ext: "mts", mime: "video/mp2t" }; } if (this.check([71], { offset: 4 }) && this.check([71], { offset: 196 })) { return { ext: "mts", mime: "video/mp2t" }; } if (this.check([66, 79, 79, 75, 77, 79, 66, 73], { offset: 60 })) { return { ext: "mobi", mime: "application/x-mobipocket-ebook" }; } if (this.check([68, 73, 67, 77], { offset: 128 })) { return { ext: "dcm", mime: "application/dicom" }; } if (this.check([76, 0, 0, 0, 1, 20, 2, 0, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 70])) { return { ext: "lnk", mime: "application/x.ms.shortcut" // Invented by us }; } if (this.check([98, 111, 111, 107, 0, 0, 0, 0, 109, 97, 114, 107, 0, 0, 0, 0])) { return { ext: "alias", mime: "application/x.apple.alias" // Invented by us }; } if (this.checkString("Kaydara FBX Binary \0")) { return { ext: "fbx", mime: "application/x.autodesk.fbx" // Invented by us }; } if (this.check([76, 80], { offset: 34 }) && (this.check([0, 0, 1], { offset: 8 }) || this.check([1, 0, 2], { offset: 8 }) || this.check([2, 0, 2], { offset: 8 }))) { return { ext: "eot", mime: "application/vnd.ms-fontobject" }; } if (this.check([6, 6, 237, 245, 216, 29, 70, 229, 189, 49, 239, 231, 254, 116, 183, 29])) { return { ext: "indd", mime: "application/x-indesign" }; } await tokenizer.peekBuffer(this.buffer, { length: Math.min(512, tokenizer.fileInfo.size), mayBeLess: true }); if (tarHeaderChecksumMatches(this.buffer)) { return { ext: "tar", mime: "application/x-tar" }; } if (this.check([255, 254])) { if (this.check([60, 0, 63, 0, 120, 0, 109, 0, 108, 0], { offset: 2 })) { return { ext: "xml", mime: "application/xml" }; } if (this.check([255, 14, 83, 0, 107, 0, 101, 0, 116, 0, 99, 0, 104, 0, 85, 0, 112, 0, 32, 0, 77, 0, 111, 0, 100, 0, 101, 0, 108, 0], { offset: 2 })) { return { ext: "skp", mime: "application/vnd.sketchup.skp" }; } return void 0; } if (this.checkString("-----BEGIN PGP MESSAGE-----")) { return { ext: "pgp", mime: "application/pgp-encrypted" }; } if (this.buffer.length >= 2 && this.check([255, 224], { offset: 0, mask: [255, 224] })) { if (this.check([16], { offset: 1, mask: [22] })) { if (this.check([8], { offset: 1, mask: [8] })) { return { ext: "aac", mime: "audio/aac" }; } return { ext: "aac", mime: "audio/aac" }; } if (this.check([2], { offset: 1, mask: [6] })) { return { ext: "mp3", mime: "audio/mpeg" }; } if (this.check([4], { offset: 1, mask: [6] })) { return { ext: "mp2", mime: "audio/mpeg" }; } if (this.check([6], { offset: 1, mask: [6] })) { return { ext: "mp1", mime: "audio/mpeg" }; } } } async readTiffTag(bigEndian) { const tagId = await this.tokenizer.readToken(bigEndian ? UINT16_BE : UINT16_LE); this.tokenizer.ignore(10); switch (tagId) { case 50341: return { ext: "arw", mime: "image/x-sony-arw" }; case 50706: return { ext: "dng", mime: "image/x-adobe-dng" }; default: } } async readTiffIFD(bigEndian) { const numberOfTags = await this.tokenizer.readToken(bigEndian ? UINT16_BE : UINT16_LE); for (let n = 0; n < numberOfTags; ++n) { const fileType = await this.readTiffTag(bigEndian); if (fileType) { return fileType; } } } async readTiffHeader(bigEndian) { const version = (bigEndian ? UINT16_BE : UINT16_LE).get(this.buffer, 2); const ifdOffset = (bigEndian ? UINT32_BE : UINT32_LE).get(this.buffer, 4); if (version === 42) { if (ifdOffset >= 6) { if (this.checkString("CR", { offset: 8 })) { return { ext: "cr2", mime: "image/x-canon-cr2" }; } if (ifdOffset >= 8 && (this.check([28, 0, 254, 0], { offset: 8 }) || this.check([31, 0, 11, 0], { offset: 8 }))) { return { ext: "nef", mime: "image/x-nikon-nef" }; } } await this.tokenizer.ignore(ifdOffset); const fileType = await this.readTiffIFD(bigEndian); return fileType ?? { ext: "tif", mime: "image/tiff" }; } if (version === 43) { return { ext: "tif", mime: "image/tiff" }; } } }; var supportedExtensions = new Set(extensions); var supportedMimeTypes = new Set(mimeTypes); // node_modules/.pnpm/file-type@19.6.0/node_modules/file-type/index.js var NodeFileTypeParser = class extends FileTypeParser { async fromStream(stream) { const tokenizer = await (stream instanceof import_web.ReadableStream ? fromWebStream(stream, this.tokenizerOptions) : fromStream2(stream, this.tokenizerOptions)); try { return await super.fromTokenizer(tokenizer); } finally { await tokenizer.close(); } } async fromFile(path) { const tokenizer = await fromFile(path); try { return await super.fromTokenizer(tokenizer); } finally { await tokenizer.close(); } } async toDetectionStream(readableStream, options = {}) { if (!(readableStream instanceof import_node_stream.Readable)) { return super.toDetectionStream(readableStream, options); } const { sampleSize = reasonableDetectionSizeInBytes } = options; return new Promise((resolve, reject) => { readableStream.on("error", reject); readableStream.once("readable", () => { (async () => { try { const pass = new import_node_stream.PassThrough(); const outputStream = import_node_stream.pipeline ? (0, import_node_stream.pipeline)(readableStream, pass, () => { }) : readableStream.pipe(pass); const chunk = readableStream.read(sampleSize) ?? readableStream.read() ?? new Uint8Array(0); try { pass.fileType = await this.fromBuffer(chunk); } catch (error) { if (error instanceof EndOfStreamError) { pass.fileType = void 0; } else { reject(error); } } resolve(outputStream); } catch (error) { reject(error); } })(); }); }); } }; async function fileTypeFromFile(path, fileTypeOptions) { return new NodeFileTypeParser(fileTypeOptions).fromFile(path, fileTypeOptions); } // src/tray.ts var import_module = require("module"); var import_node_path = require("node:path"); var tray = process.pkg ? (0, import_module.createRequire)(__filename)((0, import_node_path.join)(process.cwd(), "node_modules/bindings"))({ bindings: "tray", module_root: process.cwd() }) : (0, import_module.createRequire)(__filename)("bindings")("tray"); var _trayIcon; async function createTrayIcon(trayIcon) { if (_trayIcon) { throw new Error("May only be called once!"); } const mimeType = (await fileTypeFromFile(trayIcon.icon))?.mime; if (mimeType !== "image/x-icon") { throw new Error( `Image mime type has to be "image/x-icon"! (Instead got: ${mimeType})` ); } _trayIcon = trayIcon; if (trayIcon.items.length > 0) { const uniqueIds = new Set( trayIcon.items.map(({ id }) => id).filter((id) => id !== void 0) ); if (uniqueIds.size !== trayIcon.items.length) { throw new Error("IDs must be defined and unique!"); } trayIcon.items.forEach((item) => { item.checked ??= false; item.enabled ??= true; }); tray.create( trayIcon.icon, trayIcon.tooltip, trayIcon.items, (item) => { trayIcon.items.find(({ id }) => item.id === id)?.onClick?.(item); } ); } else { throw new Error("At least one item has to be provided."); } } function destroyTrayIcon() { if (!_trayIcon) { return; } tray.exit(); _trayIcon = void 0; } function updateTrayIconImage(icon) { wasCreatedGuard(); tray.updateIcon(icon); } function updateTrayItem(item) { wasCreatedGuard(); item.checked ??= false; item.enabled ??= true; try { tray.update(item); } catch (e) { console.error(e); } } function updateTrayTooltip(tooltip) { wasCreatedGuard(); tray.updateTooltip(tooltip); } function wasCreatedGuard() { if (!_trayIcon) { throw new Error("Tray icon hasn't been created yet!"); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { createTrayIcon, destroyTrayIcon, updateTrayIconImage, updateTrayItem, updateTrayTooltip }); /*! Bundled license information: ieee754/index.js: (*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh *) */