[XML-SIG] Re: bug in c14n.py

Joseph Reagle reagle@w3.org
Wed, 17 Apr 2002 15:18:19 -0400


--------------Boundary-00=_JA8Q2531E7NEDBEUJMXV
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 8bit


I include a c14n.py that fixes the bug that I speak of below, and a 
test_c14n.py that has a more consistent treatment of the "withComments" 
option, and also permits additional prefixes to be passed as a command line 
parameter under exclusive canonicalization.

However, I also discovered a bug from Gregor's example 1 [a]. Presently, 
c14n.py does the following:
1. takes any xml_attrs (e.g., xml:lang) from previous recursions not 
rendered and adds them to local xml_attrs.
2. if the element we are processing is in the subset, it renders the 
accumulated xml_attrs as part of that element and and resets xml_attrs=[] 
3. it recurses.

This has the effect of rendering all XML attributes that are "in affect" 
since the last ancestor was rendered. Sounds sensible, but it's not correct 
according to the the spec [b]. To fix this, I think we'd have to test 
whether the immediate parent was in the nodeset and keep a dictionary 
(instead of a list) of *all* ancestors' xml:foo attributes (not just since 
the nearest rendered one), with the *nearest* value. (Moving from a list to 
a dictionary is akin to what I did for the namespace bug.) This bug exists 
on in c14n, not exc-c14n. 

[a] 
http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig/2002JanMar/0259.html
[b] http://www.w3.org/TR/2001/REC-xml-c14n-20010315
"The processing of an element node E MUST be modified slightly when an 
XPath node-set is given as input and the element's parent is omitted from 
the node-set. The method for processing the attribute axis of an element E 
in the node-set is enhanced. All element nodes along E's ancestor axis are 
examined for nearest occurrences of attributes in the xml namespace, such 
as xml:lang and xml:space (whether or not they are in the node-set). From 
this list of attributes, remove any that are in E's attribute axis (whether 
or not they are in the node-set)."


On Monday 08 April 2002 17:44, Joseph Reagle wrote:
> I think there's a pretty big bug in c14n.py. I've attached a simple
> example [0] that when run with [1] produces [2]. (I started out thinking
> this was a problem with default namespaces, but it's something else.) I
> don't think e3 should emmit any declaration, but since the ns code only
> compares with pvalue (e2's value for the prefix f is different), it
> incorrectly emits it.
>
> However, I've made lots of tweaks. I wonder if I've introduced this
> error? I've tried to fix it, but I find the ns code rather hard to
> understand. Additionally, I think the solution is to actually keep a
> (stack of) dictionary with rendered prefix and value. ns_rendered will
> need to be a dictionary of rendered ns prefixes and values, not just the
> prefixes.
>
>
>
>
> [0] <?xml version="1.0" encoding="UTF-8"?>
> <e0>
>   <e1 f:xmlns="">
>     <e2 f:xmlns="b">
>       <e3 f:xmlns=""/>
>     </e2>
>   </e1>
> </e0>
>
> [1] test_c14n.py -i egj1.xml -x "(//. | //@* | //namespace::*)[self::e1
> or self::e3]"
>
> [2] <e1 xmlns:f=""><e3 xmlns:f=""></e3></e1>

-- 

Joseph Reagle Jr.                 http://www.w3.org/People/Reagle/
W3C Policy Analyst                mailto:reagle@w3.org
IETF/W3C XML-Signature Co-Chair   http://www.w3.org/Signature/
W3C XML Encryption Chair          http://www.w3.org/Encryption/2001/
--------------Boundary-00=_JA8Q2531E7NEDBEUJMXV
Content-Type: text/html;
  charset="iso-8859-1";
  name="test_c14n.py"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test_c14n.py"

IyEgL3Vzci9iaW4vZW52IHB5dGhvbgoKIyBUaGUgc2V2ZW4gZXhhbXBsZXMgZnJvbSB0aGUgQ2Fu
b25pY2FsIFhNTCBzcGVjLgojIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDEvUkVDLXhtbC1jMTRu
LTIwMDEwMzE1Cgp0cnk6CiAgICB1ID0gdW5pY29kZQpleGNlcHQgTmFtZUVycm9yOgogICAgZGVm
IHUoeCk6cmV0dXJuIHgKCmVnMSA9ICIiIjw/eG1sIHZlcnNpb249IjEuMCI/PgoKPD94bWwtc3R5
bGVzaGVldCAgIGhyZWY9ImRvYy54c2wiCiAgIHR5cGU9InRleHQveHNsIiAgID8+Cgo8IURPQ1RZ
UEUgZG9jIFNZU1RFTSAiZG9jLmR0ZCI+Cgo8ZG9jPkhlbGxvLCB3b3JsZCE8IS0tIENvbW1lbnQg
MQotLT48L2RvYz4KCjw/cGktd2l0aG91dC1kYXRhICAgICA/PgoKPCEtLSBDb21tZW50IDIgLS0+
Cgo8IS0tIENvbW1lbnQgMyAtLT4KIiIiCgplZzIgPSAiIiI8ZG9jPgogICA8Y2xlYW4+ICAgPC9j
bGVhbj4KICAgPGRpcnR5PiAgIEEgICBCICAgPC9kaXJ0eT4KICAgPG1peGVkPgogICAgICBBCiAg
ICAgIDxjbGVhbj4gICA8L2NsZWFuPgogICAgICBCCiAgICAgIDxkaXJ0eT4gICBBICAgQiAgIDwv
ZGlydHk+CiAgICAgIEMKICAgPC9taXhlZD4KPC9kb2M+CiIiIgoKZWczID0gIiIiPCFET0NUWVBF
IGRvYyBbPCFBVFRMSVNUIGU5IGF0dHIgQ0RBVEEgImRlZmF1bHQiPl0+Cjxkb2M+CiAgIDxlMSAg
IC8+CiAgIDxlMiAgID48L2UyPgogICA8ZTMgICAgbmFtZSA9ICJlbGVtMyIgICBpZD0iZWxlbTMi
ICAgIC8+CiAgIDxlNCAgICBuYW1lPSJlbGVtNCIgICBpZD0iZWxlbTQiICAgID48L2U0PgogICA8
ZTUgYTphdHRyPSJvdXQiIGI6YXR0cj0ic29ydGVkIiBhdHRyMj0iYWxsIiBhdHRyPSJJJ20iCiAg
ICAgICB4bWxuczpiPSJodHRwOi8vd3d3LmlldGYub3JnIgogICAgICAgeG1sbnM6YT0iaHR0cDov
L3d3dy53My5vcmciCiAgICAgICB4bWxucz0iaHR0cDovL2V4YW1wbGUub3JnIi8+CiAgIDxlNiB4
bWxucz0iIiB4bWxuczphPSJodHRwOi8vd3d3LnczLm9yZyI+CiAgICAgICA8ZTcgeG1sbnM9Imh0
dHA6Ly93d3cuaWV0Zi5vcmciPgogICAgICAgICAgIDxlOCB4bWxucz0iIiB4bWxuczphPSJodHRw
Oi8vd3d3LnczLm9yZyI+CiAgICAgICAgICAgICAgIDxlOSB4bWxucz0iIiB4bWxuczphPSJodHRw
Oi8vd3d3LmlldGYub3JnIi8+CiAgICAgICAgICAgPC9lOD4KICAgICAgIDwvZTc+CiAgIDwvZTY+
CjwvZG9jPgoiIiIKCmVnMyA9ICIiIjwhRE9DVFlQRSBkb2MgWzwhQVRUTElTVCBlOSBhdHRyIENE
QVRBICJkZWZhdWx0Ij5dPgo8ZG9jIHhtbG5zOmZvbz0iaHR0cDovL3d3dy5iYXIub3JnIj4KICAg
PGUxICAgLz4KICAgPGUyICAgPjwvZTI+CiAgIDxlMyAgICBuYW1lID0gImVsZW0zIiAgIGlkPSJl
bGVtMyIgICAgLz4KICAgPGU0ICAgIG5hbWU9ImVsZW00IiAgIGlkPSJlbGVtNCIgICAgPjwvZTQ+
CiAgIDxlNSBhOmF0dHI9Im91dCIgYjphdHRyPSJzb3J0ZWQiIGF0dHIyPSJhbGwiIGF0dHI9Ikkn
bSIKICAgICAgIHhtbG5zOmI9Imh0dHA6Ly93d3cuaWV0Zi5vcmciCiAgICAgICB4bWxuczphPSJo
dHRwOi8vd3d3LnczLm9yZyIKICAgICAgIHhtbG5zPSJodHRwOi8vZXhhbXBsZS5vcmciLz4KICAg
PGU2IHhtbG5zPSIiIHhtbG5zOmE9Imh0dHA6Ly93d3cudzMub3JnIj4KICAgICAgIDxlNyB4bWxu
cz0iaHR0cDovL3d3dy5pZXRmLm9yZyI+CiAgICAgICAgICAgPGU4IHhtbG5zPSIiIHhtbG5zOmE9
Imh0dHA6Ly93d3cudzMub3JnIiBhOmZvbz0iYmFyIj4KICAgICAgICAgICAgICAgPGU5IHhtbG5z
PSIiIHhtbG5zOmE9Imh0dHA6Ly93d3cuaWV0Zi5vcmciLz4KICAgICAgICAgICA8L2U4PgogICAg
ICAgPC9lNz4KICAgPC9lNj4KPC9kb2M+CiIiIgoKZWc0ID0gIiIiPCFET0NUWVBFIGRvYyBbIDwh
QVRUTElTVCBub3JtSWQgaWQgSUQgI0lNUExJRUQ+IDwhQVRUTElTVCBub3JtTmFtZXMgYXR0ciBO
TVRPS0VOUyAjSU1QTElFRD4gXT4gPGRvYz4KICAgPHRleHQ+Rmlyc3QgbGluZSYjeDBkOyYjMTA7
U2Vjb25kIGxpbmU8L3RleHQ+CiAgIDx2YWx1ZT4mI3gzMjs8L3ZhbHVlPgogICA8Y29tcHV0ZT48
IVtDREFUQVt2YWx1ZT4iMCIgJiYgdmFsdWU8IjEwIiA/InZhbGlkIjoiZXJyb3IiXV0+PC9jb21w
dXRlPgogICA8Y29tcHV0ZSBleHByPSd2YWx1ZT4iMCIgJmFtcDsmYW1wOyB2YWx1ZSZsdDsiMTAi
ID8idmFsaWQiOiJlcnJvciInPnZhbGlkPC9jb21wdXRlPgogICA8bm9ybSBhdHRyPScgJmFwb3M7
ICAgJiN4MjA7JiMxMzsmI3hhOyYjOTsgICAmYXBvczsgJy8+CiAgIDxub3JtTmFtZXMgYXR0cj0n
ICAgQSAgICYjeDIwOyYjMTM7JiN4YTsmIzk7ICAgQiAgICcvPgogICA8bm9ybUlkIGlkPScgJmFw
b3M7ICAgJiN4MjA7JiMxMzsmI3hhOyYjOTsgICAmYXBvczsgJy8+CjwvZG9jPiIiIgoKZWc1ID0g
IiIiPCFET0NUWVBFIGRvYyBbCjwhQVRUTElTVCBkb2MgYXR0ckV4dEVudCBFTlRJVFkgI0lNUExJ
RUQ+CjwhRU5USVRZIGVudDEgIkhlbGxvIj4KPCFFTlRJVFkgZW50MiBTWVNURU0gIndvcmxkLnR4
dCI+CjwhRU5USVRZIGVudEV4dCBTWVNURU0gImVhcnRoLmdpZiIgTkRBVEEgZ2lmPgo8IU5PVEFU
SU9OIGdpZiBTWVNURU0gInZpZXdnaWYuZXhlIj4KXT4KPGRvYyBhdHRyRXh0RW50PSJlbnRFeHQi
PgogICAmZW50MTssICZlbnQyOyEKPC9kb2M+Cgo8IS0tIExldCB3b3JsZC50eHQgY29udGFpbiAi
d29ybGQiIChleGNsdWRpbmcgdGhlIHF1b3RlcykgLS0+CiIiIgoKZWc2ID0gIiIiPD94bWwgdmVy
c2lvbj0iMS4wIiBlbmNvZGluZz0iSVNPLTg4NTktMSI/Pgo8ZG9jPiYjMTY5OzwvZG9jPiIiIgoK
ZWc3ID0gIiIiPCFET0NUWVBFIGRvYyBbCjwhQVRUTElTVCBlMiB4bWw6c3BhY2UgKGRlZmF1bHR8
cHJlc2VydmUpICdwcmVzZXJ2ZSc+CjwhQVRUTElTVCBlMyBpZCBJRCAjSU1QTElFRD4KXT4KPGRv
YyB4bWxucz0iaHR0cDovL3d3dy5pZXRmLm9yZyIgeG1sbnM6dzNjPSJodHRwOi8vd3d3LnczLm9y
ZyI+CiAgIDxlMT4KICAgICAgPGUyIHhtbG5zPSIiPgogICAgICAgICA8ZTMgaWQ9IkUzIi8+CiAg
ICAgIDwvZTI+CiAgIDwvZTE+CjwvZG9jPiIiIgoKZXhhbXBsZXMgPSBbIGVnMSwgZWcyLCBlZzMs
IGVnNCwgZWc1LCBlZzYsIGVnNyBdCnRlc3RfcmVzdWx0cyA9IHsKICAgIGVnMTogJycnUEQ5NGJX
d3RjM1I1YkdWemFHVmxkQ0JvY21WbVBTSmtiMk11ZUhOc0lnb2dJQ0IwZVhCbFBTSjBaWGgwTDNo
egogICAgYkNJZ0lDQS9QZ284Wkc5alBraGxiR3h2TENCM2IzSnNaQ0U4SVMwdElFTnZiVzFsYm5R
Z01Rb3RMVDQ4TDJSdgogICAgWXo0S1BEOXdhUzEzYVhSb2IzVjBMV1JoZEdFL1BnbzhJUzB0SUVO
dmJXMWxiblFnTWlBdExUNEtQQ0V0TFNCRAogICAgYjIxdFpXNTBJRE1nTFMwKycnJywKCiAgICBl
ZzI6ICcnJ1BHUnZZejRLSUNBZ1BHTnNaV0Z1UGlBZ0lEd3ZZMnhsWVc0K0NpQWdJRHhrYVhKMGVU
NGdJQ0JCSUNBZ1FpQWcKICAgIElEd3ZaR2x5ZEhrK0NpQWdJRHh0YVhobFpENEtJQ0FnSUNBZ1FR
b2dJQ0FnSUNBOFkyeGxZVzQrSUNBZ1BDOWoKICAgIGJHVmhiajRLSUNBZ0lDQWdRZ29nSUNBZ0lD
QThaR2x5ZEhrK0lDQWdRU0FnSUVJZ0lDQThMMlJwY25SNVBnb2cKICAgIElDQWdJQ0JEQ2lBZ0lE
d3ZiV2w0WldRK0Nqd3ZaRzlqUGc9PScnJywKCiAgICBlZzM6ICcnJ1BHUnZZeUI0Yld4dWN6cG1i
Mjg5SW1oMGRIQTZMeTkzZDNjdVltRnlMbTl5WnlJK0NpQWdJRHhsTVQ0OEwyVXgKICAgIFBnb2dJ
Q0E4WlRJK1BDOWxNajRLSUNBZ1BHVXpJR2xrUFNKbGJHVnRNeUlnYm1GdFpUMGlaV3hsYlRNaVBq
d3YKICAgIFpUTStDaUFnSUR4bE5DQnBaRDBpWld4bGJUUWlJRzVoYldVOUltVnNaVzAwSWo0OEwy
VTBQZ29nSUNBOFpUVWcKICAgIGVHMXNibk05SW1oMGRIQTZMeTlsZUdGdGNHeGxMbTl5WnlJZ2VH
MXNibk02WVQwaWFIUjBjRG92TDNkM2R5NTMKICAgIE15NXZjbWNpSUhodGJHNXpPbUk5SW1oMGRI
QTZMeTkzZDNjdWFXVjBaaTV2Y21jaUlHRjBkSEk5SWtrbmJTSWcKICAgIFlYUjBjakk5SW1Gc2JD
SWdZanBoZEhSeVBTSnpiM0owWldRaUlHRTZZWFIwY2owaWIzVjBJajQ4TDJVMVBnb2cKICAgIElD
QThaVFlnZUcxc2JuTTZZVDBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWNpUGdvZ0lDQWdJQ0FnUEdV
M0lIaHQKICAgIGJHNXpQU0pvZEhSd09pOHZkM2QzTG1sbGRHWXViM0puSWo0S0lDQWdJQ0FnSUNB
Z0lDQThaVGdnZUcxc2JuTTkKICAgIElpSWdZVHBtYjI4OUltSmhjaUkrQ2lBZ0lDQWdJQ0FnSUNB
Z0lDQWdJRHhsT1NCNGJXeHVjenBoUFNKb2RIUncKICAgIE9pOHZkM2QzTG1sbGRHWXViM0puSWlC
aGRIUnlQU0prWldaaGRXeDBJajQ4TDJVNVBnb2dJQ0FnSUNBZ0lDQWcKICAgIElEd3ZaVGcrQ2lB
Z0lDQWdJQ0E4TDJVM1Bnb2dJQ0E4TDJVMlBnbzhMMlJ2WXo0PScnJywKCiAgICBlZzQ6ICcnJ1BH
UnZZejRLSUNBZ1BIUmxlSFErUm1seWMzUWdiR2x1WlNZamVFUTdDbE5sWTI5dVpDQnNhVzVsUEM5
MFpYaDAKICAgIFBnb2dJQ0E4ZG1Gc2RXVStNand2ZG1Gc2RXVStDaUFnSUR4amIyMXdkWFJsUG5a
aGJIVmxKbWQwT3lJd0lpQW0KICAgIFlXMXdPeVpoYlhBN0lIWmhiSFZsSm14ME95SXhNQ0lnUHlK
MllXeHBaQ0k2SW1WeWNtOXlJand2WTI5dGNIVjAKICAgIFpUNEtJQ0FnUEdOdmJYQjFkR1VnWlho
d2NqMGlkbUZzZFdVK0puRjFiM1E3TUNaeGRXOTBPeUFtWVcxd095WmgKICAgIGJYQTdJSFpoYkhW
bEpteDBPeVp4ZFc5ME96RXdKbkYxYjNRN0lEOG1jWFZ2ZER0MllXeHBaQ1p4ZFc5ME96b20KICAg
IGNYVnZkRHRsY25KdmNpWnhkVzkwT3lJK2RtRnNhV1E4TDJOdmJYQjFkR1UrQ2lBZ0lEeHViM0p0
SUdGMGRISTkKICAgIElpQW5JQ0FnSUNZamVFUW1JM2hCSmlONE9TQWdJQ2NnSWo0OEwyNXZjbTAr
Q2lBZ0lEeHViM0p0VG1GdFpYTWcKICAgIFlYUjBjajBpUVNBbUkzaEVKaU40UVNZamVEa2dRaUkr
UEM5dWIzSnRUbUZ0WlhNK0NpQWdJRHh1YjNKdFNXUWcKICAgIGFXUTlJaWNnSmlONFJDWWplRUVt
STNnNUlDY2lQand2Ym05eWJVbGtQZ284TDJSdll6ND0nJycsCgogICAgZWc1OiAnJydQR1J2WXlC
aGRIUnlSWGgwUlc1MFBTSmxiblJGZUhRaVBnb2dJQ0JJWld4c2J5d2dkMjl5YkdRaENqd3ZaRzlq
CiAgICBQZz09JycnLAoKICAgIGVnNjogJycnUEdSdll6N0NxVHd2Wkc5alBnPT0nJycsCgogICAg
ZWc3OiAnJydQR1J2WXlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1cFpYUm1MbTl5WnlJZ2VHMXNi
bk02ZHpOalBTSm9kSFJ3CiAgICBPaTh2ZDNkM0xuY3pMbTl5WnlJK0NpQWdJRHhsTVQ0S0lDQWdJ
Q0FnUEdVeUlIaHRiRzV6UFNJaUlIaHRiRHB6CiAgICBjR0ZqWlQwaWNISmxjMlZ5ZG1VaVBnb2dJ
Q0FnSUNBZ0lDQThaVE1nYVdROUlrVXpJajQ4TDJVelBnb2dJQ0FnCiAgICBJQ0E4TDJVeVBnb2dJ
Q0E4TDJVeFBnbzhMMlJ2WXo0PScnJywKfQoKIyBMb2FkIFhQYXRoIGFuZCBQYXJzZXIKaW1wb3J0
IHN5cywgdHlwZXMsIHRyYWNlYmFjaywgU3RyaW5nSU8sIGJhc2U2NCwgc3RyaW5nCmZyb20geG1s
IGltcG9ydCB4cGF0aApmcm9tIHhtbC54cGF0aC5Db250ZXh0IGltcG9ydCBDb250ZXh0CmZyb20g
eG1sLmRvbS5leHQucmVhZGVyIGltcG9ydCBQeUV4cGF0CmZyb20gYzE0biBpbXBvcnQgQ2Fub25p
Y2FsaXplCiNmcm9tIHhtbC5kb20uZXh0IGltcG9ydCBDYW5vbmljYWxpemUKCiMgTXkgc3BlY2lh
bCByZWFkZXIuClBZRSA9IFB5RXhwYXQuUmVhZGVyCmNsYXNzIFJlYWRlcmZvckMxNE5FeGFtcGxl
cyhQWUUpOgogICAgJycnQSBzcGVjaWFsIHJlYWRlciB0byBoYW5kbGUgcmVzb2x1dGlvbiBvZiB0
aGUgQzE0TiBleGFtcGxlcy4KICAgICcnJwogICAgZGVmIGluaXRQYXJzZXIoc2VsZik6CiAgICAg
ICAgUFlFLmluaXRQYXJzZXIoc2VsZikKICAgICAgICBzZWxmLnBhcnNlci5FeHRlcm5hbEVudGl0
eVJlZkhhbmRsZXIgPSBzZWxmLmVudGl0eV9yZWYKCiAgICBkZWYgZW50aXR5X3JlZihzZWxmLCAq
YXJncyk6CiAgICAgICAgaWYgYXJncyAhPSAodSgnZW50MicpLCBOb25lLCB1KCd3b3JsZC50eHQn
KSwgTm9uZSk6IHJldHVybiAwCiAgICAgICAgc2VsZi5wYXJzZXIuQ2hhcmFjdGVyRGF0YUhhbmRs
ZXIoJ3dvcmxkJykKICAgICAgICByZXR1cm4gMQoKICAgICMgT3ZlcnJpZGUgc29tZSBtZXRob2Rz
IGZyb20gUHlFeHBhdC5SZWFkZXIKICAgIGRlZiB1bnBhcnNlZEVudGl0eURlY2woc2VsZiwgKmFy
Z3MpOiBwYXNzCiAgICBkZWYgbm90YXRpb25EZWNsKHNlbGYsICphcmdzKTogcGFzcwoKCnRyeToK
ICAgIGltcG9ydCBjb2RlY3MKICAgIHV0Zjhfd3JpdGVyID0gY29kZWNzLmxvb2t1cCgndXRmLTgn
KVszXQpleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBkZWYgdXRmOF93cml0ZXIocyk6CiAgICAgICAg
cmV0dXJuIHMKCmRlZiBidWlsdGluKCk6CiAgICAnJydSdW4gdGhlIGJ1aWx0aW4gdGVzdHMgZnJv
bSB0aGUgQzE0TiBzcGVjLicnJwogICAgZm9yIGkgaW4gcmFuZ2UobGVuKGV4YW1wbGVzKSk6CiAg
ICAgICAgbnVtID0gaSsxCiAgICAgICAgZWcgPSBleGFtcGxlc1tpXQoKICAgICAgICBmaWxlbmFt
ZSA9ICdvdXQlZC54bWwnICUgbnVtCiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcy51bmxpbmso
ZmlsZW5hbWUpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBwYXNzCgogICAgICAgIHByaW50
ICdEb2luZyAlZCwgJXMuLi4nICUgKG51bSwgc3RyaW5nLnJlcGxhY2UoZWdbMDozMF0sICdcbics
ICdcXG4nKSksCgogICAgICAgIHIgPSBSZWFkZXJmb3JDMTRORXhhbXBsZXMoKQogICAgICAgIHRy
eToKICAgICAgICAgICAgZG9tID0gci5mcm9tU3RyaW5nKGVnKQogICAgICAgIGV4Y2VwdCBFeGNl
cHRpb24sIGU6CiAgICAgICAgICAgIHByaW50ICdcbkV4Y2VwdGlvbicsIHJlcHIoZSkKICAgICAg
ICAgICAgdHJhY2ViYWNrLnByaW50X2V4YygpCiAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAg
ICMgR2V0IHRoZSBub2Rlc2V0OyB0aGUgdGVzdHMgaGF2ZSBzb21lIHNwZWNpYWwgY2FzZXMuCiAg
ICAgICAgaWYgZWcgPT0gZWc1OgogICAgICAgICAgICBwYXR0ZXJuID0gJygvLy4gfCAvL0AqIHwg
Ly9uYW1lc3BhY2U6OiopW25vdCAoc2VsZjo6Y29tbWVudCgpKV0nCiAgICAgICAgZWxzZToKICAg
ICAgICAgICAgcGF0dGVybiA9ICcoLy8uIHwgLy9AKiB8IC8vbmFtZXNwYWNlOjoqKScKICAgICAg
ICBpZiBlZyA9PSBlZzc6CiAgICAgICAgICAgIGNvbiA9IENvbnRleHQoZG9tLCBwcm9jZXNzb3JO
c3M9eydpZXRmJzogJ2h0dHA6Ly93d3cuaWV0Zi5vcmcnfSkKICAgICAgICBlbHNlOgogICAgICAg
ICAgICBjb24gPSBDb250ZXh0KGRvbSkKICAgICAgICBub2RlbGlzdCA9IHhwYXRoLkV2YWx1YXRl
KHBhdHRlcm4sIGNvbnRleHQ9Y29uKQoKICAgICAgICBzID0gU3RyaW5nSU8uU3RyaW5nSU8oKQog
ICAgICAgIG91dGYgPSB1dGY4X3dyaXRlcihzKQoKICAgICAgICAjIENhbm9uaWNhbGl6ZSBhIERP
TSB3aXRoIGEgZG9jdW1lbnQgc3Vic2V0IGxpc3QgYWNjb3JkaW5nIHRvIFhNTC1DMTROCiAgICAg
ICAgaWYgZWcgPT0gZWcxOgogICAgICAgICAgICBDYW5vbmljYWxpemUoZG9tLCBvdXRmLCBzdWJz
ZXQ9bm9kZWxpc3QsIGNvbW1lbnRzPTEpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgQ2Fub25p
Y2FsaXplKGRvbSwgb3V0Ziwgc3Vic2V0PW5vZGVsaXN0KQoKICAgICAgICBleHBlY3RlZCA9IGJh
c2U2NC5kZWNvZGVzdHJpbmcodGVzdF9yZXN1bHRzW2VnXSkKICAgICAgICBpZiBzLmdldHZhbHVl
KCkgPT0gZXhwZWN0ZWQ6CiAgICAgICAgICAgIHByaW50ICdPaycKICAgICAgICBlbHNlOgogICAg
ICAgICAgICBwcmludCAnRXJyb3IhJwogICAgICAgICAgICBwcmludCAnR290OlxuJywgcy5nZXR2
YWx1ZSgpCiAgICAgICAgICAgIHByaW50ICdFeHBlY3RlZDpcbicsIGV4cGVjdGVkCgpkZWYgdXNh
Z2UoKToKICAgIHByaW50ICcnJ09wdGlvbnMgYWNjZXB0ZWQ6CiAgICAtYiwgLS1idWlsdGluICAg
ICAgICAgICAgUnVuIHRoZSBDMTROIGJ1aWx0aW4gdGVzdHMKICAgIC1lICAgICAgICAgICAgICAg
ICAgICAgICBFeGNsdXNpdmUgQzE0TgogICAgLXAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2x1
c2l2ZSBDMTROIGluY2x1c2l2ZSBwcmVmaXhlcwogICAgLW4gc3RyaW5nLCAgICAgICAgICAgICAg
IEFkZGl0aW9uYWwgTlNQcmVmaXhlcyAod2hpdGVzcGFjZSBkZWxpbWl0ZWQpCiAgICAgICAgLS1u
YW1lc3BhY2VzPXN0cmluZwogICAgLWkgZmlsZSwgLS1pbj1maWxlICAgICAgIFJlYWQgc3BlY2lm
aWVkIGZpbGUqIChkZWZhdWx0IGlzIHN0ZGluKQogICAgLW8gZmlsZSwgLS1vdXQ9ZmlsZSAgICAg
IFdyaXRlIHRvIHNwZWNpZmllZCBmaWxlKiAoZGVmYXVsdCBpcyBzdGRvdXQpCiAgICAtaCwgLS1o
ZWxwICAgICAgICAgICAgICAgUHJpbnQgdGhpcyB0ZXh0CiAgICAteCBxdWVyeSwgLS14cGF0aD1x
dWVyeSAgU3BlY2lmeSBhbiBYUEFUSCBub2RlbGlzdApJZiBmaWxlIChmb3IgaW5wdXQvb3V0cHV0
KSBpcyBsaWtlIHh4eCxuYW1lIHRoZW4geHh4IGlzIHVzZWQgYXMgYW4KZW5jb2RpbmcgKGUuZy4s
ICJ1dGYtOCxmb28udHh0IikuCicnJwoKaWYgX19uYW1lX18gIT0gIl9fbWFpbl9fIjoKICAgIGJ1
aWx0aW4oKQplbHNlOgogICAgaWYgbGVuKHN5cy5hcmd2KSA9PSAxOiBzeXMuYXJndi5hcHBlbmQo
Jy1iJykKCiAgICBpbXBvcnQgZ2V0b3B0CiAgICB0cnk6CiAgICAgICAgb3B0cywgYXJncyA9IGdl
dG9wdC5nZXRvcHQoc3lzLmFyZ3ZbMTpdLCAiY2VoYmk6bzpuOnA6eDoiLAogICAgICAgICAgICBb
ICJjb21tZW50cyIsICJleGNsdXNpdmUiLCAiaGVscCIsICJidWlsdGluIiwgCiAgICAgICAgICAg
ICJpbj0iLCAib3V0PSIsICJuYW1lc3BhY2VzPSIsICJwcmVmaXhlcz0iLCAieHBhdGg9IiBdKQog
ICAgZXhjZXB0IGdldG9wdC5HZXRvcHRFcnJvciwgZToKICAgICAgICBwcmludCBzeXMuYXJndlsw
XSArICc6JywgZSwgJ1xuVHJ5IC0taGVscCBmb3IgaGVscC5cbicKICAgICAgICBzeXMuZXhpdCgx
KQogICAgaWYgbGVuKGFyZ3MpOgogICAgICAgIHByaW50ICdObyBhcmd1bWVudHMsIG9ubHkgZmxh
Z3MuIFRyeSAtLWhlbHAgZm9yIGhlbHAuJwogICAgICAgIHN5cy5leGl0KDEpCgoKICAgIElOLCBP
VVQgPSBzeXMuc3RkaW4sIHN5cy5zdGRvdXQKICAgIHF1ZXJ5ID0gJygvLy4gfCAvL0AqIHwgLy9u
YW1lc3BhY2U6OiopJwogICAgY29tbWVudHMgPSAwCiAgICBleGNsdXNpdmUsIHBmeGxpc3QgPSBO
b25lLCBbXQogICAgbnNkaWN0ID0ge30KICAgIGZvciBvcHQsYXJnIGluIG9wdHM6CiAgICAgICAg
aWYgb3B0IGluICgnLWgnLCAnLS1oZWxwJyk6CiAgICAgICAgICAgIHVzYWdlKCkKICAgICAgICAg
ICAgc3lzLmV4aXQoMCkKICAgICAgICBpZiBvcHQgaW4gKCctYicsICctLWJ1aWx0aW4nKToKICAg
ICAgICAgICAgYnVpbHRpbigpCiAgICAgICAgICAgIHN5cy5leGl0KDApCiAgICAgICAgZWxpZiBv
cHQgaW4gKCctYycsICctLWNvbW1lbnRzJyk6CiAgICAgICAgICAgIGNvbW1lbnRzID0gMQogICAg
ICAgIGVsaWYgb3B0IGluICgnLW4nLCAnLS1uYW1lc3BhY2VzJyk6CiAgICAgICAgICAgICMgY29u
dmVydCBldmVyeSBwYWlyIG9mIHdoaXRlc3BhY2UgZGVsaW1pdGVkICB2YWx1ZXMgdG8gZGljdGlv
bmFyeQogICAgICAgICAgICBuc2wgPSBhcmcuc3BsaXQoKQogICAgICAgICAgICBmb3IgaSBpbiBy
YW5nZSgwLCBsZW4obnNsKSwgMik6CiAgICAgICAgICAgICAgICBuc2RpY3RbbnNsW2ldXSA9IG5z
bFtpKzFdCiAgICAgICAgIyAgICBwcmludCAiTmFtZXNwYWNlIHByZWZpeCBhcmd1bWVudHMgaXMg
bm90IHN1cHBvcnRlZCB5ZXQuIgogICAgICAgIGVsaWYgb3B0IGluICgnLWUnLCAnLS1leGNsdXNp
dmUnKToKICAgICAgICAgICAgZXhjbHVzaXZlID0gMQogICAgICAgIGVsaWYgb3B0IGluICggJy1w
JywgJy0tcHJlZml4ZXMnKToKICAgICAgICAgICAgcGZ4bGlzdCA9IGFyZy5zcGxpdCgnLCcpCiAg
ICAgICAgZWxpZiBvcHQgaW4gKCctaScsICctLWluJyk6CiAgICAgICAgICAgIGlmIGFyZy5maW5k
KCcsJykgPT0gLTE6CiAgICAgICAgICAgICAgICBJTiA9IG9wZW4oYXJnLCAncicpCiAgICAgICAg
ICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpbXBvcnQgY29kZWNzCiAgICAgICAgICAgICAgICBl
bmNvZGluZywgZmlsZW5hbWUgPSBhcmcuc3BsaXQoJywnKQogICAgICAgICAgICAgICAgcmVhZGVy
ID0gY29kZWNzLmxvb2t1cChlbmNvZGluZylbMl0KICAgICAgICAgICAgICAgIElOID0gcmVhZGVy
KG9wZW4oZmlsZW5hbWUsICdyJykpCiAgICAgICAgZWxpZiBvcHQgaW4gKCctbycsICctLW91dCcp
OgogICAgICAgICAgICBpZiBhcmcuZmluZCgnLCcpID09IC0xOgogICAgICAgICAgICAgICAgT1VU
ID0gb3BlbihhcmcsICd3JykKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGltcG9y
dCBjb2RlY3MKICAgICAgICAgICAgICAgIGVuY29kaW5nLCBmaWxlbmFtZSA9IGFyZy5zcGxpdCgn
LCcpCiAgICAgICAgICAgICAgICB3cml0ZXIgPSBjb2RlY3MubG9va3VwKGVuY29kaW5nKVszXQog
ICAgICAgICAgICAgICAgT1VUID0gd3JpdGVyKG9wZW4oZmlsZW5hbWUsICd3JykpCiAgICAgICAg
ZWxpZiBvcHQgaW4gKCcteCcsICctLXhwYXRoJyk6CiAgICAgICAgICAgIHF1ZXJ5ID0gYXJnCiAg
ICAgICAgICAgIAogICAgciA9IFBZRSgpCiAgICBkb20gPSByLmZyb21TdHJlYW0oSU4pCiAgICBj
b250ZXh0ID0gQ29udGV4dChkb20sIHByb2Nlc3Nvck5zcz1uc2RpY3QpCiAgICBub2RlbGlzdCA9
IHhwYXRoLkV2YWx1YXRlKHF1ZXJ5LCBjb250ZXh0PWNvbnRleHQpCiAgICBpZiBleGNsdXNpdmU6
CiAgICAgICAgQ2Fub25pY2FsaXplKGRvbSwgT1VULCBzdWJzZXQ9bm9kZWxpc3QsIGNvbW1lbnRz
PWNvbW1lbnRzLCB1bnN1cHByZXNzZWRQcmVmaXhlcz1wZnhsaXN0KQogICAgZWxzZToKICAgICAg
ICBDYW5vbmljYWxpemUoZG9tLCBPVVQsIHN1YnNldD1ub2RlbGlzdCwgY29tbWVudHM9Y29tbWVu
dHMpICMgICAgbnNkaWN0PW5zZGljdAogICAgT1VULmNsb3NlKCkK

--------------Boundary-00=_JA8Q2531E7NEDBEUJMXV
Content-Type: text/plain;
  charset="iso-8859-1";
  name="c14n.py"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="c14n.py"

IyEgL3Vzci9iaW4vZW52IHB5dGhvbgonJydYTUwgQ2Fub25pY2FsaXphdGlvbgoKVGhpcyBtb2R1
bGUgZ2VuZXJhdGVzIGNhbm9uaWNhbCBYTUwgb2YgYSBkb2N1bWVudCBvciBlbGVtZW50LgogICAg
aHR0cDovL3d3dy53My5vcmcvVFIvMjAwMS9SRUMteG1sLWMxNG4tMjAwMTAzMTUKYW5kIGluY2x1
ZGVzIGEgcHJvdG90eXBlIG9mIGV4Y2x1c2l2ZSBjYW5vbmljYWxpemF0aW9uCiAgICBodHRwOi8v
d3d3LnczLm9yZy9TaWduYXR1cmUvRHJhZnRzL3htbC1leGMtYzE0bgoKUmVxdWlyZXMgUHlYTUwg
MC43LjAgb3IgbGF0ZXIuCgpLbm93biBpc3N1ZXMgaWYgdXNpbmcgRnQuTGliLnBEb21sZXR0ZToK
ICAgIDEuIFVuaWNvZGUKICAgIDIuIGRvZXMgbm90IHdoaXRlIHNwYWNlIG5vcm1hbGl6ZSBhdHRy
aWJ1dGVzIG9mIHR5cGUgTk1UT0tFTiBhbmQgSUQ/CiAgICAzLiBzZWVtcyB0byBiZSBpbmNsdWRl
ICJcbiIgYWZ0ZXIgaW1wb3J0aW5nIGV4dGVybmFsIGVudGl0aWVzPwoKTm90ZSwgdGhpcyB2ZXJz
aW9uIHByb2Nlc3NlcyBhIERPTSB0cmVlLCBhbmQgY29uc2VxdWVudGx5IGl0IHByb2Nlc3Nlcwpu
YW1lc3BhY2Ugbm9kZXMgYXMgYXR0cmlidXRlcywgbm90IGZyb20gYSBub2RlJ3MgbmFtZXNwYWNl
IGF4aXMuIFRoaXMKcGVybWl0cyBzaW1wbGUgZG9jdW1lbnQgYW5kIGVsZW1lbnQgY2Fub25pY2Fs
aXphdGlvbiB3aXRob3V0ClhQYXRoLiBXaGVuIFhQYXRoIGlzIHVzZWQsIHRoZSBYUGF0aCByZXN1
bHQgbm9kZSBsaXN0IGlzIHBhc3NlZCBhbmQgdXNlZCB0bwpkZXRlcm1pbmUgaWYgdGhlIG5vZGUg
aXMgaW4gdGhlIFhQYXRoIHJlc3VsdCBsaXN0LCBidXQgbGl0dGxlIGVsc2UuCgpBdXRob3JzOgog
ICAgIkpvc2VwaCBNLiBSZWFnbGUgSnIuIiA8cmVhZ2xlQHczLm9yZz4KICAgICJSaWNoIFNhbHoi
IDxyc2FsekB6b2xlcmEuY29tPgoKJERhdGU6IDIwMDIvMDQvMTcgMTc6NTA6MDcgJCBieSAkQXV0
aG9yOiByZWFnbGUgJAonJycKCl9jb3B5cmlnaHQgPSAnJydDb3B5cmlnaHQgMjAwMSwgWm9sZXJh
IFN5c3RlbXMgSW5jLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KQ29weXJpZ2h0IDIwMDEsIE1JVC4g
QWxsIFJpZ2h0cyBSZXNlcnZlZC4KCkRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZjoKICBQ
eXRob24gMi4wIExpY2Vuc2Ugb3IgbGF0ZXIuCiAgaHR0cDovL3d3dy5weXRob24ub3JnLzIuMC4x
L2xpY2Vuc2UuaHRtbApvcgogIFczQyBTb2Z0d2FyZSBMaWNlbnNlCiAgaHR0cDovL3d3dy53My5v
cmcvQ29uc29ydGl1bS9MZWdhbC9jb3B5cmlnaHQtc29mdHdhcmUtMTk5ODA3MjAKJycnCgppbXBv
cnQgc3RyaW5nCmZyb20geG1sLmRvbSBpbXBvcnQgTm9kZQp0cnk6CiAgICBmcm9tIHhtbC5ucyBp
bXBvcnQgWE1MTlMKZXhjZXB0OgogICAgY2xhc3MgWE1MTlM6CiAgICAgICAgQkFTRSA9ICJodHRw
Oi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIKICAgICAgICBYTUwgPSAiaHR0cDovL3d3dy53My5v
cmcvWE1MLzE5OTgvbmFtZXNwYWNlIgp0cnk6CiAgICBpbXBvcnQgY1N0cmluZ0lPCiAgICBTdHJp
bmdJTyA9IGNTdHJpbmdJTwpleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBpbXBvcnQgU3RyaW5nSU8K
Cl9hdHRycyA9IGxhbWJkYSBFOiAoRS5hdHRyaWJ1dGVzIGFuZCBFLmF0dHJpYnV0ZXMudmFsdWVz
KCkpIG9yIFtdCl9jaGlsZHJlbiA9IGxhbWJkYSBFOiBFLmNoaWxkTm9kZXMgb3IgW10KX0lOX1hN
TF9OUyA9IGxhbWJkYSBuOiBuLm5hbWVzcGFjZVVSSSA9PSBYTUxOUy5YTUwKCiMgRG9lcyBhIGRv
Y3VtZW50L1BJIGhhcyBsZXNzZXIvZ3JlYXRlciBkb2N1bWVudCBvcmRlciB0aGFuIHRoZQojIGZp
cnN0IGVsZW1lbnQ/Cl9MZXNzZXJFbGVtZW50LCBfRWxlbWVudCwgX0dyZWF0ZXJFbGVtZW50ID0g
cmFuZ2UoMykKCmRlZiBfc29ydGVyKG4xLG4yKToKICAgICcnJ19zb3J0ZXIobjEsbjIpIC0+IGlu
dAogICAgU29ydGluZyBwcmVkaWNhdGUgZm9yIG5vbi1OUyBhdHRyaWJ1dGVzLicnJwoKICAgIGkg
PSBjbXAobjEubmFtZXNwYWNlVVJJLCBuMi5uYW1lc3BhY2VVUkkpCiAgICBpZiBpOiByZXR1cm4g
aQogICAgcmV0dXJuIGNtcChuMS5sb2NhbE5hbWUsIG4yLmxvY2FsTmFtZSkKCgpkZWYgX3NvcnRl
cl9ucyhuMSxuMik6CiAgICAnJydfc29ydGVyX25zKChuLHYpLChuLHYpKSAtPiBpbnQKICAgICIo
YW4gZW1wdHkgbmFtZXNwYWNlIFVSSSBpcyBsZXhpY29ncmFwaGljYWxseSBsZWFzdCkuIicnJwoK
ICAgIGlmIG4xWzBdID09ICd4bWxucyc6IHJldHVybiAtMQogICAgaWYgbjJbMF0gPT0gJ3htbG5z
JzogcmV0dXJuIDEKICAgIHJldHVybiBjbXAobjFbMF0sIG4yWzBdKQoKZGVmIF91dGlsaXplZChu
LCBub2RlLCBvdGhlcl9hdHRycywgdW5zdXBwcmVzc2VkUHJlZml4ZXMpOgogICAgJycnX3V0aWxp
emVkKG4sIG5vZGUsIG90aGVyX2F0dHJzLCB1bnN1cHByZXNzZWRQcmVmaXhlcykgLT4gYm9vbGVh
bgogICAgUmV0dXJuIHRydWUgaWYgdGhhdCBub2Rlc3BhY2UgaXMgdXRpbGl6ZWQgd2l0aGluIHRo
ZSBub2RlJycnCgogICAgaWYgbi5zdGFydHN3aXRoKCd4bWxuczonKToKICAgICAgICBuID0gbls2
Ol0KICAgIGVsaWYgbi5zdGFydHN3aXRoKCd4bWxucycpOgogICAgICAgIG4gPSBuWzU6XQogICAg
aWYgKG49PSIiIGFuZCBub2RlLnByZWZpeCBpbiBbIiNkZWZhdWx0IiwgTm9uZV0pIG9yIFwKICAg
ICAgICBuID09IG5vZGUucHJlZml4IG9yIG4gaW4gdW5zdXBwcmVzc2VkUHJlZml4ZXM6IAogICAg
ICAgICAgICByZXR1cm4gMQogICAgZm9yIGF0dHIgaW4gb3RoZXJfYXR0cnM6CiAgICAgICAgaWYg
biA9PSBhdHRyLnByZWZpeDogcmV0dXJuIDEKICAgIHJldHVybiAwCgojX2luX3N1YnNldCA9IGxh
bWJkYSBzdWJzZXQsIG5vZGU6IG5vdCBzdWJzZXQgb3Igbm9kZSBpbiBzdWJzZXQKX2luX3N1YnNl
dCA9IGxhbWJkYSBzdWJzZXQsIG5vZGU6IHN1YnNldCBpcyBOb25lIG9yIG5vZGUgaW4gc3Vic2V0
ICMgcmljaCdzIHR3ZWFrCgpjbGFzcyBfaW1wbGVtZW50YXRpb246CiAgICAnJydJbXBsZW1lbnRh
dGlvbiBjbGFzcyBmb3IgQzE0Ti4gVGhpcyBhY2NvbXBhbmllcyBhIG5vZGUgZHVyaW5nIGl0J3MK
ICAgIHByb2Nlc3NpbmcgYW5kIGluY2x1ZGVzIHRoZSBwYXJhbWV0ZXJzIGFuZCBwcm9jZXNzaW5n
IHN0YXRlLicnJwoKICAgICMgSGFuZGxlciBmb3IgZWFjaCBub2RlIHR5cGU7IHBvcHVsYXRlZCBk
dXJpbmcgbW9kdWxlIGluc3RhbnRpYXRpb24uCiAgICBoYW5kbGVycyA9IHt9CgogICAgZGVmIF9f
aW5pdF9fKHNlbGYsIG5vZGUsIHdyaXRlLCAqKmt3KToKICAgICAgICAnJydDcmVhdGUgYW5kIHJ1
biB0aGUgaW1wbGVtZW50YXRpb24uJycnCiAgICAgICAgc2VsZi53cml0ZSA9IHdyaXRlCiAgICAg
ICAgc2VsZi5zdWJzZXQgPSBrdy5nZXQoJ3N1YnNldCcpCiAgICAgICAgc2VsZi5jb21tZW50cyA9
IGt3LmdldCgnY29tbWVudHMnLCAwKQogICAgICAgIHNlbGYudW5zdXBwcmVzc2VkUHJlZml4ZXMg
PSBrdy5nZXQoJ3Vuc3VwcHJlc3NlZFByZWZpeGVzJykKICAgICAgICBuc2RpY3QgPSBrdy5nZXQo
J25zZGljdCcsIHsgJ3htbCc6IFhNTE5TLlhNTCwgJ3htbG5zJzogWE1MTlMuQkFTRSB9KQogICAg
ICAgIAogICAgICAgICMgUHJvY2Vzc2luZyBzdGF0ZS4KICAgICAgICBzZWxmLnN0YXRlID0gKG5z
ZGljdCwgeyd4bWwnOicnfSwgW10pICMwNDE3CiAgICAgICAgCiAgICAgICAgaWYgbm9kZS5ub2Rl
VHlwZSA9PSBOb2RlLkRPQ1VNRU5UX05PREU6CiAgICAgICAgICAgIHNlbGYuX2RvX2RvY3VtZW50
KG5vZGUpCiAgICAgICAgZWxpZiBub2RlLm5vZGVUeXBlID09IE5vZGUuRUxFTUVOVF9OT0RFOgog
ICAgICAgICAgICBzZWxmLmRvY3VtZW50T3JkZXIgPSBfRWxlbWVudCAgICAgICAgIyBBdCBkb2N1
bWVudCBlbGVtZW50CiAgICAgICAgICAgIGlmIHNlbGYudW5zdXBwcmVzc2VkUHJlZml4ZXMgIT0g
Tm9uZToKICAgICAgICAgICAgICAgIHNlbGYuX2RvX2VsZW1lbnQobm9kZSkKICAgICAgICAgICAg
ZWxzZToKICAgICAgICAgICAgICAgIGluaGVyaXRlZCA9IHNlbGYuX2luaGVyaXRfY29udGV4dChu
b2RlKQogICAgICAgICAgICAgICAgc2VsZi5fZG9fZWxlbWVudChub2RlLCBpbmhlcml0ZWQpCiAg
ICAgICAgZWxpZiBub2RlLm5vZGVUeXBlID09IE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOgogICAg
ICAgICAgICBwYXNzCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgVHlwZUVycm9yLCBz
dHIobm9kZSkKCgogICAgZGVmIF9pbmhlcml0X2NvbnRleHQoc2VsZiwgbm9kZSk6CiAgICAgICAg
JycnX2luaGVyaXRfY29udGV4dChzZWxmLCBub2RlKSAtPiBsaXN0CiAgICAgICAgU2NhbiBhbmNl
c3RvcnMgb2YgYXR0cmlidXRlIGFuZCBuYW1lc3BhY2UgY29udGV4dC4gIFVzZWQgb25seQogICAg
ICAgIGZvciBzaW5nbGUgZWxlbWVudCBub2RlIGNhbm9uaWNhbGl6YXRpb24sIG5vdCBmb3Igc3Vi
c2V0CiAgICAgICAgY2Fub25pY2FsaXphdGlvbi4nJycKCiAgICAgICAgIyBDb2xsZWN0IHRoZSBp
bml0aWFsIGxpc3Qgb2YgeG1sOmZvbyBhdHRyaWJ1dGVzLgogICAgICAgIHhtbGF0dHJzID0gZmls
dGVyKF9JTl9YTUxfTlMsIF9hdHRycyhub2RlKSkKCiAgICAgICAgIyBXYWxrIHVwIGFuZCBnZXQg
YWxsIHhtbDpYWFggYXR0cmlidXRlcyB3ZSBpbmhlcml0LgogICAgICAgIGluaGVyaXRlZCwgcGFy
ZW50ID0gW10sIG5vZGUucGFyZW50Tm9kZQogICAgICAgIHdoaWxlIHBhcmVudCBhbmQgcGFyZW50
Lm5vZGVUeXBlID09IE5vZGUuRUxFTUVOVF9OT0RFOgogICAgICAgICAgICBmb3IgYSBpbiBmaWx0
ZXIoX0lOX1hNTF9OUywgX2F0dHJzKHBhcmVudCkpOgogICAgICAgICAgICAgICAgbiA9IGEubG9j
YWxOYW1lCiAgICAgICAgICAgICAgICBpZiBuIG5vdCBpbiB4bWxhdHRyczoKICAgICAgICAgICAg
ICAgICAgICB4bWxhdHRycy5hcHBlbmQobikKICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWQu
YXBwZW5kKGEpCiAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlCiAgICAgICAg
cmV0dXJuIGluaGVyaXRlZAoKCiAgICBkZWYgX2RvX2RvY3VtZW50KHNlbGYsIG5vZGUpOgogICAg
ICAgICcnJ19kb19kb2N1bWVudChzZWxmLCBub2RlKSAtPiBOb25lCiAgICAgICAgUHJvY2VzcyBh
IGRvY3VtZW50IG5vZGUuIGRvY3VtZW50T3JkZXIgaG9sZHMgd2hldGhlciB0aGUgZG9jdW1lbnQK
ICAgICAgICBlbGVtZW50IGhhcyBiZWVuIGVuY291bnRlcmVkIHN1Y2ggdGhhdCBQSXMvY29tbWVu
dHMgY2FuIGJlIHdyaXR0ZW4KICAgICAgICBhcyBzcGVjaWZpZWQuJycnCgogICAgICAgIHNlbGYu
ZG9jdW1lbnRPcmRlciA9IF9MZXNzZXJFbGVtZW50CiAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUu
Y2hpbGROb2RlczoKICAgICAgICAgICAgaWYgY2hpbGQubm9kZVR5cGUgPT0gTm9kZS5FTEVNRU5U
X05PREU6CiAgICAgICAgICAgICAgICBzZWxmLmRvY3VtZW50T3JkZXIgPSBfRWxlbWVudCAgICAg
ICAgIyBBdCBkb2N1bWVudCBlbGVtZW50CiAgICAgICAgICAgICAgICBzZWxmLl9kb19lbGVtZW50
KGNoaWxkKQogICAgICAgICAgICAgICAgc2VsZi5kb2N1bWVudE9yZGVyID0gX0dyZWF0ZXJFbGVt
ZW50ICMgQWZ0ZXIgZG9jdW1lbnQgZWxlbWVudAogICAgICAgICAgICBlbGlmIGNoaWxkLm5vZGVU
eXBlID09IE5vZGUuUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOgogICAgICAgICAgICAgICAg
c2VsZi5fZG9fcGkoY2hpbGQpCiAgICAgICAgICAgIGVsaWYgY2hpbGQubm9kZVR5cGUgPT0gTm9k
ZS5DT01NRU5UX05PREU6CiAgICAgICAgICAgICAgICBzZWxmLl9kb19jb21tZW50KGNoaWxkKQog
ICAgICAgICAgICBlbGlmIGNoaWxkLm5vZGVUeXBlID09IE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RF
OgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAg
cmFpc2UgVHlwZUVycm9yLCBzdHIoY2hpbGQpCiAgICBoYW5kbGVyc1tOb2RlLkRPQ1VNRU5UX05P
REVdID0gX2RvX2RvY3VtZW50CgoKICAgIGRlZiBfZG9fdGV4dChzZWxmLCBub2RlKToKICAgICAg
ICAnJydfZG9fdGV4dChzZWxmLCBub2RlKSAtPiBOb25lCiAgICAgICAgUHJvY2VzcyBhIHRleHQg
b3IgQ0RBVEEgbm9kZS4gIFJlbmRlciB2YXJpb3VzIHNwZWNpYWwgY2hhcmFjdGVycwogICAgICAg
IGFzIHRoZWlyIEMxNE4gZW50aXR5IHJlcHJlc2VudGF0aW9ucy4nJycKICAgICAgICBpZiBub3Qg
X2luX3N1YnNldChzZWxmLnN1YnNldCwgbm9kZSk6IHJldHVybgogICAgICAgIHMgPSBzdHJpbmcu
cmVwbGFjZShub2RlLmRhdGEsICImIiwgIiZhbXA7IikKICAgICAgICBzID0gc3RyaW5nLnJlcGxh
Y2UocywgIjwiLCAiJmx0OyIpCiAgICAgICAgcyA9IHN0cmluZy5yZXBsYWNlKHMsICI+IiwgIiZn
dDsiKQogICAgICAgIHMgPSBzdHJpbmcucmVwbGFjZShzLCAiXDAxNSIsICImI3hEOyIpCiAgICAg
ICAgaWYgczogc2VsZi53cml0ZShzKQogICAgaGFuZGxlcnNbTm9kZS5URVhUX05PREVdID0gX2Rv
X3RleHQKICAgIGhhbmRsZXJzW05vZGUuQ0RBVEFfU0VDVElPTl9OT0RFXSA9IF9kb190ZXh0CgoK
ICAgIGRlZiBfZG9fcGkoc2VsZiwgbm9kZSk6CiAgICAgICAgJycnX2RvX3BpKHNlbGYsIG5vZGUp
IC0+IE5vbmUKICAgICAgICBQcm9jZXNzIGEgUEkgbm9kZS4gUmVuZGVyIGEgbGVhZGluZyBvciB0
cmFpbGluZyAjeEEgaWYgdGhlCiAgICAgICAgZG9jdW1lbnQgb3JkZXIgb2YgdGhlIFBJIGlzIGdy
ZWF0ZXIgb3IgbGVzc2VyIChyZXNwZWN0aXZlbHkpCiAgICAgICAgdGhhbiB0aGUgZG9jdW1lbnQg
ZWxlbWVudC4KICAgICAgICAnJycKICAgICAgICBpZiBub3QgX2luX3N1YnNldChzZWxmLnN1YnNl
dCwgbm9kZSk6IHJldHVybgogICAgICAgIFcgPSBzZWxmLndyaXRlCiAgICAgICAgaWYgc2VsZi5k
b2N1bWVudE9yZGVyID09IF9HcmVhdGVyRWxlbWVudDogVygnXG4nKQogICAgICAgIFcoJzw/JykK
ICAgICAgICBXKG5vZGUubm9kZU5hbWUpCiAgICAgICAgcyA9IG5vZGUuZGF0YQogICAgICAgIGlm
IHM6CiAgICAgICAgICAgIFcoJyAnKQogICAgICAgICAgICBXKHMpCiAgICAgICAgVygnPz4nKQog
ICAgICAgIGlmIHNlbGYuZG9jdW1lbnRPcmRlciA9PSBfTGVzc2VyRWxlbWVudDogVygnXG4nKQog
ICAgaGFuZGxlcnNbTm9kZS5QUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREVdID0gX2RvX3BpCgoK
ICAgIGRlZiBfZG9fY29tbWVudChzZWxmLCBub2RlKToKICAgICAgICAnJydfZG9fY29tbWVudChz
ZWxmLCBub2RlKSAtPiBOb25lCiAgICAgICAgUHJvY2VzcyBhIGNvbW1lbnQgbm9kZS4gUmVuZGVy
IGEgbGVhZGluZyBvciB0cmFpbGluZyAjeEEgaWYgdGhlCiAgICAgICAgZG9jdW1lbnQgb3JkZXIg
b2YgdGhlIGNvbW1lbnQgaXMgZ3JlYXRlciBvciBsZXNzZXIgKHJlc3BlY3RpdmVseSkKICAgICAg
ICB0aGFuIHRoZSBkb2N1bWVudCBlbGVtZW50LgogICAgICAgICcnJwogICAgICAgIGlmIG5vdCBf
aW5fc3Vic2V0KHNlbGYuc3Vic2V0LCBub2RlKTogcmV0dXJuCiAgICAgICAgaWYgc2VsZi5jb21t
ZW50czoKICAgICAgICAgICAgVyA9IHNlbGYud3JpdGUKICAgICAgICAgICAgaWYgc2VsZi5kb2N1
bWVudE9yZGVyID09IF9HcmVhdGVyRWxlbWVudDogVygnXG4nKQogICAgICAgICAgICBXKCc8IS0t
JykKICAgICAgICAgICAgVyhub2RlLmRhdGEpCiAgICAgICAgICAgIFcoJy0tPicpCiAgICAgICAg
ICAgIGlmIHNlbGYuZG9jdW1lbnRPcmRlciA9PSBfTGVzc2VyRWxlbWVudDogVygnXG4nKQogICAg
aGFuZGxlcnNbTm9kZS5DT01NRU5UX05PREVdID0gX2RvX2NvbW1lbnQKCgogICAgZGVmIF9kb19h
dHRyKHNlbGYsIG4sIHZhbHVlKToKICAgICAgICAnJycnX2RvX2F0dHIoc2VsZiwgbm9kZSkgLT4g
Tm9uZQogICAgICAgIFByb2Nlc3MgYW4gYXR0cmlidXRlLicnJwoKICAgICAgICBXID0gc2VsZi53
cml0ZQogICAgICAgIFcoJyAnKQogICAgICAgIFcobikKICAgICAgICBXKCc9IicpCiAgICAgICAg
cyA9IHN0cmluZy5yZXBsYWNlKHZhbHVlLCAiJiIsICImYW1wOyIpCiAgICAgICAgcyA9IHN0cmlu
Zy5yZXBsYWNlKHMsICI8IiwgIiZsdDsiKQogICAgICAgIHMgPSBzdHJpbmcucmVwbGFjZShzLCAn
IicsICcmcXVvdDsnKQogICAgICAgIHMgPSBzdHJpbmcucmVwbGFjZShzLCAnXDAxMScsICcmI3g5
JykKICAgICAgICBzID0gc3RyaW5nLnJlcGxhY2UocywgJ1wwMTInLCAnJiN4QScpCiAgICAgICAg
cyA9IHN0cmluZy5yZXBsYWNlKHMsICdcMDE1JywgJyYjeEQnKQogICAgICAgIFcocykKICAgICAg
ICBXKCciJykKCgogICAgZGVmIF9kb19lbGVtZW50KHNlbGYsIG5vZGUsIGluaXRpYWxfb3RoZXJf
YXR0cnMgPSBbXSk6CiAgICAgICAgJycnX2RvX2VsZW1lbnQoc2VsZiwgbm9kZSwgaW5pdGlhbF9v
dGhlcl9hdHRycyA9IFtdKSAtPiBOb25lCiAgICAgICAgUHJvY2VzcyBhbiBlbGVtZW50IChhbmQg
aXRzIGNoaWxkcmVuKS4nJycKCiAgICAgICAgIyBHZXQgc3RhdGUgKGZyb20gdGhlIHN0YWNrKSBt
YWtlIGxvY2FsIGNvcGllcy4KICAgICAgICAjICAgICAgICBuc19wYXJlbnQgLS0gTlMgZGVjbGFy
YXRpb25zIGluIHBhcmVudAogICAgICAgICMgICAgICAgIG5zX3JlbmRlcmVkIC0tIE5TIG5vZGVz
IHJlbmRlcmVkIGJ5IGFuY2VzdG9ycwogICAgICAgICMgICAgICAgIHhtbF9hdHRycyAtLSBBdHRy
aWJ1dGVzIGluIFhNTCBuYW1lc3BhY2UgZnJvbSBwYXJlbnQKICAgICAgICAjICAgICAgICBuc19s
b2NhbCAtLSBOUyBkZWNsYXJhdGlvbnMgcmVsZXZhbnQgdG8gdGhpcyBlbGVtZW50CiAgICAgICAg
bnNfcGFyZW50LCBuc19yZW5kZXJlZCwgeG1sX2F0dHJzID0gXAogICAgICAgICAgICAgICAgc2Vs
Zi5zdGF0ZVswXSwgc2VsZi5zdGF0ZVsxXS5jb3B5KCksIHNlbGYuc3RhdGVbMl1bOl0gIzA0MTcK
ICAgICAgICBuc19sb2NhbCA9IG5zX3BhcmVudC5jb3B5KCkKCiAgICAgICAgIyBEaXZpZGUgYXR0
cmlidXRlcyBpbnRvIE5TLCBYTUwsIGFuZCBvdGhlcnMuCiAgICAgICAgb3RoZXJfYXR0cnMgPSBp
bml0aWFsX290aGVyX2F0dHJzWzpdCiAgICAgICAgaW5fc3Vic2V0ID0gX2luX3N1YnNldChzZWxm
LnN1YnNldCwgbm9kZSkKICAgICAgICBmb3IgYSBpbiBfYXR0cnMobm9kZSk6CiAgICAgICAgICAg
IGlmIGEubmFtZXNwYWNlVVJJID09IFhNTE5TLkJBU0U6CiAgICAgICAgICAgICAgICBuID0gYS5u
b2RlTmFtZQogICAgICAgICAgICAgICAgaWYgbiA9PSAieG1sbnM6IjogbiA9ICJ4bWxucyIgICAg
ICAgICMgRE9NIGJ1ZyB3b3JrYXJvdW5kCiAgICAgICAgICAgICAgICBuc19sb2NhbFtuXSA9IGEu
bm9kZVZhbHVlCiAgICAgICAgICAgIGVsaWYgYS5uYW1lc3BhY2VVUkkgPT0gWE1MTlMuWE1MOgog
ICAgICAgICAgICAgICAgaWYgc2VsZi51bnN1cHByZXNzZWRQcmVmaXhlcyA9PSBOb25lIG9yIGlu
X3N1YnNldDoKICAgICAgICAgICAgICAgICAgICB4bWxfYXR0cnMuYXBwZW5kKGEpCiAgICAgICAg
ICAgIGVsc2U6CiAgICAgICAgICAgICAgICBvdGhlcl9hdHRycy5hcHBlbmQoYSkKCiAgICAgICAg
IyBSZW5kZXIgdGhlIG5vZGUKICAgICAgICBXLCBuYW1lID0gc2VsZi53cml0ZSwgTm9uZQogICAg
ICAgIGlmIGluX3N1YnNldDoKICAgICAgICAgICAgbmFtZSA9IG5vZGUubm9kZU5hbWUKICAgICAg
ICAgICAgVygnPCcpCiAgICAgICAgICAgIFcobmFtZSkKCiAgICAgICAgICAgICMgQ3JlYXRlIGxp
c3Qgb2YgTlMgYXR0cmlidXRlcyB0byByZW5kZXIuCiAgICAgICAgICAgIG5zX3RvX3JlbmRlciA9
IFtdCiAgICAgICAgICAgIGZvciBuLHYgaW4gbnNfbG9jYWwuaXRlbXMoKToKICAgICAgICAgICAg
ICAgIHB2YWwgPSBuc19wYXJlbnQuZ2V0KG4pCgogICAgICAgICAgICAgICAgIyBJZiBkZWZhdWx0
IG5hbWVzcGFjZSBpcyBYTUxOUy5CQVNFIG9yIGVtcHR5LAogICAgICAgICAgICAgICAgIyBhbmQg
aWYgYW4gYW5jZXN0b3Igd2FzIHRoZSBzYW1lCiAgICAgICAgICAgICAgICBpZiBuID09ICJ4bWxu
cyIgYW5kIHYgaW4gWyBYTUxOUy5CQVNFLCAnJyBdIFwKICAgICAgICAgICAgICAgIGFuZCBuc19y
ZW5kZXJlZC5nZXQoJ3htbG5zJykgaW4gWyBYTUxOUy5CQVNFLCAnJywgTm9uZSBdOgogICAgICAg
ICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAgICAgIyAib21pdCBuYW1lc3BhY2Ug
bm9kZSB3aXRoIGxvY2FsIG5hbWUgeG1sLCB3aGljaCBkZWZpbmVzCiAgICAgICAgICAgICAgICAj
IHRoZSB4bWwgcHJlZml4LCBpZiBpdHMgc3RyaW5nIHZhbHVlIGlzCiAgICAgICAgICAgICAgICAj
IGh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZS4iCiAgICAgICAgICAgICAgICBp
ZiBuIGluIFsieG1sbnM6eG1sIiwgInhtbCJdIFwKICAgICAgICAgICAgICAgIGFuZCB2IGluIFsg
J2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZScgXToKICAgICAgICAgICAgICAg
ICAgICBjb250aW51ZQoKCiAgICAgICAgICAgICAgICAjIElmIG5vdCBwcmV2aW91c2x5IHJlbmRl
cmVkCiAgICAgICAgICAgICAgICAjIGFuZCBpdCdzIGluY2x1c2l2ZSAoc2VsZi51bnN1cHByZXNz
ZWRQcmVmaXhlcyA9PSBOb25lKSAgb3IgdXRpbGl6ZWQKICAgICAgICAgICAgICAgIGlmIChuLHYp
IG5vdCBpbiBuc19yZW5kZXJlZC5pdGVtcygpIFwKICAgICAgICAgICAgICAgICAgYW5kIChzZWxm
LnVuc3VwcHJlc3NlZFByZWZpeGVzID09IE5vbmUgb3IgXAogICAgICAgICAgICAgICAgICBfdXRp
bGl6ZWQobiwgbm9kZSwgb3RoZXJfYXR0cnMsIHNlbGYudW5zdXBwcmVzc2VkUHJlZml4ZXMpKToK
ICAgICAgICAgICAgICAgICAgICBuc190b19yZW5kZXIuYXBwZW5kKChuLCB2KSkKCiAgICAgICAg
ICAgICMgU29ydCBhbmQgcmVuZGVyIHRoZSBucywgbWFya2luZyB3aGF0IHdhcyByZW5kZXJlZC4K
ICAgICAgICAgICAgbnNfdG9fcmVuZGVyLnNvcnQoX3NvcnRlcl9ucykKICAgICAgICAgICAgZm9y
IG4sdiBpbiBuc190b19yZW5kZXI6CiAgICAgICAgICAgICAgICBzZWxmLl9kb19hdHRyKG4sIHYp
CiAgICAgICAgICAgICAgICBuc19yZW5kZXJlZFtuXT12ICAgICMwNDE3CgogICAgICAgICAgICAj
IEFkZCBpbiB0aGUgWE1MIGF0dHJpYnV0ZXMgKGRvbid0IHBhc3MgdG8gY2hpbGRyZW4sIHNpbmNl
CiAgICAgICAgICAgICMgd2UncmUgcmVuZGVyaW5nIHRoZW0pLCBzb3J0LCBhbmQgcmVuZGVyLgog
ICAgICAgICAgICBvdGhlcl9hdHRycy5leHRlbmQoeG1sX2F0dHJzKQogICAgICAgICAgICB4bWxf
YXR0cnMgPSBbXQogICAgICAgICAgICBvdGhlcl9hdHRycy5zb3J0KF9zb3J0ZXIpCiAgICAgICAg
ICAgIGZvciBhIGluIG90aGVyX2F0dHJzOgogICAgICAgICAgICAgICAgc2VsZi5fZG9fYXR0cihh
Lm5vZGVOYW1lLCBhLnZhbHVlKQogICAgICAgICAgICBXKCc+JykKCiAgICAgICAgIyBQdXNoIHN0
YXRlLCByZWN1cnNlLCBwb3Agc3RhdGUuCiAgICAgICAgc3RhdGUsIHNlbGYuc3RhdGUgPSBzZWxm
LnN0YXRlLCAobnNfbG9jYWwsIG5zX3JlbmRlcmVkLCB4bWxfYXR0cnMpCiAgICAgICAgZm9yIGMg
aW4gX2NoaWxkcmVuKG5vZGUpOgogICAgICAgICAgICBfaW1wbGVtZW50YXRpb24uaGFuZGxlcnNb
Yy5ub2RlVHlwZV0oc2VsZiwgYykKICAgICAgICBzZWxmLnN0YXRlID0gc3RhdGUKCiAgICAgICAg
aWYgbmFtZTogVygnPC8lcz4nICUgbmFtZSkKICAgIGhhbmRsZXJzW05vZGUuRUxFTUVOVF9OT0RF
XSA9IF9kb19lbGVtZW50CgoKZGVmIENhbm9uaWNhbGl6ZShub2RlLCBvdXRwdXQ9Tm9uZSwgKipr
dyk6CiAgICAnJydDYW5vbmljYWxpemUobm9kZSwgb3V0cHV0PU5vbmUsICoqa3cpIC0+IFVURi04
CgogICAgQ2Fub25pY2FsaXplIGEgRE9NIGRvY3VtZW50L2VsZW1lbnQgbm9kZSBhbmQgYWxsIGRl
c2NlbmRlbnRzLgogICAgUmV0dXJuIHRoZSB0ZXh0OyBpZiBvdXRwdXQgaXMgc3BlY2lmaWVkIHRo
ZW4gb3V0cHV0LndyaXRlIHdpbGwKICAgIGJlIGNhbGxlZCB0byBvdXRwdXQgdGhlIHRleHQgYW5k
IE5vbmUgd2lsbCBiZSByZXR1cm5lZAogICAgS2V5d29yZCBwYXJhbWV0ZXJzOgogICAgICAgIG5z
ZGljdDogYSBkaWN0aW9uYXJ5IG9mIHByZWZpeDp1cmkgbmFtZXNwYWNlIGVudHJpZXMKICAgICAg
ICAgICAgICAgIGFzc3VtZWQgdG8gZXhpc3QgaW4gdGhlIHN1cnJvdW5kaW5nIGNvbnRleHQKICAg
ICAgICBjb21tZW50czoga2VlcCBjb21tZW50cyBpZiBub24temVybyAoZGVmYXVsdCBpcyAwKQog
ICAgICAgIHN1YnNldDogQ2Fub25pY2FsIFhNTCBzdWJzZXR0aW5nIHJlc3VsdGluZyBmcm9tIFhQ
YXRoCiAgICAgICAgICAgICAgICAoZGVmYXVsdCBpcyBbXSkKICAgICAgICB1bnN1cHByZXNzZWRQ
cmVmaXhlczogZG8gZXhjbHVzaXZlIEMxNE4sIGFuZCB0aGlzIHNwZWNpZmllcyB0aGUKICAgICAg
ICAgICAgICAgIHByZWZpeGVzIHRoYXQgc2hvdWxkIGJlIGluaGVyaXRlZC4KICAgICcnJwogICAg
aWYgb3V0cHV0OgogICAgICAgIGFwcGx5KF9pbXBsZW1lbnRhdGlvbiwgKG5vZGUsIG91dHB1dC53
cml0ZSksIGt3KQogICAgZWxzZToKICAgICAgICBzID0gU3RyaW5nSU8uU3RyaW5nSU8oKQogICAg
ICAgIGFwcGx5KF9pbXBsZW1lbnRhdGlvbiwgKG5vZGUsIHMud3JpdGUpLCBrdykKICAgICAgICBy
ZXR1cm4gcy5nZXR2YWx1ZSgpCg==

--------------Boundary-00=_JA8Q2531E7NEDBEUJMXV--