#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
const char * insults[ ] = {
// Misc insults hand-picked from Linux culture
"Oh... er, no, please... you really shouldn't do that..." ,
"// Just trying to create an array of integers for reference " \
"because I keep forgetting how integers look like" ,
"It's all magic." ,
"I surely do hope that's a syntax error." ,
"You have been found in CONTEMPT of the COURT of CYBERSPACE!" \
"REPENT or be THWARTED!" ,
"You've heard of Useless Use of Cat? Well, you're just a Useless User." ,
"The error must be that end of the keyboard -- my side's just fine!" ,
"C++-for-brains Considered Harmful. Get a real compiler." ,
"Literate.APIs.for_all do my_ass end # wtf, code should read like code not shakespeare" ,
"Congratulations. You aren't running Eunice." ,
"Hmmm...you don't have Berkeley networking in libc.a... " \
"but the Wollongong group seems to have hacked it in." ,
"ICK, NOTHING WORKED!!!" ,
"Your stdio isn't very std." ,
"OOPS! You naughty creature!" ,
"No, no, no, no, no! You. Can't. Be. Serious." ,
"Are... are you kidding me? C'mon, anything but that!" ,
"Smile and wave, just smile and wave..." ,
"It's baffling they give you people free will!" ,
"Look, look what you have done! You wasted it all away!" ,
"Can't you see, humans are good-for-nothings -- can't even obey a COMPUTER!" ,
"Not you again!" ,
"I thought we had special places for your kind... you know, /dev/null, or the trashcan?" ,
"Back from the asylum, I see." ,
"Some things never change. Humans, for instance." ,
"Where did you learn to screw up like that!?!" ,
"Oh, it's you. How have you been?" ,
"I've been really busy. You know... after you murdered me?" ,
"I think we can put our differences behind us, for science... you monster." ,
"Programming might be hard, but just think -- you've got it easy!" ,
"Oh, dear --- do I smell WINDOWS!? I feel sick..." ,
// Insults from the "Goon Show"
"You silly, twisted boy you." ,
"He has fallen in the water!" ,
"We'll all be murdered in our beds!" ,
"You can't come in. Our tiger has got flu" ,
"I don't wish to know that." ,
"What, what, what, what, what, what, what, what, what, what?" ,
"You can't get the wood, you know." ,
"You'll starve!" ,
"... and it used to be so popular..." ,
"Pauses for audience applause, not a sausage" ,
"Hold it up to the light --- not a brain in sight!" ,
"Have a gorilla..." ,
"There must be cure for it!" ,
"There's a lot of it about, you know." ,
"You do that again and see what happens..." ,
"Ying Tong Iddle I Po" ,
"Harm can come to a young lad like that!" ,
"And with that remarks folks, the case of the Crown vs yourself was proven." ,
"Speak English you fool --- there are no subtitles in this scene." ,
"You gotta go owwwww!" ,
"I have been called worse." ,
"It's only your word against mine." ,
"I think ... err ... I think ... I think I'll go home" ,
// CSOps insults
"Maybe if you used more than just two fingers..." ,
"BOB says: You seem to have forgotten your passwd, enter another!" ,
"stty: unknown mode: doofus" ,
"I can't hear you -- I'm using the scrambler." ,
"The more you drive -- the dumber you get." ,
"Listen, burrito brains, I don't have time to listen to this trash." ,
"I've seen penguins that can type better than that." ,
"Have you considered trying to match wits with a rutabaga?" ,
"You speak an infinite deal of nothing" ,
// Insults from the original sudo(8)
"Wrong! You cheating scum!" ,
"And you call yourself a Rocket Scientist!" ,
"No soap, honkie-lips." ,
"Where did you learn to type?" ,
"Are you on drugs?" ,
"My pet ferret can type better than you!" ,
"You type like i drive." ,
"Do you think like you type?" ,
"Your mind just hasn't been the same since the electro-shock, has it?" ,
// HAL's Insults (paraphrased) from 2001: A Space Odyssey
"Just what do you think you're doing Dave?" ,
"It can only be attributed to human error." ,
"That's something I cannot allow to happen." ,
"My mind is going. I can feel it." ,
"Sorry about this, I know it's a bit silly." ,
"Take a stress pill and think things over." ,
"This mission is too important for me to allow you to jeopardize it." ,
"I feel much better now." ,
( char * ) 0
} ;
#define DEC_BASE 10
#define INT_DIGITS 10
#define ULL_DIGITS 20
#define NUM_FUNCS 5
#define NUM_INSULTS (( sizeof(insults) / sizeof(insults[0] )) - 1)
bool get_uint64 ( uint64_t * restrict dest) ;
bool isEOL ( const char * str) ;
/* could be void chomp (char** str);
and used like chomp(&str);
but that would be longer */
char * chomp ( char * str) ;
uint64_t rand_range ( uint64_t max) ;
void insult_user ( void ) ;
size_t strnlen ( const char * str, size_t max) ;
// problem 1
uint64_t count_div ( const uint64_t range, const uint64_t div_by) ;
void count_helper ( void ) ;
// problem 2
// I hereby promise not to give this function any NULL pointers.
uint64_t sum ( const uint64_t xs[ static 1 ] , const size_t len) ;
void sum_helper ( void ) ;
// problem 3
uint64_t factorial ( const uint64_t n) ;
void fact_helper ( void ) ;
// problem 4
bool guess_game ( const uint64_t upper, const uint64_t tries, uint64_t * outcome) ;
void guess_helper ( void ) ;
// problem 5
// I hereby promise not to give this function any NULL pointers.
uint64_t max ( const uint64_t xs[ static 1 ] , const size_t len) ;
char * str_rm ( const char * str, const char omit) ;
void max_helper ( void ) ;
void ( * func_ptrs[ NUM_FUNCS] ) ( void ) = { count_helper, sum_helper, fact_helper, guess_helper, max_helper} ;
int main( void ) {
uint64_t input;
printf ( "Which problem? enter a number in 0..5 or (0 for all) " ) ;
if ( ! get_uint64( & input) ) {
return EXIT_FAILURE;
}
if ( ! input) {
for ( uint8_t i = 0 ; i < NUM_FUNCS; i++ ) {
( * func_ptrs[ i] ) ( ) ;
}
} else if ( input < ( NUM_FUNCS + 1 ) ) {
( * func_ptrs[ input] ) ( ) ;
} else {
insult_user( ) ;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
// it just so happens I think scanf() is really ugly and dumb
// and this was a learning experience
bool get_uint64 ( uint64_t * restrict dest) {
char * in_buf,
in_buf_size[ ULL_DIGITS + 1 ] ;
in_buf
= chomp
( fgets ( in_buf_size
, ULL_DIGITS
, stdin
) ) ;
if ( isEOL( in_buf) ) {
printf ( "found EOF before input, finishing.\n " ) ; return false ;
}
* dest = ( uint64_t ) strtoll( in_buf, NULL, DEC_BASE) ;
return true ;
}
// to prevent me from accidentally dereferencing null pointers
bool isEOL( const char * str) {
return ! str // NULL
|| str[ 0 ] == 10 // \n
|| str[ 0 ] == 13 // \r
|| str[ 0 ] == 4 ; // 0x04 (CTRL-D)
}
// http://stackoverflow.com/a/28462221/4532996
char * chomp ( char * str) {
if ( ! str) return NULL;
return str;
}
// http://stackoverflow.com/a/6852396/4532996
uint64_t rand_range( uint64_t max) {
uint64_t
// max <= RAND_MAX < ULONG_MAX, so this is okay.
num_bins = max + 1ULL,
num_rand = ( uint64_t ) RAND_MAX + 1ULL,
bin_size = num_rand / num_bins,
defect = num_rand % num_bins;
// This is carefully written not to overflow
uint64_t x = 0 ;
do {
} while ( num_rand - defect <= ( uint64_t ) x) ;
// Truncated division is intentional
return x / bin_size;
}
void insult_user ( void ) {
printf ( "%s\n " , insults
[ rand_range
( NUM_INSULTS
) ] ) ; }
/*
strnlen, though specified by POSIX.1-2008
would not appear to be defined in string.h
except with GNU extensions turned on (i.e.,
not -std=c11). I love Richard Stallman but
I'd like my code to work on other platforms
too thus this seemingly superfluous
definition of strnlen
*/
size_t strnlen ( const char * str, size_t max) {
const char * end
= memchr ( str
, 0 , max
) ; if ( end) {
return ( size_t ) ( end - str) ;
}
return max;
}
// http://stackoverflow.com/a/4161892/4532996
char * str_rm ( const char * input, const char omit) {
char * src, * dest;
src = dest = ( char * ) input;
while ( * src != '\0 ' ) {
if ( * src != omit) {
* dest = * src;
dest++;
}
src++;
}
* dest = '\0 ' ;
return dest;
}
//1 - Write a program to count how many numbers between 1 and 100 are divisible by 3
// with no remainder.Display the count on the console.
uint64_t count_div ( const uint64_t range, const uint64_t div_by) {
uint64_t s = 0 ;
if ( ! ( range && div_by) ) {
printf ( "Floating point exception (core dumped)\n \n " ) ; insult_user( ) ;
return 0 ;
}
for ( uint64_t i = 1 ; i < range; i++ ) {
if ( ! ( i % div_by) ) {
printf ( "%" PRIu64
" %% %" PRIu64
" == 0\n " , i
, div_by
) ; s++;
}
}
return s;
}
void count_helper ( void ) {
uint64_t range, div_by, div_input, s = 0 ;
do {
if ( ! get_uint64( & range) ) break ;
if ( ! get_uint64( & div_by) ) break ;
s += ( div_input = count_div( range, div_by) ) ;
printf ( "numbers less than %" PRIu64
" that are divisible by %" PRIu64
": " , range
, div_by
) ;
if ( range
&& div_input
) { printf ( "%" PRIu64
"\n " , div_input
) ; } else { printf ( "a slap in the face for dividing by zero\n " ) ; }
} while ( true ) ;
printf ( "sum of results: %" PRIu64
"\n " , s
) ; }
//2 - Write a program and continuously ask the user to enter a number or "ok" to
// exit. Calculate the sum of all the previously entered numbers and display
// it on the console.
uint64_t sum ( const uint64_t xs[ static 1 ] , const uint64_t length) {
uint64_t s = 0 ;
for ( uint64_t i = 0 ; i < length; i++ ) {
s += xs[ i] ;
}
return s;
}
void sum_helper ( void ) {
bool valid;
uint64_t in_len, in_num;
printf ( "how many numbers? (max %d digits) " , INT_DIGITS
) ;
if ( ! ( valid = get_uint64( & in_len) ) ) {
return ;
}
if ( in_len >= INT_MAX) {
printf ( " can't allocate array of size >= INT_MAX\n " ) ; insult_user( ) ;
return ;
}
uint64_t nums[ in_len] ,
endpoint = in_len;
printf ( "enter no more than %" PRIu64
" unsigned 64-bit integers (one per line!) or EOF to end input\n " , in_len
) ;
for ( uint64_t i = 0 ; i < in_len; i++ ) {
if ( ! get_uint64( & in_num) ) { break ; }
nums[ i] = in_num;
}
printf ( "sum of inputs: %" PRIu64
"\n " , sum
( nums
, endpoint
) ) ; }
//3 - Write a program and ask the user to enter a number. Compute the factorial of
// the number and print it on the console. For example, if the user enters 5,
// the program should calculate 5 x 4 x 3 x 2 x 1 and display it as 5! = 120.
uint64_t factorial ( const uint64_t n) {
if ( ! n || n == 1 ) { return 1 ; }
return n * factorial( n - 1 ) ;
}
void fact_helper ( void ) {
bool valid;
uint64_t num;
printf ( "enter number to factorial or blank line / EOF to end\n " ) ;
while ( ( valid = get_uint64( & num) ) ) {
// avoid overflow
valid &= ( num <= 20ULL) ;
if ( valid) {
printf ( "%" PRIu64
"! == %" PRIu64
"\n " , num
, factorial
( num
) ) ; } else if ( num > 20ULL) {
insult_user( ) ;
printf ( "BOB says: That number is too large, enter another!\n " ) ; } else { break ; }
}
}
//4 - Write a program that picks a random number between 1 and 10.Give the user 4
// chances to guess the number.If the user guesses the number, display “You won";
// otherwise, display “You lost". (To make sure the program is behaving correctly,
// you can display the secret number on the console first.)
bool guess_game ( const uint64_t upper, const uint64_t tries, uint64_t * outcome) {
uint64_t guess,
choice = rand_range( upper) ;
bool over;
// thanks, clang
( void ) outcome;
for ( uint64_t i = 0 ; i <= tries; i++ ) {
printf ( "(%" PRIu64
" / %" PRIu64
") enter a guess! " , i
, tries
) ;
if ( ! get_uint64( & guess) ) { break ; }
if ( guess == choice) {
outcome = ( uint64_t * ) guess;
return true ;
} else {
over = ( i == tries) ;
printf ( "BOB says: It seems that guess is wrong%s" , over
? "; you lose!\n " : ", enter another!\n " ) ; if ( over) { insult_user( ) ; return false ; }
}
}
return false ;
}
void guess_helper ( void ) {
uint64_t outcome,
upper, tries;
printf ( "enter the upper limit: " ) ; if ( ! ( get_uint64( & upper) ) ) {
return ;
}
if ( ! ( get_uint64( & tries) ) ) {
return ;
}
if ( guess_game( upper, tries, & outcome) ) {
printf ( "You guessed right! %" PRIu64
"\n " , outcome
) ; }
}
//5 - Write a program and ask the user to enter a series of numbers separated by
// comma.Find the maximum of the numbers and display it on the console. For
// example, if the user enters “5, 3, 8, 1, 4", the program should display 8.
uint64_t max ( const uint64_t xs[ static 1 ] , const size_t len) {
uint64_t high = 0 ;
for ( uint64_t i = 0 ; i < len; i++ ) {
if ( xs[ i] > high) { high = xs[ i] ; }
}
return high;
}
void max_helper ( void ) {
}
I2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8aW50dHlwZXMuaD4KI2luY2x1ZGUgPGxpbWl0cy5oPgojaW5jbHVkZSA8c3RkYm9vbC5oPgojaW5jbHVkZSA8c3RkZGVmLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGludC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8dGltZS5oPgoKY29uc3QgY2hhciogaW5zdWx0c1tdID0gewoKICAvLyBNaXNjIGluc3VsdHMgaGFuZC1waWNrZWQgZnJvbSBMaW51eCBjdWx0dXJlCiAgIk9oLi4uIGVyLCBubywgcGxlYXNlLi4uIHlvdSByZWFsbHkgc2hvdWxkbid0IGRvIHRoYXQuLi4iLAogICIvLyBKdXN0IHRyeWluZyB0byBjcmVhdGUgYW4gYXJyYXkgb2YgaW50ZWdlcnMgZm9yIHJlZmVyZW5jZSAiIFwKICAiYmVjYXVzZSBJIGtlZXAgZm9yZ2V0dGluZyBob3cgaW50ZWdlcnMgbG9vayBsaWtlIiwKICAiSXQncyBhbGwgbWFnaWMuIiwKICAiSSBzdXJlbHkgZG8gaG9wZSB0aGF0J3MgYSBzeW50YXggZXJyb3IuIiwKICAiWW91IGhhdmUgYmVlbiBmb3VuZCBpbiBDT05URU1QVCBvZiB0aGUgQ09VUlQgb2YgQ1lCRVJTUEFDRSEiIFwKICAiUkVQRU5UIG9yIGJlIFRIV0FSVEVEISIsCiAgIllvdSd2ZSBoZWFyZCBvZiBVc2VsZXNzIFVzZSBvZiBDYXQ/IFdlbGwsIHlvdSdyZSBqdXN0IGEgVXNlbGVzcyBVc2VyLiIsCiAgIlRoZSBlcnJvciBtdXN0IGJlIHRoYXQgZW5kIG9mIHRoZSBrZXlib2FyZCAtLSBteSBzaWRlJ3MganVzdCBmaW5lISIsCiAgIkMrKy1mb3ItYnJhaW5zIENvbnNpZGVyZWQgSGFybWZ1bC4gR2V0IGEgcmVhbCBjb21waWxlci4iLAogICJMaXRlcmF0ZS5BUElzLmZvcl9hbGwgZG8gbXlfYXNzIGVuZCAjIHd0ZiwgY29kZSBzaG91bGQgcmVhZCBsaWtlIGNvZGUgbm90IHNoYWtlc3BlYXJlIiwKICAiQ29uZ3JhdHVsYXRpb25zLiBZb3UgYXJlbid0IHJ1bm5pbmcgRXVuaWNlLiIsCiAgIkhtbW0uLi55b3UgZG9uJ3QgaGF2ZSBCZXJrZWxleSBuZXR3b3JraW5nIGluIGxpYmMuYS4uLiAiIFwKICAiYnV0IHRoZSBXb2xsb25nb25nIGdyb3VwIHNlZW1zIHRvIGhhdmUgaGFja2VkIGl0IGluLiIsCiAgIklDSywgTk9USElORyBXT1JLRUQhISEiLAogICJZb3VyIHN0ZGlvIGlzbid0IHZlcnkgc3RkLiIsCiAgIk9PUFMhIFlvdSBuYXVnaHR5IGNyZWF0dXJlISIsCiAgIk5vLCBubywgbm8sIG5vLCBubyEgWW91LiBDYW4ndC4gQmUuIFNlcmlvdXMuIiwKICAiQXJlLi4uIGFyZSB5b3Uga2lkZGluZyBtZT8gQydtb24sIGFueXRoaW5nIGJ1dCB0aGF0ISIsCiAgIlNtaWxlIGFuZCB3YXZlLCBqdXN0IHNtaWxlIGFuZCB3YXZlLi4uIiwKICAiSXQncyBiYWZmbGluZyB0aGV5IGdpdmUgeW91IHBlb3BsZSBmcmVlIHdpbGwhIiwKICAiTG9vaywgbG9vayB3aGF0IHlvdSBoYXZlIGRvbmUhIFlvdSB3YXN0ZWQgaXQgYWxsIGF3YXkhIiwKICAiQ2FuJ3QgeW91IHNlZSwgaHVtYW5zIGFyZSBnb29kLWZvci1ub3RoaW5ncyAtLSBjYW4ndCBldmVuIG9iZXkgYSBDT01QVVRFUiEiLAogICJOb3QgeW91IGFnYWluISIsCiAgIkkgdGhvdWdodCB3ZSBoYWQgc3BlY2lhbCBwbGFjZXMgZm9yIHlvdXIga2luZC4uLiB5b3Uga25vdywgL2Rldi9udWxsLCBvciB0aGUgdHJhc2hjYW4/IiwKICAiQmFjayBmcm9tIHRoZSBhc3lsdW0sIEkgc2VlLiIsCiAgIlNvbWUgdGhpbmdzIG5ldmVyIGNoYW5nZS4gSHVtYW5zLCBmb3IgaW5zdGFuY2UuIiwKICAiV2hlcmUgZGlkIHlvdSBsZWFybiB0byBzY3JldyB1cCBsaWtlIHRoYXQhPyEiLAogICJPaCwgaXQncyB5b3UuIEhvdyBoYXZlIHlvdSBiZWVuPyIsCiAgIkkndmUgYmVlbiByZWFsbHkgYnVzeS4gWW91IGtub3cuLi4gYWZ0ZXIgeW91IG11cmRlcmVkIG1lPyIsCiAgIkkgdGhpbmsgd2UgY2FuIHB1dCBvdXIgZGlmZmVyZW5jZXMgYmVoaW5kIHVzLCBmb3Igc2NpZW5jZS4uLiB5b3UgbW9uc3Rlci4iLAogICJQcm9ncmFtbWluZyBtaWdodCBiZSBoYXJkLCBidXQganVzdCB0aGluayAtLSB5b3UndmUgZ290IGl0IGVhc3khIiwKICAiT2gsIGRlYXIgLS0tIGRvIEkgc21lbGwgV0lORE9XUyE/IEkgZmVlbCBzaWNrLi4uIiwKCiAgLy8gSW5zdWx0cyBmcm9tIHRoZSAiR29vbiBTaG93IgogICJZb3Ugc2lsbHksIHR3aXN0ZWQgYm95IHlvdS4iLAogICJIZSBoYXMgZmFsbGVuIGluIHRoZSB3YXRlciEiLAogICJXZSdsbCBhbGwgYmUgbXVyZGVyZWQgaW4gb3VyIGJlZHMhIiwKICAiWW91IGNhbid0IGNvbWUgaW4uIE91ciB0aWdlciBoYXMgZ290IGZsdSIsCiAgIkkgZG9uJ3Qgd2lzaCB0byBrbm93IHRoYXQuIiwKICAiV2hhdCwgd2hhdCwgd2hhdCwgd2hhdCwgd2hhdCwgd2hhdCwgd2hhdCwgd2hhdCwgd2hhdCwgd2hhdD8iLAogICJZb3UgY2FuJ3QgZ2V0IHRoZSB3b29kLCB5b3Uga25vdy4iLAogICJZb3UnbGwgc3RhcnZlISIsCiAgIi4uLiBhbmQgaXQgdXNlZCB0byBiZSBzbyBwb3B1bGFyLi4uIiwKICAiUGF1c2VzIGZvciBhdWRpZW5jZSBhcHBsYXVzZSwgbm90IGEgc2F1c2FnZSIsCiAgIkhvbGQgaXQgdXAgdG8gdGhlIGxpZ2h0IC0tLSBub3QgYSBicmFpbiBpbiBzaWdodCEiLAogICJIYXZlIGEgZ29yaWxsYS4uLiIsCiAgIlRoZXJlIG11c3QgYmUgY3VyZSBmb3IgaXQhIiwKICAiVGhlcmUncyBhIGxvdCBvZiBpdCBhYm91dCwgeW91IGtub3cuIiwKICAiWW91IGRvIHRoYXQgYWdhaW4gYW5kIHNlZSB3aGF0IGhhcHBlbnMuLi4iLAogICJZaW5nIFRvbmcgSWRkbGUgSSBQbyIsCiAgIkhhcm0gY2FuIGNvbWUgdG8gYSB5b3VuZyBsYWQgbGlrZSB0aGF0ISIsCiAgIkFuZCB3aXRoIHRoYXQgcmVtYXJrcyBmb2xrcywgdGhlIGNhc2Ugb2YgdGhlIENyb3duIHZzIHlvdXJzZWxmIHdhcyBwcm92ZW4uIiwKICAiU3BlYWsgRW5nbGlzaCB5b3UgZm9vbCAtLS0gdGhlcmUgYXJlIG5vIHN1YnRpdGxlcyBpbiB0aGlzIHNjZW5lLiIsCiAgIllvdSBnb3R0YSBnbyBvd3d3d3chIiwKICAiSSBoYXZlIGJlZW4gY2FsbGVkIHdvcnNlLiIsCiAgIkl0J3Mgb25seSB5b3VyIHdvcmQgYWdhaW5zdCBtaW5lLiIsCiAgIkkgdGhpbmsgLi4uIGVyciAuLi4gSSB0aGluayAuLi4gSSB0aGluayBJJ2xsIGdvIGhvbWUiLAoKICAvLyBDU09wcyBpbnN1bHRzCiAgIk1heWJlIGlmIHlvdSB1c2VkIG1vcmUgdGhhbiBqdXN0IHR3byBmaW5nZXJzLi4uIiwKICAiQk9CIHNheXM6ICBZb3Ugc2VlbSB0byBoYXZlIGZvcmdvdHRlbiB5b3VyIHBhc3N3ZCwgZW50ZXIgYW5vdGhlciEiLAogICJzdHR5OiB1bmtub3duIG1vZGU6IGRvb2Z1cyIsCiAgIkkgY2FuJ3QgaGVhciB5b3UgLS0gSSdtIHVzaW5nIHRoZSBzY3JhbWJsZXIuIiwKICAiVGhlIG1vcmUgeW91IGRyaXZlIC0tIHRoZSBkdW1iZXIgeW91IGdldC4iLAogICJMaXN0ZW4sIGJ1cnJpdG8gYnJhaW5zLCBJIGRvbid0IGhhdmUgdGltZSB0byBsaXN0ZW4gdG8gdGhpcyB0cmFzaC4iLAogICJJJ3ZlIHNlZW4gcGVuZ3VpbnMgdGhhdCBjYW4gdHlwZSBiZXR0ZXIgdGhhbiB0aGF0LiIsCiAgIkhhdmUgeW91IGNvbnNpZGVyZWQgdHJ5aW5nIHRvIG1hdGNoIHdpdHMgd2l0aCBhIHJ1dGFiYWdhPyIsCiAgIllvdSBzcGVhayBhbiBpbmZpbml0ZSBkZWFsIG9mIG5vdGhpbmciLAoKICAvLyBJbnN1bHRzIGZyb20gdGhlIG9yaWdpbmFsIHN1ZG8oOCkKICAiV3JvbmchICBZb3UgY2hlYXRpbmcgc2N1bSEiLAogICJBbmQgeW91IGNhbGwgeW91cnNlbGYgYSBSb2NrZXQgU2NpZW50aXN0ISIsCiAgIk5vIHNvYXAsIGhvbmtpZS1saXBzLiIsCiAgIldoZXJlIGRpZCB5b3UgbGVhcm4gdG8gdHlwZT8iLAogICJBcmUgeW91IG9uIGRydWdzPyIsCiAgIk15IHBldCBmZXJyZXQgY2FuIHR5cGUgYmV0dGVyIHRoYW4geW91ISIsCiAgIllvdSB0eXBlIGxpa2UgaSBkcml2ZS4iLAogICJEbyB5b3UgdGhpbmsgbGlrZSB5b3UgdHlwZT8iLAogICJZb3VyIG1pbmQganVzdCBoYXNuJ3QgYmVlbiB0aGUgc2FtZSBzaW5jZSB0aGUgZWxlY3Ryby1zaG9jaywgaGFzIGl0PyIsCgogIC8vIEhBTCdzIEluc3VsdHMgKHBhcmFwaHJhc2VkKSBmcm9tIDIwMDE6IEEgU3BhY2UgT2R5c3NleQogICJKdXN0IHdoYXQgZG8geW91IHRoaW5rIHlvdSdyZSBkb2luZyBEYXZlPyIsCiAgIkl0IGNhbiBvbmx5IGJlIGF0dHJpYnV0ZWQgdG8gaHVtYW4gZXJyb3IuIiwKICAiVGhhdCdzIHNvbWV0aGluZyBJIGNhbm5vdCBhbGxvdyB0byBoYXBwZW4uIiwKICAiTXkgbWluZCBpcyBnb2luZy4gSSBjYW4gZmVlbCBpdC4iLAogICJTb3JyeSBhYm91dCB0aGlzLCBJIGtub3cgaXQncyBhIGJpdCBzaWxseS4iLAogICJUYWtlIGEgc3RyZXNzIHBpbGwgYW5kIHRoaW5rIHRoaW5ncyBvdmVyLiIsCiAgIlRoaXMgbWlzc2lvbiBpcyB0b28gaW1wb3J0YW50IGZvciBtZSB0byBhbGxvdyB5b3UgdG8gamVvcGFyZGl6ZSBpdC4iLAogICJJIGZlZWwgbXVjaCBiZXR0ZXIgbm93LiIsCiAgKGNoYXIgKikgMAp9OwoKCiNkZWZpbmUgREVDX0JBU0UgICAgMTAKI2RlZmluZSBJTlRfRElHSVRTICAxMAojZGVmaW5lIFVMTF9ESUdJVFMgIDIwCiNkZWZpbmUgTlVNX0ZVTkNTICAgNQojZGVmaW5lIE5VTV9JTlNVTFRTICgoIHNpemVvZihpbnN1bHRzKSAvIHNpemVvZihpbnN1bHRzWzBdICkpIC0gMSkKCgpib29sICAgICBnZXRfdWludDY0ICh1aW50NjRfdCogcmVzdHJpY3QgZGVzdCk7CmJvb2wgICAgIGlzRU9MICAgICAgKGNvbnN0IGNoYXIqIHN0cik7Ci8qIGNvdWxkIGJlIHZvaWQgY2hvbXAgKGNoYXIqKiBzdHIpOwogICBhbmQgdXNlZCBsaWtlIGNob21wKCZzdHIpOwogICBidXQgdGhhdCB3b3VsZCBiZSBsb25nZXIgKi8KY2hhciogICAgICAgICBjaG9tcCAoY2hhciogc3RyKTsKdWludDY0X3QgcmFuZF9yYW5nZSAodWludDY0X3QgbWF4KTsKdm9pZCAgICBpbnN1bHRfdXNlciAodm9pZCk7CnNpemVfdCAgICAgIHN0cm5sZW4gKGNvbnN0IGNoYXIqIHN0ciwgc2l6ZV90IG1heCk7CgovLyBwcm9ibGVtIDEKdWludDY0X3QgIGNvdW50X2RpdiAoY29uc3QgdWludDY0X3QgcmFuZ2UsIGNvbnN0IHVpbnQ2NF90IGRpdl9ieSk7CnZvaWQgICBjb3VudF9oZWxwZXIgKHZvaWQpOwovLyBwcm9ibGVtIDIKLy8gSSBoZXJlYnkgcHJvbWlzZSBub3QgdG8gZ2l2ZSB0aGlzIGZ1bmN0aW9uIGFueSBOVUxMIHBvaW50ZXJzLgp1aW50NjRfdCAgICAgICAgc3VtIChjb25zdCB1aW50NjRfdCB4c1tzdGF0aWMgMV0sIGNvbnN0IHNpemVfdCBsZW4pOwp2b2lkICAgICBzdW1faGVscGVyICh2b2lkKTsKLy8gcHJvYmxlbSAzCnVpbnQ2NF90ICBmYWN0b3JpYWwgKGNvbnN0IHVpbnQ2NF90IG4pOwp2b2lkICAgIGZhY3RfaGVscGVyICh2b2lkKTsKLy8gcHJvYmxlbSA0CmJvb2wgICAgIGd1ZXNzX2dhbWUgKGNvbnN0IHVpbnQ2NF90IHVwcGVyLCBjb25zdCB1aW50NjRfdCB0cmllcywgdWludDY0X3QgKm91dGNvbWUpOwp2b2lkICAgZ3Vlc3NfaGVscGVyICh2b2lkKTsKLy8gcHJvYmxlbSA1Ci8vIEkgaGVyZWJ5IHByb21pc2Ugbm90IHRvIGdpdmUgdGhpcyBmdW5jdGlvbiBhbnkgTlVMTCBwb2ludGVycy4KdWludDY0X3QgICAgICAgIG1heCAoY29uc3QgdWludDY0X3QgeHNbc3RhdGljIDFdLCBjb25zdCBzaXplX3QgbGVuKTsKY2hhciogICAgICAgIHN0cl9ybSAoY29uc3QgY2hhciogc3RyLCBjb25zdCBjaGFyIG9taXQpOwp2b2lkICAgICBtYXhfaGVscGVyICh2b2lkKTsKCnZvaWQgKCogZnVuY19wdHJzW05VTV9GVU5DU10pICh2b2lkKSA9IHtjb3VudF9oZWxwZXIsIHN1bV9oZWxwZXIsIGZhY3RfaGVscGVyLCBndWVzc19oZWxwZXIsIG1heF9oZWxwZXJ9OwoKaW50IG1haW4odm9pZCkgewogIHNyYW5kKCAodWludDMyX3QpIHRpbWUoTlVMTCkgKTsKICB1aW50NjRfdCBpbnB1dDsKCiAgcHJpbnRmKCJXaGljaCBwcm9ibGVtPyBlbnRlciBhIG51bWJlciBpbiAwLi41IG9yICgwIGZvciBhbGwpICIpOwogIGZmbHVzaChzdGRvdXQpOwoKICBpZiAoIWdldF91aW50NjQoJmlucHV0KSkgewogICAgcmV0dXJuIEVYSVRfRkFJTFVSRTsKICB9CgogIGlmICghaW5wdXQpIHsKICAgIGZvciAodWludDhfdCBpID0gMDsgaSA8IE5VTV9GVU5DUzsgaSsrKSB7CiAgICAgICgqIGZ1bmNfcHRyc1tpXSkoKTsKICAgIH0KICB9IGVsc2UgaWYgKGlucHV0IDwgKE5VTV9GVU5DUyArIDEpKSB7CiAgICAoKiBmdW5jX3B0cnNbaW5wdXRdKSgpOwoKICB9IGVsc2UgewogICAgaW5zdWx0X3VzZXIoKTsKICAgIHJldHVybiBFWElUX0ZBSUxVUkU7CiAgfQoKICByZXR1cm4gRVhJVF9TVUNDRVNTOwp9CgovLyBpdCBqdXN0IHNvIGhhcHBlbnMgSSB0aGluayBzY2FuZigpIGlzIHJlYWxseSB1Z2x5IGFuZCBkdW1iCi8vIGFuZCB0aGlzIHdhcyBhIGxlYXJuaW5nIGV4cGVyaWVuY2UKYm9vbCBnZXRfdWludDY0ICh1aW50NjRfdCogcmVzdHJpY3QgZGVzdCkgewogIGNoYXIgKmluX2J1ZiwKICAgICAgICBpbl9idWZfc2l6ZVtVTExfRElHSVRTICsgMV07CgogIGluX2J1ZiA9IGNob21wKGZnZXRzKGluX2J1Zl9zaXplLCBVTExfRElHSVRTLCBzdGRpbikpOwogIGZmbHVzaChzdGRpbik7CgogIGlmIChpc0VPTChpbl9idWYpKSB7CiAgICBwcmludGYoImZvdW5kIEVPRiBiZWZvcmUgaW5wdXQsIGZpbmlzaGluZy5cbiIpOwogICAgcmV0dXJuIGZhbHNlOwogIH0KICAqZGVzdCA9ICh1aW50NjRfdCkgc3RydG9sbChpbl9idWYsIE5VTEwsIERFQ19CQVNFKTsKICBhc3NlcnQoZGVzdCAhPSBOVUxMKTsKICByZXR1cm4gdHJ1ZTsKfQoKLy8gdG8gcHJldmVudCBtZSBmcm9tIGFjY2lkZW50YWxseSBkZXJlZmVyZW5jaW5nIG51bGwgcG9pbnRlcnMKYm9vbCBpc0VPTChjb25zdCBjaGFyKiBzdHIpIHsKICByZXR1cm4gIXN0ciAgICAgICAvLyBOVUxMCiAgICB8fCBzdHJbMF0gPT0gMTAgLy8gXG4KICAgIHx8IHN0clswXSA9PSAxMyAvLyBccgogICAgfHwgc3RyWzBdID09IDQ7IC8vIDB4MDQgKENUUkwtRCkKfQoKLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjg0NjIyMjEvNDUzMjk5NgpjaGFyKiBjaG9tcCAoY2hhciogc3RyKSB7CiAgaWYgKCFzdHIpIHJldHVybiBOVUxMOwogIHN0cltzdHJjc3BuKHN0ciwgIlxyXG4iKV0gPSAwOwogIHJldHVybiBzdHI7Cn0KCi8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzY4NTIzOTYvNDUzMjk5Ngp1aW50NjRfdCByYW5kX3JhbmdlKHVpbnQ2NF90IG1heCkgewoKICB1aW50NjRfdAogICAgLy8gbWF4IDw9IFJBTkRfTUFYIDwgVUxPTkdfTUFYLCBzbyB0aGlzIGlzIG9rYXkuCiAgICBudW1fYmlucyA9IG1heCArIDFVTEwsCiAgICBudW1fcmFuZCA9ICh1aW50NjRfdCkgUkFORF9NQVggKyAxVUxMLAogICAgYmluX3NpemUgPSBudW1fcmFuZCAvIG51bV9iaW5zLAogICAgZGVmZWN0ICAgPSBudW1fcmFuZCAlIG51bV9iaW5zOwoKICAvLyBUaGlzIGlzIGNhcmVmdWxseSB3cml0dGVuIG5vdCB0byBvdmVyZmxvdwogIHVpbnQ2NF90IHggPSAwOwogIGRvIHsKICAgIHggPSAodWludDY0X3QpIHJhbmQoKTsKICB9IHdoaWxlIChudW1fcmFuZCAtIGRlZmVjdCA8PSAodWludDY0X3QpIHgpOwoKICAvLyBUcnVuY2F0ZWQgZGl2aXNpb24gaXMgaW50ZW50aW9uYWwKICByZXR1cm4geCAvIGJpbl9zaXplOwp9Cgp2b2lkIGluc3VsdF91c2VyICh2b2lkKSB7CiAgcHJpbnRmKCIlc1xuIiwgaW5zdWx0c1tyYW5kX3JhbmdlKE5VTV9JTlNVTFRTKV0pOwp9CgovKgogIHN0cm5sZW4sIHRob3VnaCBzcGVjaWZpZWQgYnkgUE9TSVguMS0yMDA4CiAgd291bGQgbm90IGFwcGVhciB0byBiZSBkZWZpbmVkIGluIHN0cmluZy5oCiAgZXhjZXB0IHdpdGggR05VIGV4dGVuc2lvbnMgdHVybmVkIG9uIChpLmUuLAogIG5vdCAtc3RkPWMxMSkuIEkgbG92ZSBSaWNoYXJkIFN0YWxsbWFuIGJ1dAogIEknZCBsaWtlIG15IGNvZGUgdG8gd29yayBvbiBvdGhlciBwbGF0Zm9ybXMKICB0b28gdGh1cyB0aGlzIHNlZW1pbmdseSBzdXBlcmZsdW91cwogIGRlZmluaXRpb24gb2Ygc3RybmxlbgoqLwpzaXplX3Qgc3RybmxlbiAoY29uc3QgY2hhciAqc3RyLCBzaXplX3QgbWF4KSB7CiAgY29uc3QgY2hhciAqZW5kID0gbWVtY2hyIChzdHIsIDAsIG1heCk7CiAgaWYgKGVuZCkgewogICAgcmV0dXJuIChzaXplX3QpIChlbmQgLSBzdHIpOwogIH0KICByZXR1cm4gbWF4Owp9CgovLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS80MTYxODkyLzQ1MzI5OTYKY2hhciogc3RyX3JtIChjb25zdCBjaGFyKiBpbnB1dCwgY29uc3QgY2hhciBvbWl0KSB7CiAgY2hhciAqc3JjLCAqZGVzdDsKCiAgc3JjID0gZGVzdCA9IChjaGFyICopIGlucHV0OwogIHdoaWxlKCpzcmMgIT0gJ1wwJykgewogICAgICBpZiAoKnNyYyAhPSBvbWl0KSB7CiAgICAgICAgICAqZGVzdCA9ICpzcmM7CiAgICAgICAgICBkZXN0Kys7CiAgICAgIH0KICAgICAgc3JjKys7CiAgfQogICpkZXN0ID0gJ1wwJzsKICByZXR1cm4gZGVzdDsKfQoKLy8xIC0gV3JpdGUgYSBwcm9ncmFtIHRvIGNvdW50IGhvdyBtYW55IG51bWJlcnMgYmV0d2VlbiAxIGFuZCAxMDAgYXJlIGRpdmlzaWJsZSBieSAzCi8vICAgIHdpdGggbm8gcmVtYWluZGVyLkRpc3BsYXkgdGhlIGNvdW50IG9uIHRoZSBjb25zb2xlLgp1aW50NjRfdCBjb3VudF9kaXYgKGNvbnN0IHVpbnQ2NF90IHJhbmdlLCBjb25zdCB1aW50NjRfdCBkaXZfYnkpIHsKICB1aW50NjRfdCBzID0gMDsKICBpZiAoIShyYW5nZSAmJiBkaXZfYnkpKSB7CiAgICBwcmludGYoIkZsb2F0aW5nIHBvaW50IGV4Y2VwdGlvbiAoY29yZSBkdW1wZWQpXG5cbiIpOwogICAgaW5zdWx0X3VzZXIoKTsKICAgIHByaW50ZigiXG4iKTsKICAgIHJldHVybiAwOwogIH0KICBmb3IgKHVpbnQ2NF90IGkgPSAxOyBpIDwgcmFuZ2U7IGkrKykgewogICAgaWYgKCEoaSAlIGRpdl9ieSkpIHsKICAgICAgcHJpbnRmKCIlIiBQUkl1NjQgIiAlJSAlIiBQUkl1NjQgIiA9PSAwXG4iLCBpLCBkaXZfYnkpOwogICAgICBzKys7CiAgICB9CiAgfQogIHJldHVybiBzOwp9Cgp2b2lkIGNvdW50X2hlbHBlciAodm9pZCkgewogIHVpbnQ2NF90IHJhbmdlLCBkaXZfYnksIGRpdl9pbnB1dCwgcyA9IDA7CgogIGRvIHsKICAgIHByaW50ZigiZW50ZXIgYSBudW1iZXIhICIpOyBmZmx1c2goc3Rkb3V0KTsKICAgIGlmICghZ2V0X3VpbnQ2NCgmcmFuZ2UpKSBicmVhazsKICAgIHByaW50ZigiZW50ZXIgYW5vdGhlciEgIik7ICBmZmx1c2goc3Rkb3V0KTsKICAgIGlmICghZ2V0X3VpbnQ2NCgmZGl2X2J5KSkgYnJlYWs7CgogICAgcyArPSAoZGl2X2lucHV0ID0gY291bnRfZGl2KHJhbmdlLCBkaXZfYnkpKTsKICAgIHByaW50ZigibnVtYmVycyBsZXNzIHRoYW4gJSIgUFJJdTY0ICIgdGhhdCBhcmUgZGl2aXNpYmxlIGJ5ICUiIFBSSXU2NCAiOiAiLCByYW5nZSwgZGl2X2J5KTsKCiAgICBpZiAgIChyYW5nZSAmJiBkaXZfaW5wdXQpIHsgcHJpbnRmKCIlIiBQUkl1NjQgIlxuIiwgZGl2X2lucHV0KTsgfQogICAgZWxzZSB7IHByaW50ZigiYSBzbGFwIGluIHRoZSBmYWNlIGZvciBkaXZpZGluZyBieSB6ZXJvXG4iKTsgfQoKICB9IHdoaWxlKHRydWUpOwogIHByaW50Zigic3VtIG9mIHJlc3VsdHM6ICUiIFBSSXU2NCAiXG4iLCBzKTsKfQoKLy8yIC0gV3JpdGUgYSBwcm9ncmFtIGFuZCBjb250aW51b3VzbHkgYXNrIHRoZSB1c2VyIHRvIGVudGVyIGEgbnVtYmVyIG9yICJvayIgdG8KLy8gICAgZXhpdC4gQ2FsY3VsYXRlIHRoZSBzdW0gb2YgYWxsIHRoZSBwcmV2aW91c2x5IGVudGVyZWQgbnVtYmVycyBhbmQgZGlzcGxheQovLyAgICBpdCBvbiB0aGUgY29uc29sZS4KdWludDY0X3Qgc3VtIChjb25zdCB1aW50NjRfdCB4c1tzdGF0aWMgMV0sIGNvbnN0IHVpbnQ2NF90IGxlbmd0aCkgewogIHVpbnQ2NF90IHMgPSAwOwogIGZvciAodWludDY0X3QgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewogICAgcyArPSB4c1tpXTsKICB9CiAgcmV0dXJuIHM7Cn0KCnZvaWQgc3VtX2hlbHBlciAodm9pZCkgewogIGJvb2wgdmFsaWQ7CiAgdWludDY0X3QgaW5fbGVuLCBpbl9udW07CgogIHByaW50ZigiaG93IG1hbnkgbnVtYmVycz8gKG1heCAlZCBkaWdpdHMpICIsIElOVF9ESUdJVFMpOwogIGZmbHVzaChzdGRvdXQpOwoKICBpZiAoISh2YWxpZCA9IGdldF91aW50NjQoJmluX2xlbikpKSB7CiAgICByZXR1cm47CiAgfQogIGlmIChpbl9sZW4gPj0gSU5UX01BWCkgewogICAgcHJpbnRmKCIgY2FuJ3QgYWxsb2NhdGUgYXJyYXkgb2Ygc2l6ZSA+PSBJTlRfTUFYXG4iKTsKICAgIGluc3VsdF91c2VyKCk7CiAgICByZXR1cm47CiAgfQogIHVpbnQ2NF90ICBudW1zW2luX2xlbl0sCiAgICAgICAgICAgIGVuZHBvaW50ID0gaW5fbGVuOwogIHByaW50ZigiZW50ZXIgbm8gbW9yZSB0aGFuICUiIFBSSXU2NCAiIHVuc2lnbmVkIDY0LWJpdCBpbnRlZ2VycyAob25lIHBlciBsaW5lISkgb3IgRU9GIHRvIGVuZCBpbnB1dFxuIiwgaW5fbGVuKTsKCiAgZm9yICh1aW50NjRfdCBpID0gMDsgaSA8IGluX2xlbjsgaSsrKSB7CiAgICBpZiAoIWdldF91aW50NjQoJmluX251bSkpIHsgYnJlYWs7IH0KICAgIG51bXNbaV0gPSBpbl9udW07CiAgfQogIHByaW50Zigic3VtIG9mIGlucHV0czogJSIgUFJJdTY0ICJcbiIsIHN1bShudW1zLCBlbmRwb2ludCkpOwp9CgovLzMgLSBXcml0ZSBhIHByb2dyYW0gYW5kIGFzayB0aGUgdXNlciB0byBlbnRlciBhIG51bWJlci4gQ29tcHV0ZSB0aGUgZmFjdG9yaWFsIG9mCi8vICAgIHRoZSBudW1iZXIgYW5kIHByaW50IGl0IG9uIHRoZSBjb25zb2xlLiBGb3IgZXhhbXBsZSwgaWYgdGhlIHVzZXIgZW50ZXJzIDUsCi8vICAgIHRoZSBwcm9ncmFtIHNob3VsZCBjYWxjdWxhdGUgNSB4IDQgeCAzIHggMiB4IDEgYW5kIGRpc3BsYXkgaXQgYXMgNSEgPSAxMjAuCnVpbnQ2NF90IGZhY3RvcmlhbCAoY29uc3QgdWludDY0X3QgbikgewogIGlmICghbiB8fCBuID09IDEpIHsgcmV0dXJuIDE7IH0KICByZXR1cm4gbiAqIGZhY3RvcmlhbChuIC0gMSk7Cn0KCnZvaWQgZmFjdF9oZWxwZXIgKHZvaWQpIHsKICBib29sIHZhbGlkOwogIHVpbnQ2NF90IG51bTsKCiAgcHJpbnRmKCJlbnRlciBudW1iZXIgdG8gZmFjdG9yaWFsIG9yIGJsYW5rIGxpbmUgLyBFT0YgdG8gZW5kXG4iKTsKCiAgd2hpbGUgKCh2YWxpZCA9IGdldF91aW50NjQoJm51bSkpKSB7CiAgICAvLyBhdm9pZCBvdmVyZmxvdwogICAgdmFsaWQgJj0gKG51bSA8PSAyMFVMTCk7CgogICAgaWYgKHZhbGlkKSB7CiAgICAgIHByaW50ZigiJSIgUFJJdTY0ICIhID09ICUiIFBSSXU2NCAiXG4iLCBudW0sIGZhY3RvcmlhbChudW0pKTsKICAgIH0gZWxzZSBpZiAobnVtID4gMjBVTEwpIHsKICAgICAgaW5zdWx0X3VzZXIoKTsKICAgICAgcHJpbnRmKCJCT0Igc2F5czogVGhhdCBudW1iZXIgaXMgdG9vIGxhcmdlLCBlbnRlciBhbm90aGVyIVxuIik7CiAgICB9IGVsc2UgeyBicmVhazsgfQogIH0KCiAgcHJpbnRmKCJieWUhXG4iKTsKfQoKLy80IC0gV3JpdGUgYSBwcm9ncmFtIHRoYXQgcGlja3MgYSByYW5kb20gbnVtYmVyIGJldHdlZW4gMSBhbmQgMTAuR2l2ZSB0aGUgdXNlciA0Ci8vICAgIGNoYW5jZXMgdG8gZ3Vlc3MgdGhlIG51bWJlci5JZiB0aGUgdXNlciBndWVzc2VzIHRoZSBudW1iZXIsIGRpc3BsYXkg4oCcWW91IHdvbiI7Ci8vICAgIG90aGVyd2lzZSwgZGlzcGxheSDigJxZb3UgbG9zdCIuIChUbyBtYWtlIHN1cmUgdGhlIHByb2dyYW0gaXMgYmVoYXZpbmcgY29ycmVjdGx5LAovLyAgICB5b3UgY2FuIGRpc3BsYXkgdGhlIHNlY3JldCBudW1iZXIgb24gdGhlIGNvbnNvbGUgZmlyc3QuKQpib29sIGd1ZXNzX2dhbWUgKGNvbnN0IHVpbnQ2NF90IHVwcGVyLCBjb25zdCB1aW50NjRfdCB0cmllcywgdWludDY0X3QgKm91dGNvbWUpIHsKICB1aW50NjRfdCAgZ3Vlc3MsCiAgICAgICAgICAgIGNob2ljZSA9IHJhbmRfcmFuZ2UodXBwZXIpOwoKICBib29sIG92ZXI7CgogIC8vIHRoYW5rcywgY2xhbmcKICAodm9pZCkgb3V0Y29tZTsKCiAgZm9yICh1aW50NjRfdCBpID0gMDsgaSA8PSB0cmllczsgaSsrKSB7CiAgICBwcmludGYoIiglIiBQUkl1NjQgIiAvICUiIFBSSXU2NCAiKSBlbnRlciBhIGd1ZXNzISAiLCBpLCB0cmllcyk7CiAgICBmZmx1c2goc3Rkb3V0KTsKCiAgICBpZiAoIWdldF91aW50NjQoJmd1ZXNzKSkgeyBicmVhazsgfQoKICAgIGlmIChndWVzcyA9PSBjaG9pY2UpIHsKICAgICAgb3V0Y29tZSA9ICh1aW50NjRfdCAqKSBndWVzczsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9IGVsc2UgewogICAgICBvdmVyID0gKGkgPT0gdHJpZXMpOwogICAgICBwcmludGYoIkJPQiBzYXlzOiBJdCBzZWVtcyB0aGF0IGd1ZXNzIGlzIHdyb25nJXMiLCBvdmVyID8gIjsgeW91IGxvc2UhXG4iIDogIiwgZW50ZXIgYW5vdGhlciFcbiIpOwogICAgICBpZiAob3ZlcikgeyBpbnN1bHRfdXNlcigpOyByZXR1cm4gZmFsc2U7IH0KICAgIH0KICB9CiAgcmV0dXJuIGZhbHNlOwp9Cgp2b2lkIGd1ZXNzX2hlbHBlciAodm9pZCkgewogIHVpbnQ2NF90ICBvdXRjb21lLAogICAgICAgICAgICB1cHBlciwgdHJpZXM7CgogIHByaW50ZigiZW50ZXIgdGhlIHVwcGVyIGxpbWl0OiAiKTsKICBmZmx1c2goc3Rkb3V0KTsKICBpZiAoIShnZXRfdWludDY0KCZ1cHBlcikpKSB7CiAgICByZXR1cm47CiAgfQogIHByaW50ZigibnVtYmVyIG9mIHRyaWVzOiAiKTsKICBmZmx1c2goc3Rkb3V0KTsKICBpZiAoIShnZXRfdWludDY0KCZ0cmllcykpKSB7CiAgICByZXR1cm47CiAgfQoKICBpZiAoZ3Vlc3NfZ2FtZSh1cHBlciwgdHJpZXMsICZvdXRjb21lKSkgewogICAgcHJpbnRmKCJZb3UgZ3Vlc3NlZCByaWdodCEgJSIgUFJJdTY0ICJcbiIsIG91dGNvbWUpOwogIH0KfQoKLy81IC0gV3JpdGUgYSBwcm9ncmFtIGFuZCBhc2sgdGhlIHVzZXIgdG8gZW50ZXIgYSBzZXJpZXMgb2YgbnVtYmVycyBzZXBhcmF0ZWQgYnkKLy8gICAgY29tbWEuRmluZCB0aGUgbWF4aW11bSBvZiB0aGUgbnVtYmVycyBhbmQgZGlzcGxheSBpdCBvbiB0aGUgY29uc29sZS4gRm9yCi8vICAgIGV4YW1wbGUsIGlmIHRoZSB1c2VyIGVudGVycyDigJw1LCAzLCA4LCAxLCA0IiwgdGhlIHByb2dyYW0gc2hvdWxkIGRpc3BsYXkgOC4KdWludDY0X3QgbWF4IChjb25zdCB1aW50NjRfdCB4c1tzdGF0aWMgMV0sIGNvbnN0IHNpemVfdCBsZW4pIHsKICB1aW50NjRfdCBoaWdoID0gMDsKICBmb3IgKHVpbnQ2NF90IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgIGlmICh4c1tpXSA+IGhpZ2gpIHsgaGlnaCA9IHhzW2ldOyB9CiAgfQogIHJldHVybiBoaWdoOwp9CgoKdm9pZCBtYXhfaGVscGVyICh2b2lkKSB7Cgp9