#include <stdio.h>
 
/*
NAND Flash Information Dumper
===============================
Created on July 12, 2020 by Jason Gin (ripitapart.com).
Made to display a specific NAND Flash ID code and corresponding parameter table,
but the data can easily be replaced with other Flash chips' data if desired.
*/
 
int main(void) {
	printf("NAND Flash Info & Parameter Page Dump:\n"); 	printf("SanDisk High Endurance 128GB microSDXC Card\n"); 	printf("Blog post for more info: wp.me/p21X5Z-vp or visit ripitapart.com\n\n");  
	// Raw NAND info and parameter page data from SanDisk High Endurance 128GB microSDXC card
	unsigned char nand_flash_id[6] = { 0x45, 0x48, 0x9A, 0xB3, 0x7E, 0x72 };
	// NOTE: Real parameter page contains 4128 bytes but is just the same repeating data
	unsigned char parameter_page_data[512] =
	{
		0x53,0x4E,0x44,0x4B,0x53,0x4E,0x44,0x4B,0x53,0x4E,0x44,0x4B,0x53,0x4E,0x44,0x4B,
		0x53,0x4E,0x44,0x4B,0x53,0x4E,0x44,0x4B,0x53,0x4E,0x44,0x4B,0x53,0x4E,0x44,0x4B,
		0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,
		0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,
		0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,
		0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,
		0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,
		0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,
		0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,
		0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,
		0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,
		0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,
		0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,
		0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,
		0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,
		0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,
		0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,
		0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,
		0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,
		0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,
		0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,
		0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,
		0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,
		0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,
		0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,
		0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,
		0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,
		0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,
		0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,0xB3,0x00,0x05,
		0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,0x01,0x48,0x9A,
		0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06,0x20,0x00,0x02,
		0x01,0x48,0x9A,0xB3,0x00,0x05,0x08,0x41,0x48,0x63,0x6A,0x08,0x08,0x00,0x08,0x06
		};
 
		// Create parameters for hex/ascii printout and print out Flash ID
		int bytes_per_row = 16;
		int total_rows = sizeof(parameter_page_data) / bytes_per_row;
 
		int nand_flash_id_index = 0;
		for (nand_flash_id_index = 0; nand_flash_id_index < sizeof(nand_flash_id); nand_flash_id_index++)
		{
			printf("%.2X ", nand_flash_id
[nand_flash_id_index
]);	 		}
 
		printf("Parameter page contents:\n"); 		printf("==========================\n"); 		printf("Data array size = %d bytes\n",sizeof(parameter_page_data
)); 		printf("Bytes per row = %d\n",bytes_per_row
); 		printf("Total rows = %d\n\n",total_rows
);  
		// Print out parameter page in human-readable form
 
		// Desired format:
		// Offset 00:01:02:03:04:05:06:07:08:09:0A:0B:0C:0D:0E:0F 0123456789ABCDEF
		// ------ --+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-- ----------------
		// 0xHHHH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH HH AAAAAAAAAAAAAAAA
 
		int row_index, column_index;
		int current_offset = 0;
 
		printf("Offset 00:01:02:03:04:05:06:07:08:09:0A:0B:0C:0D:0E:0F 0123456789ABCDEF\n"); 		printf("------ --+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-- ----------------\n"); 		for (row_index = 0; row_index < total_rows; row_index++)
		{
			// Byte offset in hex with padding
			printf("0x%.4X ", row_index 
* bytes_per_row
);  
			// Hexadecimal representation
			current_offset = (row_index * column_index);
			for (column_index = 0; column_index < bytes_per_row; column_index++)
			{
				printf("%.2X ", parameter_page_data
[current_offset
]); 				current_offset++;
			}
 
			// ASCII representation
			current_offset = (row_index * column_index);
			for (column_index = 0; column_index < bytes_per_row; column_index++)
			{
				if (parameter_page_data[current_offset] < 0x20) // less than 0x20 are ASCII control codes
				else if ((parameter_page_data[current_offset] >= 0x20) && (parameter_page_data[current_offset] < 0x80))
					printf("%c", parameter_page_data
[current_offset
]); 				else // 0x80 or greater is not valid for UTF-8
				current_offset++;
			}
		}
	return 0;
}
 
				I2luY2x1ZGUgPHN0ZGlvLmg+CgovKgpOQU5EIEZsYXNoIEluZm9ybWF0aW9uIER1bXBlcgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CkNyZWF0ZWQgb24gSnVseSAxMiwgMjAyMCBieSBKYXNvbiBHaW4gKHJpcGl0YXBhcnQuY29tKS4KTWFkZSB0byBkaXNwbGF5IGEgc3BlY2lmaWMgTkFORCBGbGFzaCBJRCBjb2RlIGFuZCBjb3JyZXNwb25kaW5nIHBhcmFtZXRlciB0YWJsZSwKYnV0IHRoZSBkYXRhIGNhbiBlYXNpbHkgYmUgcmVwbGFjZWQgd2l0aCBvdGhlciBGbGFzaCBjaGlwcycgZGF0YSBpZiBkZXNpcmVkLgoqLwoKaW50IG1haW4odm9pZCkgewoJcHJpbnRmKCJOQU5EIEZsYXNoIEluZm8gJiBQYXJhbWV0ZXIgUGFnZSBEdW1wOlxuIik7CglwcmludGYoIlNhbkRpc2sgSGlnaCBFbmR1cmFuY2UgMTI4R0IgbWljcm9TRFhDIENhcmRcbiIpOwoJcHJpbnRmKCJCbG9nIHBvc3QgZm9yIG1vcmUgaW5mbzogd3AubWUvcDIxWDVaLXZwIG9yIHZpc2l0IHJpcGl0YXBhcnQuY29tXG5cbiIpOwoJCgkvLyBSYXcgTkFORCBpbmZvIGFuZCBwYXJhbWV0ZXIgcGFnZSBkYXRhIGZyb20gU2FuRGlzayBIaWdoIEVuZHVyYW5jZSAxMjhHQiBtaWNyb1NEWEMgY2FyZAoJdW5zaWduZWQgY2hhciBuYW5kX2ZsYXNoX2lkWzZdID0geyAweDQ1LCAweDQ4LCAweDlBLCAweEIzLCAweDdFLCAweDcyIH07CgkvLyBOT1RFOiBSZWFsIHBhcmFtZXRlciBwYWdlIGNvbnRhaW5zIDQxMjggYnl0ZXMgYnV0IGlzIGp1c3QgdGhlIHNhbWUgcmVwZWF0aW5nIGRhdGEKCXVuc2lnbmVkIGNoYXIgcGFyYW1ldGVyX3BhZ2VfZGF0YVs1MTJdID0KCXsKCQkweDUzLDB4NEUsMHg0NCwweDRCLDB4NTMsMHg0RSwweDQ0LDB4NEIsMHg1MywweDRFLDB4NDQsMHg0QiwweDUzLDB4NEUsMHg0NCwweDRCLAoJCTB4NTMsMHg0RSwweDQ0LDB4NEIsMHg1MywweDRFLDB4NDQsMHg0QiwweDUzLDB4NEUsMHg0NCwweDRCLDB4NTMsMHg0RSwweDQ0LDB4NEIsCgkJMHgwOCwweDA4LDB4MDAsMHgwOCwweDA2LDB4MjAsMHgwMCwweDAyLDB4MDEsMHg0OCwweDlBLDB4QjMsMHgwMCwweDA1LDB4MDgsMHg0MSwKCQkweDQ4LDB4NjMsMHg2QSwweDA4LDB4MDgsMHgwMCwweDA4LDB4MDYsMHgyMCwweDAwLDB4MDIsMHgwMSwweDQ4LDB4OUEsMHhCMywweDAwLAoJCTB4MDUsMHgwOCwweDQxLDB4NDgsMHg2MywweDZBLDB4MDgsMHgwOCwweDAwLDB4MDgsMHgwNiwweDIwLDB4MDAsMHgwMiwweDAxLDB4NDgsCgkJMHg5QSwweEIzLDB4MDAsMHgwNSwweDA4LDB4NDEsMHg0OCwweDYzLDB4NkEsMHgwOCwweDA4LDB4MDAsMHgwOCwweDA2LDB4MjAsMHgwMCwKCQkweDAyLDB4MDEsMHg0OCwweDlBLDB4QjMsMHgwMCwweDA1LDB4MDgsMHg0MSwweDQ4LDB4NjMsMHg2QSwweDA4LDB4MDgsMHgwMCwweDA4LAoJCTB4MDYsMHgyMCwweDAwLDB4MDIsMHgwMSwweDQ4LDB4OUEsMHhCMywweDAwLDB4MDUsMHgwOCwweDQxLDB4NDgsMHg2MywweDZBLDB4MDgsCgkJMHgwOCwweDAwLDB4MDgsMHgwNiwweDIwLDB4MDAsMHgwMiwweDAxLDB4NDgsMHg5QSwweEIzLDB4MDAsMHgwNSwweDA4LDB4NDEsMHg0OCwKCQkweDYzLDB4NkEsMHgwOCwweDA4LDB4MDAsMHgwOCwweDA2LDB4MjAsMHgwMCwweDAyLDB4MDEsMHg0OCwweDlBLDB4QjMsMHgwMCwweDA1LAoJCTB4MDgsMHg0MSwweDQ4LDB4NjMsMHg2QSwweDA4LDB4MDgsMHgwMCwweDA4LDB4MDYsMHgyMCwweDAwLDB4MDIsMHgwMSwweDQ4LDB4OUEsCgkJMHhCMywweDAwLDB4MDUsMHgwOCwweDQxLDB4NDgsMHg2MywweDZBLDB4MDgsMHgwOCwweDAwLDB4MDgsMHgwNiwweDIwLDB4MDAsMHgwMiwKCQkweDAxLDB4NDgsMHg5QSwweEIzLDB4MDAsMHgwNSwweDA4LDB4NDEsMHg0OCwweDYzLDB4NkEsMHgwOCwweDA4LDB4MDAsMHgwOCwweDA2LAoJCTB4MjAsMHgwMCwweDAyLDB4MDEsMHg0OCwweDlBLDB4QjMsMHgwMCwweDA1LDB4MDgsMHg0MSwweDQ4LDB4NjMsMHg2QSwweDA4LDB4MDgsCgkJMHgwMCwweDA4LDB4MDYsMHgyMCwweDAwLDB4MDIsMHgwMSwweDQ4LDB4OUEsMHhCMywweDAwLDB4MDUsMHgwOCwweDQxLDB4NDgsMHg2MywKCQkweDZBLDB4MDgsMHgwOCwweDAwLDB4MDgsMHgwNiwweDIwLDB4MDAsMHgwMiwweDAxLDB4NDgsMHg5QSwweEIzLDB4MDAsMHgwNSwweDA4LAoJCTB4NDEsMHg0OCwweDYzLDB4NkEsMHgwOCwweDA4LDB4MDAsMHgwOCwweDA2LDB4MjAsMHgwMCwweDAyLDB4MDEsMHg0OCwweDlBLDB4QjMsCgkJMHgwMCwweDA1LDB4MDgsMHg0MSwweDQ4LDB4NjMsMHg2QSwweDA4LDB4MDgsMHgwMCwweDA4LDB4MDYsMHgyMCwweDAwLDB4MDIsMHgwMSwKCQkweDQ4LDB4OUEsMHhCMywweDAwLDB4MDUsMHgwOCwweDQxLDB4NDgsMHg2MywweDZBLDB4MDgsMHgwOCwweDAwLDB4MDgsMHgwNiwweDIwLAoJCTB4MDAsMHgwMiwweDAxLDB4NDgsMHg5QSwweEIzLDB4MDAsMHgwNSwweDA4LDB4NDEsMHg0OCwweDYzLDB4NkEsMHgwOCwweDA4LDB4MDAsCgkJMHgwOCwweDA2LDB4MjAsMHgwMCwweDAyLDB4MDEsMHg0OCwweDlBLDB4QjMsMHgwMCwweDA1LDB4MDgsMHg0MSwweDQ4LDB4NjMsMHg2QSwKCQkweDA4LDB4MDgsMHgwMCwweDA4LDB4MDYsMHgyMCwweDAwLDB4MDIsMHgwMSwweDQ4LDB4OUEsMHhCMywweDAwLDB4MDUsMHgwOCwweDQxLAoJCTB4NDgsMHg2MywweDZBLDB4MDgsMHgwOCwweDAwLDB4MDgsMHgwNiwweDIwLDB4MDAsMHgwMiwweDAxLDB4NDgsMHg5QSwweEIzLDB4MDAsCgkJMHgwNSwweDA4LDB4NDEsMHg0OCwweDYzLDB4NkEsMHgwOCwweDA4LDB4MDAsMHgwOCwweDA2LDB4MjAsMHgwMCwweDAyLDB4MDEsMHg0OCwKCQkweDlBLDB4QjMsMHgwMCwweDA1LDB4MDgsMHg0MSwweDQ4LDB4NjMsMHg2QSwweDA4LDB4MDgsMHgwMCwweDA4LDB4MDYsMHgyMCwweDAwLAoJCTB4MDIsMHgwMSwweDQ4LDB4OUEsMHhCMywweDAwLDB4MDUsMHgwOCwweDQxLDB4NDgsMHg2MywweDZBLDB4MDgsMHgwOCwweDAwLDB4MDgsCgkJMHgwNiwweDIwLDB4MDAsMHgwMiwweDAxLDB4NDgsMHg5QSwweEIzLDB4MDAsMHgwNSwweDA4LDB4NDEsMHg0OCwweDYzLDB4NkEsMHgwOCwKCQkweDA4LDB4MDAsMHgwOCwweDA2LDB4MjAsMHgwMCwweDAyLDB4MDEsMHg0OCwweDlBLDB4QjMsMHgwMCwweDA1LDB4MDgsMHg0MSwweDQ4LAoJCTB4NjMsMHg2QSwweDA4LDB4MDgsMHgwMCwweDA4LDB4MDYsMHgyMCwweDAwLDB4MDIsMHgwMSwweDQ4LDB4OUEsMHhCMywweDAwLDB4MDUsCgkJMHgwOCwweDQxLDB4NDgsMHg2MywweDZBLDB4MDgsMHgwOCwweDAwLDB4MDgsMHgwNiwweDIwLDB4MDAsMHgwMiwweDAxLDB4NDgsMHg5QSwKCQkweEIzLDB4MDAsMHgwNSwweDA4LDB4NDEsMHg0OCwweDYzLDB4NkEsMHgwOCwweDA4LDB4MDAsMHgwOCwweDA2LDB4MjAsMHgwMCwweDAyLAoJCTB4MDEsMHg0OCwweDlBLDB4QjMsMHgwMCwweDA1LDB4MDgsMHg0MSwweDQ4LDB4NjMsMHg2QSwweDA4LDB4MDgsMHgwMCwweDA4LDB4MDYKCQl9OwoJCQoJCS8vIENyZWF0ZSBwYXJhbWV0ZXJzIGZvciBoZXgvYXNjaWkgcHJpbnRvdXQgYW5kIHByaW50IG91dCBGbGFzaCBJRAoJCWludCBieXRlc19wZXJfcm93ID0gMTY7CgkJaW50IHRvdGFsX3Jvd3MgPSBzaXplb2YocGFyYW1ldGVyX3BhZ2VfZGF0YSkgLyBieXRlc19wZXJfcm93OwoKCQlpbnQgbmFuZF9mbGFzaF9pZF9pbmRleCA9IDA7CgkJcHJpbnRmKCJOQU5EIEZsYXNoIElEOiAiKTsKCQlmb3IgKG5hbmRfZmxhc2hfaWRfaW5kZXggPSAwOyBuYW5kX2ZsYXNoX2lkX2luZGV4IDwgc2l6ZW9mKG5hbmRfZmxhc2hfaWQpOyBuYW5kX2ZsYXNoX2lkX2luZGV4KyspCgkJewoJCQlwcmludGYoIiUuMlggIiwgbmFuZF9mbGFzaF9pZFtuYW5kX2ZsYXNoX2lkX2luZGV4XSk7CQoJCX0KCQlwcmludGYoIlxuXG4iKTsKCQkKCQlwcmludGYoIlBhcmFtZXRlciBwYWdlIGNvbnRlbnRzOlxuIik7CgkJcHJpbnRmKCI9PT09PT09PT09PT09PT09PT09PT09PT09PVxuIik7CgkJcHJpbnRmKCJEYXRhIGFycmF5IHNpemUgPSAlZCBieXRlc1xuIixzaXplb2YocGFyYW1ldGVyX3BhZ2VfZGF0YSkpOwoJCXByaW50ZigiQnl0ZXMgcGVyIHJvdyA9ICVkXG4iLGJ5dGVzX3Blcl9yb3cpOwoJCXByaW50ZigiVG90YWwgcm93cyA9ICVkXG5cbiIsdG90YWxfcm93cyk7CgkJCgkJLy8gUHJpbnQgb3V0IHBhcmFtZXRlciBwYWdlIGluIGh1bWFuLXJlYWRhYmxlIGZvcm0KCQkKCQkvLyBEZXNpcmVkIGZvcm1hdDoKCQkvLyBPZmZzZXQgMDA6MDE6MDI6MDM6MDQ6MDU6MDY6MDc6MDg6MDk6MEE6MEI6MEM6MEQ6MEU6MEYgMDEyMzQ1Njc4OUFCQ0RFRgoJCS8vIC0tLS0tLSAtLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSAtLS0tLS0tLS0tLS0tLS0tCgkJLy8gMHhISEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEhIIEFBQUFBQUFBQUFBQUFBQUEKCQkKCQlpbnQgcm93X2luZGV4LCBjb2x1bW5faW5kZXg7CgkJaW50IGN1cnJlbnRfb2Zmc2V0ID0gMDsKCQkKCQlwcmludGYoIk9mZnNldCAwMDowMTowMjowMzowNDowNTowNjowNzowODowOTowQTowQjowQzowRDowRTowRiAwMTIzNDU2Nzg5QUJDREVGXG4iKTsKCQlwcmludGYoIi0tLS0tLSAtLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSstLSAtLS0tLS0tLS0tLS0tLS0tXG4iKTsKCQlmb3IgKHJvd19pbmRleCA9IDA7IHJvd19pbmRleCA8IHRvdGFsX3Jvd3M7IHJvd19pbmRleCsrKQoJCXsKCQkJLy8gQnl0ZSBvZmZzZXQgaW4gaGV4IHdpdGggcGFkZGluZwoJCQlwcmludGYoIjB4JS40WCAiLCByb3dfaW5kZXggKiBieXRlc19wZXJfcm93KTsKCQkJCgkJCS8vIEhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uCgkJCWN1cnJlbnRfb2Zmc2V0ID0gKHJvd19pbmRleCAqIGNvbHVtbl9pbmRleCk7CgkJCWZvciAoY29sdW1uX2luZGV4ID0gMDsgY29sdW1uX2luZGV4IDwgYnl0ZXNfcGVyX3JvdzsgY29sdW1uX2luZGV4KyspCgkJCXsKCQkJCXByaW50ZigiJS4yWCAiLCBwYXJhbWV0ZXJfcGFnZV9kYXRhW2N1cnJlbnRfb2Zmc2V0XSk7CgkJCQljdXJyZW50X29mZnNldCsrOwoJCQl9CgkJCQoJCQkvLyBBU0NJSSByZXByZXNlbnRhdGlvbgoJCQljdXJyZW50X29mZnNldCA9IChyb3dfaW5kZXggKiBjb2x1bW5faW5kZXgpOwoJCQlmb3IgKGNvbHVtbl9pbmRleCA9IDA7IGNvbHVtbl9pbmRleCA8IGJ5dGVzX3Blcl9yb3c7IGNvbHVtbl9pbmRleCsrKQoJCQl7CgkJCQlpZiAocGFyYW1ldGVyX3BhZ2VfZGF0YVtjdXJyZW50X29mZnNldF0gPCAweDIwKSAvLyBsZXNzIHRoYW4gMHgyMCBhcmUgQVNDSUkgY29udHJvbCBjb2RlcwoJCQkJCXByaW50ZigiLiIpOwoJCQkJZWxzZSBpZiAoKHBhcmFtZXRlcl9wYWdlX2RhdGFbY3VycmVudF9vZmZzZXRdID49IDB4MjApICYmIChwYXJhbWV0ZXJfcGFnZV9kYXRhW2N1cnJlbnRfb2Zmc2V0XSA8IDB4ODApKQoJCQkJCXByaW50ZigiJWMiLCBwYXJhbWV0ZXJfcGFnZV9kYXRhW2N1cnJlbnRfb2Zmc2V0XSk7CgkJCQllbHNlIC8vIDB4ODAgb3IgZ3JlYXRlciBpcyBub3QgdmFsaWQgZm9yIFVURi04CgkJCQkJcHJpbnRmKCIuIik7CgkJCQljdXJyZW50X29mZnNldCsrOwoJCQl9CgkJCXByaW50ZigiXG4iKTsKCQl9CglyZXR1cm4gMDsKfQo=