Skip to content
Snippets Groups Projects
index.js 8.75 MiB
Newer Older
  • Learn to ignore specific revisions
  • Romain CREY's avatar
    Romain CREY committed
    
    
    		async function readChildren(level, children) {
    			while (children > 0) {
    				const e = await readElement();
    				if (e.id === 0x4282) {
    					return tokenizer.readToken(new Token.StringType(e.len, 'utf-8')); // Return DocType
    				}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    				await tokenizer.ignore(e.len); // ignore payload
    				--children;
    			}
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		const re = await readElement();
    		const docType = await readChildren(1, re.len);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		switch (docType) {
    			case 'webm':
    				return {
    					ext: 'webm',
    					mime: 'video/webm'
    				};
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    			case 'matroska':
    				return {
    					ext: 'mkv',
    					mime: 'video/x-matroska'
    				};
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// RIFF file format which might be AVI, WAV, QCP, etc
    	if (check([0x52, 0x49, 0x46, 0x46])) {
    		if (check([0x41, 0x56, 0x49], {offset: 8})) {
    			return {
    				ext: 'avi',
    				mime: 'video/vnd.avi'
    			};
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		if (check([0x57, 0x41, 0x56, 0x45], {offset: 8})) {
    			return {
    				ext: 'wav',
    				mime: 'audio/vnd.wave'
    			};
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		// QLCM, QCP file
    		if (check([0x51, 0x4C, 0x43, 0x4D], {offset: 8})) {
    			return {
    				ext: 'qcp',
    				mime: 'audio/qcelp'
    			};
    		}
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('SQLi')) {
    		return {
    			ext: 'sqlite',
    			mime: 'application/x-sqlite3'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x4E, 0x45, 0x53, 0x1A])) {
    		return {
    			ext: 'nes',
    			mime: 'application/x-nintendo-nes-rom'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('Cr24')) {
    		return {
    			ext: 'crx',
    			mime: 'application/x-google-chrome-extension'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (
    		checkString('MSCF') ||
    		checkString('ISc(')
    	) {
    		return {
    			ext: 'cab',
    			mime: 'application/vnd.ms-cab-compressed'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0xED, 0xAB, 0xEE, 0xDB])) {
    		return {
    			ext: 'rpm',
    			mime: 'application/x-rpm'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0xC5, 0xD0, 0xD3, 0xC6])) {
    		return {
    			ext: 'eps',
    			mime: 'application/eps'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// -- 5-byte signatures --
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x4F, 0x54, 0x54, 0x4F, 0x00])) {
    		return {
    			ext: 'otf',
    			mime: 'font/otf'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('#!AMR')) {
    		return {
    			ext: 'amr',
    			mime: 'audio/amr'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('{\\rtf')) {
    		return {
    			ext: 'rtf',
    			mime: 'application/rtf'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x46, 0x4C, 0x56, 0x01])) {
    		return {
    			ext: 'flv',
    			mime: 'video/x-flv'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('IMPM')) {
    		return {
    			ext: 'it',
    			mime: 'audio/x-it'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (
    		checkString('-lh0-', {offset: 2}) ||
    		checkString('-lh1-', {offset: 2}) ||
    		checkString('-lh2-', {offset: 2}) ||
    		checkString('-lh3-', {offset: 2}) ||
    		checkString('-lh4-', {offset: 2}) ||
    		checkString('-lh5-', {offset: 2}) ||
    		checkString('-lh6-', {offset: 2}) ||
    		checkString('-lh7-', {offset: 2}) ||
    		checkString('-lzs-', {offset: 2}) ||
    		checkString('-lz4-', {offset: 2}) ||
    		checkString('-lz5-', {offset: 2}) ||
    		checkString('-lhd-', {offset: 2})
    	) {
    		return {
    			ext: 'lzh',
    			mime: 'application/x-lzh-compressed'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// MPEG program stream (PS or MPEG-PS)
    	if (check([0x00, 0x00, 0x01, 0xBA])) {
    		//  MPEG-PS, MPEG-1 Part 1
    		if (check([0x21], {offset: 4, mask: [0xF1]})) {
    			return {
    				ext: 'mpg', // May also be .ps, .mpeg
    				mime: 'video/MP1S'
    			};
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		// MPEG-PS, MPEG-2 Part 1
    		if (check([0x44], {offset: 4, mask: [0xC4]})) {
    			return {
    				ext: 'mpg', // May also be .mpg, .m2p, .vob or .sub
    				mime: 'video/MP2P'
    			};
    		}
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// -- 6-byte signatures --
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])) {
    		return {
    			ext: 'xz',
    			mime: 'application/x-xz'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('<?xml ')) {
    		return {
    			ext: 'xml',
    			mime: 'application/xml'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('BEGIN:')) {
    		return {
    			ext: 'ics',
    			mime: 'text/calendar'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C])) {
    		return {
    			ext: '7z',
    			mime: 'application/x-7z-compressed'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (
    		check([0x52, 0x61, 0x72, 0x21, 0x1A, 0x7]) &&
    		(buffer[6] === 0x0 || buffer[6] === 0x1)
    	) {
    		return {
    			ext: 'rar',
    			mime: 'application/x-rar-compressed'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// -- 7-byte signatures --
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('BLENDER')) {
    		return {
    			ext: 'blend',
    			mime: 'application/x-blender'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('!<arch>')) {
    		await tokenizer.ignore(8);
    		const str = await tokenizer.readToken(new Token.StringType(13, 'ascii'));
    		if (str === 'debian-binary') {
    			return {
    				ext: 'deb',
    				mime: 'application/x-deb'
    			};
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		return {
    			ext: 'ar',
    			mime: 'application/x-unix-archive'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// -- 8-byte signatures --
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) {
    		// APNG format (https://wiki.mozilla.org/APNG_Specification)
    		// 1. Find the first IDAT (image data) chunk (49 44 41 54)
    		// 2. Check if there is an "acTL" chunk before the IDAT one (61 63 54 4C)
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		// Offset calculated as follows:
    		// - 8 bytes: PNG signature
    		// - 4 (length) + 4 (chunk type) + 13 (chunk data) + 4 (CRC): IHDR chunk
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		await tokenizer.ignore(8); // ignore PNG signature
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		async function readChunkHeader() {
    			return {
    				length: await tokenizer.readToken(Token.INT32_BE),
    				type: await tokenizer.readToken(new Token.StringType(4, 'binary'))
    			};
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		do {
    			const chunk = await readChunkHeader();
    			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); // Ignore chunk-data + CRC
    			}
    		} while (tokenizer.position < tokenizer.fileInfo.size);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x41, 0x52, 0x52, 0x4F, 0x57, 0x31, 0x00, 0x00])) {
    		return {
    			ext: 'arrow',
    			mime: 'application/x-apache-arrow'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x67, 0x6C, 0x54, 0x46, 0x02, 0x00, 0x00, 0x00])) {
    		return {
    			ext: 'glb',
    			mime: 'model/gltf-binary'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// `mov` format variants
    	if (
    		check([0x66, 0x72, 0x65, 0x65], {offset: 4}) || // `free`
    		check([0x6D, 0x64, 0x61, 0x74], {offset: 4}) || // `mdat` MJPEG
    		check([0x6D, 0x6F, 0x6F, 0x76], {offset: 4}) || // `moov`
    		check([0x77, 0x69, 0x64, 0x65], {offset: 4}) // `wide`
    	) {
    		return {
    			ext: 'mov',
    			mime: 'video/quicktime'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// -- 9-byte signatures --
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x49, 0x49, 0x52, 0x4F, 0x08, 0x00, 0x00, 0x00, 0x18])) {
    		return {
    			ext: 'orf',
    			mime: 'image/x-olympus-orf'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// -- 12-byte signatures --
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x49, 0x49, 0x55, 0x00, 0x18, 0x00, 0x00, 0x00, 0x88, 0xE7, 0x74, 0xD8])) {
    		return {
    			ext: 'rw2',
    			mime: 'image/x-panasonic-rw2'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// ASF_Header_Object first 80 bytes
    	if (check([0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9])) {
    		async function readHeader() {
    			const guid = Buffer.alloc(16);
    			await tokenizer.readBuffer(guid);
    			return {
    				id: guid,
    				size: await tokenizer.readToken(Token.UINT64_LE)
    			};
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		await tokenizer.ignore(30);
    		// Search for header should be in first 1KB of file.
    		while (tokenizer.position + 24 < tokenizer.fileInfo.size) {
    			const header = await readHeader();
    			let payload = header.size - 24;
    			if (_check(header.id, [0x91, 0x07, 0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65])) {
    				// Sync on Stream-Properties-Object (B7DC0791-A9B7-11CF-8EE6-00C00C205365)
    				const typeId = Buffer.alloc(16);
    				payload -= await tokenizer.readBuffer(typeId);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    				if (_check(typeId, [0x40, 0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B])) {
    					// Found audio:
    					return {
    						ext: 'wma',
    						mime: 'audio/x-ms-wma'
    					};
    				}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    				if (_check(typeId, [0xC0, 0xEF, 0x19, 0xBC, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B])) {
    					// Found video:
    					return {
    						ext: 'wmv',
    						mime: 'video/x-ms-asf'
    					};
    				}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    			await tokenizer.ignore(payload);
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		// Default to ASF generic extension
    		return {
    			ext: 'asf',
    			mime: 'application/vnd.ms-asf'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A])) {
    		return {
    			ext: 'ktx',
    			mime: 'image/ktx'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if ((check([0x7E, 0x10, 0x04]) || check([0x7E, 0x18, 0x04])) && check([0x30, 0x4D, 0x49, 0x45], {offset: 4})) {
    		return {
    			ext: 'mie',
    			mime: 'application/x-mie'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x27, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], {offset: 2})) {
    		return {
    			ext: 'shp',
    			mime: 'application/x-esri-shape'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A])) {
    		// JPEG-2000 family
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		await tokenizer.ignore(20);
    		const type = await tokenizer.readToken(new Token.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;
    		}
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// -- Unsafe signatures --
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (
    		check([0x0, 0x0, 0x1, 0xBA]) ||
    		check([0x0, 0x0, 0x1, 0xB3])
    	) {
    		return {
    			ext: 'mpg',
    			mime: 'video/mpeg'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x00, 0x01, 0x00, 0x00, 0x00])) {
    		return {
    			ext: 'ttf',
    			mime: 'font/ttf'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x00, 0x00, 0x01, 0x00])) {
    		return {
    			ext: 'ico',
    			mime: 'image/x-icon'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x00, 0x00, 0x02, 0x00])) {
    		return {
    			ext: 'cur',
    			mime: 'image/x-icon'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// Increase sample size from 12 to 256.
    	await tokenizer.peekBuffer(buffer, {length: Math.min(256, tokenizer.fileInfo.size), mayBeLess: true});
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// `raf` is here just to keep all the raw image detectors together.
    	if (checkString('FUJIFILMCCD-RAW')) {
    		return {
    			ext: 'raf',
    			mime: 'image/x-fujifilm-raf'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('Extended Module:')) {
    		return {
    			ext: 'xm',
    			mime: 'audio/x-xm'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('Creative Voice File')) {
    		return {
    			ext: 'voc',
    			mime: 'audio/x-voc'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x04, 0x00, 0x00, 0x00]) && buffer.length >= 16) { // Rough & quick check Pickle/ASAR
    		const jsonSize = buffer.readUInt32LE(12);
    		if (jsonSize > 12 && jsonSize < 240 && buffer.length >= jsonSize + 16) {
    			try {
    				const header = buffer.slice(16, jsonSize + 16).toString();
    				const json = JSON.parse(header);
    				// Check if Pickle is ASAR
    				if (json.files) { // Final check, assuring Pickle/ASAR format
    					return {
    						ext: 'asar',
    						mime: 'application/x-asar'
    					};
    				}
    			} catch (_) {
    			}
    		}
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E])) {
    		return {
    			ext: 'msi',
    			mime: 'application/x-msi'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x06, 0x0E, 0x2B, 0x34, 0x02, 0x05, 0x01, 0x01, 0x0D, 0x01, 0x02, 0x01, 0x01, 0x02])) {
    		return {
    			ext: 'mxf',
    			mime: 'application/mxf'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('SCRM', {offset: 44})) {
    		return {
    			ext: 's3m',
    			mime: 'audio/x-s3m'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x47], {offset: 4}) && (check([0x47], {offset: 192}) || check([0x47], {offset: 196}))) {
    		return {
    			ext: 'mts',
    			mime: 'video/mp2t'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x42, 0x4F, 0x4F, 0x4B, 0x4D, 0x4F, 0x42, 0x49], {offset: 60})) {
    		return {
    			ext: 'mobi',
    			mime: 'application/x-mobipocket-ebook'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x44, 0x49, 0x43, 0x4D], {offset: 128})) {
    		return {
    			ext: 'dcm',
    			mime: 'application/dicom'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x4C, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46])) {
    		return {
    			ext: 'lnk',
    			mime: 'application/x.ms.shortcut' // Invented by us
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x62, 0x6F, 0x6F, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x72, 0x6B, 0x00, 0x00, 0x00, 0x00])) {
    		return {
    			ext: 'alias',
    			mime: 'application/x.apple.alias' // Invented by us
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (
    		check([0x4C, 0x50], {offset: 34}) &&
    		(
    			check([0x00, 0x00, 0x01], {offset: 8}) ||
    			check([0x01, 0x00, 0x02], {offset: 8}) ||
    			check([0x02, 0x00, 0x02], {offset: 8})
    		)
    	) {
    		return {
    			ext: 'eot',
    			mime: 'application/vnd.ms-fontobject'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0x06, 0x06, 0xED, 0xF5, 0xD8, 0x1D, 0x46, 0xE5, 0xBD, 0x31, 0xEF, 0xE7, 0xFE, 0x74, 0xB7, 0x1D])) {
    		return {
    			ext: 'indd',
    			mime: 'application/x-indesign'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// Increase sample size from 256 to 512
    	await tokenizer.peekBuffer(buffer, {length: Math.min(512, tokenizer.fileInfo.size), mayBeLess: true});
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// Requires a buffer size of 512 bytes
    	if (tarHeaderChecksumMatches(buffer)) {
    		return {
    			ext: 'tar',
    			mime: 'application/x-tar'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (check([0xFF, 0xFE, 0xFF, 0x0E, 0x53, 0x00, 0x6B, 0x00, 0x65, 0x00, 0x74, 0x00, 0x63, 0x00, 0x68, 0x00, 0x55, 0x00, 0x70, 0x00, 0x20, 0x00, 0x4D, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6C, 0x00])) {
    		return {
    			ext: 'skp',
    			mime: 'application/vnd.sketchup.skp'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	if (checkString('-----BEGIN PGP MESSAGE-----')) {
    		return {
    			ext: 'pgp',
    			mime: 'application/pgp-encrypted'
    		};
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	// Check for MPEG header at different starting offsets
    	for (let start = 0; start < 2 && start < (buffer.length - 16); start++) {
    		// Check MPEG 1 or 2 Layer 3 header, or 'layer 0' for ADTS (MPEG sync-word 0xFFE)
    		if (buffer.length >= start + 2 && check([0xFF, 0xE0], {offset: start, mask: [0xFF, 0xE0]})) {
    			if (check([0x10], {offset: start + 1, mask: [0x16]})) {
    				// Check for (ADTS) MPEG-2
    				if (check([0x08], {offset: start + 1, mask: [0x08]})) {
    					return {
    						ext: 'aac',
    						mime: 'audio/aac'
    					};
    				}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    				// Must be (ADTS) MPEG-4
    				return {
    					ext: 'aac',
    					mime: 'audio/aac'
    				};
    			}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    			// MPEG 1 or 2 Layer 3 header
    			// Check for MPEG layer 3
    			if (check([0x02], {offset: start + 1, mask: [0x06]})) {
    				return {
    					ext: 'mp3',
    					mime: 'audio/mpeg'
    				};
    			}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    			// Check for MPEG layer 2
    			if (check([0x04], {offset: start + 1, mask: [0x06]})) {
    				return {
    					ext: 'mp2',
    					mime: 'audio/mpeg'
    				};
    			}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    			// Check for MPEG layer 1
    			if (check([0x06], {offset: start + 1, mask: [0x06]})) {
    				return {
    					ext: 'mp1',
    					mime: 'audio/mpeg'
    				};
    			}
    		}
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    const stream = readableStream => new Promise((resolve, reject) => {
    	// Using `eval` to work around issues when bundling with Webpack
    	const stream = eval('require')('stream'); // eslint-disable-line no-eval
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	readableStream.on('error', reject);
    	readableStream.once('readable', async () => {
    		// Set up output stream
    		const pass = new stream.PassThrough();
    		let outputStream;
    		if (stream.pipeline) {
    			outputStream = stream.pipeline(readableStream, pass, () => {
    			});
    		} else {
    			outputStream = readableStream.pipe(pass);
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		// Read the input stream and detect the filetype
    		const chunk = readableStream.read(minimumBytes) || readableStream.read() || Buffer.alloc(0);
    		try {
    			const fileType = await fromBuffer(chunk);
    			pass.fileType = fileType;
    		} catch (error) {
    			reject(error);
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const fileType = {
    	fromStream,
    	fromTokenizer,
    	fromBuffer,
    	stream
    };
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Object.defineProperty(fileType, 'extensions', {
    	get() {
    		return new Set(supported.extensions);
    	}
    });
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Object.defineProperty(fileType, 'mimeTypes', {
    	get() {
    		return new Set(supported.mimeTypes);
    	}
    });
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = fileType;
    
    /***/ }),
    /* 1666 */
    /***/ (function(module, exports, __webpack_require__) {
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    212722 212723 212724 212725 212726 212727 212728 212729 212730 212731 212732 212733 212734 212735 212736 212737 212738 212739 212740 212741 212742 212743 212744 212745 212746 212747 212748 212749 212750 212751 212752 212753 212754 212755 212756 212757 212758 212759 212760 212761 212762 212763 212764 212765 212766 212767 212768 212769 212770 212771 212772 212773 212774 212775 212776 212777 212778 212779 212780 212781 212782 212783 212784 212785 212786 212787 212788 212789 212790 212791 212792 212793 212794 212795 212796 212797 212798 212799 212800 212801 212802 212803 212804 212805 212806 212807 212808 212809 212810 212811 212812 212813 212814 212815 212816 212817 212818 212819 212820 212821 212822 212823 212824 212825 212826 212827 212828 212829 212830 212831 212832 212833 212834 212835 212836 212837 212838 212839 212840 212841 212842 212843 212844 212845 212846 212847 212848 212849 212850 212851 212852 212853 212854 212855 212856 212857 212858 212859 212860 212861 212862 212863 212864 212865 212866 212867 212868 212869 212870 212871 212872 212873 212874 212875 212876 212877 212878 212879 212880 212881 212882 212883 212884 212885 212886 212887 212888 212889 212890 212891 212892 212893 212894 212895 212896 212897 212898 212899 212900 212901 212902 212903 212904 212905 212906 212907 212908 212909 212910 212911 212912 212913 212914 212915 212916 212917 212918 212919 212920 212921 212922 212923 212924 212925 212926 212927 212928 212929 212930 212931 212932 212933 212934 212935 212936 212937 212938 212939 212940 212941 212942 212943 212944 212945 212946 212947 212948 212949 212950 212951 212952 212953 212954 212955 212956 212957 212958 212959 212960 212961 212962 212963 212964 212965 212966 212967 212968 212969 212970 212971 212972 212973 212974 212975 212976 212977 212978 212979 212980 212981 212982 212983 212984 212985 212986 212987 212988 212989 212990 212991 212992 212993 212994 212995 212996 212997 212998 212999 213000
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.writeIntBE = exports.readIntBE = exports.writeUIntBE = exports.readUIntBE = exports.writeIntLE = exports.AnsiStringType = exports.StringType = exports.BufferType = exports.IgnoreType = exports.Float80_LE = exports.Float80_BE = exports.Float64_LE = exports.Float64_BE = exports.Float32_LE = exports.Float32_BE = exports.Float16_LE = exports.Float16_BE = exports.INT64_BE = exports.UINT64_BE = exports.INT64_LE = exports.UINT64_LE = exports.INT32_LE = exports.INT32_BE = exports.INT24_BE = exports.INT24_LE = exports.INT16_LE = exports.INT16_BE = exports.INT8 = exports.UINT32_BE = exports.UINT32_LE = exports.UINT24_BE = exports.UINT24_LE = exports.UINT16_BE = exports.UINT16_LE = exports.UINT8 = void 0;
    const ieee754 = __webpack_require__(1667);
    // Primitive types
    /**
     * 8-bit unsigned integer
     */
    exports.UINT8 = {
        len: 1,
        get(buf, off) {
            return buf.readUInt8(off);
        },
        put(buf, off, v) {
            return buf.writeUInt8(v, off);
        }
    };
    /**
     * 16-bit unsigned integer, Little Endian byte order
     */
    exports.UINT16_LE = {
        len: 2,
        get(buf, off) {
            return buf.readUInt16LE(off);
        },
        put(buf, off, v) {
            return buf.writeUInt16LE(v, off);
        }
    };
    /**
     * 16-bit unsigned integer, Big Endian byte order
     */
    exports.UINT16_BE = {
        len: 2,
        get(buf, off) {
            return buf.readUInt16BE(off);
        },
        put(buf, off, v) {
            return buf.writeUInt16BE(v, off);
        }
    };
    /**
     * 24-bit unsigned integer, Little Endian byte order
     */
    exports.UINT24_LE = {
        len: 3,
        get(buf, off) {
            return buf.readUIntLE(off, 3);
        },
        put(buf, off, v) {
            return buf.writeUIntLE(v, off, 3);
        }
    };
    /**
     * 24-bit unsigned integer, Big Endian byte order
     */
    exports.UINT24_BE = {
        len: 3,
        get(buf, off) {
            return buf.readUIntBE(off, 3);
        },
        put(buf, off, v) {
            return buf.writeUIntBE(v, off, 3);
        }
    };
    /**
     * 32-bit unsigned integer, Little Endian byte order
     */
    exports.UINT32_LE = {
        len: 4,
        get(buf, off) {
            return buf.readUInt32LE(off);
        },
        put(b, o, v) {
            return b.writeUInt32LE(v, o);
        }
    };
    /**
     * 32-bit unsigned integer, Big Endian byte order
     */
    exports.UINT32_BE = {
        len: 4,
        get(buf, off) {
            return buf.readUInt32BE(off);
        },
        put(buf, off, v) {
            return buf.writeUInt32BE(v, off);
        }
    };
    /**
     * 8-bit signed integer
     */
    exports.INT8 = {
        len: 1,
        get(buf, off) {
            return buf.readInt8(off);
        },
        put(buf, off, v) {
            return buf.writeInt8(v, off);
        }
    };
    /**
     * 16-bit signed integer, Big Endian byte order
     */
    exports.INT16_BE = {
        len: 2,
        get(buf, off) {
            return buf.readInt16BE(off);
        },
        put(b, o, v) {
            return b.writeInt16BE(v, o);
        }
    };
    /**
     * 16-bit signed integer, Little Endian byte order
     */
    exports.INT16_LE = {
        len: 2,
        get(buf, off) {
            return buf.readInt16LE(off);
        },
        put(b, o, v) {
            return b.writeInt16LE(v, o);
        }
    };
    /**
     * 24-bit signed integer, Little Endian byte order
     */
    exports.INT24_LE = {
        len: 3,
        get(buf, off) {
            return buf.readIntLE(off, 3);
        },
        put(b, o, v) {
            return b.writeIntLE(v, o, 3);
        }
    };
    /**
     * 24-bit signed integer, Big Endian byte order
     */
    exports.INT24_BE = {
        len: 3,
        get(buf, off) {
            return buf.readIntBE(off, 3);
        },
        put(b, o, v) {
            return b.writeIntBE(v, o, 3);
        }
    };
    /**
     * 32-bit signed integer, Big Endian byte order
     */
    exports.INT32_BE = {
        len: 4,
        get(buf, off) {
            return buf.readInt32BE(off);
        },
        put(b, o, v) {
            return b.writeInt32BE(v, o);
        }
    };
    /**
     * 32-bit signed integer, Big Endian byte order
     */
    exports.INT32_LE = {
        len: 4,
        get(buf, off) {
            return buf.readInt32LE(off);
        },
        put(b, o, v) {
            return b.writeInt32LE(v, o);
        }
    };
    /**
     * 64-bit unsigned integer, Little Endian byte order
     */
    exports.UINT64_LE = {
        len: 8,
        get(buf, off) {
            return readUIntLE(buf, off, this.len);
        },
        put(b, o, v) {
            return writeUIntLE(b, v, o, this.len);
        }
    };
    /**
     * 64-bit signed integer, Little Endian byte order
     */
    exports.INT64_LE = {
        len: 8,
        get(buf, off) {
            return readIntLE(buf, off, this.len);
        },
        put(b, off, v) {
            return writeIntLE(b, v, off, this.len);
        }
    };
    /**
     * 64-bit unsigned integer, Big Endian byte order
     */
    exports.UINT64_BE = {
        len: 8,
        get(b, off) {
            return readUIntBE(b, off, this.len);
        },
        put(b, o, v) {
            return writeUIntBE(b, v, o, this.len);
        }
    };
    /**
     * 64-bit signed integer, Big Endian byte order
     */
    exports.INT64_BE = {
        len: 8,
        get(b, off) {
            return readIntBE(b, off, this.len);
        },
        put(b, off, v) {
            return writeIntBE(b, v, off, this.len);
        }
    };
    /**
     * IEEE 754 16-bit (half precision) float, big endian
     */
    exports.Float16_BE = {
        len: 2,
        get(b, off) {
            return ieee754.read(b, off, false, 10, this.len);
        },
        put(b, off, v) {
            ieee754.write(b, v, off, false, 10, this.len);
            return off + this.len;
        }
    };
    /**
     * IEEE 754 16-bit (half precision) float, little endian
     */
    exports.Float16_LE = {
        len: 2,
        get(b, off) {
            return ieee754.read(b, off, true, 10, this.len);
        },
        put(b, off, v) {
            ieee754.write(b, v, off, true, 10, this.len);
            return off + this.len;
        }
    };
    /**
     * IEEE 754 32-bit (single precision) float, big endian
     */
    exports.Float32_BE = {
        len: 4,
        get(b, off) {
            return b.readFloatBE(off);
        },
        put(b, off, v) {
            return b.writeFloatBE(v, off);
        }
    };
    /**
     * IEEE 754 32-bit (single precision) float, little endian
     */
    exports.Float32_LE = {
        len: 4,
        get(b, off) {
            return b.readFloatLE(off);
        },
        put(b, off, v) {
            return b.writeFloatLE(v, off);
        }
    };
    /**
     * IEEE 754 64-bit (double precision) float, big endian
     */
    exports.Float64_BE = {
        len: 8,
        get(b, off) {
            return b.readDoubleBE(off);
        },
        put(b, off, v) {