www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - =?utf-8?B?SW50ZXJuYXRpb25hbGl6YXRpb24gbGlicmFyeSDilIAgYWR2aWNlL2hlbHA=?=

reply "Uwe Salomon" <post uwesalomon.de> writes:
During the writing of a string class for my Indigo library i "discovered"  
the need for a thorough internationalization library for D. I think a good  
implementation of i18n functionality would be very important for the  
development of applications in D, thus for the future of D. There is the  
ICU port of the Mango tree, but as ICU is a C/C++ library, this is not as  
natural and fast as it could be. I would like to write a native D i18n  
library which is independent of third party libraries.

As this is too big a project to develop for myself, and (i hope) of public  
interest for the D community, i would like to ask for:

- Advice: What is needed? How should it be implemented?
- Help: Who has the time and wants to help me? A total of 2 or 3  
developers should be sufficient?

My ideas are to write a compact core library that contains the most  
important features (character properties, UTF encodings, basic message  
translation), and then write some localization modules (number formatting,  
date formatting, comparing and searching). The goals should be simplicity  
and speed (but perhaps the community wants other things more?), avoiding  
complicated implementations and "template magic". And it should be well  
documented from the beginning, not a construction site on every corner.

But that are just some ideas that come to my mind right now. I hope that  
everybody makes some helpful statements what he/she thinks should be  
covered by the library on all accounts, and what would be very nice.

Thanks & ciao
uwe
May 15 2005
next sibling parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
Good idea, I like it.

FYI: On Windows MultiByteToWideChar and WideCharToMultiByte
support many encodings other than mentioned directly in MSDN.
I am using this list:

lang_t langs[] = {
    {"asmo-708",708},
    {"dos-720",720},
    {"iso-8859-6",28596},
    {"x-mac-arabic",10004},
    {"windows-1256",1256},
    {"ibm775",775},
    {"iso-8859-4",28594},
    {"windows-1257",1257},
    {"ibm852",852},
    {"iso-8859-2",28592},
    {"x-mac-ce",10029},
    {"windows-1250",1250},
    {"euc-cn",51936},
    {"gb2312",936},
    {"hz-gb-2312",52936},
    {"x-mac-chinesesimp",10008},
    {"big5",950},
    {"x-chinese-cns",20000},
    {"x-chinese-eten",20002},
    {"x-mac-chinesetrad",10002},
    {"cp866",866},
    {"iso-8859-5",28595},
    {"koi8-r",20866},
    {"koi8-u",21866},
    {"x-mac-cyrillic",10007},
    {"windows-1251",1251},
    {"x-europa",29001},
    {"x-ia5-german",20106},
    {"ibm737",737},
    {"iso-8859-7",28597},
    {"x-mac-greek",10006},
    {"windows-1253",1253},
    {"ibm869",869},
    {"dos-862",862},
    {"iso-8859-8-i",38598},
    {"iso-8859-8",28598},
    {"x-mac-hebrew",10005},
    {"windows-1255",1255},
    {"x-ebcdic-arabic",20420},
    {"x-ebcdic-cyrillicrussian",20880},
    {"x-ebcdic-cyrillicserbianbulgarian",21025},
    {"x-ebcdic-denmarknorway",20277},
    {"x-ebcdic-denmarknorway-euro",1142},
    {"x-ebcdic-finlandsweden",20278},
    {"x-ebcdic-finlandsweden-euro",1143},
    {"x-ebcdic-finlandsweden-euro",1143},
    {"x-ebcdic-france-euro",1147},
    {"x-ebcdic-germany",20273},
    {"x-ebcdic-germany-euro",1141},
    {"x-ebcdic-greekmodern",875},
    {"x-ebcdic-greek",20423},
    {"x-ebcdic-hebrew",20424},
    {"x-ebcdic-icelandic",20871},
    {"x-ebcdic-icelandic-euro",1149},
    {"x-ebcdic-international-euro",1148},
    {"x-ebcdic-italy",20280},
    {"x-ebcdic-italy-euro",1144},
    {"x-ebcdic-japaneseandkana",50930},
    {"x-ebcdic-japaneseandjapaneselatin",50939},
    {"x-ebcdic-japaneseanduscanada",50931},
    {"x-ebcdic-japanesekatakana",20290},
    {"x-ebcdic-koreanandkoreanextended",50933},
    {"x-ebcdic-koreanextended",20833},
    {"cp870",870},
    {"x-ebcdic-simplifiedchinese",50935},
    {"x-ebcdic-spain",20284},
    {"x-ebcdic-spain-euro",1145},
    {"x-ebcdic-thai",20838},
    {"x-ebcdic-traditionalchinese",50937},
    {"cp1026",1026},
    {"x-ebcdic-turkish",20905},
    {"x-ebcdic-uk",20285},
    {"x-ebcdic-uk-euro",1146},
    {"ebcdic-cp-us",37},
    {"x-ebcdic-cp-us-euro",1140},
    {"ibm861",861},
    {"x-mac-icelandic",10079},
    {"x-iscii-as",57006},
    {"x-iscii-be",57003},
    {"x-iscii-de",57002},
    {"x-iscii-gu",57010},
    {"x-iscii-ka",57008},
    {"x-iscii-ma",57009},
    {"x-iscii-or",57007},
    {"x-iscii-pa",57011},
    {"x-iscii-ta",57004},
    {"x-iscii-te",57005},
    {"euc-jp",51932},
    {"iso-2022-jp",50220},
    {"iso-2022-jp",50222},
    {"csiso2022jp",50221},
    {"x-mac-japanese",10001},
    {"shift_jis",932},
    {"ks_c_5601-1987",949},
    {"euc-kr",51949},
    {"iso-2022-kr",50225},
    {"johab",1361},
    {"x-mac-korean",10003},
    {"iso-8859-3",28593},
    {"iso-8859-15",28605},
    {"x-ia5-norwegian",20108},
    {"ibm437",437},
    {"x-ia5-swedish",20107},
    {"windows-874",874},
    {"ibm857",857},
    {"iso-8859-9",28599},
    {"x-mac-turkish",10081},
    {"windows-1254",1254},
    //{(const char *)L"unicode",1200},
    //{"unicodefffe",1201},
    {"utf-7",65000},
    {"utf-8",65001},
    //{"us-ascii",20127},
    {"us-ascii",1252},
    {"windows-1258",1258},
    {"ibm850",850},
    {"x-ia5",20105},
    {"iso-8859-1",1252}, //was 28591
    {"macintosh",10000},
    {"windows-1252",1252},
    {"system",CP_ACP}
  };

Second member in these structs is
codepage id directly used as first
parameter of
MultiByteToWideChar and WideCharToMultiByte

Hope this will help. At least it might help to build
translation tables automaticly :)

Andrew.




"Uwe Salomon" <post uwesalomon.de> wrote in message 
news:op.sqtvopik6yjbe6 sandmann.maerchenwald.net...
 During the writing of a string class for my Indigo library i "discovered" 
 the need for a thorough internationalization library for D. I think a good 
 implementation of i18n functionality would be very important for the 
 development of applications in D, thus for the future of D. There is the 
 ICU port of the Mango tree, but as ICU is a C/C++ library, this is not as 
 natural and fast as it could be. I would like to write a native D i18n 
 library which is independent of third party libraries.

 As this is too big a project to develop for myself, and (i hope) of public 
 interest for the D community, i would like to ask for:

 - Advice: What is needed? How should it be implemented?
 - Help: Who has the time and wants to help me? A total of 2 or 3 
 developers should be sufficient?

 My ideas are to write a compact core library that contains the most 
 important features (character properties, UTF encodings, basic message 
 translation), and then write some localization modules (number formatting, 
 date formatting, comparing and searching). The goals should be simplicity 
 and speed (but perhaps the community wants other things more?), avoiding 
 complicated implementations and "template magic". And it should be well 
 documented from the beginning, not a construction site on every corner.

 But that are just some ideas that come to my mind right now. I hope that 
 everybody makes some helpful statements what he/she thinks should be 
 covered by the library on all accounts, and what would be very nice.

 Thanks & ciao
 uwe 

May 15 2005
parent "Uwe Salomon" <post uwesalomon.de> writes:
 FYI: On Windows MultiByteToWideChar and WideCharToMultiByte
 support many encodings other than mentioned directly in MSDN.

Hmm, thanks for that. As libiconv is no standard for windows :) this will come in handy. Is there anyone who knows about encoding/decoding (and programming specialties in general) on the Mac? Regrettably, i know not a thing about the Mac programming environment at all. :( uwe
May 15 2005
prev sibling next sibling parent reply Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Uwe Salomon schrieb am Sun, 15 May 2005 19:47:03 +0200:
 During the writing of a string class for my Indigo library i "discovered"  
 the need for a thorough internationalization library for D. I think a good  
 implementation of i18n functionality would be very important for the  
 development of applications in D, thus for the future of D. There is the  
 ICU port of the Mango tree, but as ICU is a C/C++ library, this is not as  
 natural and fast as it could be. I would like to write a native D i18n  
 library which is independent of third party libraries.

[snip] some links: http://www.i18ngurus.com/ http://www.openi18n.org/ http://java.sun.com/j2se/corejava/intl/ http://doc.trolltech.com/3.3/i18n.html Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCifJL3w+/yD4P9tIRAovzAKDAgMP6Ti7ENQPYwMo1uuLdrIBKfQCfbg9q 8bWa1c8AAVR++B5ytpxaugo= =XnC4 -----END PGP SIGNATURE-----
May 17 2005
parent reply "Uwe Salomon" <post uwesalomon.de> writes:
 some links:

These are very good and informative, thanks a lot! uwe
May 17 2005
parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
Uwe Salomon wrote:

 some links:

These are very good and informative, thanks a lot! uwe

Also, look at http://i18n.kde.org and http://developer.kde.org/documentation/library/kdeqt/kde3arch/kde-i18n-howto.html/ While KDE is based on Qt, it seems like they've expanded on the functionality, especially the part that has to do with translations of messages and gui. Lars Ivar Igesund
May 18 2005
parent "Uwe Salomon" <post uwesalomon.de> writes:
 While KDE is based on Qt, it seems like they've expanded on the
 functionality, especially the part that has to do with translations of
 messages and gui.

Hmm, they are using GNU gettext() instead of the Qt tr(). Perhaps it would be a good idea to go at least one of the ways, instead of inventing something totally new. I like the KDE markup i18n("String to translate"). If i used that, all the existing tools (KBabel, Emacs PO mode) as well as string extractors and friends were available already. But it will make the lib dependant on GNU gettext(), or i would have to write my own .mo reader. gettext() is nonstandard for Windows, right? Please, would anybody be so kind and explain to me how translation of user messages works under Windows (roughly)? I remember them using resource files. Does the application load the right resource file at runtime? And how does it work for the Mac? Thanks for the help! uwe
May 18 2005
prev sibling parent reply "Uwe Salomon" <post uwesalomon.de> writes:
This is a first implementation for conversion between UTF encodings. I  
used UTF-8 <=> UTF-16 as an example. In a sum, this is what i thought of:


char[] toUtf8(wchar[] str, inout size_t eaten, char[] buffer);
char[] toUtf8(wchar[] str, inout size_t eaten);
char[] toUtf8(wchar[] str, char[] buffer);
char[] toUtf8(wchar[] str);

* The first function converts str into UTF-8, beginning at str[eaten],  
adjusting eaten up to where it converted (stopping before an incomplete  
sequence at the end of str), and using buffer if large enough,  
reallocating the buffer if space is not sufficient. It throws an exception  
if faced with invalid input encoding.

* The second function allocates a sufficient buffer itself.

* The third function converts str as a whole, asserting on an incomplete  
sequence at the end of str. It uses buffer if possible.

* The fourth function does like the third, and allocates the buffer itself.

* For every function there is a variant called fast_toUtf8() with the same  
parameters which relies on valid input, producing invalid output  
otherwise. It can be used if the input is guaranteed to be valid, and is  
much faster then.


For more explanations and a coding example visit:
http://www.uwesalomon.de/code/unicode/files/conversion-d.html

The source is at
http://www.uwesalomon.de/code/unicode/conversion.d


This is a draft, and i will be very happy if everyone who is interested  
comments on it, especially the API "design" (i know, fast_toUtf8() is a  
clumsy name :). And another question (i hope this is not arrogant): should  
these functions (or especially the simple form, without eaten) be included  
into Phobos std.utf? They are *much* faster than the current  
implementation. If someone would say, "Nice stuff, kiddo. Debug that  
properly, adjust it to the std.utf module (use their exception etc.) and  
submit a patch. Perhaps we will look at it then." i would sure do that.  
:)  But i am afraid that these kind of guerilla actions are rather  
unwanted, and i should better keep my mouth shut and code some useful  
stuff...

Thanks
uwe
May 18 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Uwe Salomon" <post uwesalomon.de> wrote in message 
news:op.sqyw3zok6yjbe6 sandmann.maerchenwald.net...
 This is a first implementation for conversion between UTF encodings. I 
 used UTF-8 <=> UTF-16 as an example. In a sum, this is what i thought of:


 char[] toUtf8(wchar[] str, inout size_t eaten, char[] buffer);
 char[] toUtf8(wchar[] str, inout size_t eaten);
 char[] toUtf8(wchar[] str, char[] buffer);
 char[] toUtf8(wchar[] str);

 * The first function converts str into UTF-8, beginning at str[eaten], 
 adjusting eaten up to where it converted (stopping before an incomplete 
 sequence at the end of str), and using buffer if large enough, 
 reallocating the buffer if space is not sufficient. It throws an exception 
 if faced with invalid input encoding.

 * The second function allocates a sufficient buffer itself.

 * The third function converts str as a whole, asserting on an incomplete 
 sequence at the end of str. It uses buffer if possible.

 * The fourth function does like the third, and allocates the buffer 
 itself.

 * For every function there is a variant called fast_toUtf8() with the same 
 parameters which relies on valid input, producing invalid output 
 otherwise. It can be used if the input is guaranteed to be valid, and is 
 much faster then.


 For more explanations and a coding example visit:
 http://www.uwesalomon.de/code/unicode/files/conversion-d.html

 The source is at
 http://www.uwesalomon.de/code/unicode/conversion.d


 This is a draft, and i will be very happy if everyone who is interested 
 comments on it, especially the API "design" (i know, fast_toUtf8() is a 
 clumsy name :). And another question (i hope this is not arrogant): should 
 these functions (or especially the simple form, without eaten) be included 
 into Phobos std.utf? They are *much* faster than the current 
 implementation. If someone would say, "Nice stuff, kiddo. Debug that 
 properly, adjust it to the std.utf module (use their exception etc.) and 
 submit a patch. Perhaps we will look at it then." i would sure do that. 
 :)  But i am afraid that these kind of guerilla actions are rather 
 unwanted, and i should better keep my mouth shut and code some useful 
 stuff...

 Thanks
 uwe

Speeding up std.utf would be good - how can one argue with that? :-) Three thoughts come to mind: 1) fast_toUtf8 should be something like toUtf8Unsafe or toUtf8Unchecked to indicate to the user that it's not just a faster version of another routine (since I'd call fast_foo over foo every time!) but one that makes significant assumptions about the input. I'm not actually sure how often it would be ok to call such a function anyway so maybe it isn't even needed. Getting the wrong answer quickly is not a good trade-off. 2) it looks like you reallocate the output buffer inside the loop - can it be moved to outside? 3) the formatting of the source code is somewhat unusual. I missed the loop at first: // Now do the conversion. if (pIn < endIn) do { // Check for enough space left in the buffer. if (pOut >= endOut) [snip 50 lines of code or so] } while (++pIn < endIn); That first line with the "do" my eye skipped right over the "do" and I had to backtrack once I saw a "while" down at the bottom.
May 18 2005
next sibling parent reply "Uwe Salomon" <post uwesalomon.de> writes:
 1) fast_toUtf8 should be something like toUtf8Unsafe or toUtf8Unchecked

Yes, one of them sounds much better. I did not think long about fast_xxx()... Perhaps also toUtf8Unverified(), regrettably that is very long.
 I'm not actually sure how often it
 would be ok to call such a function anyway so maybe it isn't even needed.
 Getting the wrong answer quickly is not a good trade-off.

You are right, that is an important fact, especially for a standard library. Easy test: i converted a german email (mostly ASCII, some special characters) with 5000 characters from UTF8 to UTF16. I provided the buffer, because both functions are equally well at allocating memory. Normal compilation: * safe function: 0.100 ms * unsafe function: 0.088 ms (12% faster) Compilation -release -O: * safe function: 0.050 ms * unsafe function: 0.046 ms (8 % faster) I am not sure how all this could benefit from an assembler implementation. Anyways, the speed gain is minimal (actually, i thought it would be a lot more!). Well, no need to search for a good "unsafe" name then. ;)
 2) it looks like you reallocate the output buffer inside the loop - can  
 it be moved to outside?

Why? To shorten the loop? I thought the buffer should only be reallocated if the conversion itself shows it is too short. Do you want to move it before (so that a reallocation *cannot* occure inside the loop), or just outside (with a goto SomeWhereOutsideTheLoop and after the reallocation goto BackIntoTheLoop)?
 3) the formatting of the source code is somewhat unusual. I missed the  
 loop at first.

Changed. Thanks for the reply, uwe
May 18 2005
next sibling parent "Uwe Salomon" <post uwesalomon.de> writes:
 Normal compilation:
    * safe function: 0.100 ms
    * unsafe function: 0.088 ms (12% faster)

 Compilation -release -O:
    * safe function: 0.050 ms
    * unsafe function: 0.046 ms (8 % faster)

Maybe i should add that if you convert a text which contains a lot of UTF8 2/3-byte-encodings (asian languages), the unsafe function saves more: about 20% in comparison to the safe function. uwe
May 18 2005
prev sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Uwe Salomon" <post uwesalomon.de> wrote in message 
news:op.sqy2lzec6yjbe6 sandmann.maerchenwald.net...
 1) fast_toUtf8 should be something like toUtf8Unsafe or toUtf8Unchecked

Yes, one of them sounds much better. I did not think long about fast_xxx()... Perhaps also toUtf8Unverified(), regrettably that is very long.
 I'm not actually sure how often it
 would be ok to call such a function anyway so maybe it isn't even needed.
 Getting the wrong answer quickly is not a good trade-off.

You are right, that is an important fact, especially for a standard library. Easy test: i converted a german email (mostly ASCII, some special characters) with 5000 characters from UTF8 to UTF16. I provided the buffer, because both functions are equally well at allocating memory. Normal compilation: * safe function: 0.100 ms * unsafe function: 0.088 ms (12% faster) Compilation -release -O: * safe function: 0.050 ms * unsafe function: 0.046 ms (8 % faster) I am not sure how all this could benefit from an assembler implementation. Anyways, the speed gain is minimal (actually, i thought it would be a lot more!). Well, no need to search for a good "unsafe" name then. ;)

I could see using the unsafe versions when you check the input once and then convert many slices that one then knows to be safe. So it isn't unreasonable to have it in there. I don't know the use cases well enough to offer up an opinion.
 2) it looks like you reallocate the output buffer inside the loop - can 
 it be moved to outside?

Why? To shorten the loop? I thought the buffer should only be reallocated if the conversion itself shows it is too short. Do you want to move it before (so that a reallocation *cannot* occure inside the loop), or just outside (with a goto SomeWhereOutsideTheLoop and after the reallocation goto BackIntoTheLoop)?

How about if it needs to grow the buffer it does so with a large chunk instead of many small chunks. That is, the buffer doesn't have to fit exactly. Basically I have in mind that you estimate the maximum buffer size based on the number of input characters left and allocate that.
 3) the formatting of the source code is somewhat unusual. I missed the 
 loop at first.

Changed. Thanks for the reply, uwe

May 18 2005
parent reply "Uwe Salomon" <post uwesalomon.de> writes:
 I could see using the unsafe versions when you check the input once and  
 then
 convert many slices that one then knows to be safe. So it isn't  
 unreasonable
 to have it in there. I don't know the use cases well enough to offer up  
 an opinion.

Imagine a program that reads a lot of files from disk, does some fuzzy work on them, and writes some others back, for example a doc tool. It reads the source files in UTF8 format and converts them to the internally used UTF16 (using the safe functions). It then processes here and there, extracts the comments and formats them round. After that it puts out HTML files in UTF8. The comments need to be converted back to UTF8, and that's where the program could use the unsafe functions. At least that were my thoughts. But if the speed gain is under 30%, i think the fast versions are unnecessary. Imagine the doc tool needs a minute for output. With the current functions this would drop to 50 seconds at most, providing that the output only consists of UTF conversion (which is very unlikely).
 2) it looks like you reallocate the output buffer inside the loop - can
 it be moved to outside?

Why? To shorten the loop? I thought the buffer should only be reallocated if the conversion itself shows it is too short. Do you want to move it before (so that a reallocation *cannot* occure inside the loop), or just outside (with a goto SomeWhereOutsideTheLoop and after the reallocation goto BackIntoTheLoop)?

How about if it needs to grow the buffer it does so with a large chunk instead of many small chunks. That is, the buffer doesn't have to fit exactly. Basically I have in mind that you estimate the maximum buffer size based on the number of input characters left and allocate that.

Hmm, the current source is: if (pOut >= endOut) { // ... buffer.length = buffer.length + (endIn - pIn) + 2; // Will be enough. // ... } This will grow the buffer only once? (endIn - pIn) is the number of UTF8 characters to be processed, and they cannot expand to more than the same amount of UTF16 characters (1-byte encoded UTF8 becomes 1-word encoded UTF16, 4-byte encoded UTF8 becomes 2-word encoded UTF16). The same goes for toUtf8(). But you are right, this could still be moved before the loop, especially this one in toUtf16(). That's because (endIn - pIn) is a very accurate guess for languages with a lot of ASCII in them. Ciao uwe
May 18 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Uwe Salomon" <post uwesalomon.de> wrote in message 
news:op.sqy4o0ud6yjbe6 sandmann.maerchenwald.net...
 I could see using the unsafe versions when you check the input once and 
 then
 convert many slices that one then knows to be safe. So it isn't 
 unreasonable
 to have it in there. I don't know the use cases well enough to offer up 
 an opinion.

Imagine a program that reads a lot of files from disk, does some fuzzy work on them, and writes some others back, for example a doc tool. It reads the source files in UTF8 format and converts them to the internally used UTF16 (using the safe functions). It then processes here and there, extracts the comments and formats them round. After that it puts out HTML files in UTF8. The comments need to be converted back to UTF8, and that's where the program could use the unsafe functions. At least that were my thoughts. But if the speed gain is under 30%, i think the fast versions are unnecessary. Imagine the doc tool needs a minute for output. With the current functions this would drop to 50 seconds at most, providing that the output only consists of UTF conversion (which is very unlikely).

sounds reasonable
 2) it looks like you reallocate the output buffer inside the loop - can
 it be moved to outside?

Why? To shorten the loop? I thought the buffer should only be reallocated if the conversion itself shows it is too short. Do you want to move it before (so that a reallocation *cannot* occure inside the loop), or just outside (with a goto SomeWhereOutsideTheLoop and after the reallocation goto BackIntoTheLoop)?

How about if it needs to grow the buffer it does so with a large chunk instead of many small chunks. That is, the buffer doesn't have to fit exactly. Basically I have in mind that you estimate the maximum buffer size based on the number of input characters left and allocate that.

Hmm, the current source is: if (pOut >= endOut) { // ... buffer.length = buffer.length + (endIn - pIn) + 2; // Will be enough. // ... } This will grow the buffer only once? (endIn - pIn) is the number of UTF8 characters to be processed, and they cannot expand to more than the same amount of UTF16 characters (1-byte encoded UTF8 becomes 1-word encoded UTF16, 4-byte encoded UTF8 becomes 2-word encoded UTF16). The same goes for toUtf8().

ok - I didn't look at the details. I just saw the resizing happening in the loop and guessed it was resizing a little bit each time. What you have seems reasonable.
 But you are right, this could still be moved before the loop, especially 
 this one in toUtf16(). That's because (endIn - pIn) is a very accurate 
 guess for languages with a lot of ASCII in them.

 Ciao
 uwe 

May 18 2005
parent "Uwe Salomon" <post uwesalomon.de> writes:
 This will grow the buffer only once? (endIn - pIn) is the number of UTF8
 characters to be processed, and they cannot expand to more than the same
 amount of UTF16 characters (1-byte encoded UTF8 becomes 1-word encoded
 UTF16, 4-byte encoded UTF8 becomes 2-word encoded UTF16). The same goes
 for toUtf8().

ok - I didn't look at the details. I just saw the resizing happening in the loop and guessed it was resizing a little bit each time. What you have seems reasonable.

Still you are right. I moved it out of the loop in toUtf16(). I will think about it in the other functions, not sure what is best in each case (well, it always depends on the characters in the string). I am now writing the other 4 functions (that is much easier now, as the two were the most complex). After finishing and testing them, i'll beep again. :) By the way... how are the Phobos docs generated? Hand-crafted? I will also update the corresponding sections if you let me... Ciao uwe
May 18 2005
prev sibling parent reply "Uwe Salomon" <post uwesalomon.de> writes:
I have now moved the UTF conversion code into the std.utf module. I have  
made the following changes:

* The tabs are now spaces. Sorry... :)
* Slight change in UTF8stride array. Unicode 4.01 declares some encodings  
illegal, including 5- and 6-byte encodings and some at the beginning of  
the 2-bytes.
* Slight change in stride(wchar) and toUTFindex(wchar) and  
toUCSindex(wchar). I just changed the detection of UTF16 surrogate values  
to a faster variant that does not need a local variable as well.
* Replacement of all toUTF() functions, except the ones that only validate  
because the return type has the same encoding as the parameter. toUTF16z()  
is still there as well, but changed to use my own toUTF16 (it  
zero-terminates the strings anyways).

I have not changed the encode/decode functions, even if they really needed  
some change (especially the UTF8 decode() function). I will happily do  
that, but i want to know first if my previous work is ok.

Ciao
uwe
May 21 2005
parent "Uwe Salomon" <post uwesalomon.de> writes:
------------nYfCPQ0YqXIPLx3SP0pXvL
Content-Type: text/plain; format=flowed; delsp=yes; charset=utf-8
Content-Transfer-Encoding: 8bit

And here goes the attachment %)
------------nYfCPQ0YqXIPLx3SP0pXvL
Content-Disposition: attachment; filename=stdutf.d
Content-Type: application/octet-stream; name=stdutf.d
Content-Transfer-Encoding: Base64

Ly8gdXRmLmQNCg0KLyoNCiAqICBDb3B5cmlnaHQgKEMpIDIwMDMtMjAwNCBieSBE
aWdpdGFsIE1hcnMsIHd3dy5kaWdpdGFsbWFycy5jb20NCiAqICBXcml0dGVuIGJ5
IFdhbHRlciBCcmlnaHQNCiAqDQogKiAgVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRl
ZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQNCiAqICB3
YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxp
YWJsZSBmb3IgYW55IGRhbWFnZXMNCiAqICBhcmlzaW5nIGZyb20gdGhlIHVzZSBv
ZiB0aGlzIHNvZnR3YXJlLg0KICoNCiAqICBQZXJtaXNzaW9uIGlzIGdyYW50ZWQg
dG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSwN
CiAqICBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBh
bHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0DQogKiAgZnJlZWx5LCBzdWJqZWN0
IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOg0KICoNCiAqICBvICBUaGUg
b3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50
ZWQ7IHlvdSBtdXN0IG5vdA0KICogICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRo
ZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlDQog
KiAgICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJv
ZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlDQogKiAgICAgYXBwcmVjaWF0ZWQg
YnV0IGlzIG5vdCByZXF1aXJlZC4NCiAqICBvICBBbHRlcmVkIHNvdXJjZSB2ZXJz
aW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5v
dA0KICogICAgIGJlIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5h
bCBzb2Z0d2FyZS4NCiAqICBvICBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92
ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UNCiAqICAgICBkaXN0cmlidXRp
b24uDQogKi8NCg0KLy8gRGVzY3JpcHRpb24gb2YgVVRGLTggYXQ6DQovLyBodHRw
Oi8vd3d3LmNsLmNhbS5hYy51ay9+bWdrMjUvdW5pY29kZS5odG1sI3V0Zi04DQov
LyBodHRwOi8vYW51YmlzLmRrdXVnLmRrL0pUQzEvU0MyL1dHMi9kb2NzL24xMzM1
DQoNCm1vZHVsZSBzdGQudXRmOw0KDQpwcml2YXRlIGltcG9ydCBzdGQuc3RkaW87
DQoNCi8vZGVidWc9dXRmOyAgICAgICAgICAgIC8vIHVuY29tbWVudCB0byB0dXJu
IG9uIGRlYnVnZ2luZyBwcmludGYncw0KDQpjbGFzcyBVdGZFcnJvciA6IEVycm9y
DQp7DQogICAgc2l6ZV90IGlkeDsgICAvLyBpbmRleCBpbiBzdHJpbmcgb2Ygd2hl
cmUgZXJyb3Igb2NjdXJyZWQNCg0KICAgIHRoaXMoY2hhcltdIHMsIHNpemVfdCBp
KQ0KICAgIHsNCiAgICAgIGlkeCA9IGk7DQogICAgICBzdXBlcihzKTsNCiAgICB9
DQp9DQoNCg0KYml0IGlzVmFsaWREY2hhcihkY2hhciBjKQ0Kew0KICAgIC8qIE5v
dGU6IEZGRkUgYW5kIEZGRkYgYXJlIHNwZWNpZmljYWxseSBwZXJtaXR0ZWQgYnkg
dGhlDQogICAgICogVW5pY29kZSBzdGFuZGFyZCBmb3IgYXBwbGljYXRpb24gaW50
ZXJuYWwgdXNlLCBidXQgYXJlIG5vdA0KICAgICAqIGFsbG93ZWQgZm9yIGludGVy
Y2hhbmdlLg0KICAgICAqICh0aGFua3MgdG8gQXJjYW5lIEppbGwpDQogICAgICov
DQoNCiAgICByZXR1cm4gYyA8IDB4RDgwMCB8fA0KICAgICAgKGMgPiAweERGRkYg
JiYgYyA8PSAweDEwRkZGRiAvKiYmIGMgIT0gMHhGRkZFICYmIGMgIT0gMHhGRkZG
Ki8pOw0KfQ0KDQp1bml0dGVzdA0Kew0KICAgIGRlYnVnKHV0ZikgcHJpbnRmKCJ1
dGYuaXNWYWxpZERjaGFyLnVuaXR0ZXN0XG4iKTsNCiAgICBhc3NlcnQoaXNWYWxp
ZERjaGFyKGNhc3QoZGNoYXIpJ2EnKSA9PSB0cnVlKTsNCiAgICBhc3NlcnQoaXNW
YWxpZERjaGFyKGNhc3QoZGNoYXIpMHgxRkZGRkYpID09IGZhbHNlKTsNCn0NCg0K
DQovKiBUaGlzIGFycmF5IGdpdmVzIHRoZSBsZW5ndGggb2YgYSBVVEYtOCBzZXF1
ZW5jZSBpbmRleGVkIGJ5IHRoZSB2YWx1ZQ0KICogb2YgdGhlIGxlYWRpbmcgYnl0
ZS4gQW4gRkYgcmVwcmVzZW50cyBhbiBpbGxlZ2FsIHN0YXJ0aW5nIHZhbHVlIG9m
DQogKiBhIFVURi04IHNlcXVlbmNlLg0KICogRkYgaXMgdXNlZCBpbnN0ZWFkIG9m
IDAgdG8gYXZvaWQgaGF2aW5nIGxvb3BzIGhhbmcuDQogKi8NCg0KdWJ5dGVbMjU2
XSBVVEY4c3RyaWRlID0NClsNCiAgICAxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwx
LDEsMSwxLA0KICAgIDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsDQog
ICAgMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwNCiAgICAxLDEsMSwx
LDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLA0KICAgIDEsMSwxLDEsMSwxLDEsMSwx
LDEsMSwxLDEsMSwxLDEsDQogICAgMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwx
LDEsMSwNCiAgICAxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLA0KICAg
IDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsDQogICAgMHhGRiwweEZG
LDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4
RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwNCiAgICAweEZGLDB4RkYsMHhGRiwweEZG
LDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4
RkYsMHhGRiwweEZGLA0KICAgIDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZG
LDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4
RkYsDQogICAgMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZG
LDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwNCiAgICAw
eEZGLDB4RkYsMiwyLDIsMiwyLDIsMiwyLDIsMiwyLDIsMiwyLA0KICAgIDIsMiwy
LDIsMiwyLDIsMiwyLDIsMiwyLDIsMiwyLDIsDQogICAgMywzLDMsMywzLDMsMywz
LDMsMywzLDMsMywzLDMsMywNCiAgICA0LDQsNCw0LDQsMHhGRiwweEZGLDB4RkYs
MHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLA0KXTsNCg0K
dWludCBzdHJpZGUoY2hhcltdIHMsIHNpemVfdCBpKQ0Kew0KICAgIHJldHVybiBV
VEY4c3RyaWRlW3NbaV1dOw0KfQ0KDQp1aW50IHN0cmlkZSh3Y2hhcltdIHMsIHNp
emVfdCBpKQ0Kew0KICAgIHJldHVybiAoKHNbaV0gJiAweEY4MDApID09IDB4RDgw
MCA/IDIgOiAxKTsNCn0NCg0KdWludCBzdHJpZGUoZGNoYXJbXSBzLCBzaXplX3Qg
aSkNCnsNCiAgICByZXR1cm4gMTsNCn0NCg0KLyoqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioNCiAqIEdpdmVuIGFuIGluZGV4IGludG8g
YW4gYXJyYXkgb2YgY2hhcidzLA0KICogYW5kIGFzc3VtaW5nIHRoYXQgaW5kZXgg
aXMgYXQgdGhlIHN0YXJ0IG9mIGEgVVRGIGNoYXJhY3RlciwNCiAqIGRldGVybWlu
ZSB0aGUgbnVtYmVyIG9mIFVDUyBjaGFyYWN0ZXJzIHVwIHRvIHRoYXQgaW5kZXgu
DQogKi8NCg0Kc2l6ZV90IHRvVUNTaW5kZXgoY2hhcltdIHMsIHNpemVfdCBpKQ0K
ew0KICAgIHNpemVfdCBuOw0KICAgIHNpemVfdCBqOw0KICAgIHNpemVfdCBzdHJp
ZGU7DQoNCiAgICBmb3IgKGogPSAwOyBqIDwgaTsgaiArPSBzdHJpZGUpDQogICAg
ew0KICAgICAgc3RyaWRlID0gVVRGOHN0cmlkZVtzW2pdXTsNCiAgICAgIGlmIChz
dHJpZGUgPT0gMHhGRikNCiAgICAgICAgICBnb3RvIExlcnI7DQogICAgICBuKys7
DQogICAgfQ0KICAgIGlmIChqID4gaSkNCiAgICB7DQogICAgICBMZXJyOg0KICAg
ICAgdGhyb3cgbmV3IFV0ZkVycm9yKCIxaW52YWxpZCBVVEYtOCBzZXF1ZW5jZSIs
IGopOw0KICAgIH0NCiAgICByZXR1cm4gbjsNCn0NCg0Kc2l6ZV90IHRvVUNTaW5k
ZXgod2NoYXJbXSBzLCBzaXplX3QgaSkNCnsNCiAgICBzaXplX3QgbjsNCiAgICBz
aXplX3QgajsNCg0KICAgIGZvciAoaiA9IDA7IGogPCBpOyApDQogICAgew0KICAg
ICAgaiArPSAoKHNbal0gJiAweEY4MDApID09IDB4RDgwMCA/IDIgOiAxKTsNCiAg
ICAgIG4rKzsNCiAgICB9DQogICAgaWYgKGogPiBpKQ0KICAgIHsNCiAgICAgIExl
cnI6DQogICAgICB0aHJvdyBuZXcgVXRmRXJyb3IoIjJpbnZhbGlkIFVURi0xNiBz
ZXF1ZW5jZSIsIGopOw0KICAgIH0NCiAgICByZXR1cm4gbjsNCn0NCg0Kc2l6ZV90
IHRvVUNTaW5kZXgoZGNoYXJbXSBzLCBzaXplX3QgaSkNCnsNCiAgICByZXR1cm4g
aTsNCn0NCg0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKg0KICogR2l2ZW4gYSBVQ1MgaW5kZXggaW50byBhbiBhcnJheSBvZiBjaGFy
YWN0ZXJzLCByZXR1cm4gdGhlIFVURiBpbmRleC4NCiAqLw0KDQpzaXplX3QgdG9V
VEZpbmRleChjaGFyW10gcywgc2l6ZV90IG4pDQp7DQogICAgc2l6ZV90IGk7DQoN
CiAgICB3aGlsZSAobi0tKQ0KICAgIHsNCiAgICAgIHVpbnQgaiA9IFVURjhzdHJp
ZGVbc1tpXV07DQogICAgICBpZiAoaiA9PSAweEZGKQ0KICAgICAgICAgIHRocm93
IG5ldyBVdGZFcnJvcigiM2ludmFsaWQgVVRGLTggc2VxdWVuY2UiLCBpKTsNCiAg
ICAgIGkgKz0gajsNCiAgICB9DQogICAgcmV0dXJuIGk7DQp9DQoNCnNpemVfdCB0
b1VURmluZGV4KHdjaGFyW10gcywgc2l6ZV90IG4pDQp7DQogICAgc2l6ZV90IGk7
DQoNCiAgICB3aGlsZSAobi0tKQ0KICAgICAgaSArPSAoKHNbaV0gJiAweEY4MDAp
ID09IDB4RDgwMCA/IDIgOiAxKTsNCg0KICAgIHJldHVybiBpOw0KfQ0KDQpzaXpl
X3QgdG9VVEZpbmRleChkY2hhcltdIHMsIHNpemVfdCBuKQ0Kew0KICAgIHJldHVy
biBuOw0KfQ0KDQovKiA9PT09PT09PT09PT09PT09PT09IERlY29kZSA9PT09PT09
PT09PT09PT09PT09PT09PSAqLw0KDQpkY2hhciBkZWNvZGUoY2hhcltdIHMsIGlu
b3V0IHNpemVfdCBpZHgpDQogICAgaW4NCiAgICB7DQogICAgICBhc3NlcnQoaWR4
ID49IDAgJiYgaWR4IDwgcy5sZW5ndGgpOw0KICAgIH0NCiAgICBvdXQgKHJlc3Vs
dCkNCiAgICB7DQogICAgICBhc3NlcnQoaXNWYWxpZERjaGFyKHJlc3VsdCkpOw0K
ICAgIH0NCiAgICBib2R5DQogICAgew0KICAgICAgc2l6ZV90IGxlbiA9IHMubGVu
Z3RoOw0KICAgICAgZGNoYXIgVjsNCiAgICAgIHNpemVfdCBpID0gaWR4Ow0KICAg
ICAgY2hhciB1ID0gc1tpXTsNCg0KICAgICAgaWYgKHUgJiAweDgwKQ0KICAgICAg
eyAgIHVpbnQgbjsNCiAgICAgICAgICBjaGFyIHUyOw0KDQogICAgICAgICAgLyog
VGhlIGZvbGxvd2luZyBlbmNvZGluZ3MgYXJlIHZhbGlkLCBleGNlcHQgZm9yIHRo
ZSA1IGFuZCA2IGJ5dGUNCiAgICAgICAgICAgKiBjb21iaW5hdGlvbnM6DQogICAg
ICAgICAgICogICAgICAweHh4eHh4eA0KICAgICAgICAgICAqICAgICAgMTEweHh4
eHggMTB4eHh4eHgNCiAgICAgICAgICAgKiAgICAgIDExMTB4eHh4IDEweHh4eHh4
IDEweHh4eHh4DQogICAgICAgICAgICogICAgICAxMTExMHh4eCAxMHh4eHh4eCAx
MHh4eHh4eCAxMHh4eHh4eA0KICAgICAgICAgICAqICAgICAgMTExMTEweHggMTB4
eHh4eHggMTB4eHh4eHggMTB4eHh4eHggMTB4eHh4eHgNCiAgICAgICAgICAgKiAg
ICAgIDExMTExMTB4IDEweHh4eHh4IDEweHh4eHh4IDEweHh4eHh4IDEweHh4eHh4
IDEweHh4eHh4DQogICAgICAgICAgICovDQogICAgICAgICAgZm9yIChuID0gMTsg
OyBuKyspDQogICAgICAgICAgew0KICAgICAgICAgICAgaWYgKG4gPiA0KQ0KICAg
ICAgICAgICAgICAgIGdvdG8gTGVycjsgICAgICAgICAgLy8gb25seSBkbyB0aGUg
Zmlyc3QgNCBvZiA2IGVuY29kaW5ncw0KICAgICAgICAgICAgaWYgKCgodSA8PCBu
KSAmIDB4ODApID09IDApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAg
aWYgKG4gPT0gMSkNCiAgICAgICAgICAgICAgICAgIGdvdG8gTGVycjsNCiAgICAg
ICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9DQoN
CiAgICAgICAgICAvLyBQaWNrIG9mZiAoNyAtIG4pIHNpZ25pZmljYW50IGJpdHMg
b2YgQiBmcm9tIGZpcnN0IGJ5dGUgb2Ygb2N0ZXQNCiAgICAgICAgICBWID0gY2Fz
dChkY2hhcikodSAmICgoMSA8PCAoNyAtIG4pKSAtIDEpKTsNCg0KICAgICAgICAg
IGlmIChpICsgKG4gLSAxKSA+PSBsZW4pDQogICAgICAgICAgICBnb3RvIExlcnI7
ICAgICAgICAgICAgICAvLyBvZmYgZW5kIG9mIHN0cmluZw0KDQogICAgICAgICAg
LyogVGhlIGZvbGxvd2luZyBjb21iaW5hdGlvbnMgYXJlIG92ZXJsb25nLCBhbmQg
aWxsZWdhbDoNCiAgICAgICAgICAgKiAgICAgIDExMDAwMDB4ICgxMHh4eHh4eCkN
CiAgICAgICAgICAgKiAgICAgIDExMTAwMDAwIDEwMHh4eHh4ICgxMHh4eHh4eCkN
CiAgICAgICAgICAgKiAgICAgIDExMTEwMDAwIDEwMDB4eHh4ICgxMHh4eHh4eCAx
MHh4eHh4eCkNCiAgICAgICAgICAgKiAgICAgIDExMTExMDAwIDEwMDAweHh4ICgx
MHh4eHh4eCAxMHh4eHh4eCAxMHh4eHh4eCkNCiAgICAgICAgICAgKiAgICAgIDEx
MTExMTAwIDEwMDAwMHh4ICgxMHh4eHh4eCAxMHh4eHh4eCAxMHh4eHh4eCAxMHh4
eHh4eCkNCiAgICAgICAgICAgKi8NCiAgICAgICAgICB1MiA9IHNbaSArIDFdOw0K
ICAgICAgICAgIGlmICgodSAmIDB4RkUpID09IDB4QzAgfHwNCiAgICAgICAgICAg
ICh1ID09IDB4RTAgJiYgKHUyICYgMHhFMCkgPT0gMHg4MCkgfHwNCiAgICAgICAg
ICAgICh1ID09IDB4RjAgJiYgKHUyICYgMHhGMCkgPT0gMHg4MCkgfHwNCiAgICAg
ICAgICAgICh1ID09IDB4RjggJiYgKHUyICYgMHhGOCkgPT0gMHg4MCkgfHwNCiAg
ICAgICAgICAgICh1ID09IDB4RkMgJiYgKHUyICYgMHhGQykgPT0gMHg4MCkpDQog
ICAgICAgICAgICBnb3RvIExlcnI7ICAgICAgICAgICAgICAvLyBvdmVybG9uZyBj
b21iaW5hdGlvbg0KDQogICAgICAgICAgZm9yICh1aW50IGogPSAxOyBqICE9IG47
IGorKykNCiAgICAgICAgICB7DQogICAgICAgICAgICB1ID0gc1tpICsgal07DQog
ICAgICAgICAgICBpZiAoKHUgJiAweEMwKSAhPSAweDgwKQ0KICAgICAgICAgICAg
ICAgIGdvdG8gTGVycjsgICAgICAgICAgICAgICAgLy8gdHJhaWxpbmcgYnl0ZXMg
YXJlIDEweHh4eHh4DQogICAgICAgICAgICBWID0gKFYgPDwgNikgfCAodSAmIDB4
M0YpOw0KICAgICAgICAgIH0NCiAgICAgICAgICBpZiAoIWlzVmFsaWREY2hhcihW
KSkNCiAgICAgICAgICAgIGdvdG8gTGVycjsNCiAgICAgICAgICBpICs9IG47DQog
ICAgICB9DQogICAgICBlbHNlDQogICAgICB7DQogICAgICAgICAgViA9IGNhc3Qo
ZGNoYXIpIHU7DQogICAgICAgICAgaSsrOw0KICAgICAgfQ0KDQogICAgICBpZHgg
PSBpOw0KICAgICAgcmV0dXJuIFY7DQoNCiAgICAgIExlcnI6DQogICAgICAvL3By
aW50ZigiXG5kZWNvZGU6IGlkeCA9ICVkLCBpID0gJWQsIGxlbmd0aCA9ICVkIHMg
PSBcbiclLipzJ1xuJXhcbiclLipzJ1xuIiwgaWR4LCBpLCBzLmxlbmd0aCwgcywg
c1tpXSwgc1tpIC4uIGxlbmd0aF0pOw0KICAgICAgdGhyb3cgbmV3IFV0ZkVycm9y
KCI0aW52YWxpZCBVVEYtOCBzZXF1ZW5jZSIsIGkpOw0KICAgIH0NCg0KdW5pdHRl
c3QNCnsgICBzaXplX3QgaTsNCiAgICBkY2hhciBjOw0KDQogICAgZGVidWcodXRm
KSBwcmludGYoInV0Zi5kZWNvZGUudW5pdHRlc3RcbiIpOw0KDQogICAgc3RhdGlj
IGNoYXJbXSBzMSA9ICJhYmNkIjsNCiAgICBpID0gMDsNCiAgICBjID0gZGVjb2Rl
KHMxLCBpKTsNCiAgICBhc3NlcnQoYyA9PSBjYXN0KGRjaGFyKSdhJyk7DQogICAg
YXNzZXJ0KGkgPT0gMSk7DQogICAgYyA9IGRlY29kZShzMSwgaSk7DQogICAgYXNz
ZXJ0KGMgPT0gY2FzdChkY2hhciknYicpOw0KICAgIGFzc2VydChpID09IDIpOw0K
DQogICAgc3RhdGljIGNoYXJbXSBzMiA9ICJceEMyXHhBOSI7DQogICAgaSA9IDA7
DQogICAgYyA9IGRlY29kZShzMiwgaSk7DQogICAgYXNzZXJ0KGMgPT0gY2FzdChk
Y2hhciknXHUwMEE5Jyk7DQogICAgYXNzZXJ0KGkgPT0gMik7DQoNCiAgICBzdGF0
aWMgY2hhcltdIHMzID0gIlx4RTJceDg5XHhBMCI7DQogICAgaSA9IDA7DQogICAg
YyA9IGRlY29kZShzMywgaSk7DQogICAgYXNzZXJ0KGMgPT0gY2FzdChkY2hhcikn
XHUyMjYwJyk7DQogICAgYXNzZXJ0KGkgPT0gMyk7DQoNCiAgICBzdGF0aWMgY2hh
cltdW10gczQgPQ0KICAgIFsgIlx4RTJceDg5IiwgICAgICAgLy8gdG9vIHNob3J0
DQogICAgICAiXHhDMFx4OEEiLA0KICAgICAgIlx4RTBceDgwXHg4QSIsDQogICAg
ICAiXHhGMFx4ODBceDgwXHg4QSIsDQogICAgICAiXHhGOFx4ODBceDgwXHg4MFx4
OEEiLA0KICAgICAgIlx4RkNceDgwXHg4MFx4ODBceDgwXHg4QSIsDQogICAgXTsN
Cg0KICAgIGZvciAoaW50IGogPSAwOyBqIDwgczQubGVuZ3RoOyBqKyspDQogICAg
ew0KICAgICAgdHJ5DQogICAgICB7DQogICAgICAgICAgaSA9IDA7DQogICAgICAg
ICAgYyA9IGRlY29kZShzNFtqXSwgaSk7DQogICAgICAgICAgYXNzZXJ0KDApOw0K
ICAgICAgfQ0KICAgICAgY2F0Y2ggKFV0ZkVycm9yIHUpDQogICAgICB7DQogICAg
ICAgICAgaSA9IDIzOw0KICAgICAgICAgIGRlbGV0ZSB1Ow0KICAgICAgfQ0KICAg
ICAgYXNzZXJ0KGkgPT0gMjMpOw0KICAgIH0NCn0NCg0KLyoqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0KDQpk
Y2hhciBkZWNvZGUod2NoYXJbXSBzLCBpbm91dCBzaXplX3QgaWR4KQ0KICAgIGlu
DQogICAgew0KICAgICAgYXNzZXJ0KGlkeCA+PSAwICYmIGlkeCA8IHMubGVuZ3Ro
KTsNCiAgICB9DQogICAgb3V0IChyZXN1bHQpDQogICAgew0KICAgICAgYXNzZXJ0
KGlzVmFsaWREY2hhcihyZXN1bHQpKTsNCiAgICB9DQogICAgYm9keQ0KICAgIHsN
CiAgICAgIGNoYXJbXSBtc2c7DQogICAgICBkY2hhciBWOw0KICAgICAgc2l6ZV90
IGkgPSBpZHg7DQogICAgICB1aW50IHUgPSBzW2ldOw0KDQogICAgICBpZiAodSAm
IH4weDdGKQ0KICAgICAgeyAgIGlmICh1ID49IDB4RDgwMCAmJiB1IDw9IDB4REJG
RikNCiAgICAgICAgICB7ICAgdWludCB1MjsNCg0KICAgICAgICAgICAgaWYgKGkg
KyAxID09IHMubGVuZ3RoKQ0KICAgICAgICAgICAgeyAgIG1zZyA9ICJzdXJyb2dh
dGUgVVRGLTE2IGhpZ2ggdmFsdWUgcGFzdCBlbmQgb2Ygc3RyaW5nIjsNCiAgICAg
ICAgICAgICAgICBnb3RvIExlcnI7DQogICAgICAgICAgICB9DQogICAgICAgICAg
ICB1MiA9IHNbaSArIDFdOw0KICAgICAgICAgICAgaWYgKHUyIDwgMHhEQzAwIHx8
IHUyID4gMHhERkZGKQ0KICAgICAgICAgICAgeyAgIG1zZyA9ICJzdXJyb2dhdGUg
VVRGLTE2IGxvdyB2YWx1ZSBvdXQgb2YgcmFuZ2UiOw0KICAgICAgICAgICAgICAg
IGdvdG8gTGVycjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHUgPSAoKHUg
LSAweEQ3QzApIDw8IDEwKSArICh1MiAtIDB4REMwMCk7DQogICAgICAgICAgICBp
ICs9IDI7DQogICAgICAgICAgfQ0KICAgICAgICAgIGVsc2UgaWYgKHUgPj0gMHhE
QzAwICYmIHUgPD0gMHhERkZGKQ0KICAgICAgICAgIHsgICBtc2cgPSAidW5wYWly
ZWQgc3Vycm9nYXRlIFVURi0xNiB2YWx1ZSI7DQogICAgICAgICAgICBnb3RvIExl
cnI7DQogICAgICAgICAgfQ0KICAgICAgICAgIGVsc2UgaWYgKHUgPT0gMHhGRkZF
IHx8IHUgPT0gMHhGRkZGKQ0KICAgICAgICAgIHsgICBtc2cgPSAiaWxsZWdhbCBV
VEYtMTYgdmFsdWUiOw0KICAgICAgICAgICAgZ290byBMZXJyOw0KICAgICAgICAg
IH0NCiAgICAgICAgICBlbHNlDQogICAgICAgICAgICBpKys7DQogICAgICB9DQog
ICAgICBlbHNlDQogICAgICB7DQogICAgICAgICAgaSsrOw0KICAgICAgfQ0KDQog
ICAgICBpZHggPSBpOw0KICAgICAgcmV0dXJuIGNhc3QoZGNoYXIpdTsNCg0KICAg
ICAgTGVycjoNCiAgICAgIHRocm93IG5ldyBVdGZFcnJvcihtc2csIGkpOw0KICAg
IH0NCg0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqLw0KDQpkY2hhciBkZWNvZGUoZGNoYXJbXSBzLCBpbm91
dCBzaXplX3QgaWR4KQ0KICAgIGluDQogICAgew0KICAgICAgYXNzZXJ0KGlkeCA+
PSAwICYmIGlkeCA8IHMubGVuZ3RoKTsNCiAgICB9DQogICAgYm9keQ0KICAgIHsN
CiAgICAgIHNpemVfdCBpID0gaWR4Ow0KICAgICAgZGNoYXIgYyA9IHNbaV07DQoN
CiAgICAgIGlmICghaXNWYWxpZERjaGFyKGMpKQ0KICAgICAgICAgIGdvdG8gTGVy
cjsNCiAgICAgIGlkeCA9IGkgKyAxOw0KICAgICAgcmV0dXJuIGM7DQoNCiAgICAg
IExlcnI6DQogICAgICB0aHJvdyBuZXcgVXRmRXJyb3IoIjVpbnZhbGlkIFVURi0z
MiB2YWx1ZSIsIGkpOw0KICAgIH0NCg0KDQovKiA9PT09PT09PT09PT09PT09PT09
IEVuY29kZSA9PT09PT09PT09PT09PT09PT09PT09PSAqLw0KDQp2b2lkIGVuY29k
ZShpbm91dCBjaGFyW10gcywgZGNoYXIgYykNCiAgICBpbg0KICAgIHsNCiAgICAg
IGFzc2VydChpc1ZhbGlkRGNoYXIoYykpOw0KICAgIH0NCiAgICBib2R5DQogICAg
ew0KICAgICAgY2hhcltdIHIgPSBzOw0KDQogICAgICBpZiAoYyA8PSAweDdGKQ0K
ICAgICAgew0KICAgICAgICAgIHIgfj0gY2FzdChjaGFyKSBjOw0KICAgICAgfQ0K
ICAgICAgZWxzZQ0KICAgICAgew0KICAgICAgICAgIGNoYXJbNF0gYnVmOw0KICAg
ICAgICAgIHVpbnQgTDsNCg0KICAgICAgICAgIGlmIChjIDw9IDB4N0ZGKQ0KICAg
ICAgICAgIHsNCiAgICAgICAgICAgIGJ1ZlswXSA9IGNhc3QoY2hhcikoMHhDMCB8
IChjID4+IDYpKTsNCiAgICAgICAgICAgIGJ1ZlsxXSA9IGNhc3QoY2hhcikoMHg4
MCB8IChjICYgMHgzRikpOw0KICAgICAgICAgICAgTCA9IDI7DQogICAgICAgICAg
fQ0KICAgICAgICAgIGVsc2UgaWYgKGMgPD0gMHhGRkZGKQ0KICAgICAgICAgIHsN
CiAgICAgICAgICAgIGJ1ZlswXSA9IGNhc3QoY2hhcikoMHhFMCB8IChjID4+IDEy
KSk7DQogICAgICAgICAgICBidWZbMV0gPSBjYXN0KGNoYXIpKDB4ODAgfCAoKGMg
Pj4gNikgJiAweDNGKSk7DQogICAgICAgICAgICBidWZbMl0gPSBjYXN0KGNoYXIp
KDB4ODAgfCAoYyAmIDB4M0YpKTsNCiAgICAgICAgICAgIEwgPSAzOw0KICAgICAg
ICAgIH0NCiAgICAgICAgICBlbHNlIGlmIChjIDw9IDB4MTBGRkZGKQ0KICAgICAg
ICAgIHsNCiAgICAgICAgICAgIGJ1ZlswXSA9IGNhc3QoY2hhcikoMHhGMCB8IChj
ID4+IDE4KSk7DQogICAgICAgICAgICBidWZbMV0gPSBjYXN0KGNoYXIpKDB4ODAg
fCAoKGMgPj4gMTIpICYgMHgzRikpOw0KICAgICAgICAgICAgYnVmWzJdID0gY2Fz
dChjaGFyKSgweDgwIHwgKChjID4+IDYpICYgMHgzRikpOw0KICAgICAgICAgICAg
YnVmWzNdID0gY2FzdChjaGFyKSgweDgwIHwgKGMgJiAweDNGKSk7DQogICAgICAg
ICAgICBMID0gNDsNCiAgICAgICAgICB9DQogICAgICAgICAgZWxzZQ0KICAgICAg
ICAgIHsNCiAgICAgICAgICAgIGFzc2VydCgwKTsNCiAgICAgICAgICB9DQogICAg
ICAgICAgciB+PSBidWZbMCAuLiBMXTsNCiAgICAgIH0NCiAgICAgIHMgPSByOw0K
ICAgIH0NCg0KdW5pdHRlc3QNCnsNCiAgICBkZWJ1Zyh1dGYpIHByaW50ZigidXRm
LmVuY29kZS51bml0dGVzdFxuIik7DQoNCiAgICBjaGFyW10gcyA9ICJhYmNkIjsN
CiAgICBlbmNvZGUocywgY2FzdChkY2hhciknYScpOw0KICAgIGFzc2VydChzLmxl
bmd0aCA9PSA1KTsNCiAgICBhc3NlcnQocyA9PSAiYWJjZGEiKTsNCg0KICAgIGVu
Y29kZShzLCBjYXN0KGRjaGFyKSdcdTAwQTknKTsNCiAgICBhc3NlcnQocy5sZW5n
dGggPT0gNyk7DQogICAgYXNzZXJ0KHMgPT0gImFiY2RhXHhDMlx4QTkiKTsNCiAg
ICAvL2Fzc2VydChzID09ICJhYmNkYVx1MDBBOSIpOyAgIC8vIEJVRzogZml4IGNv
bXBpbGVyDQoNCiAgICBlbmNvZGUocywgY2FzdChkY2hhciknXHUyMjYwJyk7DQog
ICAgYXNzZXJ0KHMubGVuZ3RoID09IDEwKTsNCiAgICBhc3NlcnQocyA9PSAiYWJj
ZGFceEMyXHhBOVx4RTJceDg5XHhBMCIpOw0KfQ0KDQovKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovDQoNCnZv
aWQgZW5jb2RlKGlub3V0IHdjaGFyW10gcywgZGNoYXIgYykNCiAgICBpbg0KICAg
IHsNCiAgICAgIGFzc2VydChpc1ZhbGlkRGNoYXIoYykpOw0KICAgIH0NCiAgICBi
b2R5DQogICAgew0KICAgICAgd2NoYXJbXSByID0gczsNCg0KICAgICAgaWYgKGMg
PD0gMHhGRkZGKQ0KICAgICAgew0KICAgICAgICAgIHIgfj0gY2FzdCh3Y2hhcikg
YzsNCiAgICAgIH0NCiAgICAgIGVsc2UNCiAgICAgIHsNCiAgICAgICAgICB3Y2hh
clsyXSBidWY7DQoNCiAgICAgICAgICBidWZbMF0gPSAoKChjIC0gMHgxMDAwMCkg
Pj4gMTApICYgMHgzRkYpICsgMHhEODAwOw0KICAgICAgICAgIGJ1ZlsxXSA9ICgo
YyAtIDB4MTAwMDApICYgMHgzRkYpICsgMHhEQzAwOw0KICAgICAgICAgIHIgfj0g
YnVmOw0KICAgICAgfQ0KICAgICAgcyA9IHI7DQogICAgfQ0KDQp2b2lkIGVuY29k
ZShpbm91dCBkY2hhcltdIHMsIGRjaGFyIGMpDQogICAgaW4NCiAgICB7DQogICAg
ICBhc3NlcnQoaXNWYWxpZERjaGFyKGMpKTsNCiAgICB9DQogICAgYm9keQ0KICAg
IHsNCiAgICAgIHMgfj0gYzsNCiAgICB9DQoNCi8qID09PT09PT09PT09PT09PT09
PT0gVmFsaWRhdGlvbiA9PT09PT09PT09PT09PT09PT09PT09PSAqLw0KDQp2b2lk
IHZhbGlkYXRlKGNoYXJbXSBzKQ0Kew0KICAgIHNpemVfdCBsZW4gPSBzLmxlbmd0
aDsNCiAgICBzaXplX3QgaTsNCg0KICAgIGZvciAoaSA9IDA7IGkgPCBsZW47ICkN
CiAgICB7DQogICAgICBkZWNvZGUocywgaSk7DQogICAgfQ0KfQ0KDQp2b2lkIHZh
bGlkYXRlKHdjaGFyW10gcykNCnsNCiAgICBzaXplX3QgbGVuID0gcy5sZW5ndGg7
DQogICAgc2l6ZV90IGk7DQoNCiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyApDQog
ICAgew0KICAgICAgZGVjb2RlKHMsIGkpOw0KICAgIH0NCn0NCg0Kdm9pZCB2YWxp
ZGF0ZShkY2hhcltdIHMpDQp7DQogICAgc2l6ZV90IGxlbiA9IHMubGVuZ3RoOw0K
ICAgIHNpemVfdCBpOw0KDQogICAgZm9yIChpID0gMDsgaSA8IGxlbjsgKQ0KICAg
IHsNCiAgICAgIGRlY29kZShzLCBpKTsNCiAgICB9DQp9DQoNCg0KDQovLyBTZWN0
aW9uOiBDb252ZXJzaW9uIGZ1bmN0aW9ucw0KLy8NCi8vIEZvciBldmVyeSBjb252
ZXJzaW9uLCB0aGVyZSBhcmUgYWx3YXlzIDIgZnVuY3Rpb25zLiBBcyBhbiBleGFt
cGxlLCB0aGUgVVRGLTgNCi8vIHRvIFVURi0xNiBjb252ZXJzaW9uIGZ1bmN0aW9u
cyBoYXZlIHRoZSBmb2xsb3dpbmcgcHJvdG90eXBlczoNCi8vDQovLyAoY29kZSkN
Ci8vIHdjaGFyW10gdG9VVEYxNihjaGFyW10gc3RyLCBpbm91dCBzaXplX3QgZWF0
ZW4sIHdjaGFyW10gYnVmZmVyKTsNCi8vIHdjaGFyW10gdG9VVEYxNihjaGFyW10g
c3RyLCB3Y2hhcltdIGJ1ZmZlcik7DQovLyAoZW5kKQ0KLy8NCi8vIFRoZXkgYm90
aCBjb252ZXJ0IHRoZSBVVEYtOCBzdHJpbmcgc3RyIHRvIGl0cyBVVEYtMTYgZXF1
aXZhbGVudC4gZWF0ZW4gaXMgdGhlDQovLyBudW1iZXIgb2YgY2hhcmFjdGVycyBp
biBzdHIgdGhhdCB3ZXJlIGFscmVhZHkgY29udmVydGVkLCBhbmQgaXQgaXMgdXBk
YXRlZCBieQ0KLy8gdGhlIGZ1bmN0aW9uIGFmdGVyIGNvbnZlcnNpb24uIFlvdSBj
YW4gcHJvdmlkZSBhIGJ1ZmZlciB3aGVyZSB0aGUgcmVzdWx0DQovLyBzaG91bGQg
YmUgc3RvcmVkIGluLCBidXQgaXQgd2lsbCBiZSByZWFsbG9jYXRlZCBpZiBpcyB0
b28gc21hbGwgdG8gY29udGFpbg0KLy8gdGhlIHJlc3VsdGluZyBzdHJpbmcuIFRo
ZSBmdW5jdGlvbiByZXR1cm5zIHRoZSByZXN1bHRpbmcgc3RyaW5nLCB3aGljaCBp
cw0KLy8gYWx3YXlzIHplcm8tdGVybWluYXRlZCBiZWhpbmQgdGhlIGxhc3QgY2hh
cmFjdGVyIChjb3N0cyBub3RoaW5nLCBoZWxwcyBhDQovLyBsb3QpLg0KLy8NCi8v
IFRoZSBjb252ZXJzaW9uIHN0YXJ0cyBhdCBzdHJbZWF0ZW5dLCB3aGljaCBtdXN0
IGJlIGEgbGVhZGluZyBieXRlLiBJZiBzdHINCi8vIGVuZHMgd2l0aCBhbiBpbmNv
bXBsZXRlIGNvZGUg4pSAIHRoaXMgY2FuIGhhcHBlbiB3aGVuIHlvdSByZWFkIGNo
dW5rcyBmcm9tIGENCi8vIGZpbGUsIGZvciBleGFtcGxlIOKUgCBlYXRlbiBpcyBz
ZXQgdG8gdGhlIGluZGV4IG9mIHRoZSBsZWFkaW5nIGJ5dGUgb2YgdGhhdA0KLy8g
Y29kZSBhZnRlciB0aGUgY29udmVyc2lvbi4gSWYgc3RyIGlzIGNvbXBsZXRlLCBp
dCBpcyBzZXQgdG8gc3RyLmxlbmd0aC4NCi8vDQovLyBUaGUgc2Vjb25kIHZhcmlh
bnQgYWx3YXlzIGNvbnZlcnRzIHRoZSB3aG9sZSBzdHIsIHRodXMgaW5jb21wbGV0
ZSBjb2RlIHBvaW50cw0KLy8gYXQgdGhlIGVuZCBvZiBpdCB0cmlnZ2VyIGFuIDxJ
bnZhbGlkRW5jb2Rpbmc+IGV4Y2VwdGlvbi4gVGhlcmUgYXJlIGZ1bmN0aW9ucw0K
Ly8gZm9yIGV2ZXJ5IHBvc3NpYmxlIGVuY29kaW5nIGNvbWJpbmF0aW9uLiBTZWUg
PHRvVVRGOCgpPiwgPHRvVVRGMTYoKT4gYW5kDQovLyA8dG9VVEYzMigpPi4NCi8v
DQovLyBJZiB5b3Ugd2FudCB0byBtaW5pbWl6ZSBtZW1vcnkgYWxsb2NhdGlvbiB3
aGVuIGNvbnZlcnRpbmcgc2V2ZXJhbCBzdHJpbmdzLA0KLy8gcHJvdmlkZSB5b3Vy
IG93biBidWZmZXIuIEEgc2FtcGxlIGFsZ29yaXRobSB0byByZWFkIHNvbWUgY2h1
bmtzIGZyb20gYSBmaWxlDQovLyBhbmQgY29udmVydCB0aGVtIGxvb2tzIGxpa2Ug
dGhpczoNCi8vDQovLyAoY29kZSkNCi8vIHdjaGFyW10gYnVmZmVyICAgPSBudWxs
OyAvLyBObyBuZWVkIHRvIGFsbG9jYXRlIHlvdXJzZWxmLg0KLy8gc2l6ZV90IGVh
dGVuICAgICA9IDA7DQovLyBzaXplX3QgYnl0ZXNSZWFkID0gMDsNCi8vIGNoYXJb
XSBpbnB1dDsNCi8vIGlucHV0Lmxlbmd0aCAgICAgPSBDSFVOS19TSVpFICsgNDsg
Ly8gU29tZSBtb3JlIGZvciBleGNlc3MgYnl0ZXMuDQovLw0KLy8gd2hpbGUgKCFm
aWxlLmF0RU9GKQ0KLy8gew0KLy8gICBieXRlc1JlYWQgPSBmaWxlLnJlYWRCeXRl
cyhpbnB1dC5wdHIgKyAoYnl0ZXNSZWFkIC0gZWF0ZW4pLCBDSFVOS19TSVpFKTsN
Ci8vICAgYnVmZmVyICAgID0gdG9VdGYxNihpbnB1dFswIC4uIGJ5dGVzUmVhZF0s
IGVhdGVuLCBidWZmZXIpOw0KLy8NCi8vICAgZG9Tb21ldGhpbmdXaXRoKGJ1ZmZl
cik7DQovLw0KLy8gICAvLyBOb3cgbW92ZSB0aGUgZXhjZXNzIGJ5dGVzIHRvIHRo
ZSBmcm9udCAodGhleSBhcmUgZmV3KS4NCi8vICAgLy8gV2UgbXVzdCB1c2UgbWVt
bW92ZSAob3Igc29tZXRoaW5nIHNpbWlsYXIpLCBtZW1jcHkgd2lsbCBub3QgYWx3
YXlzIHdvcmsuDQovLyAgIG1lbW1vdmUoaW5wdXQucHRyLCBpbnB1dC5wdHIgKyBl
YXRlbiwgKGJ5dGVzUmVhZCAtIGVhdGVuKSAqIGNoYXIuc2l6ZW9mKTsNCi8vICAg
ZWF0ZW4gPSAwOw0KLy8gfQ0KLy8NCi8vIGlmIChieXRlc1JlYWQgPiBlYXRlbikN
Ci8vICAgdGhyb3cgbmV3IFNvbWVFeGNlcHRpb24oIk1pc3NpbmcgVVRGLTggdHJh
aWwgYnl0ZXMiKTsNCi8vIChlbmQpDQovLw0KLy8gVGhlIGZ1bmN0aW9ucyBkbyBm
dWxsIGVycm9yIGNoZWNraW5nIG9uIHRoZSBpbnB1dCBzdHIsIGRldGVjdGluZyBh
bGwNCi8vIGVuY29kaW5nIGVycm9ycy4gVGhleSB3aWxsIHRocm93IGFuIDxVdGZF
cnJvcj4gZXhjZXB0aW9uIHdoZW4NCi8vIGVuY291bnRlcmluZyBhbiBlcnJvciwg
YW5kIGFsd2F5cyBwcm9kdWNlIHZhbGlkIFVURiBjb2RlIG90aGVyd2lzZS4NCi8v
DQoNCg0KLyogPT09PT09PT09PT09PT09PT09PSBDb252ZXJzaW9uIHRvIFVURjgg
PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCg0KcHVibGljIGNoYXJbXSB0b1VU
Rjgod2NoYXJbXSBzdHIsIGlub3V0IHNpemVfdCBlYXRlbiwgY2hhcltdIGJ1ZmZl
ciA9IG51bGwpDQogICAgaW4NCiAgICB7DQogICAgICBhc3NlcnQoZWF0ZW4gPD0g
c3RyLmxlbmd0aCk7DQogICAgfQ0KICAgIGJvZHkNCiAgICB7DQogICAgICAvLyBJ
ZiBidWZmZXIgaXMgbm90IHN1ZmZpY2llbnQsIHJlYWxsb2NhdGUuDQogICAgICBp
ZiAoYnVmZmVyLmxlbmd0aCA8IHN0ci5sZW5ndGggKyA0KQ0KICAgICAgICBidWZm
ZXIubGVuZ3RoID0gc3RyLmxlbmd0aCArIDQ7DQoNCiAgICAgIC8vIFBvaW50ZXJz
IGZvciBjb252ZXJzaW9uLg0KICAgICAgd2NoYXIqIHBJbiAgID0gc3RyLnB0ciAr
IGVhdGVuOw0KICAgICAgd2NoYXIqIGVuZEluID0gc3RyLnB0ciArIHN0ci5sZW5n
dGg7DQogICAgICBjaGFyKiBwT3V0ICAgPSBidWZmZXIucHRyOw0KICAgICAgY2hh
ciogZW5kT3V0ID0gYnVmZmVyLnB0ciArIGJ1ZmZlci5sZW5ndGggLSA0Ow0KDQog
ICAgICAvLyBDaGVjayBpZiBzdHIgZW5kcyB3aXRoIGEgbGVhZGluZyBieXRlLiBJ
Z25vcmUgaXQgdGhlbi4NCiAgICAgIGlmIChlbmRJbiAhPSBwSW4gJiYgKCooZW5k
SW4gLSAxKSAmIDB4RkMwMCkgPT0gMHhEODAwKQ0KICAgICAgICAtLWVuZEluOw0K
DQogICAgICAvLyBOb3cgZG8gdGhlIGNvbnZlcnNpb24uDQogICAgICBpZiAocElu
IDwgZW5kSW4pDQogICAgICB7DQogICAgICAgIGRvDQogICAgICAgIHsNCiAgICAg
ICAgICAvLyBDaGVjayBmb3IgZW5vdWdoIHNwYWNlIGxlZnQgaW4gdGhlIGJ1ZmZl
ci4NCiAgICAgICAgICBpZiAocE91dCA+PSBlbmRPdXQpDQogICAgICAgICAgew0K
ICAgICAgICAgICAgLy8gUmVhbGxvY2F0ZSB0aGUgYnVmZmVyLg0KICAgICAgICAg
ICAgZW5kT3V0ICAgICAgICA9IGJ1ZmZlci5wdHI7ICAgICAgICAvLyBTYXZlIG9s
ZCBidWZmZXIgYmVnaW5uaW5nIGluIGVuZE91dC4NCiAgICAgICAgICAgIGJ1ZmZl
ci5sZW5ndGggPSBidWZmZXIubGVuZ3RoICsgKGVuZEluIC0gcEluKSAqIDMgKyAx
OyAgLy8gV2lsbCBiZSBlbm91Z2guDQogICAgICAgICAgICBwT3V0ICAgICAgICAg
ID0gYnVmZmVyLnB0ciArIChwT3V0IC0gZW5kT3V0KTsNCiAgICAgICAgICAgIGVu
ZE91dCAgICAgICAgPSBidWZmZXIucHRyICsgYnVmZmVyLmxlbmd0aCAtIDQ7DQog
ICAgICAgICAgfQ0KDQogICAgICAgICAgLy8gTm93IGRvIHRoZSBjb252ZXJzaW9u
Lg0KICAgICAgICAgIC8vIDEtYnl0ZS1jb2RlLi4uDQogICAgICAgICAgaWYgKCpw
SW4gPCAweDgwKQ0KICAgICAgICAgIHsNCiAgICAgICAgICAgICpwT3V0KysgPSAq
cEluOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIC8vIDItYnl0ZS1jb2RlLi4u
DQogICAgICAgICAgZWxzZSBpZiAoKnBJbiA8IDB4MDgwMCkNCiAgICAgICAgICB7
DQogICAgICAgICAgICBwT3V0WzBdID0gKCgqcEluID4+IDYpICYgMHgzRikgfCAw
eEMwOw0KICAgICAgICAgICAgcE91dFsxXSA9ICgqcEluICYgMHgzRikgfCAweDgw
Ow0KICAgICAgICAgICAgcE91dCAgICs9IDI7DQogICAgICAgICAgfQ0KDQogICAg
ICAgICAgLy8gMy1ieXRlLWNvZGUuLi4NCiAgICAgICAgICBlbHNlIGlmICgoKnBJ
biAmIDB4RjgwMCkgIT0gMHhEODAwKQ0KICAgICAgICAgIHsNCiAgICAgICAgICAg
IHBPdXRbMF0gPSAoKCpwSW4gPj4gMTIpICYgMHgzRikgfCAweEUwOw0KICAgICAg
ICAgICAgcE91dFsxXSA9ICgoKnBJbiA+PiA2KSAgJiAweDNGKSB8IDB4ODA7DQog
ICAgICAgICAgICBwT3V0WzJdID0gKCpwSW4gJiAweDNGKSB8IDB4ODA7DQogICAg
ICAgICAgICBwT3V0ICAgKz0gMzsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAv
LyBMZWFkaW5nIHN1cnJvZ2F0ZS4uLg0KICAgICAgICAgIGVsc2UgaWYgKCpwSW4g
PCAweERDMDApDQogICAgICAgICAgew0KICAgICAgICAgICAgLy8gQ2hlY2sgZm9y
IGNvcnJlY3QgdHJhaWwgc3Vycm9nYXRlLg0KICAgICAgICAgICAgaWYgKChwSW5b
MV0gJiAweEZDMDApICE9IDB4REMwMCkNCiAgICAgICAgICAgICAgZ290byBFcnJv
cl9UcmFpbFN1cnJvZ2F0ZU1pc3Npbmc7DQoNCiAgICAgICAgICAgIHVzaG9ydCBo
ZWxwID0gKCpwSW4gJiAweDAzRkMpICsgMHg0MDsNCg0KICAgICAgICAgICAgcE91
dFswXSA9IChjYXN0KGNoYXIpIChoZWxwID4+IDgpKSB8IDB4RjA7DQogICAgICAg
ICAgICBwT3V0WzFdID0gKChjYXN0KGNoYXIpIGhlbHApID4+IDIpIHwgMHg4MDsN
CiAgICAgICAgICAgIHBPdXRbMl0gPSAoKCpwSW4gJiAweDAzKSA8PCA0KSB8ICgo
cEluWzFdICYgMHgwM0MwKSA+PiA2KSB8IDB4ODA7DQogICAgICAgICAgICBwT3V0
WzNdID0gKHBJblsxXSAmIDB4M0YpIHwgMHg4MDsNCiAgICAgICAgICAgIHBPdXQg
ICArPSA0Ow0KICAgICAgICAgICAgKytwSW47DQogICAgICAgICAgfQ0KDQogICAg
ICAgICAgLy8gVHJhaWwgc3Vycm9nYXRlLi4uIChpbGxlZ2FsKQ0KICAgICAgICAg
IGVsc2UNCiAgICAgICAgICAgIGdvdG8gRXJyb3JfVHJhaWxTdXJyb2dhdGVBbG9u
ZTsNCiAgICAgICAgfQ0KICAgICAgICB3aGlsZSAoKytwSW4gPCBlbmRJbik7DQog
ICAgICB9DQoNCiAgICAgIC8vIFplcm8tdGVybWluYXRlIHRoZSByZXN1bHQsIGFu
ZCByZXR1cm4gaXQuDQogICAgICAqcE91dCA9IDA7DQogICAgICBlYXRlbiA9IHBJ
biAtIHN0ci5wdHI7DQoNCiAgICAgIHJldHVybiBidWZmZXJbMCAuLiAocE91dCAt
IGJ1ZmZlci5wdHIpXTsNCg0KICAgICAgLy8gRXJyb3IgbWVzc2FnZXMuDQogICAg
ICBFcnJvcl9UcmFpbFN1cnJvZ2F0ZUFsb25lOg0KICAgICAgICB0aHJvdyBuZXcg
VXRmRXJyb3IoIlVURi0xNiB0cmFpbCBzdXJyb2dhdGUgd2l0aG91dCBsZWFkaW5n
IHN1cnJvZ2F0ZSIsIHBJbiAtIHN0ci5wdHIpOw0KDQogICAgICBFcnJvcl9UcmFp
bFN1cnJvZ2F0ZU1pc3Npbmc6DQogICAgICAgIHRocm93IG5ldyBVdGZFcnJvcigi
VVRGLTE2IG1pc3NpbmcgdHJhaWwgc3Vycm9nYXRlIGFmdGVyIGxlYWRpbmcgc3Vy
cm9nYXRlIiwgcEluIC0gc3RyLnB0cik7DQogICAgfQ0KDQpwdWJsaWMgY2hhcltd
IHRvVVRGOCh3Y2hhcltdIHN0ciwgY2hhcltdIGJ1ZmZlciA9IG51bGwpDQogICAg
ew0KICAgICAgc2l6ZV90IGVhdGVuICA9IDA7DQogICAgICBjaGFyW10gcmVzdWx0
ID0gdG9VVEY4KHN0ciwgZWF0ZW4sIGJ1ZmZlcik7DQoNCiAgICAgIGlmIChlYXRl
biA8IHN0ci5sZW5ndGgpDQogICAgICAgIHRocm93IG5ldyBVdGZFcnJvcigiVVRG
LTE2IHVuZmluaXNoZWQgY29kZSBzZXF1ZW5jZSIsIGVhdGVuKTsNCg0KICAgICAg
cmV0dXJuIHJlc3VsdDsNCiAgICB9DQoNCnB1YmxpYyBjaGFyW10gdG9VVEY4KGRj
aGFyW10gc3RyLCBpbm91dCBzaXplX3QgZWF0ZW4sIGNoYXJbXSBidWZmZXIgPSBu
dWxsKQ0KICAgIGluDQogICAgew0KICAgICAgYXNzZXJ0KGVhdGVuIDw9IHN0ci5s
ZW5ndGgpOw0KICAgIH0NCiAgICBib2R5DQogICAgew0KICAgICAgLy8gSWYgYnVm
ZmVyIGlzIG5vdCBzdWZmaWNpZW50LCByZWFsbG9jYXRlLiBXZSBob3BlIHRoYXQg
dGhlIHVzZWQgVVRGLTgNCiAgICAgIC8vIGVuY29kaW5ncyBhcmUgbm90IGxvbmdl
ciB0aGFuIDIgYnl0ZXMuIElmIHRoYXQgaXMgd3JvbmcgKGluIEFzaWEgZm9yDQog
ICAgICAvLyBleGFtcGxlKSwgd2Ugd2lsbCBoYXZlIHRvIGFsbG9jYXRlIGFnYWlu
IGluIHRoZSBsb29wLiAtLT4gRGVhciBBc2lhbnMsDQogICAgICAvLyBwbGVhc2Ug
cHJvdmlkZSBhIHN1ZmZpY2llbnQgYnVmZmVyLiA6KQ0KICAgICAgaWYgKGJ1ZmZl
ci5sZW5ndGggPCBzdHIubGVuZ3RoICsgNCkNCiAgICAgICAgYnVmZmVyLmxlbmd0
aCA9IChzdHIubGVuZ3RoIDw8IDEpICsgNDsNCg0KICAgICAgLy8gUG9pbnRlcnMg
Zm9yIGNvbnZlcnNpb24uDQogICAgICBkY2hhciogcEluICAgPSBzdHIucHRyICsg
ZWF0ZW47DQogICAgICBkY2hhciogZW5kSW4gPSBzdHIucHRyICsgc3RyLmxlbmd0
aDsNCiAgICAgIGNoYXIqIHBPdXQgICA9IGJ1ZmZlci5wdHI7DQogICAgICBjaGFy
KiBlbmRPdXQgPSBidWZmZXIucHRyICsgYnVmZmVyLmxlbmd0aCAtIDQ7DQoNCiAg
ICAgIC8vIE5vdyBkbyB0aGUgY29udmVyc2lvbi4NCiAgICAgIGlmIChwSW4gPCBl
bmRJbikNCiAgICAgIHsNCiAgICAgICAgZG8NCiAgICAgICAgew0KICAgICAgICAg
IC8vIENoZWNrIGZvciBlbm91Z2ggc3BhY2UgbGVmdCBpbiB0aGUgYnVmZmVyLg0K
ICAgICAgICAgIGlmIChwT3V0ID49IGVuZE91dCkNCiAgICAgICAgICB7DQogICAg
ICAgICAgICAvLyBSZWFsbG9jYXRlIHRoZSBidWZmZXIuDQogICAgICAgICAgICBl
bmRPdXQgICAgICAgID0gYnVmZmVyLnB0cjsgICAgICAvLyBTYXZlIG9sZCBidWZm
ZXIgYmVnaW5uaW5nIGluIGVuZE91dC4NCiAgICAgICAgICAgIGJ1ZmZlci5sZW5n
dGggPSAoKHN0ci5sZW5ndGgpIDw8IDIpICsgMTsgLy8gTm93IG1ha2Ugc3VyZSB3
ZSB3aWxsIG5ldmVyIGFsbG9jYXRlIGFnYWluIQ0KICAgICAgICAgICAgcE91dCAg
ICAgICAgICA9IGJ1ZmZlci5wdHIgKyAocE91dCAtIGVuZE91dCk7DQogICAgICAg
ICAgICBlbmRPdXQgICAgICAgID0gYnVmZmVyLnB0ciArIGJ1ZmZlci5sZW5ndGgg
LSA0Ow0KICAgICAgICAgIH0NCg0KICAgICAgICAgIC8vIDEtYnl0ZS1jb2RlLi4u
DQogICAgICAgICAgaWYgKCpwSW4gPCAweDgwKQ0KICAgICAgICAgIHsNCiAgICAg
ICAgICAgICpwT3V0KysgPSAqcEluOw0KICAgICAgICAgIH0NCg0KICAgICAgICAg
IC8vIDItYnl0ZS1jb2RlLi4uDQogICAgICAgICAgZWxzZSBpZiAoKnBJbiA8IDB4
MDgwMCkNCiAgICAgICAgICB7DQogICAgICAgICAgICBwT3V0WzBdID0gKCgqcElu
ID4+IDYpICYgMHgzRikgfCAweEMwOw0KICAgICAgICAgICAgcE91dFsxXSA9ICgq
cEluICYgMHgzRikgfCAweDgwOw0KICAgICAgICAgICAgcE91dCAgICs9IDI7DQog
ICAgICAgICAgfQ0KDQogICAgICAgICAgLy8gMy1ieXRlLWNvZGUuLi4NCiAgICAg
ICAgICBlbHNlIGlmICgqcEluIDwgMHgxMDAwMCkNCiAgICAgICAgICB7DQogICAg
ICAgICAgICAvLyBDaGVjayBmb3IgZm9yYmlkZGVuIHN1cnJvZ2F0ZSBjb2RlIHBv
aW50cy4NCiAgICAgICAgICAgIGlmICgoKnBJbiAmIDB4RjgwMCkgPT0gMHhEODAw
KQ0KICAgICAgICAgICAgICBnb3RvIEVycm9yX0ludmFsaWRDb2RlOw0KDQogICAg
ICAgICAgICBwT3V0WzBdID0gKCgqcEluID4+IDEyKSAmIDB4M0YpIHwgMHhFMDsN
CiAgICAgICAgICAgIHBPdXRbMV0gPSAoKCpwSW4gPj4gNikgICYgMHgzRikgfCAw
eDgwOw0KICAgICAgICAgICAgcE91dFsyXSA9ICgqcEluICYgMHgzRikgfCAweDgw
Ow0KICAgICAgICAgICAgcE91dCAgICs9IDM7DQogICAgICAgICAgfQ0KDQogICAg
ICAgICAgLy8gNC1ieXRlLWNvZGUuLi4NCiAgICAgICAgICBlbHNlDQogICAgICAg
ICAgew0KICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIHVwcGVyIGJvdW5kYXJ5Lg0K
ICAgICAgICAgICAgaWYgKCpwSW4gPiAweDEwRkZGRikNCiAgICAgICAgICAgICAg
Z290byBFcnJvcl9VcHBlckJvdW5kYXJ5Ow0KDQogICAgICAgICAgICBwT3V0WzBd
ID0gKCgqcEluID4+IDE4KSAmIDB4MDcpIHwgMHhGMDsNCiAgICAgICAgICAgIHBP
dXRbMV0gPSAoKCpwSW4gPj4gMTIpICYgMHgzRikgfCAweDgwOw0KICAgICAgICAg
ICAgcE91dFsyXSA9ICgoKnBJbiA+PiA2KSAgJiAweDNGKSB8IDB4ODA7DQogICAg
ICAgICAgICBwT3V0WzNdID0gKCpwSW4gJiAweDNGKSB8IDB4ODA7DQogICAgICAg
ICAgICBwT3V0ICAgKz0gNDsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAg
ICAgd2hpbGUgKCsrcEluIDwgZW5kSW4pOw0KICAgICAgfQ0KDQogICAgICAvLyBa
ZXJvLXRlcm1pbmF0ZSB0aGUgcmVzdWx0LCBhbmQgcmV0dXJuIGl0Lg0KICAgICAg
KnBPdXQgPSAwOw0KICAgICAgZWF0ZW4gPSBwSW4gLSBzdHIucHRyOw0KDQogICAg
ICByZXR1cm4gYnVmZmVyWzAgLi4gKHBPdXQgLSBidWZmZXIucHRyKV07DQoNCiAg
ICAgIC8vIEVycm9yIG1lc3NhZ2VzLg0KICAgICAgRXJyb3JfSW52YWxpZENvZGU6
DQogICAgICAgIHRocm93IG5ldyBVdGZFcnJvcigiVVRGLTMyIEludmFsaWQgc3Vy
cm9nYXRlIGNvZGUgcG9pbnQiLCBwSW4gLSBzdHIucHRyKTsNCg0KICAgICAgRXJy
b3JfVXBwZXJCb3VuZGFyeToNCiAgICAgICAgdGhyb3cgbmV3IFV0ZkVycm9yKCJV
VEYtMzIgSW52YWxpZCBjb2RlIHBvaW50IGFib3ZlIFUrMTBGRkZGIiwgcEluIC0g
c3RyLnB0cik7DQogICAgfQ0KDQpwdWJsaWMgY2hhcltdIHRvVVRGOChkY2hhcltd
IHN0ciwgY2hhcltdIGJ1ZmZlciA9IG51bGwpDQogICAgew0KICAgICAgc2l6ZV90
IGVhdGVuID0gMDsNCiAgICAgIHJldHVybiB0b1VURjgoc3RyLCBlYXRlbiwgYnVm
ZmVyKTsNCiAgICB9DQoNCnB1YmxpYyBjaGFyW10gdG9VVEY4KGNoYXJbXSBzKQ0K
ICAgIGluDQogICAgew0KICAgICAgdmFsaWRhdGUocyk7DQogICAgfQ0KICAgIGJv
ZHkNCiAgICB7DQogICAgICByZXR1cm4gczsNCiAgICB9DQoNCg0KDQovKiA9PT09
PT09PT09PT09PT09PT09IENvbnZlcnNpb24gdG8gVVRGMTYgPT09PT09PT09PT09
PT09PT09PT09PT0gKi8NCg0KcHVibGljIHdjaGFyW10gdG9VVEYxNihjaGFyW10g
c3RyLCBpbm91dCBzaXplX3QgZWF0ZW4sIHdjaGFyW10gYnVmZmVyID0gbnVsbCkN
CiAgICBpbg0KICAgIHsNCiAgICAgIGFzc2VydChlYXRlbiA8PSBzdHIubGVuZ3Ro
KTsNCiAgICB9DQogICAgYm9keQ0KICAgIHsNCiAgICAgIC8vIElmIGJ1ZmZlciBp
cyBub3Qgc3VmZmljaWVudCwgcmVhbGxvY2F0ZS4gV2Ugd2lsbCBub3QgZG8gdGhh
dCBpbiB0aGUgbG9vcCwNCiAgICAgIC8vIGJlY2F1c2UgdGhlIHByZXZhbGVudCBj
YXNlIGlzIEFTQ0lJIGlucHV0LCBhbmQgdGhlbiBvbmUgYnl0ZSBVVEYtOCBpcyBv
bmUNCiAgICAgIC8vIHdvcmQgVVRGLTE2Lg0KICAgICAgaWYgKGJ1ZmZlci5sZW5n
dGggPCBzdHIubGVuZ3RoICsgMikNCiAgICAgICAgYnVmZmVyLmxlbmd0aCA9IHN0
ci5sZW5ndGggKyAyOw0KDQogICAgICAvLyBQb2ludGVycyBmb3IgY29udmVyc2lv
bi4NCiAgICAgIGNoYXIqIHBJbiAgICAgPSBzdHIucHRyICsgZWF0ZW47DQogICAg
ICBjaGFyKiBlbmRJbiAgID0gc3RyLnB0ciArIHN0ci5sZW5ndGg7DQogICAgICB3
Y2hhciogcE91dCAgID0gYnVmZmVyLnB0cjsNCg0KICAgICAgLy8gQ2hlY2sgaWYg
c3RyIGVuZHMgd2l0aCBhbiBpbmNvbXBsZXRlIGNvZGUgcG9pbnQuDQogICAgICBm
b3IgKDs7KQ0KICAgICAgew0KICAgICAgICBpZiAoZW5kSW4gPT0gcEluKQ0KICAg
ICAgICB7DQogICAgICAgICAgaWYgKChzdHIubGVuZ3RoIC0gZWF0ZW4pID4gMikN
CiAgICAgICAgICAgIGdvdG8gRXJyb3JfVHJhaWxCeXRlQWxvbmU7DQoNCiAgICAg
ICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmICgoKigt
LWVuZEluKSAmIDB4QzApICE9IDB4ODApDQogICAgICAgIHsNCiAgICAgICAgICAv
LyBJZiB0aGUgbnVtYmVyIG9mIHRyYWlsIGJ5dGVzIGlzIGhpZ2hlciB0aGFuIHJl
bWFpbmluZyBsZW5ndGgsIHN0cg0KICAgICAgICAgIC8vIGVuZHMgd2l0aCBhbiBp
bmNvbXBsZXRlIGNvZGUgcG9pbnQuIFdlIGhhdmUgdG8gc3RvcCBiZWZvcmUgdGhl
IGxhc3QNCiAgICAgICAgICAvLyBsZWFkaW5nIGJ5dGUgdGhlbjsgYXMgZW5kSW4g
cG9pbnRzIG9uIGl0LCB3ZSBsZWF2ZSBpdCB0aGVyZS4NCiAgICAgICAgICAvLw0K
ICAgICAgICAgIC8vIElmIGl0IGlzIGVxdWFsLCB3ZSBoYXZlIHRvIHNldCBlbmRJ
biB0byB0aGUgb2xkIHZhbHVlOyB0aGF0IGlzLCBiZWhpbmQNCiAgICAgICAgICAv
LyB0aGUgZW5kIG9mIHN0ci4NCiAgICAgICAgICAvLw0KICAgICAgICAgIC8vIElm
IGl0IGlzIGxvd2VyLCB0aGVyZSBhcmUgZXhjZXNzIHRyYWlsIGJ5dGVzLiBUaGlz
IGlzIGFuIGludmFsaWQNCiAgICAgICAgICAvLyBlbmNvZGluZywgYnV0IHdlIGRv
IG5vdCBjYXJlIGFib3V0IHRoZSBlcnJvciBub3c7IFRoZSBjb252ZXJ0ZXIgd2ls
bA0KICAgICAgICAgIC8vIGZpbmQgaXQgYW55d2F5cy4gVGh1cyB3ZSBzZXQgZW5k
SW4gdG8gdGhlIG9sZCB2YWx1ZSBhcyB3ZWxsLg0KICAgICAgICAgIC8vDQogICAg
ICAgICAgaWYgKFVURjhzdHJpZGVbKmVuZEluXSA8PSBzdHIubGVuZ3RoIC0gKGVu
ZEluIC0gcEluKSkNCiAgICAgICAgICAgIGVuZEluID0gc3RyLnB0ciArIHN0ci5s
ZW5ndGg7DQoNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgfQ0K
DQogICAgICAvLyBOb3cgZG8gdGhlIGNvbnZlcnNpb24uDQogICAgICB3aGlsZSAo
cEluIDwgZW5kSW4pDQogICAgICB7DQogICAgICAgIC8vIFRlc3QgbGVhZGluZyBi
eXRlLg0KICAgICAgICBzd2l0Y2ggKFVURjhzdHJpZGVbKnBJbl0pDQogICAgICAg
IHsNCiAgICAgICAgICAvLyBJbnZhbGlkLg0KICAgICAgICAgIGNhc2UgMHhGRjoN
CiAgICAgICAgICB7DQogICAgICAgICAgICBpZiAoKnBJbiA8IDB4QzApDQogICAg
ICAgICAgICAgIGdvdG8gRXJyb3JfVHJhaWxCeXRlQWxvbmU7DQogICAgICAgICAg
ICBlbHNlIGlmICgqcEluIDwgMHhDMikNCiAgICAgICAgICAgICAgZ290byBFcnJv
cl9CeXRlSW52YWxpZDsNCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgICAg
Z290byBFcnJvcl9PdmVybG9uZzsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAv
LyAxLWJ5dGUtZW5jb2RpbmcuDQogICAgICAgICAgY2FzZSAxOg0KICAgICAgICAg
IHsNCiAgICAgICAgICAgICpwT3V0KysgPSAqcEluKys7DQogICAgICAgICAgICBi
cmVhazsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAvLyAyLWJ5dGUtZW5jb2Rp
bmcuLi4NCiAgICAgICAgICBjYXNlIDI6DQogICAgICAgICAgew0KICAgICAgICAg
ICAgLy8gVGVzdCBmb3IgYSBjb3JyZWN0IHRyYWlsIGJ5dGUuDQogICAgICAgICAg
ICBpZiAoKHBJblsxXSAmIDB4QzApICE9IDB4ODApDQogICAgICAgICAgICAgIGdv
dG8gRXJyb3JfVHJhaWxCeXRlTWlzc2luZzsNCg0KICAgICAgICAgICAgKnBPdXQr
KyA9ICgocEluWzBdICYgMHgwMDFGKSA8PCA2KSB8IChwSW5bMV0gJiAweDNGKTsN
CiAgICAgICAgICAgIHBJbiAgICArPSAyOw0KDQogICAgICAgICAgICBicmVhazsN
CiAgICAgICAgICB9DQoNCiAgICAgICAgICAvLyAzLWJ5dGUtZW5jb2RpbmcuLi4N
CiAgICAgICAgICBjYXNlIDM6DQogICAgICAgICAgew0KICAgICAgICAgICAgLy8g
VGVzdCBmb3IgMiBjb3JyZWN0IHRyYWlsIGJ5dGVzLg0KICAgICAgICAgICAgaWYg
KCgqKGNhc3Qod2NoYXIqKSAmcEluWzFdKSAmIDB4QzBDMCkgIT0gMHg4MDgwKQ0K
ICAgICAgICAgICAgICBnb3RvIEVycm9yX1RyYWlsQnl0ZU1pc3Npbmc7DQoNCiAg
ICAgICAgICAgIC8vIFRlc3QgZm9yIGludmFsaWQgc2VxdWVuY2VzIDxFMCwgODAt
OUYsID8+Lg0KICAgICAgICAgICAgaWYgKCgqKGNhc3Qod2NoYXIqKSAmcEluWzBd
KSAmIDB4RkYyMCkgPT0gMHhFMDAwKQ0KICAgICAgICAgICAgICBnb3RvIEVycm9y
X1RyYWlsQnl0ZUludmFsaWQ7DQoNCiAgICAgICAgICAgIC8vIFRlc3QgZm9yIGlu
dmFsaWQgc2VxdWVuY2VzIDxFRCwgQTAtQkYsID8+Lg0KICAgICAgICAgICAgaWYg
KCgqKGNhc3Qod2NoYXIqKSAmcEluWzBdKSAmIDB4RkYyMCkgPT0gMHhFRDIwKQ0K
ICAgICAgICAgICAgICBnb3RvIEVycm9yX1RyYWlsQnl0ZUludmFsaWQ7DQoNCiAg
ICAgICAgICAgICpwT3V0KysgPSAoKHBJblswXSAmIDB4MDAwRikgPDwgMTIpIHwg
KChwSW5bMV0gJiAweDAwM0YpIDw8IDYpIHwgKHBJblsyXSAmIDB4M0YpOw0KICAg
ICAgICAgICAgcEluICAgICs9IDM7DQoNCiAgICAgICAgICAgIGJyZWFrOw0KICAg
ICAgICAgIH0NCg0KICAgICAgICAgIC8vIDQtYnl0ZS1lbmNvZGluZy4uLg0KICAg
ICAgICAgIGNhc2UgNDoNCiAgICAgICAgICB7DQogICAgICAgICAgICAvLyBUZXN0
IGZvciAzIGNvcnJlY3QgdHJhaWwgYnl0ZXMuDQogICAgICAgICAgICBpZiAoKCoo
Y2FzdCh3Y2hhciopICZwSW5bMV0pICYgMHhDMEMwKSAhPSAweDgwODAgfHwgKHBJ
blszXSAmIDB4QzApICE9IDB4ODApDQogICAgICAgICAgICAgIGdvdG8gRXJyb3Jf
VHJhaWxCeXRlTWlzc2luZzsNCg0KICAgICAgICAgICAgLy8gVGVzdCBmb3IgaW52
YWxpZCBzZXF1ZW5jZXMgPEYwLCA4MC04RiwgPz4uDQogICAgICAgICAgICBpZiAo
KCooY2FzdCh3Y2hhciopICZwSW5bMF0pICYgMHhGRjMwKSA9PSAweEYwMDApDQog
ICAgICAgICAgICAgIGdvdG8gRXJyb3JfVHJhaWxCeXRlSW52YWxpZDsNCg0KICAg
ICAgICAgICAgLy8gVGVzdCBmb3IgaW52YWxpZCBzZXF1ZW5jZXMgPEY0LCA5MC1C
RiwgPz4uDQogICAgICAgICAgICBpZiAocEluWzBdID09IDB4RjQgJiYgKHBJblsx
XSAmIDB4MzApICE9IDApDQogICAgICAgICAgICAgIGdvdG8gRXJyb3JfVHJhaWxC
eXRlSW52YWxpZDsNCg0KICAgICAgICAgICAgcE91dFswXSA9ICgoKHBJblswXSAm
IDB4MDAwNykgPDwgOCkgfCAoKHBJblsxXSAmIDB4M0YpIDw8IDIpIHwgKChwSW5b
Ml0gJiAweDMwKSA+PiA0KSkgKyAweEQ3QzA7DQogICAgICAgICAgICBwT3V0WzFd
ID0gKCgocEluWzJdICYgMHgwMDBGKSA8PCA2KSB8IChwSW5bM10gJiAweDNGKSkg
fCAweERDMDA7DQogICAgICAgICAgICBwT3V0ICAgKz0gMjsNCiAgICAgICAgICAg
IHBJbiAgICArPSA0Ow0KDQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgICB9
DQogICAgICAgIH0NCiAgICAgIH0NCg0KICAgICAgLy8gWmVyby10ZXJtaW5hdGUg
dGhlIHJlc3VsdCwgYW5kIHJldHVybiBpdC4NCiAgICAgICpwT3V0ID0gMDsNCiAg
ICAgIGVhdGVuID0gcEluIC0gc3RyLnB0cjsNCg0KICAgICAgcmV0dXJuIGJ1ZmZl
clswIC4uIChwT3V0IC0gYnVmZmVyLnB0cildOw0KDQogICAgICAvLyBFcnJvciBt
ZXNzYWdlcy4NCiAgICAgIEVycm9yX0J5dGVJbnZhbGlkOg0KICAgICAgICB0aHJv
dyBuZXcgVXRmRXJyb3IoIlVURi04IGludmFsaWQgYnl0ZSIsIHBJbiAtIHN0ci5w
dHIpOw0KDQogICAgICBFcnJvcl9UcmFpbEJ5dGVBbG9uZToNCiAgICAgICAgdGhy
b3cgbmV3IFV0ZkVycm9yKCJVVEYtOCB0cmFpbCBieXRlIHdpdGhvdXQgbGVhZGlu
ZyBieXRlIiwgcEluIC0gc3RyLnB0cik7DQoNCiAgICAgIEVycm9yX1RyYWlsQnl0
ZU1pc3Npbmc6DQogICAgICAgIHRocm93IG5ldyBVdGZFcnJvcigiVVRGLTggbWlz
c2luZyB0cmFpbCBieXRlIGFmdGVyIGxlYWRpbmcgYnl0ZSIsIHBJbiAtIHN0ci5w
dHIpOw0KDQogICAgICBFcnJvcl9UcmFpbEJ5dGVJbnZhbGlkOg0KICAgICAgICB0
aHJvdyBuZXcgVXRmRXJyb3IoIlVURi04IGludmFsaWQgdHJhaWwgYnl0ZSIsIHBJ
biAtIHN0ci5wdHIpOw0KDQogICAgICBFcnJvcl9PdmVybG9uZzoNCiAgICAgICAg
dGhyb3cgbmV3IFV0ZkVycm9yKCJVVEYtOCBvdmVybG9uZyBlbmNvZGluZyIsIHBJ
biAtIHN0ci5wdHIpOw0KICAgIH0NCg0KcHVibGljIHdjaGFyW10gdG9VVEYxNihj
aGFyW10gc3RyLCB3Y2hhcltdIGJ1ZmZlciA9IG51bGwpDQogICAgew0KICAgICAg
c2l6ZV90IGVhdGVuICAgPSAwOw0KICAgICAgd2NoYXJbXSByZXN1bHQgPSB0b1VU
RjE2KHN0ciwgZWF0ZW4sIGJ1ZmZlcik7DQoNCiAgICAgIGlmIChlYXRlbiA8IHN0
ci5sZW5ndGgpDQogICAgICAgIHRocm93IG5ldyBVdGZFcnJvcigiVVRGLTggdW5m
aW5pc2hlZCBjb2RlIHNlcXVlbmNlIiwgZWF0ZW4pOw0KDQogICAgICByZXR1cm4g
cmVzdWx0Ow0KICAgIH0NCg0KDQpwdWJsaWMgd2NoYXJbXSB0b1VURjE2KGRjaGFy
W10gc3RyLCBpbm91dCBzaXplX3QgZWF0ZW4sIHdjaGFyW10gYnVmZmVyID0gbnVs
bCkNCiAgICBpbg0KICAgIHsNCiAgICAgIGFzc2VydChlYXRlbiA8PSBzdHIubGVu
Z3RoKTsNCiAgICB9DQogICAgYm9keQ0KICAgIHsNCiAgICAgIC8vIElmIGJ1ZmZl
ciBpcyBub3Qgc3VmZmljaWVudCwgcmVhbGxvY2F0ZS4gV2UgaG9wZSB0aGF0IHRo
ZXJlIGFyZSBubw0KICAgICAgLy8gYW5jaWVudCBzY3JpcHRzIHVzZWQsIHRoZW4g
b3VyIGNob2ljZSB3aWxsIGJlIGVub3VnaC4gT3RoZXJ3aXNlIHdlIHdpbGwNCiAg
ICAgIC8vIGhhdmUgdG8gcmVhbGxvY2F0ZSBpbiB0aGUgbG9vcC4NCiAgICAgIGlm
IChidWZmZXIubGVuZ3RoIDwgc3RyLmxlbmd0aCArIDIpDQogICAgICAgIGJ1ZmZl
ci5sZW5ndGggPSBzdHIubGVuZ3RoICsgMjsNCg0KICAgICAgLy8gUG9pbnRlcnMg
Zm9yIGNvbnZlcnNpb24uDQogICAgICBkY2hhciogcEluICAgID0gc3RyLnB0ciAr
IGVhdGVuOw0KICAgICAgZGNoYXIqIGVuZEluICA9IHN0ci5wdHIgKyBzdHIubGVu
Z3RoOw0KICAgICAgd2NoYXIqIHBPdXQgICA9IGJ1ZmZlci5wdHI7DQogICAgICB3
Y2hhciogZW5kT3V0ID0gYnVmZmVyLnB0ciArIGJ1ZmZlci5sZW5ndGggLSAyOw0K
DQogICAgICAvLyBOb3cgZG8gdGhlIGNvbnZlcnNpb24uDQogICAgICBpZiAocElu
IDwgZW5kSW4pDQogICAgICB7DQogICAgICAgIGRvDQogICAgICAgIHsNCiAgICAg
ICAgICAvLyBDaGVjayBmb3IgZW5vdWdoIHNwYWNlIGxlZnQgaW4gdGhlIGJ1ZmZl
ci4NCiAgICAgICAgICBpZiAocE91dCA+PSBlbmRPdXQpDQogICAgICAgICAgew0K
ICAgICAgICAgICAgLy8gUmVhbGxvY2F0ZSB0aGUgYnVmZmVyLg0KICAgICAgICAg
ICAgZW5kT3V0ICAgICAgICA9IGJ1ZmZlci5wdHI7ICAgICAgLy8gU2F2ZSBvbGQg
YnVmZmVyIGJlZ2lubmluZyBpbiBlbmRPdXQuDQogICAgICAgICAgICBidWZmZXIu
bGVuZ3RoID0gYnVmZmVyLmxlbmd0aCArICgoZW5kSW4gLSBwSW4pIDw8IDEpICsg
MTsgLy8gV2lsbCBiZSBlbm91Z2guDQogICAgICAgICAgICBwT3V0ICAgICAgICAg
ID0gYnVmZmVyLnB0ciArIChwT3V0IC0gZW5kT3V0KTsNCiAgICAgICAgICAgIGVu
ZE91dCAgICAgICAgPSBidWZmZXIucHRyICsgYnVmZmVyLmxlbmd0aCAtIDI7DQog
ICAgICAgICAgfQ0KDQogICAgICAgICAgLy8gU2ltcGxlIGVuY29kaW5nLg0KICAg
ICAgICAgIGlmICgqcEluIDwgMHgxMDAwMCkNCiAgICAgICAgICB7DQogICAgICAg
ICAgICAvLyBDaGVjayBmb3IgZm9yYmlkZGVuIHN1cnJvZ2F0ZSBjb2RlIHBvaW50
cy4NCiAgICAgICAgICAgIGlmICgoKnBJbiAmIDB4RjgwMCkgPT0gMHhEODAwKQ0K
ICAgICAgICAgICAgICBnb3RvIEVycm9yX0ludmFsaWRDb2RlOw0KDQogICAgICAg
ICAgICAqcE91dCsrID0gKnBJbjsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAv
LyBTdXJyb2dhdGUgZW5jb2RpbmcuDQogICAgICAgICAgZWxzZQ0KICAgICAgICAg
IHsNCiAgICAgICAgICAgIC8vIENoZWNrIGZvciB1cHBlciBib3VuZGFyeS4NCiAg
ICAgICAgICAgIGlmICgqcEluID4gMHgxMEZGRkYpDQogICAgICAgICAgICAgIGdv
dG8gRXJyb3JfVXBwZXJCb3VuZGFyeTsNCg0KICAgICAgICAgICAgcE91dFswXSA9
ICgqcEluID4+IDEwKSArIDB4RDdDMDsNCiAgICAgICAgICAgIHBPdXRbMV0gPSAo
KnBJbiAmIDB4MDNGRikgfCAweERDMDA7DQogICAgICAgICAgICBwT3V0ICAgKz0g
MjsNCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgd2hpbGUgKCsrcElu
IDwgZW5kSW4pOw0KICAgICAgfQ0KDQogICAgICAvLyBaZXJvLXRlcm1pbmF0ZSB0
aGUgcmVzdWx0LCBhbmQgcmV0dXJuIGl0Lg0KICAgICAgKnBPdXQgPSAwOw0KICAg
ICAgZWF0ZW4gPSBwSW4gLSBzdHIucHRyOw0KDQogICAgICByZXR1cm4gYnVmZmVy
WzAgLi4gKHBPdXQgLSBidWZmZXIucHRyKV07DQoNCiAgICAgIC8vIEVycm9yIG1l
c3NhZ2VzLg0KICAgICAgRXJyb3JfSW52YWxpZENvZGU6DQogICAgICAgIHRocm93
IG5ldyBVdGZFcnJvcigiVVRGLTMyIEludmFsaWQgc3Vycm9nYXRlIGNvZGUgcG9p
bnQiLCBwSW4gLSBzdHIucHRyKTsNCg0KICAgICAgRXJyb3JfVXBwZXJCb3VuZGFy
eToNCiAgICAgICAgdGhyb3cgbmV3IFV0ZkVycm9yKCJVVEYtMzIgSW52YWxpZCBj
b2RlIHBvaW50IGFib3ZlIFUrMTBGRkZGIiwgcEluIC0gc3RyLnB0cik7DQogICAg
fQ0KDQpwdWJsaWMgd2NoYXJbXSB0b1VURjE2KGRjaGFyW10gc3RyLCB3Y2hhcltd
IGJ1ZmZlciA9IG51bGwpDQogICAgew0KICAgICAgc2l6ZV90IGVhdGVuID0gMDsN
CiAgICAgIHJldHVybiB0b1VURjE2KHN0ciwgZWF0ZW4sIGJ1ZmZlcik7DQogICAg
fQ0KDQpwdWJsaWMgd2NoYXIqIHRvVVRGMTZ6KGNoYXJbXSBzKQ0KICAgIHsNCiAg
ICAgIHJldHVybiB0b1VURjE2KHMpLnB0cjsNCiAgICB9DQoNCnB1YmxpYyB3Y2hh
cltdIHRvVVRGMTYod2NoYXJbXSBzKQ0KICAgIGluDQogICAgew0KICAgICAgdmFs
aWRhdGUocyk7DQogICAgfQ0KICAgIGJvZHkNCiAgICB7DQogICAgICByZXR1cm4g
czsNCiAgICB9DQoNCg0KDQovKiA9PT09PT09PT09PT09PT09PT09IENvbnZlcnNp
b24gdG8gVVRGMzIgPT09PT09PT09PT09PT09PT09PT09PT0gKi8NCg0KcHVibGlj
IGRjaGFyW10gdG9VVEYzMihjaGFyW10gc3RyLCBpbm91dCBzaXplX3QgZWF0ZW4s
IGRjaGFyW10gYnVmZmVyID0gbnVsbCkNCiAgICBpbg0KICAgIHsNCiAgICAgIGFz
c2VydChlYXRlbiA8PSBzdHIubGVuZ3RoKTsNCiAgICB9DQogICAgYm9keSAvLyBU
aGlzIGZ1bmN0aW9uIGlzIHZlcnkgc2ltaWxhciB0byBVVEYtOCB0byBVVEYtMTYu
DQogICAgew0KICAgICAgLy8gSWYgYnVmZmVyIGlzIG5vdCBzdWZmaWNpZW50LCBy
ZWFsbG9jYXRlLiBXZSB3aWxsIG5vdCBkbyB0aGF0IGluIHRoZSBsb29wLA0KICAg
ICAgLy8gYmVjYXVzZSB0aGUgcHJldmFsZW50IGNhc2UgaXMgQVNDSUkgaW5wdXQs
IGFuZCB0aGVuIG9uZSBieXRlIFVURi04IGlzIG9uZQ0KICAgICAgLy8gZHdvcmQg
VVRGLTMyLg0KICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPCBzdHIubGVuZ3RoICsg
MSkNCiAgICAgICAgYnVmZmVyLmxlbmd0aCA9IHN0ci5sZW5ndGggKyAxOw0KDQog
ICAgICAvLyBQb2ludGVycyBmb3IgY29udmVyc2lvbi4NCiAgICAgIGNoYXIqIHBJ
biAgICAgPSBzdHIucHRyICsgZWF0ZW47DQogICAgICBjaGFyKiBlbmRJbiAgID0g
c3RyLnB0ciArIHN0ci5sZW5ndGg7DQogICAgICBkY2hhciogcE91dCAgID0gYnVm
ZmVyLnB0cjsNCg0KICAgICAgLy8gQ2hlY2sgaWYgc3RyIGVuZHMgd2l0aCBhbiBp
bmNvbXBsZXRlIGNvZGUgcG9pbnQuDQogICAgICBmb3IgKDs7KQ0KICAgICAgew0K
ICAgICAgICBpZiAoZW5kSW4gPT0gcEluKQ0KICAgICAgICB7DQogICAgICAgICAg
aWYgKChzdHIubGVuZ3RoIC0gZWF0ZW4pID4gMikNCiAgICAgICAgICAgIGdvdG8g
RXJyb3JfVHJhaWxCeXRlQWxvbmU7DQoNCiAgICAgICAgICByZXR1cm4gbnVsbDsN
CiAgICAgICAgfQ0KDQogICAgICAgIGlmICgoKigtLWVuZEluKSAmIDB4QzApICE9
IDB4ODApDQogICAgICAgIHsNCiAgICAgICAgICAvLyBBZGp1c3QgZW5kSW4gYWNj
b3JkaW5nbHkuDQogICAgICAgICAgaWYgKFVURjhzdHJpZGVbKmVuZEluXSA8PSBz
dHIubGVuZ3RoIC0gKGVuZEluIC0gcEluKSkNCiAgICAgICAgICAgIGVuZEluID0g
c3RyLnB0ciArIHN0ci5sZW5ndGg7DQoNCiAgICAgICAgICBicmVhazsNCiAgICAg
ICAgfQ0KICAgICAgfQ0KDQogICAgICAvLyBOb3cgZG8gdGhlIGNvbnZlcnNpb24u
DQogICAgICB3aGlsZSAocEluIDwgZW5kSW4pDQogICAgICB7DQogICAgICAgIC8v
IFRlc3QgbGVhZGluZyBieXRlLg0KICAgICAgICBzd2l0Y2ggKFVURjhzdHJpZGVb
KnBJbl0pDQogICAgICAgIHsNCiAgICAgICAgICAvLyBJbnZhbGlkLg0KICAgICAg
ICAgIGNhc2UgMHhGRjoNCiAgICAgICAgICB7DQogICAgICAgICAgICBpZiAoKnBJ
biA8IDB4QzApDQogICAgICAgICAgICAgIGdvdG8gRXJyb3JfVHJhaWxCeXRlQWxv
bmU7DQogICAgICAgICAgICBlbHNlIGlmICgqcEluIDwgMHhDMikNCiAgICAgICAg
ICAgICAgZ290byBFcnJvcl9CeXRlSW52YWxpZDsNCiAgICAgICAgICAgIGVsc2UN
CiAgICAgICAgICAgICAgZ290byBFcnJvcl9PdmVybG9uZzsNCiAgICAgICAgICB9
DQoNCiAgICAgICAgICAvLyAxLWJ5dGUtZW5jb2RpbmcuDQogICAgICAgICAgY2Fz
ZSAxOg0KICAgICAgICAgIHsNCiAgICAgICAgICAgICpwT3V0KysgPSAqcEluKys7
DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAv
LyAyLWJ5dGUtZW5jb2RpbmcuLi4NCiAgICAgICAgICBjYXNlIDI6DQogICAgICAg
ICAgew0KICAgICAgICAgICAgLy8gVGVzdCBmb3IgYSBjb3JyZWN0IHRyYWlsIGJ5
dGUuDQogICAgICAgICAgICBpZiAoKHBJblsxXSAmIDB4QzApICE9IDB4ODApDQog
ICAgICAgICAgICAgIGdvdG8gRXJyb3JfVHJhaWxCeXRlTWlzc2luZzsNCg0KICAg
ICAgICAgICAgKnBPdXQrKyA9ICgocEluWzBdICYgMHgwMDFGKSA8PCA2KSB8IChw
SW5bMV0gJiAweDNGKTsNCiAgICAgICAgICAgIHBJbiAgICArPSAyOw0KDQogICAg
ICAgICAgICBicmVhazsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAvLyAzLWJ5
dGUtZW5jb2RpbmcuLi4NCiAgICAgICAgICBjYXNlIDM6DQogICAgICAgICAgew0K
ICAgICAgICAgICAgLy8gVGVzdCBmb3IgMiBjb3JyZWN0IHRyYWlsIGJ5dGVzLg0K
ICAgICAgICAgICAgaWYgKCgqKGNhc3Qod2NoYXIqKSAmcEluWzFdKSAmIDB4QzBD
MCkgIT0gMHg4MDgwKQ0KICAgICAgICAgICAgICBnb3RvIEVycm9yX1RyYWlsQnl0
ZU1pc3Npbmc7DQoNCiAgICAgICAgICAgIC8vIFRlc3QgZm9yIGludmFsaWQgc2Vx
dWVuY2VzIDxFMCwgODAtOUYsID8+Lg0KICAgICAgICAgICAgaWYgKCgqKGNhc3Qo
d2NoYXIqKSAmcEluWzBdKSAmIDB4RkYyMCkgPT0gMHhFMDAwKQ0KICAgICAgICAg
ICAgICBnb3RvIEVycm9yX1RyYWlsQnl0ZUludmFsaWQ7DQoNCiAgICAgICAgICAg
IC8vIFRlc3QgZm9yIGludmFsaWQgc2VxdWVuY2VzIDxFRCwgQTAtQkYsID8+Lg0K
ICAgICAgICAgICAgaWYgKCgqKGNhc3Qod2NoYXIqKSAmcEluWzBdKSAmIDB4RkYy
MCkgPT0gMHhFRDIwKQ0KICAgICAgICAgICAgICBnb3RvIEVycm9yX1RyYWlsQnl0
ZUludmFsaWQ7DQoNCiAgICAgICAgICAgICpwT3V0KysgPSAoKHBJblswXSAmIDB4
MDAwRikgPDwgMTIpIHwgKChwSW5bMV0gJiAweDAwM0YpIDw8IDYpIHwgKHBJblsy
XSAmIDB4M0YpOw0KICAgICAgICAgICAgcEluICAgICs9IDM7DQoNCiAgICAgICAg
ICAgIGJyZWFrOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIC8vIDQtYnl0ZS1l
bmNvZGluZy4uLg0KICAgICAgICAgIGNhc2UgNDoNCiAgICAgICAgICB7DQogICAg
ICAgICAgICAvLyBUZXN0IGZvciAzIGNvcnJlY3QgdHJhaWwgYnl0ZXMuDQogICAg
ICAgICAgICBpZiAoKCooY2FzdCh3Y2hhciopICZwSW5bMV0pICYgMHhDMEMwKSAh
PSAweDgwODAgfHwgKHBJblszXSAmIDB4QzApICE9IDB4ODApDQogICAgICAgICAg
ICAgIGdvdG8gRXJyb3JfVHJhaWxCeXRlTWlzc2luZzsNCg0KICAgICAgICAgICAg
Ly8gVGVzdCBmb3IgaW52YWxpZCBzZXF1ZW5jZXMgPEYwLCA4MC04RiwgPz4uDQog
ICAgICAgICAgICBpZiAoKCooY2FzdCh3Y2hhciopICZwSW5bMF0pICYgMHhGRjMw
KSA9PSAweEYwMDApDQogICAgICAgICAgICAgIGdvdG8gRXJyb3JfVHJhaWxCeXRl
SW52YWxpZDsNCg0KICAgICAgICAgICAgLy8gVGVzdCBmb3IgaW52YWxpZCBzZXF1
ZW5jZXMgPEY0LCA5MC1CRiwgPz4uDQogICAgICAgICAgICBpZiAocEluWzBdID09
IDB4RjQgJiYgKHBJblsxXSAmIDB4MzApICE9IDApDQogICAgICAgICAgICAgIGdv
dG8gRXJyb3JfVHJhaWxCeXRlSW52YWxpZDsNCg0KICAgICAgICAgICAgKnBPdXQr
KyA9ICgocEluWzBdICYgMHgwMDAwMDAwNykgPDwgMTgpIHwgKChwSW5bMV0gJiAw
eDAwMDAzRikgPDwgMTIpIHwgKChwSW5bMl0gJiAweDAwM0YpIDw8IDYpIHwgKHBJ
blszXSAmIDB4M0YpOw0KICAgICAgICAgICAgcEluICAgICs9IDQ7DQoNCiAgICAg
ICAgICAgIGJyZWFrOw0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgfQ0K
DQogICAgICAvLyBaZXJvLXRlcm1pbmF0ZSB0aGUgcmVzdWx0LCBhbmQgcmV0dXJu
IGl0Lg0KICAgICAgKnBPdXQgPSAwOw0KICAgICAgZWF0ZW4gPSBwSW4gLSBzdHIu
cHRyOw0KDQogICAgICByZXR1cm4gYnVmZmVyWzAgLi4gKHBPdXQgLSBidWZmZXIu
cHRyKV07DQoNCiAgICAgIC8vIEVycm9yIG1lc3NhZ2VzLg0KICAgICAgRXJyb3Jf
Qnl0ZUludmFsaWQ6DQogICAgICAgIHRocm93IG5ldyBVdGZFcnJvcigiVVRGLTgg
aW52YWxpZCBieXRlIiwgcEluIC0gc3RyLnB0cik7DQoNCiAgICAgIEVycm9yX1Ry
YWlsQnl0ZUFsb25lOg0KICAgICAgICB0aHJvdyBuZXcgVXRmRXJyb3IoIlVURi04
IHRyYWlsIGJ5dGUgd2l0aG91dCBsZWFkaW5nIGJ5dGUiLCBwSW4gLSBzdHIucHRy
KTsNCg0KICAgICAgRXJyb3JfVHJhaWxCeXRlTWlzc2luZzoNCiAgICAgICAgdGhy
b3cgbmV3IFV0ZkVycm9yKCJVVEYtOCBtaXNzaW5nIHRyYWlsIGJ5dGUgYWZ0ZXIg
bGVhZGluZyBieXRlIiwgcEluIC0gc3RyLnB0cik7DQoNCiAgICAgIEVycm9yX1Ry
YWlsQnl0ZUludmFsaWQ6DQogICAgICAgIHRocm93IG5ldyBVdGZFcnJvcigiVVRG
LTggaW52YWxpZCB0cmFpbCBieXRlIiwgcEluIC0gc3RyLnB0cik7DQoNCiAgICAg
IEVycm9yX092ZXJsb25nOg0KICAgICAgICB0aHJvdyBuZXcgVXRmRXJyb3IoIlVU
Ri04IG92ZXJsb25nIGVuY29kaW5nIiwgcEluIC0gc3RyLnB0cik7DQogICAgfQ0K
DQpwdWJsaWMgZGNoYXJbXSB0b1VURjMyKGNoYXJbXSBzdHIsIGRjaGFyW10gYnVm
ZmVyID0gbnVsbCkNCiAgICB7DQogICAgICBzaXplX3QgZWF0ZW4gID0gMDsNCiAg
ICAgIGRjaGFyW10gcmVzdWx0ID0gdG9VVEYzMihzdHIsIGVhdGVuLCBidWZmZXIp
Ow0KDQogICAgICBpZiAoZWF0ZW4gPCBzdHIubGVuZ3RoKQ0KICAgICAgICB0aHJv
dyBuZXcgVXRmRXJyb3IoIlVURi04IHVuZmluaXNoZWQgY29kZSBzZXF1ZW5jZSIs
IGVhdGVuKTsNCg0KICAgICAgcmV0dXJuIHJlc3VsdDsNCiAgICB9DQoNCnB1Ymxp
YyBkY2hhcltdIHRvVVRGMzIod2NoYXJbXSBzdHIsIGlub3V0IHNpemVfdCBlYXRl
biwgZGNoYXJbXSBidWZmZXIgPSBudWxsKQ0KICAgIGluDQogICAgew0KICAgICAg
YXNzZXJ0KGVhdGVuIDw9IHN0ci5sZW5ndGgpOw0KICAgIH0NCiAgICBib2R5DQog
ICAgew0KICAgICAgLy8gSWYgYnVmZmVyIGlzIG5vdCBzdWZmaWNpZW50LCByZWFs
bG9jYXRlLiBXZSB3aWxsIG5vdCBkbyB0aGF0IGluIHRoZSBsb29wLA0KICAgICAg
Ly8gYmVjYXVzZSBtb3N0bHkgb25lIHdvcmQgVVRGLTE2IGlzIG9uZSBkd29yZCBV
VEYtMzIuDQogICAgICBpZiAoYnVmZmVyLmxlbmd0aCA8IHN0ci5sZW5ndGggKyAx
KQ0KICAgICAgICBidWZmZXIubGVuZ3RoID0gc3RyLmxlbmd0aCArIDE7DQoNCiAg
ICAgIC8vIFBvaW50ZXJzIGZvciBjb252ZXJzaW9uLg0KICAgICAgd2NoYXIqIHBJ
biAgID0gc3RyLnB0ciArIGVhdGVuOw0KICAgICAgd2NoYXIqIGVuZEluID0gc3Ry
LnB0ciArIHN0ci5sZW5ndGg7DQogICAgICBkY2hhciogcE91dCAgPSBidWZmZXIu
cHRyOw0KDQogICAgICAvLyBDaGVjayBpZiBzdHIgZW5kcyB3aXRoIGEgbGVhZGlu
ZyBieXRlLiBJZ25vcmUgaXQgdGhlbi4NCiAgICAgIGlmIChlbmRJbiAhPSBwSW4g
JiYgKCooZW5kSW4gLSAxKSAmIDB4RkMwMCkgPT0gMHhEODAwKQ0KICAgICAgICAt
LWVuZEluOw0KDQogICAgICAvLyBOb3cgZG8gdGhlIGNvbnZlcnNpb24uDQogICAg
ICBpZiAocEluIDwgZW5kSW4pDQogICAgICB7DQogICAgICAgIGRvDQogICAgICAg
IHsNCiAgICAgICAgICAvLyBOb3cgZG8gdGhlIGNvbnZlcnNpb24uDQogICAgICAg
ICAgaWYgKCgqcEluICYgMHhGODAwKSAhPSAweEQ4MDApDQogICAgICAgICAgew0K
ICAgICAgICAgICAgKnBPdXQrKyA9ICpwSW47DQogICAgICAgICAgfQ0KDQogICAg
ICAgICAgLy8gTGVhZGluZyBzdXJyb2dhdGUuLi4NCiAgICAgICAgICBlbHNlIGlm
ICgqcEluIDwgMHhEQzAwKQ0KICAgICAgICAgIHsNCiAgICAgICAgICAgIC8vIENo
ZWNrIGZvciBjb3JyZWN0IHRyYWlsIHN1cnJvZ2F0ZS4NCiAgICAgICAgICAgIGlm
ICgocEluWzFdICYgMHhGQzAwKSAhPSAweERDMDApDQogICAgICAgICAgICAgIGdv
dG8gRXJyb3JfVHJhaWxTdXJyb2dhdGVNaXNzaW5nOw0KDQogICAgICAgICAgICAq
cE91dCsrID0gKCgqcEluICYgMHgwM0ZGKSArIDB4MDAwMDAwNDApIDw8IDEwIHwg
KHBJblsxXSAmIDB4MDNGRik7DQogICAgICAgICAgICArK3BJbjsNCiAgICAgICAg
ICB9DQoNCiAgICAgICAgICAvLyBUcmFpbCBzdXJyb2dhdGUuLi4gKGlsbGVnYWwp
DQogICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgZ290byBFcnJvcl9UcmFpbFN1
cnJvZ2F0ZUFsb25lOw0KICAgICAgICB9DQogICAgICAgIHdoaWxlICgrK3BJbiA8
IGVuZEluKTsNCiAgICAgIH0NCg0KICAgICAgLy8gWmVyby10ZXJtaW5hdGUgdGhl
IHJlc3VsdCwgYW5kIHJldHVybiBpdC4NCiAgICAgICpwT3V0ID0gMDsNCiAgICAg
IGVhdGVuID0gcEluIC0gc3RyLnB0cjsNCg0KICAgICAgcmV0dXJuIGJ1ZmZlclsw
IC4uIChwT3V0IC0gYnVmZmVyLnB0cildOw0KDQogICAgICAvLyBFcnJvciBtZXNz
YWdlcy4NCiAgICAgIEVycm9yX1RyYWlsU3Vycm9nYXRlQWxvbmU6DQogICAgICAg
IHRocm93IG5ldyBVdGZFcnJvcigiVVRGLTE2IHRyYWlsIHN1cnJvZ2F0ZSB3aXRo
b3V0IGxlYWRpbmcgc3Vycm9nYXRlIiwgcEluIC0gc3RyLnB0cik7DQoNCiAgICAg
IEVycm9yX1RyYWlsU3Vycm9nYXRlTWlzc2luZzoNCiAgICAgICAgdGhyb3cgbmV3
IFV0ZkVycm9yKCJVVEYtMTYgbWlzc2luZyB0cmFpbCBzdXJyb2dhdGUgYWZ0ZXIg
bGVhZGluZyBzdXJyb2dhdGUiLCBwSW4gLSBzdHIucHRyKTsNCiAgICB9DQoNCnB1
YmxpYyBkY2hhcltdIHRvVVRGMzIod2NoYXJbXSBzdHIsIGRjaGFyW10gYnVmZmVy
ID0gbnVsbCkNCiAgICB7DQogICAgICBzaXplX3QgZWF0ZW4gID0gMDsNCiAgICAg
IGRjaGFyW10gcmVzdWx0ID0gdG9VVEYzMihzdHIsIGVhdGVuLCBidWZmZXIpOw0K
DQogICAgICBpZiAoZWF0ZW4gPCBzdHIubGVuZ3RoKQ0KICAgICAgICB0aHJvdyBu
ZXcgVXRmRXJyb3IoIlVURi0xNiB1bmZpbmlzaGVkIGNvZGUgc2VxdWVuY2UiLCBl
YXRlbik7DQoNCiAgICAgIHJldHVybiByZXN1bHQ7DQogICAgfQ0KDQpwdWJsaWMg
ZGNoYXJbXSB0b1VURjMyKGRjaGFyW10gcykNCiAgICBpbg0KICAgIHsNCiAgICAg
IHZhbGlkYXRlKHMpOw0KICAgIH0NCiAgICBib2R5DQogICAgew0KICAgICAgcmV0
dXJuIHM7DQogICAgfQ0KDQoNCg0KLyogPT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT0gdGVzdHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PSAqLw0KDQp1bml0dGVzdA0Kew0KICAgIGRlYnVnKHV0ZikgcHJpbnRmKCJ1dGYu
dG9VVEYudW5pdHRlc3RcbiIpOw0KDQogICAgY2hhcltdIGM7DQogICAgd2NoYXJb
XSB3Ow0KICAgIGRjaGFyW10gZDsNCg0KICAgIGMgPSAiaGVsbG8iOw0KICAgIHcg
PSB0b1VURjE2KGMpOw0KICAgIGFzc2VydCh3ID09ICJoZWxsbyIpOw0KICAgIGQg
PSB0b1VURjMyKGMpOw0KICAgIGFzc2VydChkID09ICJoZWxsbyIpOw0KDQogICAg
YyA9IHRvVVRGOCh3KTsNCiAgICBhc3NlcnQoYyA9PSAiaGVsbG8iKTsNCiAgICBk
ID0gdG9VVEYzMih3KTsNCiAgICBhc3NlcnQoZCA9PSAiaGVsbG8iKTsNCg0KICAg
IGMgPSB0b1VURjgoZCk7DQogICAgYXNzZXJ0KGMgPT0gImhlbGxvIik7DQogICAg
dyA9IHRvVVRGMTYoZCk7DQogICAgYXNzZXJ0KHcgPT0gImhlbGxvIik7DQoNCg0K
ICAgIGMgPSAiaGVsXHUxMjM0byI7DQogICAgdyA9IHRvVVRGMTYoYyk7DQogICAg
YXNzZXJ0KHcgPT0gImhlbFx1MTIzNG8iKTsNCiAgICBkID0gdG9VVEYzMihjKTsN
CiAgICBhc3NlcnQoZCA9PSAiaGVsXHUxMjM0byIpOw0KDQogICAgYyA9IHRvVVRG
OCh3KTsNCiAgICBhc3NlcnQoYyA9PSAiaGVsXHUxMjM0byIpOw0KICAgIGQgPSB0
b1VURjMyKHcpOw0KICAgIGFzc2VydChkID09ICJoZWxcdTEyMzRvIik7DQoNCiAg
ICBjID0gdG9VVEY4KGQpOw0KICAgIGFzc2VydChjID09ICJoZWxcdTEyMzRvIik7
DQogICAgdyA9IHRvVVRGMTYoZCk7DQogICAgYXNzZXJ0KHcgPT0gImhlbFx1MTIz
NG8iKTsNCg0KDQogICAgYyA9ICJoZVxVMDAxMEFBQUFsbG8iOw0KICAgIHcgPSB0
b1VURjE2KGMpOw0KICAgIC8vZm9yZWFjaCAod2NoYXIgYzsgdykgcHJpbnRmKCJj
ID0geCV4XG4iLCBjKTsNCiAgICAvL2ZvcmVhY2ggKHdjaGFyIGM7IGNhc3Qod2No
YXJbXSkiaGVcVTAwMTBBQUFBbGxvIikgcHJpbnRmKCJjID0geCV4XG4iLCBjKTsN
CiAgICBhc3NlcnQodyA9PSAiaGVcVTAwMTBBQUFBbGxvIik7DQogICAgZCA9IHRv
VVRGMzIoYyk7DQogICAgYXNzZXJ0KGQgPT0gImhlXFUwMDEwQUFBQWxsbyIpOw0K
DQogICAgYyA9IHRvVVRGOCh3KTsNCiAgICBhc3NlcnQoYyA9PSAiaGVcVTAwMTBB
QUFBbGxvIik7DQogICAgZCA9IHRvVVRGMzIodyk7DQogICAgYXNzZXJ0KGQgPT0g
ImhlXFUwMDEwQUFBQWxsbyIpOw0KDQogICAgYyA9IHRvVVRGOChkKTsNCiAgICBh
c3NlcnQoYyA9PSAiaGVcVTAwMTBBQUFBbGxvIik7DQogICAgdyA9IHRvVVRGMTYo
ZCk7DQogICAgYXNzZXJ0KHcgPT0gImhlXFUwMDEwQUFBQWxsbyIpOw0KfQ0K
------------nYfCPQ0YqXIPLx3SP0pXvL--
May 21 2005