Re: Append with naive multiplexing of FDWs

Ahsan Hadi <[email protected]> Tue, 14 Jan 2020 14:37:48 +0500
Newsgroups gmane.comp.db.postgresql.devel.general
Message-ID <CA+9bhCK7chd0qx+mny+U9xaOs2FDNJ7RaxG4=9rpgT6oAKBgWA@mail.gmail.com>
--00000000000001b2b2059c16598a
Content-Type: multipart/alternative; boundary="00000000000001b2b0059c165988"

--00000000000001b2b0059c165988
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi Hackers,

Sharing the email below from Movead Li, I believe he wanted to share the
benchmarking results as a response to this email thread but it started a
new thread.. Here it is...

"
Hello

I have tested the patch with a partition table with several foreign
partitions living on seperate data nodes. The initial testing was done
with a partition table having 3 foreign partitions, test was done with
variety of scale facters. The seonnd test was with fixed data per data
node but number of data nodes were increased incrementally to see
the peformance impact as more nodes are added to the cluster. The
test three is similar to the initial test but with much huge data and
4 nodes.

The results are summary is given below and test script attached:

*Test ENV*
Parent node:2Core 8G
Child Nodes:2Core 4G


*Test one:*

1.1 The partition struct as below:

 [ ptf:(a int, b int, c varchar)]
    (Parent node)
        |             |             |
    [ptf1]      [ptf2]      [ptf3]
 (Node1)   (Node2)    (Node3)

The table data is partitioned across nodes, the test is done using a
simple select query and a count aggregate as shown below. The result
is an average of executing each query multiple times to ensure reliable
and consistent results.

=E2=91=A0select * from ptf where b =3D 100;
=E2=91=A1select count(*) from ptf;

1.2. Test Results

 For =E2=91=A0 result:
       scalepernode    master    patched     performance
           2G                    7s             2s               350%
           5G                    173s         63s             275%
           10G                  462s         156s           296%
           20G                  968s         327s           296%
           30G                  1472s       494s           297%

 For =E2=91=A1 result:
       scalepernode    master    patched     performance
           2G                    1079s       291s           370%
           5G                    2688s       741s           362%
           10G                  4473s       1493s         299%

It takes too long time to test a aggregate so the test was done with a
smaller data size.


1.3. summary

With the table partitioned over 3 nodes, the average performance gain
across variety of scale factors is almost 300%


*Test Two*
2.1 The partition struct as below:

 [ ptf:(a int, b int, c varchar)]
    (Parent node)
        |             |             |
    [ptf1]         ...      [ptfN]
 (Node1)      (...)    (NodeN)

=E2=91=A0select * from ptf
=E2=91=A1select * from ptf where b =3D 100;

This test is done with same size of data per node but table is partitioned
across N number of nodes. Each varation (master or patches) is tested
at-least 3 times to get reliable and consistent results. The purpose of the
test is to see impact on performance as number of data nodes are increased.

2.2 The results

For =E2=91=A0 result=EF=BC=88scalepernode=3D2G=EF=BC=89:
    nodenumber  master    patched     performance
             2             432s        180s              240%
             3             636s         223s             285%
             4             830s         283s             293%
             5             1065s       361s             295%
For =E2=91=A1 result=EF=BC=88scalepernode=3D10G=EF=BC=89:
    nodenumber  master    patched     performance
             2             281s        140s             201%
             3             421s        140s             300%
             4             562s        141s             398%
             5             702s        141s             497%
             6             833s        139s             599%
             7             986s        141s             699%
             8             1125s      140s             803%


*Test Three*

This test is similar to the [test one] but with much huge data and
4 nodes.

For =E2=91=A0 result:
    scalepernode    master    patched     performance
      100G                6592s       1649s         399%
For =E2=91=A1 result:
    scalepernode    master    patched     performance
      100G                35383      12363         286%
The result show it work well in much huge data.


*Summary*
The patch is pretty good, it works well when there were little data back to
the parent node. The patch doesn=E2=80=99t provide parallel FDW scan, it en=
sures
that child nodes can send data to parent in parallel but  the parent can
only
sequennly process the data from data nodes.

Providing there is no performance degrdation for non FDW append queries,
I would recomend to consider this patch as an interim soluton while we are
waiting for parallel FDW scan.
"



On Thu, Dec 12, 2019 at 5:41 PM Kyotaro Horiguchi <[email protected]>
wrote:

> Hello.
>
> I think I can say that this patch doesn't slows non-AsyncAppend,
> non-postgres_fdw scans.
>
>
> At Mon, 9 Dec 2019 12:18:44 -0500, Bruce Momjian <[email protected]> wrote
> in
> > Certainly any overhead on normal queries would be unacceptable.
>
> I took performance numbers on the current shape of the async execution
> patch for the following scan cases.
>
> t0   : single local table (parallel disabled)
> pll  : local partitioning (local Append, parallel disabled)
> ft0  : single foreign table
> pf0  : inheritance on 4 foreign tables, single connection
> pf1  : inheritance on 4 foreign tables, 4 connections
> ptf0 : partition on 4 foreign tables, single connection
> ptf1 : partition on 4 foreign tables, 4 connections
>
> The benchmarking system is configured as the follows on a single
> machine.
>
>           [ benchmark client   ]
>            |                  |
>     (localhost:5433)    (localhost:5432)
>            |                  |
>    +----+  |   +------+       |
>    |    V  V   V      |       V
>    | [master server]  |  [async server]
>    |       V          |       V
>    +--fdw--+          +--fdw--+
>
>
> The patch works roughly in the following steps.
>
> 1. Planner decides how many children out of an append can run
>   asynchrnously (called as async-capable.).
>
> 2. While ExecInit if an Append doesn't have an async-capable children,
>   ExecAppend that is exactly the same function is set as
>   ExecProcNode. Otherwise ExecAppendAsync is used.
>
> If the infrastructure part in the patch causes any degradation, the
> "t0"(scan on local single table) and/or "pll" test (scan on a local
> paritioned table) gets slow.
>
> 3. postgresql_fdw always runs async-capable code path.
>
> If the postgres_fdw part causes degradation, ft0 reflects that.
>
>
> The tables has two integers and the query does sum(a) on all tuples.
>
> With the default fetch_size =3D 100, number is run time in ms.  Each
> number is the average of 14 runs.
>
>      master  patched   gain
> t0   7325    7130     +2.7%
> pll  4558    4484     +1.7%
> ft0  3670    3675     -0.1%
> pf0  2322    1550    +33.3%
> pf1  2367    1475    +37.7%
> ptf0 2517    1624    +35.5%
> ptf1 2343    1497    +36.2%
>
> With larger fetch_size (200) the gain mysteriously decreases for
> sharing single connection cases (pf0, ptf0), but others don't seem
> change so much.
>
>      master  patched   gain
> t0   7212    7252     -0.6%
> pll  4546    4397     +3.3%
> ft0  3712    3731     -0.5%
> pf0  2131    1570    +26.4%
> pf1  1926    1189    +38.3%
> ptf0 2001    1557    +22.2%
> ptf1 1903    1193    +37.4%
>
> FWIW, attached are the test script.
>
> gentblr2.sql: Table creation script.
> testrun.sh  : Benchmarking script.
>
>
> regards.
>
> --
> Kyotaro Horiguchi
> NTT Open Source Software Center
>

--00000000000001b2b0059c165988
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div>Hi Hackers,</div><d=
iv><br></div><div>Sharing the email below from Movead Li, I believe he want=
ed to share the benchmarking results as a response to this email thread but=
 it started a new thread.. Here it is...</div><div><br></div><div>&quot;</d=
iv><div>Hello</div><div><br></div><div><div style=3D"font-family:&quot;Micr=
osoft YaHei UI&quot;,Tahoma;line-height:normal">I have tested the patch wit=
h a partition table with several foreign</div><div style=3D"font-family:&qu=
ot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal">partitions living on=
 seperate data nodes. The initial testing was done</div><div style=3D"font-=
family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal">with a par=
tition table having 3 foreign partitions, test was done=C2=A0<span style=3D=
"font-size:10.5pt;background-color:transparent">with</span></div><div style=
=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><=
span style=3D"font-size:10.5pt;background-color:transparent">variety of sca=
le facters. The seonnd test was with fixed data=C2=A0</span><span style=3D"=
font-size:10.5pt;background-color:transparent">per data</span></div><div st=
yle=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal=
"><span style=3D"font-size:10.5pt;background-color:transparent">node but nu=
mber of data nodes were increased incrementally=C2=A0</span><span style=3D"=
font-size:10.5pt;background-color:transparent">to see</span></div><div styl=
e=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal">=
<span style=3D"font-size:10.5pt;background-color:transparent">the peformanc=
e impact as more nodes are added=C2=A0</span><span style=3D"font-size:10.5p=
t;background-color:transparent">to the cluster.=C2=A0</span><span style=3D"=
font-size:10.5pt;background-color:transparent">The</span></div><div style=
=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><=
span style=3D"font-size:10.5pt;background-color:transparent">test three=C2=
=A0is similar to the=C2=A0initial=C2=A0test but with=C2=A0</span><span styl=
e=3D"font-size:10.5pt;background-color:transparent">much huge data and</spa=
n></div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;lin=
e-height:normal"><span style=3D"font-size:10.5pt;background-color:transpare=
nt">4 nodes.</span></div><div style=3D"font-family:&quot;Microsoft YaHei UI=
&quot;,Tahoma;line-height:normal"><br></div><div style=3D"font-family:&quot=
;Microsoft YaHei UI&quot;,Tahoma;line-height:normal">The results are summar=
y is given below and test script attached:</div></div><div style=3D"font-fa=
mily:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><br></div><d=
iv style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:n=
ormal"><div><b>Test ENV</b></div><div>Parent node:2Core 8G</div><div>Child =
Nodes:2Core 4G</div><div><br></div><div><br></div></div><div style=3D"font-=
family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><div><b>Te=
st one:</b></div><div><br></div><div>1.1 The partition struct as below:</di=
v><div><br></div><div>=C2=A0[ ptf:(a int, b int, c varchar)]</div><div>=C2=
=A0 =C2=A0=C2=A0(Parent node)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 | =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 |</div><div>=C2=A0 =C2=A0 [ptf1] =C2=A0 =C2=A0 =C2=A0[ptf2] =C2=A0 =
=C2=A0 =C2=A0[ptf3]</div><div>=C2=A0(Node1) =C2=A0 (Node2) =C2=A0 =C2=A0(No=
de3)</div><div><br></div><div>The table data is partitioned across nodes, t=
he test is done using a</div><div>simple=C2=A0<span style=3D"font-size:10.5=
pt;background-color:transparent">select query and a count=C2=A0aggregate as=
 shown below.=C2=A0The result</span></div><div><span style=3D"font-size:10.=
5pt;background-color:transparent">is an=C2=A0</span><span style=3D"font-siz=
e:10.5pt;background-color:transparent">average=C2=A0</span><span style=3D"f=
ont-size:10.5pt;background-color:transparent">of executing each query multi=
ple times to ensure reliable</span></div><div><span style=3D"font-size:10.5=
pt;background-color:transparent">and=C2=A0</span><span style=3D"font-size:1=
0.5pt;background-color:transparent">consistent=C2=A0</span><span style=3D"f=
ont-size:10.5pt;background-color:transparent">results.</span></div><div><br=
></div><div>=E2=91=A0select * from ptf where b =3D 100;</div><div>=E2=91=A1=
select count(*) from=C2=A0ptf;</div><div><br></div><div><div>1.2. Test Resu=
lts</div><div><br></div><div><b>=C2=A0</b>For =E2=91=A0 result:</div><div>=
=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0scalepernode =C2=A0 =C2=A0master=C2=A0 =C2=
=A0 patched =C2=A0 =C2=A0 performance</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A02G=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 7s =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 2s=
=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0350%<=
/div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A05G=C2=A0 =C2=A0=C2=A0=C2=
=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 173s =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 63s =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 275%</di=
v><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A010G=C2=A0 =C2=A0=C2=A0=C2=
=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 462s =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 156s =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 296%</div><div>=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A020G=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=
=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 968s =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 327s =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0296%</div><div>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A030G=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =
=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 1472s =C2=A0 =C2=A0 =C2=A0 494s =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0297%</div><div>=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=
=A0=C2=A0=C2=A0 =C2=A0</div><div><b>=C2=A0</b>For =E2=91=A1 result:</div><d=
iv>=C2=A0 =C2=A0 =C2=A0 =C2=A0scalepernode =C2=A0 =C2=A0master=C2=A0 =C2=A0=
 patched=C2=A0=C2=A0 =C2=A0 performance</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A02G=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=
=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A01079s =C2=A0 =C2=A0 =C2=A0=C2=A0291s =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 370%</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A05G=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=
=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 2688s =C2=A0 =C2=A0 =C2=A0 741s =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 362%</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A010G=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =
=C2=A0 =C2=A0 4473s =C2=A0 =C2=A0 =C2=A0 1493s =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
299%</div><div><br></div><div>It takes too long time to test a=C2=A0aggrega=
te so the test was done with a</div><div>smaller=C2=A0<span style=3D"font-s=
ize:10.5pt;background-color:transparent">data size.</span></div></div><div>=
<br></div><div><br></div><div><div>1.3. summary</div><div><br></div><div>Wi=
th the table partitioned over 3 nodes, the average performance gain</div><d=
iv>across variety of scale factors is almost 300%</div></div></div><div><br=
></div><div><br></div><div><div style=3D"font-family:&quot;Microsoft YaHei =
UI&quot;,Tahoma;line-height:normal"><b>Test Two</b></div><div style=3D"font=
-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><b></b></=
div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-he=
ight:normal">2.1 The partition struct as below:</div><div style=3D"font-fam=
ily:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><br></div><di=
v style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:no=
rmal">=C2=A0[ ptf:(a int, b int, c varchar)]</div><div style=3D"font-family=
:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal">=C2=A0 =C2=A0=C2=
=A0(Parent node)</div><div style=3D"font-family:&quot;Microsoft YaHei UI&qu=
ot;,Tahoma;line-height:normal">=C2=A0 =C2=A0 =C2=A0 =C2=A0 | =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |</=
div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-he=
ight:normal">=C2=A0 =C2=A0 [ptf1] =C2=A0 =C2=A0 =C2=A0 =C2=A0 ... =C2=A0 =
=C2=A0 =C2=A0[ptfN]</div><div style=3D"font-family:&quot;Microsoft YaHei UI=
&quot;,Tahoma;line-height:normal">=C2=A0(Node1) =C2=A0 =C2=A0 =C2=A0(...) =
=C2=A0 =C2=A0(NodeN)</div><div style=3D"font-family:&quot;Microsoft YaHei U=
I&quot;,Tahoma;line-height:normal"><br></div><div style=3D"font-family:&quo=
t;Microsoft YaHei UI&quot;,Tahoma;line-height:normal">=E2=91=A0select * fro=
m ptf</div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;=
line-height:normal">=E2=91=A1select * from ptf where b =3D 100;</div><div s=
tyle=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:norma=
l"><br></div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahom=
a;line-height:normal">This test is done with same size of data per node but=
 table is partitioned</div><div style=3D"font-family:&quot;Microsoft YaHei =
UI&quot;,Tahoma;line-height:normal">across=C2=A0<span style=3D"font-size:10=
.5pt;background-color:transparent">N number=C2=A0</span><span style=3D"font=
-size:10.5pt;background-color:transparent">of nodes.=C2=A0Each varation (ma=
ster or patches) is tested</span></div><div style=3D"font-family:&quot;Micr=
osoft YaHei UI&quot;,Tahoma;line-height:normal"><span style=3D"font-size:10=
.5pt;background-color:transparent">at-least 3 times=C2=A0</span><span style=
=3D"font-size:10.5pt;background-color:transparent">to get reliable and=C2=
=A0</span><span style=3D"font-size:10.5pt;background-color:transparent">con=
sistent results. The purpose of the</span></div><div style=3D"font-family:&=
quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><span style=3D"fon=
t-size:10.5pt;background-color:transparent">test is to see impact on=C2=A0<=
/span><span style=3D"font-size:10.5pt;background-color:transparent">perform=
ance as number of=C2=A0</span><span style=3D"font-size:10.5pt;background-co=
lor:transparent">data nodes are increased.</span></div></div><div><br></div=
><div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-=
height:normal"><span style=3D"color:rgb(80,0,80)">2.2 The results</span></d=
iv><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-hei=
ght:normal"><br></div><div style=3D"line-height:normal"><font face=3D"Micro=
soft YaHei UI, Tahoma">For =E2=91=A0 result=EF=BC=88scalepernode=3D2G=EF=BC=
=89:</font></div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,T=
ahoma;line-height:normal"><span style=3D"color:rgb(80,0,80)"><span style=3D=
"color:rgb(0,0,0)">=C2=A0 =C2=A0=C2=A0nodenumber =C2=A0master=C2=A0 =C2=A0 =
patched =C2=A0 =C2=A0 performance</span></span></div><div style=3D"font-fam=
ily:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><span style=
=3D"color:rgb(80,0,80)"><span style=3D"color:rgb(0,0,0)">=C2=A0 =C2=A0=C2=
=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A02 =C2=A0=C2=A0=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0=C2=A0432s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 180s=C2=A0 =
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 240%</span></span></div=
><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-heigh=
t:normal"><span style=3D"color:rgb(80,0,80)"><span style=3D"color:rgb(0,0,0=
)">=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A03 =C2=A0=
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0636s=C2=A0 =C2=A0=
=C2=A0=C2=A0 =C2=A0 =C2=A0223s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =
=C2=A0 =C2=A0285%</span></span></div><div style=3D"font-family:&quot;Micros=
oft YaHei UI&quot;,Tahoma;line-height:normal"><span style=3D"color:rgb(80,0=
,80)"><span style=3D"color:rgb(0,0,0)">=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=
=A0=C2=A0=C2=A0 =C2=A0=C2=A04 =C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=
=C2=A0 =C2=A0830s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0283s=C2=A0 =C2=A0=
=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0293%</span></span></div><div s=
tyle=3D"line-height:normal"><span style=3D"font-family:&quot;Microsoft YaHe=
i UI&quot;,Tahoma;color:rgb(0,0,0)">=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=
=C2=A0 =C2=A0=C2=A0=C2=A05 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=
=A0=C2=A0=C2=A01065s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0361s=C2=A0 =C2=A0=C2=A0=
=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0</span><font face=3D"Microsoft YaHei UI, Tah=
oma">=C2=A0 =C2=A0295%</font></div><div style=3D"line-height:normal"></div>=
<div style=3D"line-height:normal"><font face=3D"Microsoft YaHei UI, Tahoma"=
>For =E2=91=A1 result=EF=BC=88scalepernode=3D10G=EF=BC=89:</font></div><div=
 style=3D"line-height:normal"><font face=3D"Microsoft YaHei UI, Tahoma">=C2=
=A0 =C2=A0=C2=A0nodenumber =C2=A0master=C2=A0 =C2=A0 patched =C2=A0 =C2=A0 =
performance</font></div><div style=3D"line-height:normal"><font face=3D"Mic=
rosoft YaHei UI, Tahoma">=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=
=A0=C2=A0=C2=A02 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0281s=
=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 140s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=
=C2=A0 =C2=A0 =C2=A0201%</font></div><div style=3D"font-family:&quot;Micros=
oft YaHei UI&quot;,Tahoma;line-height:normal"><span style=3D"color:rgb(80,0=
,80)"><span style=3D"color:rgb(0,0,0)">=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=
=A0=C2=A0 =C2=A0=C2=A0=C2=A03 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=
=C2=A0=C2=A0=C2=A0421s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 140s=C2=A0 =C2=A0=C2=
=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0300%</span></span></div><div styl=
e=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal">=
<span style=3D"color:rgb(80,0,80)"><span style=3D"color:rgb(0,0,0)">=C2=A0 =
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A04 =C2=A0=C2=A0 =C2=
=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0562s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=
=A0 141s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0398%</spa=
n></span></div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tah=
oma;line-height:normal"><span style=3D"color:rgb(80,0,80)"><span style=3D"c=
olor:rgb(0,0,0)">=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=
=C2=A05 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0702s=
=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 141s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=
=C2=A0 =C2=A0 =C2=A0497%</span></span></div><div style=3D"font-family:&quot=
;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><span style=3D"color:r=
gb(80,0,80)"><span style=3D"color:rgb(0,0,0)">=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=
=A0=C2=A0=C2=A0 =C2=A0 =C2=A06 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=
=C2=A0=C2=A0=C2=A0833s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 139s=C2=A0 =C2=A0=C2=
=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0599%</span></span></div><div styl=
e=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal">=
<span style=3D"color:rgb(80,0,80)"><span style=3D"color:rgb(0,0,0)">=C2=A0 =
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A07 =C2=A0=C2=A0=C2=A0 =C2=
=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 986s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 141=
s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0699%</span></spa=
n></div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;lin=
e-height:normal"><span style=3D"color:rgb(80,0,80)"><span style=3D"color:rg=
b(0,0,0)">=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A08=C2=A0=
 =C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A01125s=C2=A0 =C2=A0=
=C2=A0=C2=A0 140s=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0=
803%</span></span></div></div><div style=3D"font-family:&quot;Microsoft YaH=
ei UI&quot;,Tahoma;line-height:normal"><span style=3D"color:rgb(80,0,80)"><=
span style=3D"color:rgb(0,0,0)"><br></span></span></div><div style=3D"font-=
family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><span styl=
e=3D"color:rgb(80,0,80)"><span style=3D"color:rgb(0,0,0)"><br></span></span=
></div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line=
-height:normal"><b>Test Three</b></div><div style=3D"font-family:&quot;Micr=
osoft YaHei UI&quot;,Tahoma;line-height:normal"><span style=3D"color:rgb(80=
,0,80)"><span style=3D"color:rgb(0,0,0)"><br></span></span></div><div><div>=
<span style=3D"font-size:10.5pt;line-height:1.5;background-color:transparen=
t">This test is similar to the [test one] but with=C2=A0</span><span style=
=3D"font-size:10.5pt;line-height:1.5;background-color:transparent">much hug=
e data and=C2=A0</span></div><div><span style=3D"font-size:10.5pt;line-heig=
ht:1.5;background-color:transparent">4 nodes.</span></div><div><div><span s=
tyle=3D"font-size:10.5pt;line-height:1.5;background-color:transparent"><br>=
</span></div><div><span style=3D"font-size:10.5pt;line-height:1.5;backgroun=
d-color:transparent">For =E2=91=A0 result:</span></div><div><span style=3D"=
color:rgb(0,0,0);font-size:10.5pt;line-height:1.5;background-color:rgba(0,0=
,0,0)">=C2=A0 =C2=A0 scalepernode =C2=A0 =C2=A0master</span><span style=3D"=
color:rgb(0,0,0);font-size:10.5pt;line-height:1.5;background-color:rgba(0,0=
,0,0)">=C2=A0 =C2=A0 patched =C2=A0 =C2=A0 performance</span></div><div><sp=
an style=3D"font-size:10.5pt;line-height:1.5;background-color:transparent">=
=C2=A0 =C2=A0 =C2=A0 100G =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0</span><span style=3D"font-size:10.5pt;line-height:1.5;background-col=
or:transparent">6592</span><span style=3D"font-size:10.5pt;line-height:1.5;=
background-color:transparent">s =C2=A0 =C2=A0 =C2=A0=C2=A0</span><span styl=
e=3D"font-size:10.5pt;line-height:1.5;background-color:transparent">1649</s=
pan><span style=3D"font-size:10.5pt;line-height:1.5;background-color:transp=
arent">s =C2=A0 =C2=A0 =C2=A0 =C2=A0 399%</span></div><div>For =E2=91=A1 re=
sult:</div><div>=C2=A0 =C2=A0=C2=A0<span style=3D"color:rgb(0,0,0);font-siz=
e:10.5pt;line-height:1.5;background-color:rgba(0,0,0,0)">scalepernode =C2=
=A0 =C2=A0master</span><span style=3D"color:rgb(0,0,0);font-size:10.5pt;lin=
e-height:1.5;background-color:rgba(0,0,0,0)">=C2=A0 =C2=A0 patched</span>=
=C2=A0<span style=3D"font-size:10.5pt;line-height:1.5;background-color:tran=
sparent">=C2=A0 =C2=A0 performance</span></div><div><span style=3D"font-siz=
e:10.5pt;line-height:1.5;background-color:transparent">=C2=A0 =C2=A0 =C2=A0=
 100G =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A035383 =C2=A0 =
=C2=A0 =C2=A012363 =C2=A0 =C2=A0 =C2=A0 =C2=A0 286%</span></div><div><span =
style=3D"font-size:10.5pt;line-height:1.5;background-color:transparent">The=
 result show it work well in much huge data.</span></div></div></div><div><=
span style=3D"font-size:10.5pt;line-height:1.5;background-color:transparent=
"><br></span></div><div><span style=3D"font-size:10.5pt;line-height:1.5;bac=
kground-color:transparent"><br></span></div><div><div style=3D"font-family:=
&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><b>Summary</b></d=
iv><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-hei=
ght:normal"><b></b></div><div style=3D"font-family:&quot;Microsoft YaHei UI=
&quot;,Tahoma;line-height:normal">The patch is pretty good, it works well w=
hen there were little data=C2=A0<span style=3D"font-size:10.5pt;background-=
color:transparent">back to</span></div><div style=3D"font-family:&quot;Micr=
osoft YaHei UI&quot;,Tahoma;line-height:normal"><span style=3D"font-size:10=
.5pt;background-color:transparent">the parent node. The patch doesn=E2=80=
=99t provide parallel FDW scan, it ensures</span></div><div style=3D"font-f=
amily:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><span style=
=3D"font-size:10.5pt;background-color:transparent">that=C2=A0</span><span s=
tyle=3D"font-size:10.5pt;background-color:transparent">child nodes can send=
 data to parent in parallel but =C2=A0the=C2=A0parent=C2=A0can=C2=A0</span>=
<span style=3D"font-size:10.5pt;background-color:transparent">only</span></=
div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-he=
ight:normal"><span style=3D"font-size:10.5pt;background-color:transparent">=
sequennly process the data from data nodes.</span></div><div style=3D"font-=
family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:normal"><br></div>=
<div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height=
:normal">Providing there is no performance degrdation for non FDW append qu=
eries,</div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma=
;line-height:normal">I would recomend to consider this patch as an=C2=A0<sp=
an style=3D"font-size:10.5pt;background-color:transparent">interim soluton =
while we are</span></div><div style=3D"font-family:&quot;Microsoft YaHei UI=
&quot;,Tahoma;line-height:normal"><span style=3D"font-size:10.5pt;backgroun=
d-color:transparent">waiting for parallel FDW scan.</span></div></div><div =
style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;line-height:norm=
al"><span style=3D"font-size:10.5pt;background-color:transparent">&quot;</s=
pan></div><div style=3D"font-family:&quot;Microsoft YaHei UI&quot;,Tahoma;l=
ine-height:normal"><span style=3D"font-size:10.5pt;background-color:transpa=
rent"><br></span></div><div style=3D"font-family:&quot;Microsoft YaHei UI&q=
uot;,Tahoma;line-height:normal"><span style=3D"font-size:10.5pt;background-=
color:transparent"><br></span></div></div><br><div class=3D"gmail_quote"><d=
iv dir=3D"ltr" class=3D"gmail_attr">On Thu, Dec 12, 2019 at 5:41 PM Kyotaro=
 Horiguchi &lt;<a href=3D"mailto:[email protected]">horikyota.ntt@gma=
il.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;borde=
r-left-color:rgb(204,204,204);padding-left:1ex">Hello.<br>
<br>
I think I can say that this patch doesn&#39;t slows non-AsyncAppend,<br>
non-postgres_fdw scans.<br>
<br>
<br>
At Mon, 9 Dec 2019 12:18:44 -0500, Bruce Momjian &lt;<a href=3D"mailto:bruc=
[email protected]" target=3D"_blank">[email protected]</a>&gt; wrote in <br>
&gt; Certainly any overhead on normal queries would be unacceptable.<br>
<br>
I took performance numbers on the current shape of the async execution<br>
patch for the following scan cases.<br>
<br>
t0=C2=A0 =C2=A0: single local table (parallel disabled)<br>
pll=C2=A0 : local partitioning (local Append, parallel disabled)<br>
ft0=C2=A0 : single foreign table<br>
pf0=C2=A0 : inheritance on 4 foreign tables, single connection<br>
pf1=C2=A0 : inheritance on 4 foreign tables, 4 connections<br>
ptf0 : partition on 4 foreign tables, single connection<br>
ptf1 : partition on 4 foreign tables, 4 connections<br>
<br>
The benchmarking system is configured as the follows on a single<br>
machine.<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 [ benchmark client=C2=A0 =C2=A0]<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |<br>
=C2=A0 =C2=A0 (localhost:5433)=C2=A0 =C2=A0 (localhost:5432)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |<br>
=C2=A0 =C2=A0+----+=C2=A0 |=C2=A0 =C2=A0+------+=C2=A0 =C2=A0 =C2=A0 =C2=A0=
|<br>
=C2=A0 =C2=A0|=C2=A0 =C2=A0 V=C2=A0 V=C2=A0 =C2=A0V=C2=A0 =C2=A0 =C2=A0 |=
=C2=A0 =C2=A0 =C2=A0 =C2=A0V<br>
=C2=A0 =C2=A0| [master server]=C2=A0 |=C2=A0 [async server]<br>
=C2=A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0V=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 |=C2=A0 =C2=A0 =C2=A0 =C2=A0V<br>
=C2=A0 =C2=A0+--fdw--+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 +--fdw--+<br>
<br>
<br>
The patch works roughly in the following steps.<br>
<br>
1. Planner decides how many children out of an append can run<br>
=C2=A0 asynchrnously (called as async-capable.).<br>
<br>
2. While ExecInit if an Append doesn&#39;t have an async-capable children,<=
br>
=C2=A0 ExecAppend that is exactly the same function is set as<br>
=C2=A0 ExecProcNode. Otherwise ExecAppendAsync is used.<br>
<br>
If the infrastructure part in the patch causes any degradation, the<br>
&quot;t0&quot;(scan on local single table) and/or &quot;pll&quot; test (sca=
n on a local<br>
paritioned table) gets slow.<br>
<br>
3. postgresql_fdw always runs async-capable code path.<br>
<br>
If the postgres_fdw part causes degradation, ft0 reflects that.<br>
<br>
<br>
The tables has two integers and the query does sum(a) on all tuples.<br>
<br>
With the default fetch_size =3D 100, number is run time in ms.=C2=A0 Each<b=
r>
number is the average of 14 runs.<br>
<br>
=C2=A0 =C2=A0 =C2=A0master=C2=A0 patched=C2=A0 =C2=A0gain<br>
t0=C2=A0 =C2=A07325=C2=A0 =C2=A0 7130=C2=A0 =C2=A0 =C2=A0+2.7%<br>
pll=C2=A0 4558=C2=A0 =C2=A0 4484=C2=A0 =C2=A0 =C2=A0+1.7%<br>
ft0=C2=A0 3670=C2=A0 =C2=A0 3675=C2=A0 =C2=A0 =C2=A0-0.1%<br>
pf0=C2=A0 2322=C2=A0 =C2=A0 1550=C2=A0 =C2=A0 +33.3%<br>
pf1=C2=A0 2367=C2=A0 =C2=A0 1475=C2=A0 =C2=A0 +37.7%<br>
ptf0 2517=C2=A0 =C2=A0 1624=C2=A0 =C2=A0 +35.5%<br>
ptf1 2343=C2=A0 =C2=A0 1497=C2=A0 =C2=A0 +36.2%<br>
<br>
With larger fetch_size (200) the gain mysteriously decreases for<br>
sharing single connection cases (pf0, ptf0), but others don&#39;t seem<br>
change so much.<br>
<br>
=C2=A0 =C2=A0 =C2=A0master=C2=A0 patched=C2=A0 =C2=A0gain<br>
t0=C2=A0 =C2=A07212=C2=A0 =C2=A0 7252=C2=A0 =C2=A0 =C2=A0-0.6%<br>
pll=C2=A0 4546=C2=A0 =C2=A0 4397=C2=A0 =C2=A0 =C2=A0+3.3%<br>
ft0=C2=A0 3712=C2=A0 =C2=A0 3731=C2=A0 =C2=A0 =C2=A0-0.5%<br>
pf0=C2=A0 2131=C2=A0 =C2=A0 1570=C2=A0 =C2=A0 +26.4%<br>
pf1=C2=A0 1926=C2=A0 =C2=A0 1189=C2=A0 =C2=A0 +38.3%<br>
ptf0 2001=C2=A0 =C2=A0 1557=C2=A0 =C2=A0 +22.2%<br>
ptf1 1903=C2=A0 =C2=A0 1193=C2=A0 =C2=A0 +37.4%<br>
<br>
FWIW, attached are the test script.<br>
<br>
gentblr2.sql: Table creation script.<br>
testrun.sh=C2=A0 : Benchmarking script.<br>
<br>
<br>
regards.<br>
<br>
-- <br>
Kyotaro Horiguchi<br>
NTT Open Source Software Center<br>
</blockquote></div></div></div>

--00000000000001b2b0059c165988--
--00000000000001b2b2059c16598a
Content-Type: application/x-tar; name="script.tar"
Content-Disposition: attachment; filename="script.tar"
Content-Transfer-Encoding: base64
Content-ID: <f_k5domtk10>
X-Attachment-Id: f_k5domtk10

c2NyaXB0LwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwNDA3NzcAMDAwMDAw
MAAwMDAwMDAwADAwMDAwMDAwMDAwADEzNjA3MzAwMTM2ADAwNzMxNwAgNQAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1c3RhcgAwMAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABz
Y3JpcHQvcHJlcGFyZS5weQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDEwMDc3NwAwMDAwMDAw
ADAwMDAwMDAAMDAwMDAwNDI3NzEAMTM2MDUwNDM0MDQAMDExMzQyACAwAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHVzdGFyADAwAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMh
L3Vzci9iaW4vZW52IHB5dGhvbjMKZnJvbSB1dGlsIGltcG9ydCAqCgpkZWYgaGFuZGxlX2FyZ3Vt
ZW50KHJvb3QpOgogICAgY29tbWFuZF9saXN0ID0gWydiaW4nLCdzdGFydGFsbCcsJ3N0b3BhbGwn
LCdnZGF0YScsJ2luaXRkYicsJ3J1bnNlbGVjdCcsJ3J1bmNvdW50JywncnVuc2VsZWN0YWxsJywg
J2luY3JlYXNlZGF0YScsICdyZXNldHBhcmVudCddCiAgICBkZWJ1Z19vdXRwdXQoJ2hhbmRsZV9h
cmd1bWVudCBzdGFydCcpCiAgICByb290LmFyZ2xpc3QgPSBzeXMuYXJndgogICAgcm9vdC5hcmdu
dW0gPSBsZW4ocm9vdC5hcmdsaXN0KQoKICAgIGlmIHJvb3QuYXJnbnVtIDwgMjoKICAgICAgICBl
cnJvcl9leGl0KCdXcm9uZyBjYWxsIG9mIHRoaXMgdG9vbCcpCiAgICAKICAgIGlmIHJvb3QuYXJn
bGlzdFsxXSBpbiBjb21tYW5kX2xpc3Q6CiAgICAgICAgcm9vdC5jb21tYW5ka2luZCA9IHJvb3Qu
YXJnbGlzdFsxXQogICAgZWxzZToKICAgICAgICBlcnJvcl9leGl0KCdXcm9uZyBjYWxsIG9mIHRo
aXMgdG9vbCcpCgogICAgaWYgJ2dkYXRhJyA9PSByb290LmNvbW1hbmRraW5kOgogICAgICAgIGlm
IHJvb3QuYXJnbnVtID09IDI6CiAgICAgICAgICAgIHJvb3QuZGF0YXNjYWxlID0gMQogICAgICAg
IGVsaWYgcm9vdC5hcmdudW0gPT0gMzoKICAgICAgICAgICAgaWYgbm90IHJvb3QuYXJnbGlzdFsy
XS5pc251bWVyaWMoKToKICAgICAgICAgICAgICAgIGVycm9yX2V4aXQoJ1dyb25nIGNhbGwgb2Yg
dGhpcyB0b29sJykKICAgICAgICAgICAgcm9vdC5kYXRhc2NhbGUgPSBpbnQocm9vdC5hcmdsaXN0
WzJdKQogICAgZWxpZiAnaW5jcmVhc2VkYXRhJyA9PSByb290LmNvbW1hbmRraW5kOgogICAgICAg
IGlmIHJvb3QuYXJnbnVtID09IDI6CiAgICAgICAgICAgIHJvb3QuaW5jcmVhc2VzY2FsZSA9IDEK
ICAgICAgICBlbGlmIHJvb3QuYXJnbnVtID09IDM6CiAgICAgICAgICAgIGlmIG5vdCByb290LmFy
Z2xpc3RbMl0uaXNudW1lcmljKCk6CiAgICAgICAgICAgICAgICBlcnJvcl9leGl0KCdXcm9uZyBj
YWxsIG9mIHRoaXMgdG9vbCcpCiAgICAgICAgICAgIHJvb3QuaW5jcmVhc2VzY2FsZSA9IGludChy
b290LmFyZ2xpc3RbMl0pCiAgICBkZWJ1Z19vdXRwdXQoJ2hhbmRsZV9hcmd1bWVudCBlbmQnKQoK
Y2xhc3MgUHJlcGFyZToKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzZWxmLm9wX2lu
c3RhbGxfcGF0aD0nL2gxL29wdC9wZycKICAgICAgICBzZWxmLmNwX2luc3RhbGxfcGF0aD0nL2gx
L29wdC9wZ193aXRocGF0Y2gnCiAgICAgICAgc2VsZi5yZW1vdGVfaW5zdGFsbF9wYXRoPScvaDEv
b3B0L3BnJwogICAgICAgIHNlbGYudGFyZmlsZW5hbWUgPSAncGdfYmluLnRhcicKICAgICAgICBz
ZWxmLmRhdGFkaXIgPSAnL2gxL29wdC9wZy9kYXRhJwogICAgICAgIHNlbGYudHQgPSAncGZ0Jwog
ICAgICAgIHNlbGYubm9kZV9jb25mID0gJ25vZGVfY29uZicKICAgICAgICBzZWxmLm9wcmVzdWx0
ZmlsZSA9ICdvcC5vdXQnCiAgICAgICAgc2VsZi5jcHJlc3VsdGZpbGUgPSAnY3Aub3V0JwogICAg
ICAgIHNlbGYudGVzdHRpbWVzID0gMwogICAgICAgIHNlbGYucmVtb3RlcG9ydCA9IDU0MzQKICAg
ICAgICBzZWxmLmRic3NldmVyeW5vZGUgPSAxCiAgICAgICAgc2VsZi5maXJzdF9nZW5lcmF0ZV9w
YXJlbnRfc3FsID0gVHJ1ZQogICAgICAgICNzZWxmLm9uZUdzY2FsZSA9IDE0MDAKICAgICAgICBz
ZWxmLm9uZUdzY2FsZSA9IDE0MDAwMDAwCiAgICAKICAgIGRlZiBnZXRfbm9kZV90dXBsZShzZWxm
LCBub2Rlc3RyKToKICAgICAgICBibGFua19wb3MgPSBub2Rlc3RyLmZpbmQoJyAnKQogICAgICAg
IGlmIC0xID09IGJsYW5rX3BvczoKICAgICAgICAgICAgZXJyb3JfZXhpdCgnV3Jvbmcgbm9kZSBz
dHInKQogICAgICAgIGlwID0gbm9kZXN0clswOmJsYW5rX3Bvc10KICAgICAgICBub2RlcyA9IG5v
ZGVzdHJbYmxhbmtfcG9zKzE6XQogICAgICAgIG5vZGVzID0gaW50KG5vZGVzKQogICAgICAgIHJl
dHVybiAoaXAsIG5vZGVzKQogICAgCiAgICBkZWYgbG9hZF9ub2RlcyhzZWxmKToKICAgICAgIAkj
c2VsZi5ub2RlX2xpc3QgPSBbJzE4LjIxNy4xNjUuMjM4JywnMy4xMzMuMTI0LjIwNScsJzE4LjIx
Ni4xODguMTA4JywnMy4xMzUuMTg3LjEyMycsJzMuMTUuMjE4LjIwNCddCiAgICAgICAgI3NlbGYu
bm9kZV9saXN0ID0gWycxOC4yMTcuMTY1LjIzOCcsJzMuMTMzLjEyNC4yMDUnLCcxOC4yMTYuMTg4
LjEwOCcsJzMuMTM1LjE4Ny4xMjMnXQogICAgICAgICNzZWxmLm5vZGVfbGlzdCA9IFsnMTguMjE3
LjE2NS4yMzgnLCczLjEzMy4xMjQuMjA1JywnMTguMjE2LjE4OC4xMDgnXQogICAgICAgICNzZWxm
Lm5vZGVfbGlzdCA9IFsnMTguMjE3LjE2NS4yMzgnLCczLjEzMy4xMjQuMjA1J10KICAgICAgICBz
ZWxmLm5vZGVfbGlzdCA9IFtdCiAgICAgICAgZmlsZSA9IG9wZW4oc2VsZi5ub2RlX2NvbmYsICdy
JykKICAgICAgICBmb3IgbGluZSBpbiBmaWxlLnJlYWRsaW5lcygpOgogICAgICAgICAgICBsaW5l
ID0gbGluZS5zdHJpcCgnXG4nKQogICAgICAgICAgICB0dXBsZV9pdGVtID0gc2VsZi5nZXRfbm9k
ZV90dXBsZShsaW5lKQogICAgICAgICAgICBzZWxmLm5vZGVfbGlzdC5hcHBlbmQodHVwbGVfaXRl
bSkKICAgICAgICBmaWxlLmNsb3NlKCkKICAgICAgICAjcHJpbnQoc2VsZi5ub2RlX2xpc3QpCiAg
ICAgICAgc2VsZi5ub2RlX3VzZXIgPSAnZWMyLXVzZXInCiAgICAgICAgc2VsZi5rZXlwYXRoID0g
Jy9ob21lL2VjMi11c2VyL2hpZ2hnb2tleS5wZW0nCiAgICAgICAgc2VsZi5jaGVja19kaXIoKQoK
ICAgIGRlZiBjaGVja19kaXIoc2VsZik6CiAgICAgICAgaWYgbm90IGRpcl9leGlzdChzZWxmLm9w
X2luc3RhbGxfcGF0aCk6CiAgICAgICAgICAgIGVycm9yX2V4aXQoJ29wIGluc3RhbGwgcGF0aCBp
cyBub3QgZXhpc3RzJykKICAgICAgICBpZiBub3QgZGlyX2V4aXN0KHNlbGYuY3BfaW5zdGFsbF9w
YXRoKToKICAgICAgICAgICAgZXJyb3JfZXhpdCgnY3AgaW5zdGFsbCBwYXRoIGlzIG5vdCBleGlz
dHMnKQogICAgCiAgICBkZWYgY2xlYW5fcmVtb3RlKHNlbGYpOgogICAgICAgIGZvciBpdGVtX3R1
cGxlIGluIHNlbGYubm9kZV9saXN0OgogICAgICAgICAgICBpdGVtID0gaXRlbV90dXBsZVswXQog
ICAgICAgICAgICBpZiBkaXJfcmVtb3RlX2V4aXN0KHNlbGYucmVtb3RlX2luc3RhbGxfcGF0aCwg
c2VsZi5ub2RlX3VzZXIsIGl0ZW0pOgogICAgICAgICAgICAgICAgY21kID0gJ3JtIC1yZiAlcycg
JSBzZWxmLnJlbW90ZV9pbnN0YWxsX3BhdGgKICAgICAgICAgICAgICAgIGV4ZWNfY29tbWFuZF9z
eXN0ZW1fcmVtb3RlKGNtZCxzZWxmLm5vZGVfdXNlciwgaXRlbSkKICAgICAgICAgICAgY21kID0g
J21rZGlyIC1wICAlcycgJSBzZWxmLnJlbW90ZV9pbnN0YWxsX3BhdGgKICAgICAgICAgICAgZXhl
Y19jb21tYW5kX3N5c3RlbV9yZW1vdGUoY21kLHNlbGYubm9kZV91c2VyLCBpdGVtKQogICAgCiAg
ICBkZWYgcHJlcGFyZV9iaW4oc2VsZik6CiAgICAgICAgaWYgbm90IGZpbGVfZXhpc3Qoc2VsZi50
YXJmaWxlbmFtZSk6CiAgICAgICAgICAgIHJlY29yZGN3ZCA9IGdldGN3ZCgpCiAgICAgICAgICAg
IGNtZCA9ICdjZCAlczt0YXIgLWN6dmYgJXMvJXMgLicgJSAoc2VsZi5vcF9pbnN0YWxsX3BhdGgs
IHJlY29yZGN3ZCwgc2VsZi50YXJmaWxlbmFtZSkKICAgICAgICAgICAgZXhlY19jb21hbmRfc3lz
dGVtKGNtZCkKICAgICAgICAgICAgY21kID0gJ2NkICVzJyAlIChyZWNvcmRjd2QpCiAgICAgICAg
ICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQpCgogICAgICAgIAogICAgICAgIGZvciBpdGVtX3R1
cGxlIGluIHNlbGYubm9kZV9saXN0OgogICAgICAgICAgICBpdGVtID0gaXRlbV90dXBsZVswXQog
ICAgICAgICAgICBjbWQgPSAnc2NwIC1yIC1pIH4vaGlnaGdva2V5LnBlbSAlcyAlc0Alczolcycg
JSAoc2VsZi50YXJmaWxlbmFtZSwgc2VsZi5ub2RlX3VzZXIsIGl0ZW0sIHNlbGYucmVtb3RlX2lu
c3RhbGxfcGF0aCkKICAgICAgICAgICAgZXhlY19jb21hbmRfc3lzdGVtKGNtZCkKCiAgICAgICAg
ICAgIGNtZCA9ICdjZCAlczt0YXIgLXh6dmYgJXMnICUgKHNlbGYucmVtb3RlX2luc3RhbGxfcGF0
aCwgc2VsZi50YXJmaWxlbmFtZSkKICAgICAgICAgICAgZXhlY19jb21tYW5kX3N5c3RlbV9yZW1v
dGUoY21kLCBzZWxmLm5vZGVfdXNlciwgaXRlbSkKCiAgICAgICAgICAgIHNsZWVwKDEpCiAgICAg
ICAgICAgIGNtZCA9ICdybSAtcmYgJXMnICUgKHNlbGYuZGF0YWRpcikKICAgICAgICAgICAgZXhl
Y19jb21tYW5kX3N5c3RlbV9yZW1vdGUoY21kLCBzZWxmLm5vZGVfdXNlciwgaXRlbSwgRmFsc2Up
CgogICAgZGVmIGluaXRkYl9yZW1vdGUoc2VsZik6CiAgICAgICAgbG9vcCA9IDEKICAgICAgICBm
b3IgaXRlbV90dXBsZSBpbiBzZWxmLm5vZGVfbGlzdDoKICAgICAgICAgICAgaXRlbSA9IGl0ZW1f
dHVwbGVbMF0KICAgICAgICAgICAgd2hpbGUgbG9vcCA8PSBpdGVtX3R1cGxlWzFdOgogICAgICAg
ICAgICAgICAgZGF0YWRpciA9IHNlbGYuZGF0YWRpciArIHN0cihsb29wKSAKICAgICAgICAgICAg
ICAgIGlmIGRpcl9yZW1vdGVfZXhpc3QoZGF0YWRpciwgc2VsZi5ub2RlX3VzZXIsIGl0ZW0pOgog
ICAgICAgICAgICAgICAgICAgIGNtZCA9ICdybSAtcmYgJXMnICUgZGF0YWRpcgogICAgICAgICAg
ICAgICAgICAgIGV4ZWNfY29tbWFuZF9zeXN0ZW1fcmVtb3RlKGNtZCxzZWxmLm5vZGVfdXNlciwg
aXRlbSkKICAgICAgICAgICAgICAgIGNtZCA9ICdjZCAlcy9iaW47IC4vaW5pdGRiICVzJyAlIChz
ZWxmLnJlbW90ZV9pbnN0YWxsX3BhdGgsIGRhdGFkaXIpCiAgICAgICAgICAgICAgICBleGVjX2Nv
bW1hbmRfc3lzdGVtX3JlbW90ZShjbWQsIHNlbGYubm9kZV91c2VyLCBpdGVtKQogICAgICAgICAg
ICAgICAgbG9vcCArPSAxCiAgICAgICAgICAgIGxvb3AgPSAxCgogICAgZGVmIG9wZ19vcChzZWxm
LCBraW5kKToKICAgICAgICBpZiBraW5kICE9ICdzdGFydCcgYW5kIGtpbmQgIT0gJ3N0b3AnOgog
ICAgICAgICAgICBlcnJvcl9leGl0KCdXcm9uZyBraW5kJykKICAgICAgICBjbWQgPSAnY2QgJXMv
YmluOyAuL3BnX2N0bCAlcyAtRCAuLi9kYXRhJyAlIChzZWxmLm9wX2luc3RhbGxfcGF0aCwga2lu
ZCkKICAgICAgICBleGVjX2NvbWFuZF9zeXN0ZW0oY21kLEZhbHNlLCBGYWxzZSkKICAgIAogICAg
ZGVmIGNwZ19vcChzZWxmLGtpbmQpOgogICAgICAgIGlmIGtpbmQgIT0gJ3N0YXJ0JyBhbmQga2lu
ZCAhPSAnc3RvcCc6CiAgICAgICAgICAgIGVycm9yX2V4aXQoJ1dyb25nIGtpbmQnKQogICAgICAg
IGNtZCA9ICdjZCAlcy9iaW47IC4vcGdfY3RsICVzIC1EIC4uL2RhdGEnICUgKHNlbGYuY3BfaW5z
dGFsbF9wYXRoLCBraW5kKQogICAgICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQsRmFsc2UsIEZh
bHNlKQoKICAgIGRlZiBvcGdfc3RhcnQoc2VsZik6CiAgICAgICAgc2VsZi5vcGdfb3AoJ3N0b3An
KQogICAgICAgIHNlbGYuY3BnX29wKCdzdG9wJykKICAgICAgICBzZWxmLm9wZ19vcCgnc3RhcnQn
KQoKICAgIGRlZiBjcGdfc3RhcnQoc2VsZik6CiAgICAgICAgc2VsZi5vcGdfb3AoJ3N0b3AnKQog
ICAgICAgIHNlbGYuY3BnX29wKCdzdG9wJykKICAgICAgICBzZWxmLmNwZ19vcCgnc3RhcnQnKQog
ICAgCiAgICBkZWYgc3RhcnRhbGwoc2VsZik6CiAgICAgICAgbG9vcCA9IDEKICAgICAgICBmb3Ig
aXRlbV90dXBsZSBpbiBzZWxmLm5vZGVfbGlzdDoKICAgICAgICAgICAgaXRlbSA9IGl0ZW1fdHVw
bGVbMF0KICAgICAgICAgICAgd2hpbGUgKGxvb3AgPD0gaXRlbV90dXBsZVsxXSk6CiAgICAgICAg
ICAgICAgICBkYXRhZGlyID0gc2VsZi5kYXRhZGlyICsgc3RyKGxvb3ApCiAgICAgICAgICAgICAg
ICBjbWQgPSAnY2QgJXMvYmluOyAuL3BnX2N0bCBzdGFydCAtRCAlcycgJSAoc2VsZi5yZW1vdGVf
aW5zdGFsbF9wYXRoLCBkYXRhZGlyKQogICAgICAgICAgICAgICAgZXhlY19jb21tYW5kX3N5c3Rl
bV9yZW1vdGUoY21kLCBzZWxmLm5vZGVfdXNlciwgaXRlbSkKICAgICAgICAgICAgICAgIGxvb3Ag
Kz0gMQogICAgICAgICAgICBsb29wID0gMQoKICAgIGRlZiBzdG9wYWxsKHNlbGYpOgogICAgICAg
IGxvb3AgPSAxCiAgICAgICAgZm9yIGl0ZW1fdHVwbGUgaW4gc2VsZi5ub2RlX2xpc3Q6CiAgICAg
ICAgICAgIGl0ZW0gPSBpdGVtX3R1cGxlWzBdCiAgICAgICAgICAgIHdoaWxlIChsb29wIDw9IGl0
ZW1fdHVwbGVbMV0pOgogICAgICAgICAgICAgICAgZGF0YWRpciA9IHNlbGYuZGF0YWRpciArIHN0
cihsb29wKQogICAgICAgICAgICAgICAgY21kID0gJ2NkICVzL2JpbjsgLi9wZ19jdGwgc3RvcCAt
RCAlcycgJSAoc2VsZi5yZW1vdGVfaW5zdGFsbF9wYXRoLCBkYXRhZGlyKQogICAgICAgICAgICAg
ICAgZXhlY19jb21tYW5kX3N5c3RlbV9yZW1vdGUoY21kLCBzZWxmLm5vZGVfdXNlciwgaXRlbSwg
RmFsc2UpCiAgICAgICAgICAgICAgICBsb29wICs9IDEKICAgICAgICAgICAgbG9vcCA9IDEKICAg
ICAgICBjbWQgPSAnY2QgJXMvYmluOyAuL3BnX2N0bCBzdG9wIC1EIC4uL2RhdGEnICUgKHNlbGYu
b3BfaW5zdGFsbF9wYXRoKQogICAgICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQsIEZhbHNlLCBG
YWxzZSkKICAgICAgICBjbWQgPSAnY2QgJXMvYmluOyAuL3BnX2N0bCBzdG9wIC1EIC4uL2RhdGEn
ICUgKHNlbGYuY3BfaW5zdGFsbF9wYXRoKQogICAgICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQs
IEZhbHNlLCBGYWxzZSkKICAgIAogICAgZGVmIGdlbmVyYWxfcGFyZW50X3NxbChzZWxmKToKICAg
ICAgICBzcWxfbGlzdCA9IFtdCiAgICAgICAgc3FsX2xpc3QuYXBwZW5kKCdDUkVBVEUgRVhURU5T
SU9OIElGIE5PVCBFWElTVFMgcG9zdGdyZXNfZmR3OycpCiAgICAgICAgc3FsX2xpc3QuYXBwZW5k
KCdEUk9QIFRBQkxFIElGIEVYSVNUUyBwZnQgQ0FTQ0FERTsnKQogICAgICAgIGxvb3AgPSAxCiAg
ICAgICAgbG9vcDIgPSAxCiAgICAgICAgZm9yIGl0ZW1fdHVwbGUgaW4gc2VsZi5ub2RlX2xpc3Q6
CiAgICAgICAgICAgIGl0ZW0gPSBpdGVtX3R1cGxlWzBdCiAgICAgICAgICAgIHdoaWxlIGxvb3Ag
PD0gaXRlbV90dXBsZVsxXToKICAgICAgICAgICAgICAgIHNxbF9saXN0LmFwcGVuZCgnRFJPUCBT
RVJWRVIgSUYgRVhJU1RTIHN2JXMgQ0FTQ0FERTsnICUgKGxvb3AgKyBsb29wMiAqIDEwKSkKICAg
ICAgICAgICAgICAgIGxvb3AgKz0xCiAgICAgICAgICAgIGxvb3AyICs9IDEKICAgICAgICAgICAg
bG9vcCA9IDEKICAgICAgICAKICAgICAgICBsb29wID0gMQogICAgICAgIGxvb3AyID0gMQogICAg
ICAgIGZvciBpdGVtX3R1cGxlIGluIHNlbGYubm9kZV9saXN0OgogICAgICAgICAgICBpdGVtID0g
aXRlbV90dXBsZVswXQogICAgICAgICAgICB3aGlsZSBsb29wIDw9IGl0ZW1fdHVwbGVbMV06CiAg
ICAgICAgICAgICAgICBzcWxfbGlzdC5hcHBlbmQoJ0NSRUFURSBTRVJWRVIgc3YlcyBGT1JFSUdO
IERBVEEgV1JBUFBFUiBwb3N0Z3Jlc19mZHcgT1BUSU9OUyAoaG9zdCBcJyVzXCcsIHBvcnQgXCcl
c1wnLCBkYm5hbWUgXCdwb3N0Z3Jlc1wnKTsnICUgKGxvb3AgKyBsb29wMiAqIDEwLGl0ZW0sIHNl
bGYucmVtb3RlcG9ydCArIGxvb3ApKQogICAgICAgICAgICAgICAgbG9vcCArPTEKICAgICAgICAg
ICAgbG9vcDIgKz0gMQogICAgICAgICAgICBsb29wID0gMQogICAgICAgIAogICAgICAgIGxvb3Ag
PSAxCiAgICAgICAgbG9vcDIgPSAxCiAgICAgICAgZm9yIGl0ZW1fdHVwbGUgaW4gc2VsZi5ub2Rl
X2xpc3Q6CiAgICAgICAgICAgIGl0ZW0gPSBpdGVtX3R1cGxlWzBdCiAgICAgICAgICAgIHdoaWxl
IGxvb3AgPD0gaXRlbV90dXBsZVsxXToKICAgICAgICAgICAgICAgIHNxbF9saXN0LmFwcGVuZCgn
Q1JFQVRFIFVTRVIgTUFQUElORyBGT1IgcHVibGljIFNFUlZFUiBzdiVzOycgJSAobG9vcCArIGxv
b3AyICogMTApKQogICAgICAgICAgICAgICAgbG9vcCArPTEKICAgICAgICAgICAgbG9vcDIgKz0g
MQogICAgICAgICAgICBsb29wID0gMQogICAgICAgIAogICAgICAgIGxvb3AgPSAxCiAgICAgICAg
bG9vcDIgPSAxCiAgICAgICAgZm9yIGl0ZW1fdHVwbGUgaW4gc2VsZi5ub2RlX2xpc3Q6CiAgICAg
ICAgICAgIGl0ZW0gPSBpdGVtX3R1cGxlWzBdCiAgICAgICAgICAgIHdoaWxlIGxvb3AgPD0gaXRl
bV90dXBsZVsxXToKICAgICAgICAgICAgICAgIHNxbF9saXN0LmFwcGVuZCgnQ1JFQVRFIEZPUkVJ
R04gVEFCTEUgcGZ0JXMgKGEgaW50LCBiIGludCwgYyB0ZXh0KSBTRVJWRVIgc3YlczsnICUgKGxv
b3AgKyBsb29wMiAqIDEwLCBsb29wICsgbG9vcDIgKiAxMCkpCiAgICAgICAgICAgICAgICBsb29w
ICs9MQogICAgICAgICAgICBsb29wMiArPSAxCiAgICAgICAgICAgIGxvb3AgPSAxCgogICAgICAg
IHNxbF9saXN0LmFwcGVuZCgnQ1JFQVRFIFRBQkxFIHBmdCAoYSBpbnQsIGIgaW50LCBjIHRleHQp
IFBBUlRJVElPTiBCWSBMSVNUKGEpOycpCiAgICAgICAgCiAgICAgICAgbG9vcCA9IDEKICAgICAg
ICBsb29wMiA9IDEKICAgICAgICBmb3IgaXRlbV90dXBsZSBpbiBzZWxmLm5vZGVfbGlzdDoKICAg
ICAgICAgICAgaXRlbSA9IGl0ZW1fdHVwbGVbMF0KICAgICAgICAgICAgd2hpbGUgbG9vcCA8PSBp
dGVtX3R1cGxlWzFdOgogICAgICAgICAgICAgICAgc3FsX2xpc3QuYXBwZW5kKCdBTFRFUiBUQUJM
RSBwZnQgQVRUQUNIIFBBUlRJVElPTiBwZnQlcyBGT1IgVkFMVUVTIElOICglcyk7JyAlIChsb29w
ICsgbG9vcDIgKiAxMCwgbG9vcCArIGxvb3AyICogMTApICkKICAgICAgICAgICAgICAgIGxvb3Ag
Kz0xCiAgICAgICAgICAgIGxvb3AyICs9IDEKICAgICAgICAgICAgbG9vcCA9IDEKCiAgICAgICAg
aWYgc2VsZi5maXJzdF9nZW5lcmF0ZV9wYXJlbnRfc3FsOgogICAgICAgICAgICBmaWxlID0gb3Bl
bigncGFyZW50LnNxbCcsICd3JykKICAgICAgICAgICAgc2VsZi5maXJzdF9nZW5lcmF0ZV9wYXJl
bnRfc3FsID0gRmFsc2UKICAgICAgICBlbHNlOgogICAgICAgICAgICBmaWxlID0gb3BlbigncGFy
ZW50LnNxbCcsICdhJykKICAgICAgICBmb3IgaXRlbSBpbiBzcWxfbGlzdDoKICAgICAgICAgICAg
ZmlsZS53cml0ZShpdGVtICsgJ1xuJykKICAgICAgICBmaWxlLmNsb3NlKCkKICAgIAogICAgZGVm
IGdlbmVyYWxfbm9kZV9zcWwoc2VsZik6CiAgICAgICAgc3FsX2xpc3QgPSBbXQogICAgICAgIHNx
bF9saXN0LmFwcGVuZCgnRFJPUCBUQUJMRSBJRiBFWElTVFMgOnRhYmxlbmFtZSBDQVNDQURFOycp
CiAgICAgICAgc3FsX2xpc3QuYXBwZW5kKCdDUkVBVEUgVEFCTEUgOnRhYmxlbmFtZShhIGludCwg
YiBpbnQsIGMgdGV4dCk7JykKICAgICAgICBzcWxfbGlzdC5hcHBlbmQoJ0lOU0VSVCBJTlRPIDp0
YWJsZW5hbWUgU0VMRUNUIDpsaXN0X3ZhbHVlLCBnZW5lcmF0ZV9zZXJpZXMoMSwlcyo6c2NhbGUp
LCBtZDUocmFuZG9tKCk6OnRleHQpJyAlIChzZWxmLm9uZUdzY2FsZSkpCiAgICAgICAgZmlsZSA9
IG9wZW4oJ25vZGUuc3FsJywgJ3cnKQogICAgICAgIGZvciBpdGVtIGluIHNxbF9saXN0OgogICAg
ICAgICAgICBmaWxlLndyaXRlKGl0ZW0gKyAnXG4nKQogICAgICAgIGZpbGUuY2xvc2UoKQogICAg
ICAgIHBhc3MKICAgIAogICAgZGVmIGNvcHlfc3FsKHNlbGYpOgogICAgICAgIHNlbGYuZ2VuZXJh
bF9ub2RlX3NxbCgpCiAgICAgICAgZm9yIGl0ZW1fdHVwbGUgaW4gc2VsZi5ub2RlX2xpc3Q6CiAg
ICAgICAgICAgIGl0ZW0gPSBpdGVtX3R1cGxlWzBdCiAgICAgICAgICAgIGNtZCA9ICdzY3AgLWkg
fi9oaWdoZ29rZXkucGVtIG5vZGUuc3FsICVzQCVzOiVzL25vZGUuc3FsJyAlIChzZWxmLm5vZGVf
dXNlciwgaXRlbSwgc2VsZi5vcF9pbnN0YWxsX3BhdGgpCiAgICAgICAgICAgIGV4ZWNfY29tYW5k
X3N5c3RlbShjbWQpCiAgICAgICAgc2VsZi5nZW5lcmFsX3BhcmVudF9zcWwoKQogICAgICAgIGNt
ZCA9ICdjcCBwYXJlbnQuc3FsICVzL2RhdGEvbm9kZS5zcWwnICUgKHNlbGYub3BfaW5zdGFsbF9w
YXRoKQogICAgICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQpCiAgICAgICAgY21kID0gJ2NwIHBh
cmVudC5zcWwgJXMvZGF0YS9ub2RlLnNxbCcgJSAoc2VsZi5jcF9pbnN0YWxsX3BhdGgpCiAgICAg
ICAgZXhlY19jb21hbmRfc3lzdGVtKGNtZCkKICAgIAogICAgZGVmIHJlc2V0cGFyZW50KHNlbGYp
OgogICAgICAgIHNlbGYuZ2VuZXJhbF9wYXJlbnRfc3FsKCkKICAgICAgICBjbWQgPSAnY3AgcGFy
ZW50LnNxbCAlcy9kYXRhL25vZGUuc3FsJyAlIChzZWxmLm9wX2luc3RhbGxfcGF0aCkKICAgICAg
ICBleGVjX2NvbWFuZF9zeXN0ZW0oY21kKQogICAgICAgIGNtZCA9ICdjcCBwYXJlbnQuc3FsICVz
L2RhdGEvbm9kZS5zcWwnICUgKHNlbGYuY3BfaW5zdGFsbF9wYXRoKQogICAgICAgIGV4ZWNfY29t
YW5kX3N5c3RlbShjbWQpCiAgICAgICAgc2VsZi5nZW5lcmF0ZWRhdGFfdGhyZWFkKCdjcCcsMCww
KQogICAgICAgIHNlbGYuZ2VuZXJhdGVkYXRhX3RocmVhZCgnb3AnLDAsMCkKCiAgICBkZWYgZ2Vu
ZXJhdGVkYXRhX3RocmVhZChzZWxmLCBpdGVtLCBsb29wLCBsb29wMik6CiAgICAgICAgaWYgaXRl
bSA9PSAnb3AnOgogICAgICAgICAgICBzZWxmLm9wZ19zdGFydCgpCiAgICAgICAgICAgIGNtZCA9
ICclcy9iaW4vcHNxbCAtZCBwb3N0Z3JlcyAtZiAlcy9kYXRhL25vZGUuc3FsJyAlIChzZWxmLm9w
X2luc3RhbGxfcGF0aCwgc2VsZi5vcF9pbnN0YWxsX3BhdGgpCiAgICAgICAgICAgIG91dHB1dCgn
Pj5HZW5lcmF0ZSBvcGcgdGFibGVzJykKICAgICAgICAgICAgZXhlY19jb21hbmRfc3lzdGVtKGNt
ZCkKICAgICAgICBlbGlmIGl0ZW0gPT0gJ2NwJzoKICAgICAgICAgICAgc2VsZi5jcGdfc3RhcnQo
KQogICAgICAgICAgICBjbWQgPSAnJXMvYmluL3BzcWwgLWQgcG9zdGdyZXMgLWYgJXMvZGF0YS9u
b2RlLnNxbCcgJSAoc2VsZi5jcF9pbnN0YWxsX3BhdGgsc2VsZi5jcF9pbnN0YWxsX3BhdGgpCiAg
ICAgICAgICAgIG91dHB1dCgnPj5HZW5lcmF0ZSBjcGcgdGFibGVzJykKICAgICAgICAgICAgZXhl
Y19jb21hbmRfc3lzdGVtKGNtZCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBjbWQgPSAnJXMv
YmluL3BzcWwgLXAgJXMgLWQgcG9zdGdyZXMgLXYgbGlzdF92YWx1ZT0lcyAtdiBzY2FsZT0lcyAt
diB0YWJsZW5hbWU9cGZ0JXMgLWYgJXMvbm9kZS5zcWwnICUgXAogICAgICAgICAgICAgICAgICAg
IChzZWxmLnJlbW90ZV9pbnN0YWxsX3BhdGgsIHNlbGYucmVtb3RlcG9ydCArIGxvb3AsIGxvb3Ay
KjEwK2xvb3AsIHNlbGYuZGF0YXNjYWxlLGxvb3AyKjEwK2xvb3Asc2VsZi5vcF9pbnN0YWxsX3Bh
dGgpCiAgICAgICAgICAgIG91dHB1dCgnPj5HZW5lcmF0ZSAlcyBub2RlIGRhdGEnICUgaXRlbSkK
ICAgICAgICAgICAgZXhlY19jb21tYW5kX3N5c3RlbV9yZW1vdGUoY21kLCBzZWxmLm5vZGVfdXNl
ciwgaXRlbSwgVHJ1ZSkKCiAgICBkZWYgZ2VuZXJhdGVkYXRhKHNlbGYpOgogICAgICAgIHRocnVu
aW5nID0gVHJ1ZQogICAgICAgIHRocmVhZGxpc3QgPSBbXQogICAgICAgIGxvb3AgPSAxCiAgICAg
ICAgbG9vcDIgPSAxCiAgICAgICAgb3V0cHV0KCc+PkdlbmVyYXRlIGRhdGFzLi4uJykKICAgICAg
ICBzZWxmLmdlbmVyYXRlZGF0YV90aHJlYWQoJ2NwJywwLDApCiAgICAgICAgc2VsZi5nZW5lcmF0
ZWRhdGFfdGhyZWFkKCdvcCcsMCwwKQogICAgICAgIHNlbGYuc3RhcnRhbGwoKQogICAgICAgIGZv
ciBpdGVtX3R1cGxlIGluIHNlbGYubm9kZV9saXN0OgogICAgICAgICAgICBpdGVtID0gaXRlbV90
dXBsZVswXQogICAgICAgICAgICB3aGlsZSAobG9vcCA8PSBpdGVtX3R1cGxlWzFdKToKICAgICAg
ICAgICAgICAgIG10ID0gbXlUaHJlYWQoc2VsZi5nZW5lcmF0ZWRhdGFfdGhyZWFkLCBpdGVtLCBs
b29wLCBsb29wMikKICAgICAgICAgICAgICAgIG10LnN0YXJ0KCkKICAgICAgICAgICAgICAgIHRo
cmVhZGxpc3QuYXBwZW5kKG10KQogICAgICAgICAgICAgICAgbG9vcCArPSAxCiAgICAgICAgICAg
IGxvb3AyICs9IDEKICAgICAgICAgICAgbG9vcCA9IDEKICAgICAgICAKICAgICAgICB3aGlsZSh0
aHJ1bmluZyk6CiAgICAgICAgICAgIHNsZWVwKDIpCiAgICAgICAgICAgIHRocnVuaW5nID0gRmFs
c2UKICAgICAgICAgICAgZm9yIG10IGluIHRocmVhZGxpc3Q6CiAgICAgICAgICAgICAgICBtdHMg
PSBtdC5pc0FsaXZlKCkKICAgICAgICAgICAgICAgIHRocnVuaW5nID0gdGhydW5pbmcgb3IgbXRz
CiAgICAKICAgIGRlZiBpbmNyZWFzZWRhdGFfdGhyZWFkKHNlbGYsIGl0ZW0sIGxvb3AsIGxvb3Ay
KToKICAgICAgICBzcWwgPSdJTlNFUlQgSU5UTyBwZnQlcyBTRUxFQ1QgJXMsIGdlbmVyYXRlX3Nl
cmllcyglcywlcyolcyksIG1kNShyYW5kb20oKTo6dGV4dCknICUgXAogICAgICAgICAgICAgICAg
KGxvb3ArMTAqbG9vcDIsIGxvb3ArMTAqbG9vcDIsIGxvb3ArMTAqbG9vcDIsc2VsZi5vbmVHc2Nh
bGUsIHNlbGYuaW5jcmVhc2VzY2FsZSkKICAgICAgICBjbWQgPSAnJXMvYmluL3BzcWwgLXAgJXMg
LWQgcG9zdGdyZXMgLWMgXCclc1wnJyAlIChzZWxmLnJlbW90ZV9pbnN0YWxsX3BhdGgsIHNlbGYu
cmVtb3RlcG9ydCArIGxvb3Asc3FsKQogICAgICAgIG91dHB1dCgnPj5HZW5lcmF0ZSAlc0cgdG8g
JXMgbm9kZSBkYXRhJyAlIChzZWxmLmluY3JlYXNlc2NhbGUsaXRlbSkpCiAgICAgICAgZXhlY19j
b21tYW5kX3N5c3RlbV9yZW1vdGUoY21kLCBzZWxmLm5vZGVfdXNlciwgaXRlbSwgVHJ1ZSkKCiAg
ICBkZWYgaW5jcmVhc2VkYXRhKHNlbGYpOgogICAgICAgIHRocmVhZGxpc3QgPSBbXQogICAgICAg
IGxvb3AgPSAxCiAgICAgICAgbG9vcDIgPSAxCiAgICAgICAgdGhydW5pbmcgPSBUcnVlCiAgICAg
ICAgZm9yIGl0ZW1fdHVwbGUgaW4gc2VsZi5ub2RlX2xpc3Q6CiAgICAgICAgICAgIGl0ZW0gPSBp
dGVtX3R1cGxlWzBdCiAgICAgICAgICAgIHdoaWxlIChsb29wIDw9IGl0ZW1fdHVwbGVbMV0pOgog
ICAgICAgICAgICAgICAgbXQgPSBteVRocmVhZChzZWxmLmluY3JlYXNlZGF0YV90aHJlYWQsIGl0
ZW0sIGxvb3AsIGxvb3AyKQogICAgICAgICAgICAgICAgbXQuc3RhcnQoKQogICAgICAgICAgICAg
ICAgdGhyZWFkbGlzdC5hcHBlbmQobXQpCiAgICAgICAgICAgICAgICBsb29wICs9IDEKICAgICAg
ICAgICAgbG9vcDIgKz0gMQogICAgICAgICAgICBsb29wID0gMQogICAgICAgIAogICAgICAgIHdo
aWxlKHRocnVuaW5nKToKICAgICAgICAgICAgc2xlZXAoMikKICAgICAgICAgICAgdGhydW5pbmcg
PSBGYWxzZQogICAgICAgICAgICBmb3IgbXQgaW4gdGhyZWFkbGlzdDoKICAgICAgICAgICAgICAg
IG10cyA9IG10LmlzQWxpdmUoKQogICAgICAgICAgICAgICAgdGhydW5pbmcgPSB0aHJ1bmluZyBv
ciBtdHMKICAgICAgICBwYXNzCiAgICAKICAgIGRlZiBjaGFuZ2Vfbm9kZV9wZ2NvbmYoc2VsZik6
CiAgICAgICAgbG9jYWxfcGdfY29uZiA9ICclcy8lcy9wb3N0Z3Jlc3FsLmNvbmYnICUgKHNlbGYu
b3BfaW5zdGFsbF9wYXRoLCdkYXRhJykKICAgICAgICBsb2NhbF9wZ19jb25mX2NoYW5nZSA9ICcl
cy8lcy9wb3N0Z3Jlc3FsLmNvbmYuY2hhbmdlJyAlIChzZWxmLm9wX2luc3RhbGxfcGF0aCwgJ2Rh
dGEnKQogICAgICAgIGxvY2FsX3BnX2hiYSA9ICclcy8lcy9wZ19oYmEuY29uZicgJSAoc2VsZi5v
cF9pbnN0YWxsX3BhdGgsJ2RhdGEnKQogICAgICAgIGxvY2FsX3BnX2hiYV9jaGFuZ2UgPSAnJXMv
JXMvcGdfaGJhLmNvbmYuY2hhbmdlJyAlIChzZWxmLm9wX2luc3RhbGxfcGF0aCwnZGF0YScpCiAg
ICAgICAgZGVidWdfb3V0cHV0KCdjaGFuZ2Vfbm9kZV9wZ2NvbmYnKQogICAgICAgIGxvb3AgPSAx
CgogICAgICAgIGZvciBpdGVtX3R1cGxlIGluIHNlbGYubm9kZV9saXN0OgogICAgICAgICAgICBp
dGVtID0gaXRlbV90dXBsZVswXQogICAgICAgICAgICB3aGlsZSAobG9vcCA8PSBpdGVtX3R1cGxl
WzFdKToKICAgICAgICAgICAgICAgIGNtZCA9ICdjcCAlcyAlcztjcCAlcyAlcycgJSAobG9jYWxf
cGdfY29uZiwgbG9jYWxfcGdfY29uZl9jaGFuZ2UsIGxvY2FsX3BnX2hiYSwgbG9jYWxfcGdfaGJh
X2NoYW5nZSkKICAgICAgICAgICAgICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQpCgogICAgICAg
ICAgICAgICAgY29uZl9pdGVtID0gJ2xpc3Rlbl9hZGRyZXNzZXMgPSBcJypcJycKICAgICAgICAg
ICAgICAgIGNtZCA9ICdlY2hvICIlcyIgPj4gJXMnICUgKGNvbmZfaXRlbSwgbG9jYWxfcGdfY29u
Zl9jaGFuZ2UpCiAgICAgICAgICAgICAgICBleGVjX2NvbWFuZF9zeXN0ZW0oY21kLFRydWUpCgog
ICAgICAgICAgICAgICAgY29uZl9pdGVtID0gJ3BvcnQgPSAlcycgJSAoc2VsZi5yZW1vdGVwb3J0
ICsgbG9vcCkKICAgICAgICAgICAgICAgIGNtZCA9ICdlY2hvICIlcyIgPj4gJXMnICUgKGNvbmZf
aXRlbSwgbG9jYWxfcGdfY29uZl9jaGFuZ2UpCiAgICAgICAgICAgICAgICBleGVjX2NvbWFuZF9z
eXN0ZW0oY21kLFRydWUpCgogICAgICAgICAgICAgICAgY29uZl9pdGVtID0gJ2hvc3QgICAgYWxs
ICAgICAgICAgICAgIGFsbCAgICAgICAgICAgICBhbGwgICAgICAgICAgICB0cnVzdCcKICAgICAg
ICAgICAgICAgIGNtZCA9ICdlY2hvICIlcyIgPj4gJXMnICUgKGNvbmZfaXRlbSwgbG9jYWxfcGdf
aGJhX2NoYW5nZSkKICAgICAgICAgICAgICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQsVHJ1ZSkK
CiAgICAgICAgICAgICAgICBkYXRhZGlyID0gc2VsZi5kYXRhZGlyICsgc3RyKGxvb3ApCiAgICAg
ICAgICAgICAgICB0YXJfcGdjb25mX2ZpbGVfcGF0aCA9ICclcy9wb3N0Z3Jlc3FsLmNvbmYnICUg
KGRhdGFkaXIpCiAgICAgICAgICAgICAgICBjbWQgPSAnc2NwIC1pIH4vaGlnaGdva2V5LnBlbSAl
cyAlc0AlczolcycgJSAobG9jYWxfcGdfY29uZl9jaGFuZ2UsIHNlbGYubm9kZV91c2VyLCBpdGVt
LCB0YXJfcGdjb25mX2ZpbGVfcGF0aCkKICAgICAgICAgICAgICAgIGV4ZWNfY29tYW5kX3N5c3Rl
bShjbWQsIFRydWUpCgogICAgICAgICAgICAgICAgdGFyX3BnaGJhX2ZpbGVfcGF0aCA9ICclcy9w
Z19oYmEuY29uZicgJSAoZGF0YWRpcikKICAgICAgICAgICAgICAgIGNtZCA9ICdzY3AgLWkgfi9o
aWdoZ29rZXkucGVtICVzICVzQCVzOiVzJyAlIChsb2NhbF9wZ19oYmFfY2hhbmdlLCBzZWxmLm5v
ZGVfdXNlciwgaXRlbSwgdGFyX3BnaGJhX2ZpbGVfcGF0aCkKICAgICAgICAgICAgICAgIGV4ZWNf
Y29tYW5kX3N5c3RlbShjbWQsIFRydWUpCiAgICAgICAgICAgICAgICBsb29wICs9IDEKICAgICAg
ICAgICAgbG9vcCA9IDEKCiAgICBkZWYgZXhlY190ZXN0X2NvdW50KHNlbGYpOgogICAgICAgIHNx
bCA9ICdleHBsYWluIGFuYWx5c2UgdmVyYm9zZSBzZWxlY3QgY291bnQoKikgZnJvbSAlcycgJSBz
ZWxmLnR0CiAgICAgICAgY21kID0gJyVzL2Jpbi9wc3FsIC1kIHBvc3RncmVzIC1jIFwnJXNcJycg
JSAoc2VsZi50ZXN0cGF0aCxzcWwpCiAgICAgICAgb3V0cHV0KHNxbCkKICAgICAgICB0MSA9IGdl
dHRpbWUoKQogICAgICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQsIFRydWUpCiAgICAgICAgdDIg
PSBnZXR0aW1lKCkKICAgICAgICBvdXRwdXQoJz4+PlJ1biB0aW1lICVzIHNlY29uZCcgJSBpbnQo
dDItdDEpKQoKICAgIGRlZiBleGVjX3Rlc3Rfc2VsZWN0KHNlbGYpOgogICAgICAgIHNxbF9iYXNl
ID0gJ3NlbGVjdCAqIGZyb20gJXMgd2hlcmUgYiA9IDEwMCcgJSBzZWxmLnR0CiAgICAgICAgc3Fs
ID0gJ2V4cGxhaW4gYW5hbHlzZSB2ZXJib3NlICVzJyAlIHNxbF9iYXNlCiAgICAgICAgY21kID0g
JyVzL2Jpbi9wc3FsIC1kIHBvc3RncmVzIC1jIFwnJXNcJycgJSAoc2VsZi50ZXN0cGF0aCxzcWwp
CiAgICAgICAgdDEgPSBnZXR0aW1lKCkKICAgICAgICBvdXRwdXQoc3FsKQogICAgICAgIGV4ZWNf
Y29tYW5kX3N5c3RlbShjbWQsIFRydWUpCiAgICAgICAgdDIgPSBnZXR0aW1lKCkKICAgICAgICBv
dXRwdXQoJz4+Pj5SdW4gdGltZSAlcyBzZWNvbmQnICUgaW50KHQyLXQxKSkKICAgIAogICAgZGVm
IGV4ZWNfdGVzdF9zZWxlY3RhbGwoc2VsZik6CiAgICAgICAgc3FsX2Jhc2UgPSAnc2VsZWN0ICog
ZnJvbSAlcycgJSBzZWxmLnR0CiAgICAgICAgc3FsID0gJ2V4cGxhaW4gYW5hbHlzZSB2ZXJib3Nl
ICVzJyAlIHNxbF9iYXNlCiAgICAgICAgY21kID0gJyVzL2Jpbi9wc3FsIC1kIHBvc3RncmVzIC1j
IFwnJXNcJycgJSAoc2VsZi50ZXN0cGF0aCxzcWwpCiAgICAgICAgdDEgPSBnZXR0aW1lKCkKICAg
ICAgICBvdXRwdXQoc3FsKQogICAgICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQsIFRydWUpCiAg
ICAgICAgdDIgPSBnZXR0aW1lKCkKICAgICAgICBvdXRwdXQoJz4+Pj5SdW4gdGltZSAlcyBzZWNv
bmQnICUgaW50KHQyLXQxKSkKICAgIAogICAgZGVmIHJ1bnRlc3Qoc2VsZiwga2luZCk6CiAgICAg
ICAgCiAgICAgICAgb3V0cHV0KCc+PlRlc3QgV2l0aCBQYXRjaCcpCiAgICAgICAgY291bnQgPSBz
ZWxmLnRlc3R0aW1lcwogICAgICAgIHNlbGYudGVzdHBhdGggPSBzZWxmLmNwX2luc3RhbGxfcGF0
aAogICAgICAgIHNlbGYuY3BnX3N0YXJ0KCkKICAgICAgICB3aGlsZSBjb3VudCA+IDA6CiAgICAg
ICAgICAgIG91dHB1dCgnPj4+VGhlICVzdGggdGVzdCcgJSAoNCAtIGNvdW50KSApCiAgICAgICAg
ICAgIGlmIGtpbmQgPT0gMToKICAgICAgICAgICAgICAgIHNlbGYuZXhlY190ZXN0X3NlbGVjdCgp
CiAgICAgICAgICAgIGVsaWYga2luZCA9PSAyOgogICAgICAgICAgICAgICAgc2VsZi5leGVjX3Rl
c3RfY291bnQoKQogICAgICAgICAgICBlbGlmIGtpbmQgPT0gMzoKICAgICAgICAgICAgICAgIHNl
bGYuZXhlY190ZXN0X3NlbGVjdGFsbCgpCiAgICAgICAgICAgIGNvdW50IC09IDEKICAgICAgICAK
ICAgICAgICBvdXRwdXQoJz4+VGVzdCBXaXRob3V0IFBhdGNoJykKICAgICAgICBjb3VudCA9IHNl
bGYudGVzdHRpbWVzCiAgICAgICAgc2VsZi50ZXN0cGF0aCA9IHNlbGYub3BfaW5zdGFsbF9wYXRo
CiAgICAgICAgc2VsZi5vcGdfc3RhcnQoKQogICAgICAgIHdoaWxlIGNvdW50ID4gMDoKICAgICAg
ICAgICAgb3V0cHV0KCc+Pj5UaGUgJXN0aCB0ZXN0JyAlICg0IC0gY291bnQpICkKICAgICAgICAg
ICAgaWYga2luZCA9PSAxOgogICAgICAgICAgICAgICAgc2VsZi5leGVjX3Rlc3Rfc2VsZWN0KCkK
ICAgICAgICAgICAgZWxpZiBraW5kID09IDI6CiAgICAgICAgICAgICAgICBzZWxmLmV4ZWNfdGVz
dF9jb3VudCgpCiAgICAgICAgICAgIGVsaWYga2luZCA9PSAzOgogICAgICAgICAgICAgICAgc2Vs
Zi5leGVjX3Rlc3Rfc2VsZWN0YWxsKCkKICAgICAgICAgICAgY291bnQgLT0gMQogICAgCgoKCnAg
PSBQcmVwYXJlKCkKCmhhbmRsZV9hcmd1bWVudChwKQpwLmxvYWRfbm9kZXMoKQoKaWYgcC5jb21t
YW5ka2luZCA9PSAnYmluJzoKICAgIHAuY2xlYW5fcmVtb3RlKCkKICAgIHAucHJlcGFyZV9iaW4o
KQplbGlmIHAuY29tbWFuZGtpbmQgPT0gJ2luaXRkYic6CiAgICBwLmluaXRkYl9yZW1vdGUoKQog
ICAgcC5jaGFuZ2Vfbm9kZV9wZ2NvbmYoKQogICAgcC5jb3B5X3NxbCgpCmVsaWYgcC5jb21tYW5k
a2luZCA9PSAnZ2RhdGEnOgogICAgcC5nZW5lcmF0ZWRhdGEoKQplbGlmIHAuY29tbWFuZGtpbmQg
PT0gJ3N0YXJ0YWxsJzoKICAgIHAuc3RhcnRhbGwoKQplbGlmIHAuY29tbWFuZGtpbmQgPT0gJ3N0
b3BhbGwnOgogICAgcC5zdG9wYWxsKCkKZWxpZiBwLmNvbW1hbmRraW5kID09ICdydW5zZWxlY3Qn
OgogICAgcC5ydW50ZXN0KDEpCmVsaWYgcC5jb21tYW5ka2luZCA9PSAncnVuY291bnQnOgogICAg
cC5ydW50ZXN0KDIpCmVsaWYgcC5jb21tYW5ka2luZCA9PSAncnVuc2VsZWN0YWxsJzoKICAgIHAu
cnVudGVzdCgzKQplbGlmIHAuY29tbWFuZGtpbmQgPT0gJ2luY3JlYXNlZGF0YSc6CiAgICBwLmlu
Y3JlYXNlZGF0YSgpCmVsaWYgcC5jb21tYW5ka2luZCA9PSAncmVzZXRwYXJlbnQnOgogICAgcC5y
ZXNldHBhcmVudCgpCgAAAAAAAABzY3JpcHQvcnVudGVzdDEucHkAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAMDEwMDc3NwAwMDAwMDAwADAwMDAwMDAAMDAwMDAwMDEyMzMAMTM2MDY3NTExMTYAMDEx
NDY0ACAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHVzdGFyADAw
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAACMhL3Vzci9iaW4vZW52IHB5dGhvbjMKJycnClVzZSB0aGlzIHRv
IHRlc3QgaW5jcmVhc2Ugc2NhbGUgb2YgcGVyIG5vZGUKJycnCmZyb20gdXRpbCBpbXBvcnQgKgoK
dG90bGUgPSAyCgpjbWRfbGlzdCA9IFsnc3RvcGFsbCcsJ2JpbicsJ2luaXRkYicsJ2dkYXRhIDEn
LCAncnVuc2VsZWN0YWxsJ10KCmNtZF9saXN0LmFwcGVuZCgnaW5jcmVhc2VkYXRhIDEnKQpjbWRf
bGlzdC5hcHBlbmQoJ3J1bnNlbGVjdGFsbCcpCgpjbWRfbGlzdC5hcHBlbmQoJ2luY3JlYXNlZGF0
YSAzJykKY21kX2xpc3QuYXBwZW5kKCdydW5zZWxlY3RhbGwnKQoKY21kX2xpc3QuYXBwZW5kKCdp
bmNyZWFzZWRhdGEgNScpCmNtZF9saXN0LmFwcGVuZCgncnVuc2VsZWN0YWxsJykKCmNtZF9saXN0
LmFwcGVuZCgnaW5jcmVhc2VkYXRhIDEwJykKY21kX2xpc3QuYXBwZW5kKCdydW5zZWxlY3RhbGwn
KQoKY21kX2xpc3QuYXBwZW5kKCdpbmNyZWFzZWRhdGEgMTAnKQpjbWRfbGlzdC5hcHBlbmQoJ3J1
bnNlbGVjdGFsbCcpCgpjbWRfbGlzdC5hcHBlbmQoJ3N0b3BhbGwnKQoKZm9yIGl0ZW0gaW4gY21k
X2xpc3Q6CiAgICBjbWQgPSAnLi9wcmVwYXJlLnB5ICVzJyAlIGl0ZW0KICAgIG91dHB1dCgnPicg
KyBpdGVtKQogICAgZXhlY19jb21hbmRfc3lzdGVtKGNtZCwgVHJ1ZSkKb3V0cHV0KCdGSU5JU0gn
KQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAABzY3JpcHQvcnVudGVzdDIucHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAMDEwMDc3NwAwMDAwMDAwADAwMDAwMDAAMDAwMDAwMDI0NzUAMTM2MDY3NTM3MDAAMDExNDc3
ACAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHVzdGFyADAwAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAACMhL3Vzci9iaW4vZW52IHB5dGhvbjMKZnJvbSB1dGlsIGltcG9ydCAq
Cgpub2RlX2xpc3QgPSBbJzE4LjIxNy4xNjUuMjM4JywnMy4xMzMuMTI0LjIwNScsJzE4LjIxNi4x
ODguMTA4JywnMy4xMzUuMTg3LjEyMycsJzMuMTUuMjE4LjIwNCcsICczLjE1LjIxNC4yMDUnLCAn
MTguMTg4LjExMC4yMjYnLCAnMTguMTkxLjExLjE1J10Kbm9kZV9saXN0X2xlbiA9IGxlbihub2Rl
X2xpc3QpCm5vZGVfbWF4ID0gOAoKZ2VuZXJhdGVfbm9kZV9jb25mKG5vZGVfbGlzdCwgbm9kZV9s
aXN0X2xlbiwgbm9kZV9saXN0X2xlbikKCmNtZF9saXN0ID0gWydzdG9wYWxsJywnYmluJywnaW5p
dGRiJywnZ2RhdGEgMTAnXQpmb3IgaXRlbSBpbiBjbWRfbGlzdDoKICAgIGNtZCA9ICcuL3ByZXBh
cmUucHkgJXMnICUgaXRlbQogICAgb3V0cHV0KCc+JyArIGl0ZW0pCiAgICBleGVjX2NvbWFuZF9z
eXN0ZW0oY21kLCBUcnVlKQoKbG9vcCA9IDIKd2hpbGUgbG9vcCA8PSBub2RlX21heDoKICAgIG91
dHB1dCgnPnRlc3QgaW4gJXMgbm9kZXMnICUgbG9vcCkKICAgIGdlbmVyYXRlX25vZGVfY29uZihu
b2RlX2xpc3QsIG5vZGVfbGlzdF9sZW4sIGxvb3ApCiAgICBsb29wICs9IDEKICAgIGNtZF9saXN0
ID0gWydyZXNldHBhcmVudCcsICdydW5zZWxlY3QnXQogICAgZm9yIGl0ZW0gaW4gY21kX2xpc3Q6
CiAgICAgICAgY21kID0gJy4vcHJlcGFyZS5weSAlcycgJSBpdGVtCiAgICAgICAgb3V0cHV0KCc+
JyArIGl0ZW0pCiAgICAgICAgZXhlY19jb21hbmRfc3lzdGVtKGNtZCwgVHJ1ZSkKCgoKY21kX2xp
c3QgPSBbJ2dkYXRhIDInXQpmb3IgaXRlbSBpbiBjbWRfbGlzdDoKICAgIGNtZCA9ICcuL3ByZXBh
cmUucHkgJXMnICUgaXRlbQogICAgb3V0cHV0KCc+JyArIGl0ZW0pCiAgICBleGVjX2NvbWFuZF9z
eXN0ZW0oY21kLCBUcnVlKQoKbm9kZV9tYXggPSA1Cmxvb3AgPSAyCndoaWxlIGxvb3AgPD0gbm9k
ZV9tYXg6CiAgICBvdXRwdXQoJz50ZXN0IGluICVzIG5vZGVzJyAlIGxvb3ApCiAgICBnZW5lcmF0
ZV9ub2RlX2NvbmYobm9kZV9saXN0LCBub2RlX2xpc3RfbGVuLCBsb29wKQogICAgbG9vcCArPSAx
CiAgICBjbWRfbGlzdCA9IFsncmVzZXRwYXJlbnQnLCAncnVuc2VsZWN0YWxsJ10KICAgIGZvciBp
dGVtIGluIGNtZF9saXN0OgogICAgICAgIGNtZCA9ICcuL3ByZXBhcmUucHkgJXMnICUgaXRlbQog
ICAgICAgIG91dHB1dCgnPicgKyBpdGVtKQogICAgICAgIGV4ZWNfY29tYW5kX3N5c3RlbShjbWQs
IFRydWUpCgpjbWQgPSAnLi9wcmVwYXJlLnB5IHN0b3BhbGwnCm91dHB1dCgnPnN0b3BhbGwnKQpl
eGVjX2NvbWFuZF9zeXN0ZW0oY21kLCBUcnVlKQpvdXRwdXQoJ0ZJTklTSCcpCgAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAHNjcmlwdC9ydW50ZXN0My5weQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw
MTAwNzc3ADAwMDAwMDAAMDAwMDAwMAAwMDAwMDAwMDU3NQAxMzYwNTc1MjY3NwAwMTE1MTIAIDAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdXN0YXIAMDAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAIyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwpmcm9tIHV0aWwgaW1wb3J0ICoKCm5v
ZGVfbGlzdCA9IFsnMTMuNTkuMjIuMTUzJywgJzMuMTMzLjE1NC4yMDInLCczLjEzNi4yMi4xOTkn
LCczLjEzMy4xMzYuMTEzJ10KZ2VuZXJhdGVfbm9kZV9jb25mKG5vZGVfbGlzdCxsZW4obm9kZV9s
aXN0KSwgNCkKCmNtZF9saXN0ID0gWydzdG9wYWxsJywnYmluJywnaW5pdGRiJywnZ2RhdGEgMScs
ICdydW5zZWxlY3QnLCdydW5jb3VudCcsJ3N0b3BhbGwnXQpmb3IgaXRlbSBpbiBjbWRfbGlzdDoK
ICAgIGNtZCA9ICcuL3ByZXBhcmUucHkgJXMnICUgaXRlbQogICAgb3V0cHV0KCc+JyArIGl0ZW0p
CiAgICBleGVjX2NvbWFuZF9zeXN0ZW0oY21kLCBUcnVlKQpvdXRwdXQoJ0ZJTklTSCcpAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAABzY3JpcHQvdXRpbC5weQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDEw
MDc3NwAwMDAwMDAwADAwMDAwMDAAMDAwMDAwMDUwMTIAMTM2MDU3NTMxMjYAMDEwNjU1ACAwAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHVzdGFyADAwAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAACMhL3Vzci9iaW4vZW52IHB5dGhvbjMNCmltcG9ydCBvcw0KaW1wb3J0IHN5cw0K
aW1wb3J0IHRpbWUNCmltcG9ydCB0aHJlYWRpbmcNCg0KY2xhc3MgbXlUaHJlYWQgKHRocmVhZGlu
Zy5UaHJlYWQpOg0KICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmdW5jLCB0dXBsZV9pdGVtLCBsb29w
LCBsb29wMik6DQogICAgICAgIHRocmVhZGluZy5UaHJlYWQuX19pbml0X18oc2VsZikNCiAgICAg
ICAgc2VsZi5mdW5jID0gZnVuYw0KICAgICAgICBzZWxmLnR1cGxlX2l0ZW0gPSB0dXBsZV9pdGVt
DQogICAgICAgIHNlbGYubG9vcCA9IGxvb3ANCiAgICAgICAgc2VsZi5sb29wMiA9IGxvb3AyDQog
ICAgZGVmIHJ1bihzZWxmKTogDQogICAgICAgIHNlbGYuZnVuYyhzZWxmLnR1cGxlX2l0ZW0sIHNl
bGYubG9vcCwgc2VsZi5sb29wMikNCg0KZGVmIGdldF9lbnYoZW52KToNCiAgICByZXR1cm4gb3Mu
Z2V0ZW52KGVudikNCg0KZGVmIG91dHB1dChtZXNzYWdlKToNCiAgICBwcmludChtZXNzYWdlKQ0K
ICAgIHN5cy5zdGRvdXQuZmx1c2goKQ0KDQpkZWYgZGVidWdfb3V0cHV0KG1lc3NhZ2UpOg0KICAg
IGRlYnVnX2VuYWJsZSA9IEZhbHNlDQogICAgaWYoZGVidWdfZW5hYmxlKToNCiAgICAgICAgb3V0
cHV0KG1lc3NhZ2UpDQoNCmRlZiBzdGFuZGVyX291dHB1dChtZXNzYWdlKToNCiAgICBwcmludCht
ZXNzYWdlKQ0KDQpkZWYgZXJyb3JfZXhpdChtZXNzYWdlKToNCiAgICBpZiBtZXNzYWdlOg0KICAg
ICAgICBvdXRwdXQobWVzc2FnZSkNCiAgICBzeXMuZXhpdCgxKQ0KDQpkZWYgbm9tYWxfZXhpdCht
ZXNzYWdlKToNCiAgICBpZiBtZXNzYWdlOg0KICAgICAgICBvdXRwdXQobWVzc2FnZSkNCiAgICBz
eXMuZXhpdCgwKQ0KDQpkZWYgcGF0aF9zcGxpY2UocGF0aDEsIHBhdGgyLCBzeXN0ZW10eXBlKToN
CiAgICByZXR1cm4gb3MucGF0aC5qb2luKHBhdGgxLHBhdGgyKQ0KDQpkZWYgZmlsZV9leGlzdChw
YXRoKToNCiAgICByZXR1cm4gb3MucGF0aC5pc2ZpbGUocGF0aCkNCg0KZGVmIGRpcl9leGlzdChw
YXRoKToNCiAgICByZXR1cm4gb3MucGF0aC5pc2RpcihwYXRoKQ0KDQpkZWYgZXhlY19jb21hbmRf
c3lzdGVtKHRoZWNvbW1hbmQsIG91dGxvZz1GYWxzZSwgcmVwb3J0PVRydWUpOg0KICAgIGRlYnVn
X291dHB1dCh0aGVjb21tYW5kKQ0KICAgIGlmIG5vdCBvdXRsb2c6DQogICAgICAgIHRoZWNvbW1h
bmQgKz0gJyA+IC9kZXYvbnVsbCAyPiYxJw0KICAgIHJlc3VsdD1vcy5zeXN0ZW0odGhlY29tbWFu
ZCkNCiAgICBpZiAwICE9IHJlc3VsdCBhbmQgcmVwb3J0Og0KICAgICAgICBlcnJvcl9leGl0KCJG
YWlsIHRvIHJ1biBjb21tYW5kICVzIiAlICh0aGVjb21tYW5kKSkNCg0KZGVmIGV4ZWNfY29tbWFu
ZF9zeXN0ZW1fcmVtb3RlKHRoZWNvbW1hbmQsIHVzZXIsIGhvc3QsIHJlcG9ydGVycm9yPVRydWUs
IG91dGxvZz1GYWxzZSk6DQogICAgaWYgbm90IG91dGxvZzoNCiAgICAgICAgdGhlY29tbWFuZCAr
PSAnID4gL2Rldi9udWxsIDI+JjEnDQogICAgY21kID0gJ3NzaCAtdCAtaSB+L2hpZ2hnb2tleS5w
ZW0gJXNAJXMgXCIlc1wiJyAlICh1c2VyLCBob3N0LCB0aGVjb21tYW5kKQ0KDQogICAgcmVzdWx0
PW9zLnN5c3RlbShjbWQpDQogICAgaWYgMCAhPSByZXN1bHQ6DQogICAgICAgIGlmIHJlcG9ydGVy
cm9yOg0KICAgICAgICAgICAgZXJyb3JfZXhpdCgiRmFpbCB0byBydW4gY29tbWFuZCAlcyIgJSAo
Y21kKSkNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHJldHVybiBGYWxzZQ0KICAgIHJldHVy
biBUcnVlDQoNCmRlZiBkaXJfcmVtb3RlX2V4aXN0KHBhdGgsIHVzZXIsIGhvc3QpOg0KICAgIGNt
ZCA9ICdscyAlcycgJSBwYXRoDQogICAgcmV0dWx0ID0gZXhlY19jb21tYW5kX3N5c3RlbV9yZW1v
dGUoY21kLCB1c2VyLCBob3N0LCBGYWxzZSkNCiAgICByZXR1cm4gcmV0dWx0DQoNCmRlZiBzbGVl
cCh0aW1lMSk6DQogICAgdGltZS5zbGVlcCh0aW1lMSkNCg0KZGVmIGdldGN3ZCgpOg0KICAgIHJl
dHVybiBvcy5nZXRjd2QoKQ0KDQpkZWYgY2hkaXIocGF0aCk6DQogICAgb3MuY2hkaXIocGF0aCkN
Cg0KZGVmIGdldHRpbWUoKToNCiAgICByID0gdGltZS50aW1lKCkNCiAgICByZXR1cm4gcg0KDQpk
ZWYgZ2VuZXJhdGVfbm9kZV9jb25mKG5vZGVfbGlzdCwgbm9kZV9saXN0X2xlbiwgbnVtKToNCg0K
ICAgIHpzID0gaW50KG51bSAvIG5vZGVfbGlzdF9sZW4pDQogICAgeXMgPSBpbnQobnVtICUgbm9k
ZV9saXN0X2xlbikNCiAgICANCiAgICBsb29wID0gMA0KICAgIGZpbGUgPSBvcGVuKCdub2RlX2Nv
bmYnLCAndycpDQogICAgd2hpbGUgbG9vcCA8IG51bToNCiAgICAgICAgY3VyX25vZGVfbnVtID0g
enMNCiAgICAgICAgaWYgbG9vcCArIDEgPD0geXM6DQogICAgICAgICAgICBjdXJfbm9kZV9udW0g
Kz0gMQ0KDQogICAgICAgIGlmIGxvb3AgKyAxID4gbm9kZV9saXN0X2xlbjoNCiAgICAgICAgICAg
IGJyZWFrDQoNCiAgICAgICAgZmlsZS53cml0ZShzdHIobm9kZV9saXN0W2xvb3BdKSkNCiAgICAg
ICAgDQogICAgICAgIGZpbGUud3JpdGUoJyAlc1xuJyAlIGN1cl9ub2RlX251bSkNCiAgICAgICAg
bG9vcCArPSAxDQoNCg0KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAA=
--00000000000001b2b2059c16598a--