libgcrypt documentation

Simon Josefsson jas@extundo.com
Tue, 10 Sep 2002 05:01:27 +0200


--=-=-=

Werner Koch <wk@gnupg.org> writes:

> On Sun, 08 Sep 2002 11:43:45 -0300, Rafael P Laufer said:
>
>> Where is this reference manual ??
>
> libgcrypt-1.1.9/doc/gcrypt.info
>
> Be warned, a lot of stuff is missing.  Do you want to volunteer?

Not volunteering, but offering a starting point -- at least a possible
starting point, I find writing API documentation using gdoc is nice.
Just C-x 4 h on a function (using gnome-doc.el, from e.g. the
gnome-libs-data Debian package), write documentation, and it is
automatically generated into texinfo which can be included in the main
manual.  No need to synch separate manual with the code.

I started moving some documentation from doc/gcrypt.texi into
cipher/cipher.c but soon got bored...  I'm not sure how to do the
#define macros too.  Ideally they should be converted into @deftypefn
Macro: or something like that.  Perhaps someone like to pick up.

If someone has ideas on or pointers to a more robust tools for this
approach, I'd appreciate it.  I haven't seen anything like this for
texinfo (I added texinfo support to gdoc for another project).

Index: configure.ac
===================================================================
RCS file: /cvs/gnupg/libgcrypt/configure.ac,v
retrieving revision 1.19
diff -u -p -r1.19 configure.ac
--- configure.ac	23 Aug 2002 20:05:18 -0000	1.19
+++ configure.ac	10 Sep 2002 02:51:57 -0000
@@ -175,6 +175,7 @@ AM_MISSING_PROG(AUTOCONF, autoconf, $mis
 AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
 AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
 dnl AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AM_MISSING_PROG(PERL, perl, $missing_dir)
 AC_PROG_CC
 AC_PROG_CPP
 AM_PROG_AS
Index: cipher/cipher.c
===================================================================
RCS file: /cvs/gnupg/libgcrypt/cipher/cipher.c,v
retrieving revision 1.46
diff -u -p -r1.46 cipher.c
--- cipher/cipher.c	17 Aug 2002 09:15:54 -0000	1.46
+++ cipher/cipher.c	10 Sep 2002 02:51:57 -0000
@@ -490,13 +490,17 @@ cipher_get_blocksize( int algo )
     return 0;
 }
 
-
-/****************
- * Open a cipher handle for use with algorithm ALGO, in mode MODE
- * and return the handle.  Return NULL and set the internal error variable
- * if something goes wrong.
- */
-
+/**
+ * gcry_cipher_open:
+ * @algo: Algorithm number, e.g. %GCRY_CIPHER_AES.
+ * @mode: Mode of operation, e.g. %GCRY_CIPHER_MODE_CBC.
+ * @flags: Flags, including %GCRY_CIPHER_SECURE and %GCRY_CIPHER_ENABLE_SYNC.
+ * 
+ * This function creates the context required for most of the othercipher
+ * functions.  
+ * 
+ * Return value: In case of an error @code{NULL} is returned.
+ **/
 GCRY_CIPHER_HD
 gcry_cipher_open( int algo, int mode, unsigned int flags )
 {
@@ -580,6 +584,12 @@ gcry_cipher_open( int algo, int mode, un
 }
 
 
+/**
+ * gcry_cipher_close:
+ * @h: Handle from gcry_cipher_open().
+ * 
+ * This function releases the context created by @code{gcry_cipher_open}.
+ **/
 void
 gcry_cipher_close( GCRY_CIPHER_HD h )
 {
@@ -953,6 +963,13 @@ cipher_sync( GCRY_CIPHER_HD c )
 }
 
 
+/**
+ * gcry_cipher_ctl:
+ * 
+ * gcry_cipher_ctl() controls various aspects of the cipher module and
+ * specific cipher contexts.  Usually some more specialzed functions are
+ * used for this purpose.
+ **/
 int
 gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen)
 {
Index: doc/Makefile.am
===================================================================
RCS file: /cvs/gnupg/libgcrypt/doc/Makefile.am,v
retrieving revision 1.21
diff -u -p -r1.21 Makefile.am
--- doc/Makefile.am	14 May 2002 13:11:06 -0000	1.21
+++ doc/Makefile.am	10 Sep 2002 02:51:57 -0000
@@ -22,3 +22,7 @@ DISTCLEANFILES = gcrypt.cps
 info_TEXINFOS = gcrypt.texi
 gcrypt_TEXINFOS = lgpl.texi gpl.texi fdl.texi
 
+gcrypt.info: gcrypt.texi cipher-ref.texi
+
+cipher-ref.texi: $(top_srcdir)/cipher/cipher.c
+	$(PERL) gdoc -texinfo $(top_srcdir)/cipher/cipher.c > $@
Index: doc/gcrypt.texi
===================================================================
RCS file: /cvs/gnupg/libgcrypt/doc/gcrypt.texi,v
retrieving revision 1.3
diff -u -p -r1.3 gcrypt.texi
--- doc/gcrypt.texi	14 Aug 2002 19:07:55 -0000	1.3
+++ doc/gcrypt.texi	10 Sep 2002 02:51:57 -0000
@@ -272,29 +272,10 @@ gcc -o foo foo.c `libgcrypt-config --cfl
 @c **********************************************************
 @c *******************  Ciphers  ****************************
 @c **********************************************************
-@c @include cipher-ref.texi
 @node Cipher Functions
 @chapter Cipher Functions
 
-
-@deftypefun GCRY_CIPHER_HD gcry_cipher_open (int @var{algo}, int @var{mode}, unsigned int @var{flags})
-
-This function creates the context required for most of the othercipher
-functions.  In case of an error @code{NULL} is returned.
-@end deftypefun
-
-@deftypefun void gcry_cipher_close (GCRY_CIPHER_HD @var{h})
-
-This function releases the context created by @code{gcry_cipher_open}.
-@end deftypefun
-
-
-@deftypefun int gcry_cipher_ctl (GCRY_CIPHER_HD @var{h}, int @var{cmd}, void *@var{buffer}, size_t @var{buflen})
-
-@code{gcry_cipher_ctl} controls various aspects of the cipher module and
-specific cipher contexts.  Usually some more specialzed functions are
-used for this purpose.
-@end deftypefun
+@include cipher-ref.texi
 
 @deftypefun int gcry_cipher_setkey (GCRY_CIPHER_HD @var{h}, void *@var{k}, size_t @var{l})
 

--=-=-=
Content-Type: application/x-perl
Content-Disposition: attachment; filename=gdoc
Content-Transfer-Encoding: base64
Content-Description: gnome-doc

IyEvdXNyL2Jpbi9wZXJsCgojIyBDb3B5cmlnaHQgKGMpIDE5OTggTWljaGFlbCBadWNjaGksIEFs
bCBSaWdodHMgUmVzZXJ2ZWQgICAgICAgICMjCiMjICAgICAgICAgICAgICAgICAgICBoYWNrZWQg
dG8gYWxsb3cgLXRleCBvcHRpb24gLS1ubWF2ICAgICAgICAgIyMKIyMgICAgICAgICAgICAgICAg
ICAgIGhhY2tlZCB0byBhbGxvdyAtdGV4aW5mbyBvcHRpb24gLS1qYXMgICAgICAjIwojIyAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICMjCiMjIFRoaXMgc29mdHdhcmUgZmFsbHMgdW5kZXIgdGhlIEdOVSBQdWJsaWMgTGljZW5zZS4g
UGxlYXNlIHJlYWQgIyMKIyMgICAgICAgICAgICAgIHRoZSBDT1BZSU5HIGZpbGUgZm9yIG1vcmUg
aW5mb3JtYXRpb24gICAgICAgICAgICAjIwoKIwojIFRoaXMgd2lsbCByZWFkIGEgJ2MnIGZpbGUg
YW5kIHNjYW4gZm9yIGVtYmVkZGVkIGNvbW1lbnRzIGluIHRoZQojIHN0eWxlIG9mIGdub21lIGNv
bW1lbnRzICgrbWlub3IgZXh0ZW5zaW9ucyAtIHNlZSBiZWxvdykuCiMKIyBUaGlzIHByb2dyYW0g
aXMgbW9kaWZpZWQgYnkgTmlrb3MgTWF2cm95YW5vcG91bG9zLCBmb3IgdGhlIGdudXRscwojIHBy
b2plY3QuCgojIE5vdGU6IFRoaXMgb25seSBzdXBwb3J0cyAnYycuCgojIHVzYWdlOgojIGdkb2Mg
WyAtZG9jYm9vayB8IC1odG1sIHwgLXRleHQgfCAtbWFuIHwgLXRleCB8IC10ZXhpbmZvIF0KIyAg
ICAgIFsgLWZ1bmN0aW9uIGZ1bmNuYW1lIFsgLWZ1bmN0aW9uIGZ1bmNuYW1lIC4uLl0gXSBjIGZp
bGUocylzID4gb3V0cHV0ZmlsZQojCiMgIFNldCBvdXRwdXQgZm9ybWF0IHVzaW5nIG9uZSBvZiAt
ZG9jYm9vayAtaHRtbCAtdGV4dCBvciAtbWFuLiAgRGVmYXVsdCBpcyBtYW4uCiMKIyAgLWZ1bmN0
aW9uIGZ1bmNuYW1lCiMJSWYgc2V0LCB0aGVuIG9ubHkgZ2VuZXJhdGUgZG9jdW1lbnRhdGlvbiBm
b3IgdGhlIGdpdmVuIGZ1bmN0aW9uKHMpLiAgQWxsCiMJb3RoZXIgZnVuY3Rpb25zIGFyZSBpZ25v
cmVkLgojCiMgIGMgZmlsZXMgLSBsaXN0IG9mICdjJyBmaWxlcyB0byBwcm9jZXNzCiMKIyAgQWxs
IG91dHB1dCBnb2VzIHRvIHN0ZG91dCwgd2l0aCBlcnJvcnMgdG8gc3RkZXJyLgoKIwojIGZvcm1h
dCBvZiBjb21tZW50cy4KIyBJbiB0aGUgZm9sbG93aW5nIHRhYmxlLCAoLi4uKT8gc2lnbmlmaWVz
IG9wdGlvbmFsIHN0cnVjdHVyZS4KIyAgICAgICAgICAgICAgICAgICAgICAgICAoLi4uKSogc2ln
bmlmaWVzIDAgb3IgbW9yZSBzdHJ1Y3R1cmUgZWxlbWVudHMKIyAvKioKIyAgKiBmdW5jdGlvbl9u
YW1lKDopPyAoLSBzaG9ydCBkZXNjcmlwdGlvbik/CiMgKCogQHBhcmFtZXRlcng6IChkZXNjcmlw
dGlvbiBvZiBwYXJhbWV0ZXIgeCk/KSoKIyAoKiBhIGJsYW5rIGxpbmUpPwojICAqIChEZXNjcmlw
dGlvbjopPyAoRGVzY3JpcHRpb24gb2YgZnVuY3Rpb24pPwojICAqIChzZWN0aW9uIGhlYWRlcjog
KHNlY3Rpb24gZGVzY3JpcHRpb24pPyApKgojICAoKik/Ki8KIwojIFNvIC4uIHRoZSB0cml2aWFs
IGV4YW1wbGUgd291bGQgYmU6CiMKIyAvKioKIyAgKiBteV9mdW5jdGlvbgojICAqKi8KIwojIElm
IHRoZSBEZXNjcmlwdGlvbjogaGVhZGVyIHRhZyBpcyBvbW1pdHRlZCwgdGhlbiB0aGVyZSBtdXN0
IGJlIGEgYmxhbmsgbGluZQojIGFmdGVyIHRoZSBsYXN0IHBhcmFtZXRlciBzcGVjaWZpY2F0aW9u
LgojIGUuZy4KIyAvKioKIyAgKiBteV9mdW5jdGlvbiAtIGRvZXMgbXkgc3R1ZmYKIyAgKiBAbXlf
YXJnOiBpdHMgbWluZSBkYW1uaXQKIyAgKgojICAqIERvZXMgbXkgc3R1ZmYgZXhwbGFpbmVkLiAK
IyAgKi8KIwojICBvciwgY291bGQgYWxzbyB1c2U6CiMgLyoqCiMgICogbXlfZnVuY3Rpb24gLSBk
b2VzIG15IHN0dWZmCiMgICogQG15X2FyZzogaXRzIG1pbmUgZGFtbml0CiMgICogRGVzY3JpcHRp
b246IERvZXMgbXkgc3R1ZmYgZXhwbGFpbmVkLiAKIyAgKi8KIyBldGMuCiMKIyBBbGwgZGVzY3Jp
cHRpb25zIGNhbiBiZSBtdWx0aWxpbmUsIGFwYXJ0IGZyb20gdGhlIHNob3J0IGZ1bmN0aW9uIGRl
c2NyaXB0aW9uLgojCiMgQWxsIGRlc2NyaXB0aXZlIHRleHQgaXMgZnVydGhlciBwcm9jZXNzZWQs
IHNjYW5uaW5nIGZvciB0aGUgZm9sbG93aW5nIHNwZWNpYWwKIyBwYXR0ZXJucywgd2hpY2ggYXJl
IGhpZ2hsaWdodGVkIGFwcHJvcHJpYXRlbHkuCiMKIyAnZnVuY25hbWUoKScgLSBmdW5jdGlvbgoj
ICckRU5WVkFSJyAtIGVudmlyb25tZW50YWwgdmFyaWFibGUKIyAnJnN0cnVjdF9uYW1lJyAtIG5h
bWUgb2YgYSBzdHJ1Y3R1cmUKIyAnQHBhcmFtZXRlcicgLSBuYW1lIG9mIGEgcGFyYW1ldGVyCiMg
JyVDT05TVCcgLSBuYW1lIG9mIGEgY29uc3RhbnQuCgojCiMgRXh0ZW5zaW9ucyBmb3IgTGFUZVg6
CiMKIyAxLiB0aGUgc3ltYm9sICctPicgd2lsbCBiZSByZXBsYWNlZCB3aXRoIGEgcmlnaHRhcnJv
dwojIDIuIHheeSB3aXRoICR7eH1ee3l9JC4KIyAzLiB4eHhcOiB3aXRoIHh4eDoKCgojIG1hdGNo
IGV4cHJlc3Npb25zIHVzZWQgdG8gZmluZCBlbWJlZGRlZCB0eXBlIGluZm9ybWF0aW9uCiR0eXBl
X2NvbnN0YW50ID0gIlxcXCUoXFx3KykiOwojJHR5cGVfZnVuYyA9ICIoXFx3K1xcKFxcKSkiOwok
dHlwZV9mdW5jID0gIihcXCh3fHxcXFxcKStcXChcXCkpIjsKJHR5cGVfcGFyYW0gPSAiXFxcQChc
XHcrKSI7CiR0eXBlX3N0cnVjdCA9ICJcXFwmKFxcdyspIjsKJHR5cGVfZW52ID0gIihcXFwkXFx3
KykiOwoKCiMgT3V0cHV0IGNvbnZlcnNpb24gc3Vic3RpdHV0aW9ucy4KIyAgT25lIGZvciBlYWNo
IG91dHB1dCBmb3JtYXQKCiMgdGhlc2Ugd29yayBmYWlybHkgd2VsbAolaGlnaGxpZ2h0c19odG1s
ID0gKCAkdHlwZV9jb25zdGFudCwgIjxpPlwkMTwvaT4iLAoJCSAgICAgJHR5cGVfZnVuYywgIjxi
PlwkMTwvYj4iLAoJCSAgICAgJHR5cGVfc3RydWN0LCAiPGk+XCQxPC9pPiIsCgkJICAgICAkdHlw
ZV9wYXJhbSwgIjx0dD48Yj5cJDE8L2I+PC90dD4iICk7CiRibGFua2xpbmVfaHRtbCA9ICI8cD4i
OwoKJWhpZ2hsaWdodHNfdGV4aW5mbyA9ICggJHR5cGVfY29uc3RhbnQsICJAdmFye1wkMX0iLAoJ
CQkkdHlwZV9mdW5jLCAiQGNvZGV7XCQxfSIsCgkJCSR0eXBlX3N0cnVjdCwgIkBjb2Rle1wkMX0i
LAoJCQkkdHlwZV9wYXJhbSwgIkBjb2Rle1wkMX0iICk7CiRibGFua2xpbmVfdGV4aW5mbyA9ICIi
OwoKJWhpZ2hsaWdodHNfdGV4ID0gKCAkdHlwZV9jb25zdGFudCwgIntcXFxcaXQgXCQxfSIsCgkJ
ICAgICAkdHlwZV9mdW5jLCAie1xcXFxiZiBcJDF9IiwKCQkgICAgICR0eXBlX3N0cnVjdCwgIntc
XFxcaXQgXCQxfSIsCgkJICAgICAkdHlwZV9wYXJhbSwgIntcXFxcYmYgXCQxfSIgKTsKJGJsYW5r
bGluZV90ZXggPSAiXFxwYXIiOwoKIyBzZ21sLCBkb2Nib29rIGZvcm1hdAolaGlnaGxpZ2h0c19z
Z21sID0gKCAkdHlwZV9jb25zdGFudCwgIjxyZXBsYWNlYWJsZSBjbGFzcz1cIm9wdGlvblwiPlwk
MTwvcmVwbGFjZWFibGU+IiwKCQkgICAgICR0eXBlX2Z1bmMsICI8ZnVuY3Rpb24+XCQxPC9mdW5j
dGlvbj4iLAoJCSAgICAgJHR5cGVfc3RydWN0LCAiPHN0cnVjdG5hbWU+XCQxPC9zdHJ1Y3RuYW1l
PiIsCgkJICAgICAkdHlwZV9lbnYsICI8ZW52YXI+XCQxPC9lbnZhcj4iLAoJCSAgICAgJHR5cGVf
cGFyYW0sICI8cGFyYW1ldGVyPlwkMTwvcGFyYW1ldGVyPiIgKTsKJGJsYW5rbGluZV9zZ21sID0g
IjwvcGFyYT48cGFyYT5cbiI7CgojIHRoZXNlIGFyZSBwcmV0dHkgcm91Z2gKJWhpZ2hsaWdodHNf
bWFuID0gKCAkdHlwZV9jb25zdGFudCwgIlxcbi5JIFxcXCJcJDFcXFwiXFxuIiwKCQkgICAgJHR5
cGVfZnVuYywgIlxcbi5CIFxcXCJcJDFcXFwiXFxuIiwKCQkgICAgJHR5cGVfc3RydWN0LCAiXFxu
LkkgXFxcIlwkMVxcXCJcXG4iLAoJCSAgICAkdHlwZV9wYXJhbS4iKFtcLlwsIF0qKVxuPyIsICJc
XG4uSSBcXFwiXCQxXCQyXFxcIlxcbiIgKTsKJGJsYW5rbGluZV9tYW4gPSAiIjsKCiMgdGV4dC1t
b2RlCiVoaWdobGlnaHRzX3RleHQgPSAoICR0eXBlX2NvbnN0YW50LCAiXCQxIiwKCQkgICAgICR0
eXBlX2Z1bmMsICJcJDEiLAoJCSAgICAgJHR5cGVfc3RydWN0LCAiXCQxIiwKCQkgICAgICR0eXBl
X3BhcmFtLCAiXCQxIiApOwokYmxhbmtsaW5lX3RleHQgPSAiIjsKCgpzdWIgdXNhZ2UgewogICAg
cHJpbnQgIlVzYWdlOiAkMCBbIC12IF0gWyAtZG9jYm9vayB8IC1odG1sIHwgLXRleHQgfCAtbWFu
IHwgLXRleCB8IC10ZXhpbmZvIF1cbiI7CiAgICBwcmludCAiICAgICAgICAgWyAtZnVuY3Rpb24g
ZnVuY25hbWUgWyAtZnVuY3Rpb24gZnVuY25hbWUgLi4uXSBdXG4iOwogICAgcHJpbnQgIiAgICAg
ICAgIGMgc291cmNlIGZpbGUocykgPiBvdXRwdXRmaWxlXG4iOwogICAgZXhpdCAxOwp9CgojIHJl
YWQgYXJndW1lbnRzCmlmICgkI0FSR1Y9PS0xKSB7CiAgICB1c2FnZSgpOwp9CgokdmVyYm9zZSA9
IDA7CiRvdXRwdXRfbW9kZSA9ICJtYW4iOwolaGlnaGxpZ2h0cyA9ICVoaWdobGlnaHRzX21hbjsK
JGJsYW5rbGluZSA9ICRibGFua2xpbmVfbWFuOwokbW9kdWxlbmFtZSA9ICJBUEkgRG9jdW1lbnRh
dGlvbiI7CiRmdW5jdGlvbl9vbmx5ID0gMDsKd2hpbGUgKCRBUkdWWzBdID1+IG0vXi0oLiopLykg
ewogICAgJGNtZCA9IHNoaWZ0IEBBUkdWOwogICAgaWYgKCRjbWQgZXEgIi1odG1sIikgewoJJG91
dHB1dF9tb2RlID0gImh0bWwiOwoJJWhpZ2hsaWdodHMgPSAlaGlnaGxpZ2h0c19odG1sOwoJJGJs
YW5rbGluZSA9ICRibGFua2xpbmVfaHRtbDsKICAgIH0gZWxzaWYgKCRjbWQgZXEgIi1tYW4iKSB7
Cgkkb3V0cHV0X21vZGUgPSAibWFuIjsKCSVoaWdobGlnaHRzID0gJWhpZ2hsaWdodHNfbWFuOwoJ
JGJsYW5rbGluZSA9ICRibGFua2xpbmVfbWFuOwogICAgfSBlbHNpZiAoJGNtZCBlcSAiLXRleCIp
IHsKCSRvdXRwdXRfbW9kZSA9ICJ0ZXgiOwoJJWhpZ2hsaWdodHMgPSAlaGlnaGxpZ2h0c190ZXg7
CgkkYmxhbmtsaW5lID0gJGJsYW5rbGluZV90ZXg7CiAgICB9IGVsc2lmICgkY21kIGVxICItdGV4
aW5mbyIpIHsKCSRvdXRwdXRfbW9kZSA9ICJ0ZXhpbmZvIjsKCSVoaWdobGlnaHRzID0gJWhpZ2hs
aWdodHNfdGV4aW5mbzsKCSRibGFua2xpbmUgPSAkYmxhbmtsaW5lX3RleGluZm87CiAgICB9IGVs
c2lmICgkY21kIGVxICItdGV4dCIpIHsKCSRvdXRwdXRfbW9kZSA9ICJ0ZXh0IjsKCSVoaWdobGln
aHRzID0gJWhpZ2hsaWdodHNfdGV4dDsKCSRibGFua2xpbmUgPSAkYmxhbmtsaW5lX3RleHQ7CiAg
ICB9IGVsc2lmICgkY21kIGVxICItZG9jYm9vayIpIHsKCSRvdXRwdXRfbW9kZSA9ICJzZ21sIjsK
CSVoaWdobGlnaHRzID0gJWhpZ2hsaWdodHNfc2dtbDsKCSRibGFua2xpbmUgPSAkYmxhbmtsaW5l
X3NnbWw7CiAgICB9IGVsc2lmICgkY21kIGVxICItbW9kdWxlIikgeyAjIG5vdCBuZWVkZWQgZm9y
IHNnbWwsIGluaGVyaXRzIGZyb20gY2FsbGluZyBkb2N1bWVudAoJJG1vZHVsZW5hbWUgPSBzaGlm
dCBAQVJHVjsKICAgIH0gZWxzaWYgKCRjbWQgZXEgIi1mdW5jdGlvbiIpIHsgIyB0byBvbmx5IG91
dHB1dCBzcGVjaWZpYyBmdW5jdGlvbnMKCSRmdW5jdGlvbl9vbmx5ID0gMTsKCSRmdW5jdGlvbiA9
IHNoaWZ0IEBBUkdWOwoJJGZ1bmN0aW9uX3RhYmxleyRmdW5jdGlvbn0gPSAxOwogICAgfSBlbHNp
ZiAoJGNtZCBlcSAiLXYiKSB7CgkkdmVyYm9zZSA9IDE7CiAgICB9IGVsc2lmICgoJGNtZCBlcSAi
LWgiKSB8fCAoJGNtZCBlcSAiLS1oZWxwIikpIHsKCXVzYWdlKCk7CiAgICB9Cn0KCgojIGdlbmVy
YXRlIGEgc2VxdWVuY2Ugb2YgY29kZSB0aGF0IHdpbGwgc3BsaWNlIGluIGhpZ2hsaWdodGluZyBp
bmZvcm1hdGlvbgojIHVzaW5nIHRoZSBzLy8gb3BlcmF0b3IuCiRkb2hpZ2hsaWdodCA9ICIiOwpm
b3JlYWNoICRwYXR0ZXJuIChrZXlzICVoaWdobGlnaHRzKSB7CiMgICAgcHJpbnQgInNjYW5uaW5n
IHBhdHRlcm4gJHBhdHRlcm4gKCRoaWdobGlnaHRzeyRwYXR0ZXJufSlcbiI7CiAgICAkZG9oaWdo
bGlnaHQgLj0gICJcJGNvbnRlbnRzID1+IHM6JHBhdHRlcm46JGhpZ2hsaWdodHN7JHBhdHRlcm59
OmdzO1xuIjsKfQoKIyMKIyBkdW1wcyBzZWN0aW9uIGNvbnRlbnRzIHRvIGFycmF5cy9oYXNoZXMg
aW50ZW5kZWQgZm9yIHRoYXQgcHVycG9zZS4KIwpzdWIgZHVtcF9zZWN0aW9uIHsKICAgIG15ICRu
YW1lID0gc2hpZnQgQF87CiAgICBteSAkY29udGVudHMgPSBqb2luICJcbiIsIEBfOwoKICAgIGlm
ICgkbmFtZSA9fiBtLyR0eXBlX2NvbnN0YW50LykgewoJJG5hbWUgPSAkMTsKIwlwcmludCBTVERF
UlIgImNvbnN0YW50IHNlY3Rpb24gJyQxJyA9ICckY29udGVudHMnXG4iOwoJJGNvbnN0YW50c3sk
bmFtZX0gPSAkY29udGVudHM7CiAgICB9IGVsc2lmICgkbmFtZSA9fiBtLyR0eXBlX3BhcmFtLykg
ewojCXByaW50IFNUREVSUiAicGFyYW1ldGVyIGRlZiAnJDEnID0gJyRjb250ZW50cydcbiI7Cgkk
bmFtZSA9ICQxOwoJJHBhcmFtZXRlcnN7JG5hbWV9ID0gJGNvbnRlbnRzOwogICAgfSBlbHNlIHsK
IwlwcmludCBTVERFUlIgIm90aGVyIHNlY3Rpb24gJyRuYW1lJyA9ICckY29udGVudHMnXG4iOwoJ
JHNlY3Rpb25zeyRuYW1lfSA9ICRjb250ZW50czsKCXB1c2ggQHNlY3Rpb25saXN0LCAkbmFtZTsK
ICAgIH0KfQoKIyMKIyBvdXRwdXQgZnVuY3Rpb24KIwojIHBhcmFtZXRlcnMsIGEgaGFzaC4KIyAg
ZnVuY3Rpb24gPT4gImZ1bmN0aW9uIG5hbWUiCiMgIHBhcmFtZXRlcmxpc3QgPT4gQGxpc3Qgb2Yg
cGFyYW1ldGVycwojICBwYXJhbWV0ZXJzID0+ICVwYXJhbWV0ZXIgZGVzY3JpcHRpb25zCiMgIHNl
Y3Rpb25saXN0ID0+IEBsaXN0IG9mIHNlY3Rpb25zCiMgIHNlY3Rpb25zID0+ICVkZXNjcmlvbnQg
ZGVzY3JpcHRpb25zCiMgIAoKc3ViIG91dHB1dF9oaWdobGlnaHQgewogICAgbXkgJGNvbnRlbnRz
ID0gam9pbiAiXG4iLCBAXzsKICAgIG15ICRsaW5lOwoKICAgIGV2YWwgJGRvaGlnaGxpZ2h0Owog
ICAgZm9yZWFjaCAkbGluZSAoc3BsaXQgIlxuIiwgJGNvbnRlbnRzKSB7CglpZiAoJGxpbmUgZXEg
IiIpewoJICAgIHByaW50ICRsaW5lcHJlZml4LCAkYmxhbmtsaW5lOwoJfSBlbHNlIHsKCSAgICBw
cmludCAkbGluZXByZWZpeCwgJGxpbmU7Cgl9CglwcmludCAiXG4iOwogICAgfQp9CgojIG91dHB1
dCBpbiB0ZXhpbmZvCnN1YiBvdXRwdXRfdGV4aW5mbyB7CiAgICBteSAlYXJncyA9ICV7JF9bMF19
OwogICAgbXkgKCRwYXJhbWV0ZXIsICRzZWN0aW9uKTsKICAgIG15ICRjb3VudDsKICAgIHByaW50
ICJcblxuIjsKCiAgICBwcmludCAiXEBkZWZ0eXBlZnVuICI7CgogICAgcHJpbnQgJGFyZ3N7J2Z1
bmN0aW9udHlwZSd9OwogICAgcHJpbnQgIlxAY29kZXsiLiRhcmdzeydmdW5jdGlvbid9LiJ9ICI7
CiAgICBwcmludCAiKCI7CiAgICAkY291bnQgPSAwOwogICAgZm9yZWFjaCAkcGFyYW1ldGVyIChA
eyRhcmdzeydwYXJhbWV0ZXJsaXN0J319KSB7CglwcmludCAkYXJnc3sncGFyYW1ldGVydHlwZXMn
fXskcGFyYW1ldGVyfS4iIFxAdmFyeyIuJHBhcmFtZXRlci4ifSI7CglpZiAoJGNvdW50ICE9ICQj
eyRhcmdzeydwYXJhbWV0ZXJsaXN0J319KSB7CgkgICAgJGNvdW50Kys7CgkgICAgcHJpbnQgIiwg
IjsKCX0KICAgIH0KICAgIHByaW50ICIpXG4iOwogICAgZm9yZWFjaCAkcGFyYW1ldGVyIChAeyRh
cmdzeydwYXJhbWV0ZXJsaXN0J319KSB7CglpZiAoJGFyZ3N7J3BhcmFtZXRlcnMnfXskcGFyYW1l
dGVyfSkgewoJICAgIHByaW50ICJcQHZhcnsiLiRwYXJhbWV0ZXIuIn06ICI7CgkgICAgb3V0cHV0
X2hpZ2hsaWdodCgkYXJnc3sncGFyYW1ldGVycyd9eyRwYXJhbWV0ZXJ9KTsKCSAgICBwcmludCAi
XG4iOwoJfQogICAgfQogICAgZm9yZWFjaCAkc2VjdGlvbiAoQHskYXJnc3snc2VjdGlvbmxpc3Qn
fX0pIHsKCW91dHB1dF9oaWdobGlnaHQoJGFyZ3N7J3NlY3Rpb25zJ317JHNlY3Rpb259KTsKICAg
IH0KICAgIHByaW50ICJcQGVuZCBkZWZ0eXBlZnVuXG4iOwp9CgojIG91dHB1dCBpbiBodG1sCnN1
YiBvdXRwdXRfaHRtbCB7CiAgICBteSAlYXJncyA9ICV7JF9bMF19OwogICAgbXkgKCRwYXJhbWV0
ZXIsICRzZWN0aW9uKTsKICAgIG15ICRjb3VudDsKICAgIHByaW50ICJcblxuPGEgbmFtZT1cIiIu
ICRhcmdzeydmdW5jdGlvbid9IC4gIlwiPiZuYnNwPC9hPjxoMj5GdW5jdGlvbjwvaDI+XG4iOwoK
ICAgIHByaW50ICI8aT4iLiRhcmdzeydmdW5jdGlvbnR5cGUnfS4iPC9pPlxuIjsKICAgIHByaW50
ICI8Yj4iLiRhcmdzeydmdW5jdGlvbid9LiI8L2I+XG4iOwogICAgcHJpbnQgIigiOwogICAgJGNv
dW50ID0gMDsKICAgIGZvcmVhY2ggJHBhcmFtZXRlciAoQHskYXJnc3sncGFyYW1ldGVybGlzdCd9
fSkgewoJcHJpbnQgIjxpPiIuJGFyZ3N7J3BhcmFtZXRlcnR5cGVzJ317JHBhcmFtZXRlcn0uIjwv
aT4gPGI+Ii4kcGFyYW1ldGVyLiI8L2I+XG4iOwoJaWYgKCRjb3VudCAhPSAkI3skYXJnc3sncGFy
YW1ldGVybGlzdCd9fSkgewoJICAgICRjb3VudCsrOwoJICAgIHByaW50ICIsICI7Cgl9CiAgICB9
CiAgICBwcmludCAiKVxuIjsKCiAgICBwcmludCAiPGgzPkFyZ3VtZW50czwvaDM+XG4iOwogICAg
cHJpbnQgIjxkbD5cbiI7CiAgICBmb3JlYWNoICRwYXJhbWV0ZXIgKEB7JGFyZ3N7J3BhcmFtZXRl
cmxpc3QnfX0pIHsKCXByaW50ICI8ZHQ+PGk+Ii4kYXJnc3sncGFyYW1ldGVydHlwZXMnfXskcGFy
YW1ldGVyfS4iPC9pPiA8Yj4iLiRwYXJhbWV0ZXIuIjwvYj5cbiI7CglwcmludCAiPGRkPiI7Cglv
dXRwdXRfaGlnaGxpZ2h0KCRhcmdzeydwYXJhbWV0ZXJzJ317JHBhcmFtZXRlcn0pOwogICAgfQog
ICAgcHJpbnQgIjwvZGw+XG4iOwogICAgZm9yZWFjaCAkc2VjdGlvbiAoQHskYXJnc3snc2VjdGlv
bmxpc3QnfX0pIHsKCXByaW50ICI8aDM+JHNlY3Rpb248L2gzPlxuIjsKCXByaW50ICI8dWw+XG4i
OwoJb3V0cHV0X2hpZ2hsaWdodCgkYXJnc3snc2VjdGlvbnMnfXskc2VjdGlvbn0pOwoJcHJpbnQg
IjwvdWw+XG4iOwogICAgfQogICAgcHJpbnQgIjxocj5cbiI7Cn0KCiMgb3V0cHV0IGluIHRleApz
dWIgb3V0cHV0X3RleCB7CiAgICBteSAlYXJncyA9ICV7JF9bMF19OwogICAgbXkgKCRwYXJhbWV0
ZXIsICRzZWN0aW9uKTsKICAgIG15ICRjb3VudDsKICAgIG15ICRmdW5jID0gJGFyZ3N7J2Z1bmN0
aW9uJ307CiAgICBteSAkcGFyYW07CiAgICBteSAkcGFyYW0yOwogICAgbXkgJHNlYzsKICAgIG15
ICRjaGVjazsKICAgIG15ICR0eXBlOwoKICAgICRmdW5jID1+IHMvXy9cXF8vZzsKCiAgICBwcmlu
dCAiXG5cblxcc3Vic2VjdGlvbnsiLiAkZnVuYyAuICJ9XG5cXGxhYmVseyIgLiAkYXJnc3snZnVu
Y3Rpb24nfSAuICJ9XG4iOwoKICAgICR0eXBlID0gJGFyZ3N7J2Z1bmN0aW9udHlwZSd9OwogICAg
JHR5cGUgPX4gcy9fL1xcXy9nOwoKICAgIHByaW50ICJ7XFxpdCAiLiR0eXBlLiJ9XG4iOwogICAg
cHJpbnQgIntcXGJmICIuJGZ1bmMuIn1cbiI7CiAgICBwcmludCAiKFxuIjsKICAgICRjb3VudCA9
IDA7CiAgICBmb3JlYWNoICRwYXJhbWV0ZXIgKEB7JGFyZ3N7J3BhcmFtZXRlcmxpc3QnfX0pIHsK
ICAgICAgICAkcGFyYW0gPSAkYXJnc3sncGFyYW1ldGVydHlwZXMnfXskcGFyYW1ldGVyfTsKICAg
ICAgICAkcGFyYW0yID0gJHBhcmFtZXRlcjsKCSRwYXJhbSA9fiBzL18vXFxfL2c7CiAgICAgICAg
JHBhcmFtMiA9fiBzL18vXFxfL2c7CgoJcHJpbnQgIntcXGl0ICIuJHBhcmFtLiJ9IHtcXGJmICIu
JHBhcmFtMi4ifVxuIjsKCWlmICgkY291bnQgIT0gJCN7JGFyZ3N7J3BhcmFtZXRlcmxpc3QnfX0p
IHsKCSAgICAkY291bnQrKzsKCSAgICBwcmludCAiLCAiOwoJfQogICAgfQogICAgcHJpbnQgIilc
biI7CgogICAgcHJpbnQgIlxue1xcbGFyZ2V7QXJndW1lbnRzfX1cbiI7CgogICAgcHJpbnQgIlxc
YmVnaW57aXRlbWl6ZX1cbiI7CiAgICAkY2hlY2s9MDsKICAgIGZvcmVhY2ggJHBhcmFtZXRlciAo
QHskYXJnc3sncGFyYW1ldGVybGlzdCd9fSkgewogICAgICAgICRwYXJhbTEgPSAkYXJnc3sncGFy
YW1ldGVydHlwZXMnfXskcGFyYW1ldGVyfTsKICAgICAgICAkcGFyYW0xID1+IHMvXy9cXF8vZzsK
ICAgICAgICAkcGFyYW0yID0gJHBhcmFtZXRlcjsKCSRwYXJhbTIgPX4gcy9fL1xcXy9nOwoKCSRj
aGVjayA9IDE7CglwcmludCAiXFxpdGVtIHtcXGl0ICIuJHBhcmFtMS4ifSB7XFxiZiAiLiRwYXJh
bTIuIn06IFxuIjsKIwlwcmludCAiXG4iOwoKCSRwYXJhbTMgPSAkYXJnc3sncGFyYW1ldGVycyd9
eyRwYXJhbWV0ZXJ9OwoJJHBhcmFtMyA9fiBzL18vXFxfL2c7CgkkcGFyYW0zID1+IHMvJihbYS16
QS1aXF9dKykve1xcaXQgXDF9L2c7CgoJb3V0cHV0X2hpZ2hsaWdodCgkcGFyYW0zKTsKICAgIH0K
ICAgIGlmICgkY2hlY2s9PTApIHsKCXByaW50ICJcXGl0ZW0gdm9pZFxuIjsKICAgIH0KICAgIHBy
aW50ICJcXGVuZHtpdGVtaXplfVxuIjsKCiAgICBmb3JlYWNoICRzZWN0aW9uIChAeyRhcmdzeydz
ZWN0aW9ubGlzdCd9fSkgewoJJHNlYyA9ICRzZWN0aW9uOwoJJHNlYyA9fiBzL18vXFxfL2c7Cgkk
c2VjID1+IHMvJihbYS16QS1aXF9dKykve1xcaXQgXDF9L2c7CgoJcHJpbnQgIlxuXFxwYXJ7XFxs
YXJnZXskc2VjfX1cXHBhclxuIjsKCXByaW50ICJcXGJlZ2lue3JtZmFtaWx5fVxuIjsKCgkkc2Vj
ID0gJGFyZ3N7J3NlY3Rpb25zJ317JHNlY3Rpb259OwoJJHNlYyA9fiBzL18vXFxfL2c7Cgkkc2Vj
ID1+IHMvXFw6LzovZzsKCSRzZWMgPX4gcy8mKFthLXpBLVpcX10rKS97XFxpdCBcMX0vZzsKCSRz
ZWMgPX4gcy8tPi9cJFxccmlnaHRhcnJvd1wkL2c7Cgkkc2VjID1+IHMvKFswLTldKylcXihbMC05
XSspL1wkXHtcMVx9XF5ce1wyXH1cJC9nOwoKCW91dHB1dF9oaWdobGlnaHQoJHNlYyk7Cglwcmlu
dCAiXFxlbmR7cm1mYW1pbHl9XG4iOwogICAgfQogICAgcHJpbnQgIlxuIjsKfQoKCiMgb3V0cHV0
IGluIHNnbWwgRG9jQm9vawpzdWIgb3V0cHV0X3NnbWwgewogICAgbXkgJWFyZ3MgPSAleyRfWzBd
fTsKICAgIG15ICgkcGFyYW1ldGVyLCAkc2VjdGlvbik7CiAgICBteSAkY291bnQ7CiAgICBteSAk
aWQ7CgogICAgJGlkID0gJGFyZ3N7J21vZHVsZSd9LiItIi4kYXJnc3snZnVuY3Rpb24nfTsKICAg
ICRpZCA9fiBzL1teQS1aYS16MC05XS8tL2c7CgogICAgcHJpbnQgIjxyZWZlbnRyeT5cbiI7CiAg
ICBwcmludCAiPHJlZm1ldGE+XG4iOwogICAgcHJpbnQgIjxyZWZlbnRyeXRpdGxlPjxwaHJhc2Ug
aWQ9XCIkaWRcIj4iLiRhcmdzeydmdW5jdGlvbid9LiI8L3BocmFzZT48L3JlZmVudHJ5dGl0bGU+
XG4iOwogICAgcHJpbnQgIjwvcmVmbWV0YT5cbiI7CiAgICBwcmludCAiPHJlZm5hbWVkaXY+XG4i
OwogICAgcHJpbnQgIiA8cmVmbmFtZT4iLiRhcmdzeydmdW5jdGlvbid9LiI8L3JlZm5hbWU+XG4i
OwogICAgcHJpbnQgIiA8cmVmcHVycG9zZT5cbiI7CiAgICBwcmludCAiICAiLiRhcmdzeydwdXJw
b3NlJ30uIlxuIjsKICAgIHByaW50ICIgPC9yZWZwdXJwb3NlPlxuIjsKICAgIHByaW50ICI8L3Jl
Zm5hbWVkaXY+XG4iOwoKICAgIHByaW50ICI8cmVmc3lub3BzaXNkaXY+XG4iOwogICAgcHJpbnQg
IiA8dGl0bGU+U3lub3BzaXM8L3RpdGxlPlxuIjsKICAgIHByaW50ICIgIDxmdW5jc3lub3BzaXM+
XG4iOwogICAgcHJpbnQgIiAgIDxmdW5jZGVmPiIuJGFyZ3N7J2Z1bmN0aW9udHlwZSd9LiIgIjsK
ICAgIHByaW50ICI8ZnVuY3Rpb24+Ii4kYXJnc3snZnVuY3Rpb24nfS4iICI7CiAgICBwcmludCAi
PC9mdW5jdGlvbj48L2Z1bmNkZWY+XG4iOwoKIyAgICBwcmludCAiPHJlZnNlY3QxPlxuIjsKIyAg
ICBwcmludCAiIDx0aXRsZT5TeW5vcHNpczwvdGl0bGU+XG4iOwojICAgIHByaW50ICIgIDxmdW5j
c3lub3BzaXM+XG4iOwojICAgIHByaW50ICIgICA8ZnVuY2RlZj4iLiRhcmdzeydmdW5jdGlvbnR5
cGUnfS4iICI7CiMgICAgcHJpbnQgIjxmdW5jdGlvbj4iLiRhcmdzeydmdW5jdGlvbid9LiIgIjsK
IyAgICBwcmludCAiPC9mdW5jdGlvbj48L2Z1bmNkZWY+XG4iOwoKICAgICRjb3VudCA9IDA7CiAg
ICBpZiAoJCN7JGFyZ3N7J3BhcmFtZXRlcmxpc3QnfX0gPj0gMCkgewoJZm9yZWFjaCAkcGFyYW1l
dGVyIChAeyRhcmdzeydwYXJhbWV0ZXJsaXN0J319KSB7CgkgICAgcHJpbnQgIiAgIDxwYXJhbWRl
Zj4iLiRhcmdzeydwYXJhbWV0ZXJ0eXBlcyd9eyRwYXJhbWV0ZXJ9OwoJICAgIHByaW50ICIgPHBh
cmFtZXRlcj4kcGFyYW1ldGVyPC9wYXJhbWV0ZXI+PC9wYXJhbWRlZj5cbiI7Cgl9CiAgICB9IGVs
c2UgewoJcHJpbnQgIiAgPHZvaWQ+XG4iOwogICAgfQogICAgcHJpbnQgIiAgPC9mdW5jc3lub3Bz
aXM+XG4iOwogICAgcHJpbnQgIjwvcmVmc3lub3BzaXNkaXY+XG4iOwojICAgIHByaW50ICI8L3Jl
ZnNlY3QxPlxuIjsKCiAgICAjIHByaW50IHBhcmFtZXRlcnMKICAgIHByaW50ICI8cmVmc2VjdDE+
XG4gPHRpdGxlPkFyZ3VtZW50czwvdGl0bGU+XG4iOwojICAgIHByaW50ICI8cGFyYT5cbkFyZ3Vt
ZW50c1xuIjsKICAgIGlmICgkI3skYXJnc3sncGFyYW1ldGVybGlzdCd9fSA+PSAwKSB7Cglwcmlu
dCAiIDx2YXJpYWJsZWxpc3Q+XG4iOwoJZm9yZWFjaCAkcGFyYW1ldGVyIChAeyRhcmdzeydwYXJh
bWV0ZXJsaXN0J319KSB7CgkgICAgcHJpbnQgIiAgPHZhcmxpc3RlbnRyeT5cbiAgIDx0ZXJtPjxw
YXJhbWV0ZXI+JHBhcmFtZXRlcjwvcGFyYW1ldGVyPjwvdGVybT5cbiI7CgkgICAgcHJpbnQgIiAg
IDxsaXN0aXRlbT5cbiAgICA8cGFyYT5cbiI7CgkgICAgJGxpbmVwcmVmaXg9IiAgICAgIjsKCSAg
ICBvdXRwdXRfaGlnaGxpZ2h0KCRhcmdzeydwYXJhbWV0ZXJzJ317JHBhcmFtZXRlcn0pOwoJICAg
IHByaW50ICIgICAgPC9wYXJhPlxuICAgPC9saXN0aXRlbT5cbiAgPC92YXJsaXN0ZW50cnk+XG4i
OwoJfQoJcHJpbnQgIiA8L3ZhcmlhYmxlbGlzdD5cbiI7CiAgICB9IGVsc2UgewoJcHJpbnQgIiA8
cGFyYT5cbiAgTm9uZVxuIDwvcGFyYT5cbiI7CiAgICB9CiAgICBwcmludCAiPC9yZWZzZWN0MT5c
biI7CgogICAgIyBwcmludCBvdXQgZWFjaCBzZWN0aW9uCiAgICAkbGluZXByZWZpeD0iICAgIjsK
ICAgIGZvcmVhY2ggJHNlY3Rpb24gKEB7JGFyZ3N7J3NlY3Rpb25saXN0J319KSB7CglwcmludCAi
PHJlZnNlY3QxPlxuIDx0aXRsZT4kc2VjdGlvbjwvdGl0bGU+XG4gPHBhcmE+XG4iOwojCXByaW50
ICI8cGFyYT5cbiRzZWN0aW9uXG4iOwoJaWYgKCRzZWN0aW9uID1+IG0vRVhBTVBMRS9pKSB7Cgkg
ICAgcHJpbnQgIjxleGFtcGxlPjxwYXJhPlxuIjsKCX0KCW91dHB1dF9oaWdobGlnaHQoJGFyZ3N7
J3NlY3Rpb25zJ317JHNlY3Rpb259KTsKIwlwcmludCAiPC9wYXJhPiI7CglpZiAoJHNlY3Rpb24g
PX4gbS9FWEFNUExFL2kpIHsKCSAgICBwcmludCAiPC9wYXJhPjwvZXhhbXBsZT5cbiI7Cgl9Cglw
cmludCAiIDwvcGFyYT5cbjwvcmVmc2VjdDE+XG4iOwogICAgfQoKICAgIHByaW50ICJcblxuIjsK
fQoKIyMKIyBvdXRwdXQgaW4gbWFuCnN1YiBvdXRwdXRfbWFuIHsKICAgIG15ICVhcmdzID0gJXsk
X1swXX07CiAgICBteSAoJHBhcmFtZXRlciwgJHNlY3Rpb24pOwogICAgbXkgJGNvdW50OwoKICAg
IHByaW50ICIuVEggXCIkYXJnc3snbW9kdWxlJ31cIiBcIiRhcmdzeydmdW5jdGlvbid9XCIgXCIy
NSBNYXkgMTk5OFwiIFwiQVBJIE1hbnVhbFwiIEdOT01FXG4iOwoKICAgIHByaW50ICIuU0ggRnVu
Y3Rpb25cbiI7CgogICAgcHJpbnQgIi5JIFwiIi4kYXJnc3snZnVuY3Rpb250eXBlJ30uIlwiXG4i
OwogICAgcHJpbnQgIi5CIFwiIi4kYXJnc3snZnVuY3Rpb24nfS4iXCJcbiI7CiAgICBwcmludCAi
KFxuIjsKICAgICRjb3VudCA9IDA7CiAgICBmb3JlYWNoICRwYXJhbWV0ZXIgKEB7JGFyZ3N7J3Bh
cmFtZXRlcmxpc3QnfX0pIHsKCXByaW50ICIuSSBcIiIuJGFyZ3N7J3BhcmFtZXRlcnR5cGVzJ317
JHBhcmFtZXRlcn0uIlwiXG4uQiBcIiIuJHBhcmFtZXRlci4iXCJcbiI7CglpZiAoJGNvdW50ICE9
ICQjeyRhcmdzeydwYXJhbWV0ZXJsaXN0J319KSB7CgkgICAgJGNvdW50Kys7CgkgICAgcHJpbnQg
IixcbiI7Cgl9CiAgICB9CiAgICBwcmludCAiKVxuIjsKCiAgICBwcmludCAiLlNIIEFyZ3VtZW50
c1xuIjsKICAgIGZvcmVhY2ggJHBhcmFtZXRlciAoQHskYXJnc3sncGFyYW1ldGVybGlzdCd9fSkg
ewoJcHJpbnQgIi5JUCBcIiIuJGFyZ3N7J3BhcmFtZXRlcnR5cGVzJ317JHBhcmFtZXRlcn0uIiAi
LiRwYXJhbWV0ZXIuIlwiIDEyXG4iOwoJb3V0cHV0X2hpZ2hsaWdodCgkYXJnc3sncGFyYW1ldGVy
cyd9eyRwYXJhbWV0ZXJ9KTsKICAgIH0KICAgIGZvcmVhY2ggJHNlY3Rpb24gKEB7JGFyZ3N7J3Nl
Y3Rpb25saXN0J319KSB7CglwcmludCAiLlNIIFwiJHNlY3Rpb25cIlxuIjsKCW91dHB1dF9oaWdo
bGlnaHQoJGFyZ3N7J3NlY3Rpb25zJ317JHNlY3Rpb259KTsKICAgIH0KfQoKIyMKIyBvdXRwdXQg
aW4gdGV4dApzdWIgb3V0cHV0X3RleHQgewogICAgbXkgJWFyZ3MgPSAleyRfWzBdfTsKICAgIG15
ICgkcGFyYW1ldGVyLCAkc2VjdGlvbik7CgogICAgcHJpbnQgIkZ1bmN0aW9uID0gIi4kYXJnc3sn
ZnVuY3Rpb24nfS4iXG4iOwogICAgcHJpbnQgIiAgcmV0dXJuIHR5cGU6ICIuJGFyZ3N7J2Z1bmN0
aW9udHlwZSd9LiJcblxuIjsKICAgIGZvcmVhY2ggJHBhcmFtZXRlciAoQHskYXJnc3sncGFyYW1l
dGVybGlzdCd9fSkgewoJcHJpbnQgIiAiLiRhcmdzeydwYXJhbWV0ZXJ0eXBlcyd9eyRwYXJhbWV0
ZXJ9LiIgIi4kcGFyYW1ldGVyLiJcbiI7CglwcmludCAiICAgIC0+ICIuJGFyZ3N7J3BhcmFtZXRl
cnMnfXskcGFyYW1ldGVyfS4iXG4iOwogICAgfQogICAgZm9yZWFjaCAkc2VjdGlvbiAoQHskYXJn
c3snc2VjdGlvbmxpc3QnfX0pIHsKCXByaW50ICIgJHNlY3Rpb246XG4iOwoJcHJpbnQgIiAgICAt
PiAiOwoJb3V0cHV0X2hpZ2hsaWdodCgkYXJnc3snc2VjdGlvbnMnfXskc2VjdGlvbn0pOwogICAg
fQp9CgojIwojIGdlbmVyaWMgb3V0cHV0IGZ1bmN0aW9uIC0gY2FsbHMgdGhlIHJpZ2h0IG9uZSBi
YXNlZAojIG9uIGN1cnJlbnQgb3V0cHV0IG1vZGUuCnN1YiBvdXRwdXRfZnVuY3Rpb24gewojICAg
IG91dHB1dF9odG1sKEBfKTsKICAgIGV2YWwgIm91dHB1dF8iLiRvdXRwdXRfbW9kZS4iKFxAXyk7
IjsKfQoKCiMjCiMgdGFrZXMgYSBmdW5jdGlvbiBwcm90b3R5cGUgYW5kIHNwaXRzIG91dCBhbGwg
dGhlIGRldGFpbHMKIyBzdG9yZWQgaW4gdGhlIGdsb2JhbCBhcnJheXMvaHNhaGVzLgpzdWIgZHVt
cF9mdW5jdGlvbiB7CiAgICBteSAkcHJvdG90eXBlID0gc2hpZnQgQF87CgogICAgaWYgKCRwcm90
b3R5cGUgPX4gbS9eKCkoW2EtekEtWjAtOV9+Ol0rKVxzKlwoKFteXCldKilcKS8gfHwKCSRwcm90
b3R5cGUgPX4gbS9eKFx3KylccysoW2EtekEtWjAtOV9+Ol0rKVxzKlwoKFteXCldKilcKS8gfHwK
CSRwcm90b3R5cGUgPX4gbS9eKFx3K1xzKlwqKVxzKihbYS16QS1aMC05X346XSspXHMqXCgoW15c
KV0qKVwpLyB8fAoJJHByb3RvdHlwZSA9fiBtL14oXHcrXHMrXHcrKVxzKyhbYS16QS1aMC05X346
XSspXHMqXCgoW15cKV0qKVwpLyB8fAoJJHByb3RvdHlwZSA9fiBtL14oXHcrXHMrXHcrXHMqXCop
XHMqKFthLXpBLVowLTlffjpdKylccypcKChbXlwpXSopXCkvKSAgewoJJHJldHVybl90eXBlID0g
JDE7CgkkZnVuY3Rpb25fbmFtZSA9ICQyOwoJJGFyZ3MgPSAkMzsKCiMJcHJpbnQgU1RERVJSICJB
UkdTID0gJyRhcmdzJ1xuIjsKCglmb3JlYWNoICRhcmcgKHNwbGl0ICcsJywgJGFyZ3MpIHsKCSAg
ICAjIHN0cmlwIGxlYWRpbmcvdHJhaWxpbmcgc3BhY2VzCgkgICAgJGFyZyA9fiBzL15ccyovLzsK
CSAgICAkYXJnID1+IHMvXHMqJC8vOwojCSAgICBwcmludCBTVERFUlIgIlNDQU4gQVJHOiAnJGFy
ZydcbiI7CgkgICAgQGFyZ3MgPSBzcGxpdCgnXHMnLCAkYXJnKTsKCiMJICAgIHByaW50IFNUREVS
UiAiIC0+IEBhcmdzXG4iOwoJICAgICRwYXJhbSA9IHBvcCBAYXJnczsKIwkgICAgcHJpbnQgU1RE
RVJSICIgLT4gQGFyZ3NcbiI7CgkgICAgaWYgKCRwYXJhbSA9fiBtL14oXCorKSguKikvKSB7CgkJ
JHBhcmFtID0gJDI7CgkJcHVzaCBAYXJncywgJDE7CgkgICAgfQoJICAgICR0eXBlID0gam9pbiAi
ICIsIEBhcmdzOwoKCSAgICBpZiAoJHBhcmFtZXRlcnN7JHBhcmFtfSBlcSAiIiAmJiAkcGFyYW0g
IT0gInZvaWQiKSB7CgkJJHBhcmFtZXRlcnN7JHBhcmFtfSA9ICItLSB1bmRlc2NyaWJlZCAtLSI7
CgkJcHJpbnQgU1RERVJSICJXYXJuaW5nKCRsaW5lbm8pOiBGdW5jdGlvbiBwYXJhbWV0ZXIgJyRw
YXJhbScgbm90IGRlc2NyaWJlZCBpbiAnJGZ1bmN0aW9uX25hbWUnXG4iOwoJICAgIH0KCgkgICAg
cHVzaCBAcGFyYW1ldGVybGlzdCwgJHBhcmFtOwoJICAgICRwYXJhbWV0ZXJ0eXBlc3skcGFyYW19
ID0gJHR5cGU7CgojCSAgICBwcmludCBTVERFUlIgInBhcmFtID0gJyRwYXJhbScsIHR5cGUgPSAn
JHR5cGUnXG4iOwoJfQogICAgfSBlbHNlIHsKCXByaW50IFNUREVSUiAiRXJyb3IoJGxpbmVubyk6
IGNhbm5vdCB1bmRlcnN0YW5kIHByb3RvdHlwZTogJyRwcm90b3R5cGUnXG4iOwoJcmV0dXJuOwog
ICAgfQoKICAgIGlmICgkZnVuY3Rpb25fb25seT09MCB8fCBkZWZpbmVkKCRmdW5jdGlvbl90YWJs
ZXskZnVuY3Rpb25fbmFtZX0pKSB7CglvdXRwdXRfZnVuY3Rpb24oeydmdW5jdGlvbicgPT4gJGZ1
bmN0aW9uX25hbWUsCgkJCSAnbW9kdWxlJyA9PiAkbW9kdWxlbmFtZSwKCQkJICdmdW5jdGlvbnR5
cGUnID0+ICRyZXR1cm5fdHlwZSwKCQkJICdwYXJhbWV0ZXJsaXN0JyA9PiBcQHBhcmFtZXRlcmxp
c3QsCgkJCSAncGFyYW1ldGVycycgPT4gXCVwYXJhbWV0ZXJzLAoJCQkgJ3BhcmFtZXRlcnR5cGVz
JyA9PiBcJXBhcmFtZXRlcnR5cGVzLAoJCQkgJ3NlY3Rpb25saXN0JyA9PiBcQHNlY3Rpb25saXN0
LAoJCQkgJ3NlY3Rpb25zJyA9PiBcJXNlY3Rpb25zLAoJCQkgJ3B1cnBvc2UnID0+ICRmdW5jdGlv
bl9wdXJwb3NlCgkJCSB9KTsKICAgIH0KfQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIG1haW4KIyBzdGF0ZXMK
IyAwIC0gbm9ybWFsIGNvZGUKIyAxIC0gbG9va2luZyBmb3IgZnVuY3Rpb24gbmFtZQojIDIgLSBz
Y2FubmluZyBmaWVsZCBzdGFydC4KIyAzIC0gc2Nhbm5pbmcgcHJvdG90eXBlLgokc3RhdGUgPSAw
Owokc2VjdGlvbiA9ICIiOwoKJGRvY19zcGVjaWFsID0gIlxAXCVcJFwmIjsKCiRkb2Nfc3RhcnQg
PSAiXi9cXCpcXCpcJCI7CiRkb2NfZW5kID0gIlxcKi8iOwokZG9jX2NvbSA9ICJcXHMqXFwqXFxz
KiI7CiRkb2NfZnVuYyA9ICRkb2NfY29tLiIoXFx3Kyk6PyI7CiRkb2Nfc2VjdCA9ICRkb2NfY29t
LiIoWyIuJGRvY19zcGVjaWFsLiJdP1tcXHcgXSspOiguKikiOwokZG9jX2NvbnRlbnQgPSAkZG9j
X2NvbS4iKC4qKSI7CgolY29uc3RhbnRzID0gKCk7CiVwYXJhbWV0ZXJzID0gKCk7CkBwYXJhbWV0
ZXJsaXN0ID0gKCk7CiVzZWN0aW9ucyA9ICgpOwpAc2VjdGlvbmxpc3QgPSAoKTsKCiRjb250ZW50
cyA9ICIiOwokc2VjdGlvbl9kZWZhdWx0ID0gIkRlc2NyaXB0aW9uIjsJIyBkZWZhdWx0IHNlY3Rp
b24KJHNlY3Rpb24gPSAkc2VjdGlvbl9kZWZhdWx0OwoKJGxpbmVubyA9IDA7CmZvcmVhY2ggJGZp
bGUgKEBBUkdWKSB7CiAgICBpZiAoIW9wZW4oSU4sIjwkZmlsZSIpKSB7CglwcmludCBTVERFUlIg
IkVycm9yOiBDYW5ub3Qgb3BlbiBmaWxlICRmaWxlXG4iOwoJbmV4dDsKICAgIH0KICAgIHdoaWxl
ICg8SU4+KSB7CgkkbGluZW5vKys7CgoJaWYgKCRzdGF0ZSA9PSAwKSB7CgkgICAgaWYgKC8kZG9j
X3N0YXJ0L28pIHsKCQkkc3RhdGUgPSAxOwkJIyBuZXh0IGxpbmUgaXMgYWx3YXlzIHRoZSBmdW5j
dGlvbiBuYW1lCgkgICAgfQoJfSBlbHNpZiAoJHN0YXRlID09IDEpIHsJIyB0aGlzIGxpbmUgaXMg
dGhlIGZ1bmN0aW9uIG5hbWUgKGFsd2F5cykKCSAgICBpZiAoLyRkb2NfZnVuYy9vKSB7CgkJJGZ1
bmN0aW9uID0gJDE7CgkJJHN0YXRlID0gMjsKCQlpZiAoLy0oLiopLykgewoJCSAgICAkZnVuY3Rp
b25fcHVycG9zZSA9ICQxOwoJCX0gZWxzZSB7CgkJICAgICRmdW5jdGlvbl9wdXJwb3NlID0gIiI7
CgkJfQoJCWlmICgkdmVyYm9zZSkgewoJCSAgICBwcmludCBTVERFUlIgIkluZm8oJGxpbmVubyk6
IFNjYW5uaW5nIGRvYyBmb3IgJGZ1bmN0aW9uXG4iOwoJCX0KCSAgICB9IGVsc2UgewoJCXByaW50
IFNUREVSUiAiV0FSTigkbGluZW5vKTogQ2Fubm90IHVuZGVyc3RhbmQgJF8gb24gbGluZSAkbGlu
ZW5vIiwKCQkiIC0gSSB0aG91Z2h0IGl0IHdhcyBhIGRvYyBsaW5lXG4iOwoJCSRzdGF0ZSA9IDA7
CgkgICAgfQoJfSBlbHNpZiAoJHN0YXRlID09IDIpIHsJIyBsb29rIGZvciBoZWFkOiBsaW5lcywg
YW5kIGluY2x1ZGUgY29udGVudAoJICAgIGlmICgvJGRvY19zZWN0L28pIHsKCQkkbmV3c2VjdGlv
biA9ICQxOwoJCSRuZXdjb250ZW50cyA9ICQyOwoKCQlpZiAoJGNvbnRlbnRzIG5lICIiKSB7CgkJ
ICAgIGR1bXBfc2VjdGlvbigkc2VjdGlvbiwgJGNvbnRlbnRzKTsKCQkgICAgJHNlY3Rpb24gPSAk
c2VjdGlvbl9kZWZhdWx0OwoJCX0KCgkJJGNvbnRlbnRzID0gJG5ld2NvbnRlbnRzOwoJCWlmICgk
Y29udGVudHMgbmUgIiIpIHsKCQkgICAgJGNvbnRlbnRzIC49ICJcbiI7CgkJfQoJCSRzZWN0aW9u
ID0gJG5ld3NlY3Rpb247CgkgICAgfSBlbHNpZiAoLyRkb2NfZW5kLykgewoKCQlpZiAoJGNvbnRl
bnRzIG5lICIiKSB7CgkJICAgIGR1bXBfc2VjdGlvbigkc2VjdGlvbiwgJGNvbnRlbnRzKTsKCQkg
ICAgJHNlY3Rpb24gPSAkc2VjdGlvbl9kZWZhdWx0OwoJCSAgICAkY29udGVudHMgPSAiIjsKCQl9
CgojCSAgICBwcmludCBTVERFUlIgImVuZCBvZiBkb2MgY29tbWVudCwgbG9va2luZyBmb3IgcHJv
dG90eXBlXG4iOwoJCSRwcm90b3R5cGUgPSAiIjsKCQkkc3RhdGUgPSAzOwoJICAgIH0gZWxzaWYg
KC8kZG9jX2NvbnRlbnQvKSB7CgkJIyBtaWd1ZWwtc3R5bGUgY29tbWVudCBrbHVkZ2UsIGxvb2sg
Zm9yIGJsYW5rIGxpbmVzIGFmdGVyCgkJIyBAcGFyYW1ldGVyIGxpbmUgdG8gc2lnbmlmeSBzdGFy
dCBvZiBkZXNjcmlwdGlvbgoJCWlmICgkMSBlcSAiIiAmJiAkc2VjdGlvbiA9fiBtL15ALykgewoJ
CSAgICBkdW1wX3NlY3Rpb24oJHNlY3Rpb24sICRjb250ZW50cyk7CgkJICAgICRzZWN0aW9uID0g
JHNlY3Rpb25fZGVmYXVsdDsKCQkgICAgJGNvbnRlbnRzID0gIiI7CgkJfSBlbHNlIHsKCQkgICAg
JGNvbnRlbnRzIC49ICQxLiJcbiI7CgkJfQoJICAgIH0gZWxzZSB7CgkJIyBpIGRvbnQga25vdyAt
IGJhZCBsaW5lPyAgaWdub3JlLgoJCXByaW50IFNUREVSUiAiV0FSTklORygkbGluZW5vKTogYmFk
IGxpbmU6ICRfIjsgCgkgICAgfQoJfSBlbHNpZiAoJHN0YXRlID09IDMpIHsJIyBzY2FubmluZyBm
b3IgZnVuY3Rpb24geyAoZW5kIG9mIHByb3RvdHlwZSkKCSAgICBpZiAobSNccyovXCpccytNQUNE
T0NccyojaW8pIHsKCSAgICAgICMgZG8gbm90aGluZwoJICAgIH0KCSAgICBlbHNpZiAoLyhbXlx7
XSopLykgewoJCSRwcm90b3R5cGUgLj0gJDE7CgkgICAgfQoJICAgIGlmICgvXHsvKSB7CgkJJHBy
b3RvdHlwZSA9fiBzQC9cKi4qP1wqL0BAZ29zOwkjIHN0cmlwIGNvbW1lbnRzLgoJCSRwcm90b3R5
cGUgPX4gc0BbXHJcbl0rQCBAZ29zOyAjIHN0cmlwIG5ld2xpbmVzL2NyJ3MuCgkJJHByb3RvdHlw
ZSA9fiBzQF4gK0BAZ29zOyAjIHN0cmlwIGxlYWRpbmcgc3BhY2VzCgkJZHVtcF9mdW5jdGlvbigk
cHJvdG90eXBlKTsKCgkJJGZ1bmN0aW9uID0gIiI7CgkJJWNvbnN0YW50cyA9ICgpOwoJCSVwYXJh
bWV0ZXJzID0gKCk7CgkJJXBhcmFtZXRlcnR5cGVzID0gKCk7CgkJQHBhcmFtZXRlcmxpc3QgPSAo
KTsKCQklc2VjdGlvbnMgPSAoKTsKCQlAc2VjdGlvbmxpc3QgPSAoKTsKCQkkcHJvdG90eXBlID0g
IiI7CgoJCSRzdGF0ZSA9IDA7CgkgICAgfQoJfQogICAgfQp9Cgo=
--=-=-=--