Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tQ27t-00HBNe-PR for pgsql-hackers@arkaria.postgresql.org; Tue, 24 Dec 2024 10:26:58 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tQ26t-0044Cq-UY for pgsql-hackers@arkaria.postgresql.org; Tue, 24 Dec 2024 10:25:55 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tQ26t-0044Ch-As for pgsql-hackers@lists.postgresql.org; Tue, 24 Dec 2024 10:25:55 +0000 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tQ26l-000KOJ-2d for pgsql-hackers@lists.postgresql.org; Tue, 24 Dec 2024 10:25:54 +0000 Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-2f43da61ba9so4383145a91.2 for ; Tue, 24 Dec 2024 02:25:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1735035947; x=1735640747; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=XZINT4QO/JZ4Knz8EmwhCUo6fVMCZW7PDPDta+4Su8U=; b=iRgGh6sfmxGq7H6f3EMVdt/5atpPO5imSaOy4tXCfnRT7BiZS6iSUKoYQvrFDvupjA JpT+Aq5kFFLd4mqLYdY/1bLMybzD41KL6u/PYCG2RhcSI+GmBI85oiryrtVm/qM2wfpI sBacrLLvCje2BE7VM9yu7EsnsXUP+RADB8DDIp9udeeHdSrK5+klJreDrzONeuum5b+Q pCVvdUc+aQcNFzZZ3Ub6JJtD6NQYF9pQDyxzZi6qp+g/CkzUXVVvr05a/RuL9aOvkXde c76eWYJkhp4olNSeX3j1KHlsqKBhaHFnsdTpsqVMzcrcRzUyfyl241xt5/6vJWdMl8l3 GYBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735035947; x=1735640747; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=XZINT4QO/JZ4Knz8EmwhCUo6fVMCZW7PDPDta+4Su8U=; b=mUt7gKZ5PQTNuN7jFiZ4pnGJdkLhfBNtGQwNNlyKuJ9kM6Ioyf4uUvug4w8XQBI3d7 4ylCIjWP0H5U12Bw6CNHpvMsXjxkikJkv/KMnT1fnhfGtjHLuI5nxl9R2/pWTdfFMARC jHPc5p4arF8z7zaL+S7AQhmePAguiateQUPYS3IayPvG9kXDynCFw9Lg3HT4CvBDUHwU AesXW1xBLUIlZvIKxsSIuYwetYLVl5j06kHpBAA8DJtDCupZFaJAdJb18Jd/0GWfCAi7 6QzVCwyFfgDBaqjfrwIOtRWKKTIO8YLmlC/WZgDYbcfdFuOX4ZKYxS9MXaFMrc7S9o/8 CJrg== X-Gm-Message-State: AOJu0YzZVSqfiM5zJLQrqZ88dgAEgU1lhGooQQSc3dqjkjAM22eJkRTp xrVK2m3ajWlANz6RU96DFDv+YpAkV0lmhFcXhvQbhBpQaizBwCEH6Vz8oeLtHlmFQoGVLO9Uxs+ GRtxSO8uSUqWuP5bFVFCPeZQCOikvdqoc X-Gm-Gg: ASbGnctj0Z46lnKodyPfAHIIzjicgrq/K/fKmz4YVlsZ4SWjEPHraN2mFdipRDss+/m eYuSooUelhOqOQVJLHbn62mRdbeFNorWgH/LGCHPg65vNVt+bs2WDobZXPPNqScFCibeSz4A= X-Google-Smtp-Source: AGHT+IFLuBjt4PDoCRnBBeDCGm5TocWdA0QpqzZGKBYxGjynZiHorHXHfVH0OsRA+mH4hSYCAM6xSN74PQnwIuvwH9E= X-Received: by 2002:a17:90a:da8e:b0:2ee:f80c:688d with SMTP id 98e67ed59e1d1-2f452ec37a0mr21822228a91.25.1735035946625; Tue, 24 Dec 2024 02:25:46 -0800 (PST) MIME-Version: 1.0 References: <0b1f670d-b39d-4966-bf32-f0d502ebc564@postgrespro.ru> In-Reply-To: <0b1f670d-b39d-4966-bf32-f0d502ebc564@postgrespro.ru> From: Ranier Vilela Date: Tue, 24 Dec 2024 07:25:37 -0300 Message-ID: Subject: Re: Exists pull-up application with JoinExpr To: Alena Rybakina Cc: PostgreSQL Hackers Content-Type: multipart/mixed; boundary="000000000000459143062a01896b" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000459143062a01896b Content-Type: multipart/alternative; boundary="000000000000459142062a018969" --000000000000459142062a018969 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Alena. Em ter., 24 de dez. de 2024 =C3=A0s 01:44, Alena Rybakina < a.rybakina@postgrespro.ru> escreveu: > Hi, hackers! > > I found one pull-up that works if the inner join condition is written > through the where condition, > > create temp table ta (id int primary key, val int); > insert into ta values(1,1); > insert into ta values(2,2);insert into ta values(3,3); > create temp table tb (id int primary key, aval int); > insert into tb values(4,1); > insert into tb values(5,1); > insert into tb values(1,2); > > create temp table tc (id int primary key, aid int); > insert into tc values(6,1); > insert into tc values(7,2); > > EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) > SELECT * > FROM ta > WHERE EXISTS (SELECT * > FROM tb, tc > WHERE ta.id =3D tb.id); > QUERY PLAN > ------------------------------------------------------------------------- > Nested Loop Semi Join (actual rows=3D1 loops=3D1) > Buffers: local hit=3D6 > -> Seq Scan on ta (actual rows=3D3 loops=3D1) > Buffers: local hit=3D1 > -> Nested Loop (actual rows=3D0 loops=3D3) > Buffers: local hit=3D5 > -> Index Only Scan using tb_pkey on tb (actual rows=3D0 loops= =3D3) > Index Cond: (id =3D ta.id) > Heap Fetches: 1 > Buffers: local hit=3D4 > -> Seq Scan on tc (actual rows=3D1 loops=3D1) > Buffers: local hit=3D1 > Planning: > Buffers: shared hit=3D67 read=3D12 > (14 rows) > > but it doesn't work if it is written through the outside condition. > > alena@postgres=3D# EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) > SELECT * > FROM ta > WHERE EXISTS (SELECT * > FROM tb JOIN tc > ON ta.id =3D tb.id); > QUERY PLAN > ------------------------------------------------------ > Seq Scan on ta (actual rows=3D1 loops=3D1) > Filter: EXISTS(SubPlan 1) > Rows Removed by Filter: 2 > Buffers: local hit=3D5 > SubPlan 1 > -> Nested Loop (actual rows=3D0 loops=3D3) > Buffers: local hit=3D4 > -> Seq Scan on tb (actual rows=3D0 loops=3D3) > Filter: (ta.id =3D id) > Rows Removed by Filter: 3 > Buffers: local hit=3D3 > -> Seq Scan on tc (actual rows=3D1 loops=3D1) > Buffers: local hit=3D1 > Planning: > Buffers: shared hit=3D16 read=3D9 > (15 rows) > > > I have written a patch to add this functionality and now it gives an quer= y > plan: > > alena@postgres=3D# EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) > SELECT * > FROM ta > WHERE EXISTS (SELECT * > FROM tb JOIN tc > ON ta.id =3D tb.id); > QUERY PLAN > ------------------------------------------------------------------------- > Nested Loop Semi Join (actual rows=3D1 loops=3D1) > Buffers: local hit=3D6 > -> Seq Scan on ta (actual rows=3D3 loops=3D1) > Buffers: local hit=3D1 > -> Nested Loop (actual rows=3D0 loops=3D3) > Buffers: local hit=3D5 > -> Index Only Scan using tb_pkey on tb (actual rows=3D0 loops= =3D3) > Index Cond: (id =3D ta.id) > Heap Fetches: 1 > Buffers: local hit=3D4 > -> Seq Scan on tc (actual rows=3D1 loops=3D1) > Buffers: local hit=3D1 > (12 rows) > > tb and tc form a Cartesian product, but in the case of the intersection > condition with tuples from the table ta (ta.id =3D tb.id). So, according = to > the join condition, tb intersects only with 1, and only it gets into the > result, but at the same time they appear twice - this is because of the > Cartesian product of tb with tc > *How it works:* > > I rewrote the code a bit so that it considers not only the quals in > jointree->quals, but also those in join expression > (subselect->jointree->fromlist). If they satisfy the conditions for using > pull up, I add them to the list of clauses and form a "Bool" expression > from them, joined by an "AND" operation. > I took a look at this patch and I did a little polishing on it. And I believe that in testing, you need to set it to BUFFERS OFF, because of the recent change made to ANALYZE. The tests are failing, like this: QUERY PLAN ------------------------------------------------------------------------- Nested Loop Semi Join (actual rows=3D2 loops=3D1) + Buffers: local hit=3D7 -> Seq Scan on ta (actual rows=3D2 loops=3D1) + Buffers: local hit=3D1 -> Nested Loop (actual rows=3D1 loops=3D2) + Buffers: local hit=3D6 -> Index Only Scan using tb_pkey on tb (actual rows=3D1 loops=3D2) Index Cond: (id =3D ta.id) Heap Fetches: 2 + Buffers: local hit=3D4 -> Seq Scan on tc (actual rows=3D1 loops=3D2) -(7 rows) + Buffers: local hit=3D2 +(12 rows) best regards, Ranier Vilela --000000000000459142062a018969 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Alena.

Em ter., 24 de dez= . de 2024 =C3=A0s 01:44, Alena Rybakina <a.rybakina@postgrespro.ru> escreveu:
=20 =20 =20

Hi, hackers!

I found one pull-up that works if the inner join condition is written through the where condition,

create temp table ta (id int prima=
ry key, val int);
insert into ta values(1,1);
insert into ta values(2,2);
insert into ta values(3,3);

create temp table tb (id int primary key, aval int);
insert into tb values(4,1);
insert into tb values(5,1);
insert into tb values(1,2);

create temp table tc (id int primary key, aid int);
insert into tc values(6,1);
insert into tc values(7,2);

EXPLAIN (ANALYZE, COSTS OFF, SUMMA=
RY OFF, TIMING OFF)
 SELECT *
   FROM ta
  WHERE EXISTS (SELECT *
                  FROM tb, tc
                  WHERE ta.id =3D tb.id);
                               QUERY PLAN                               =20
-------------------------------------------------------------------------
 Nested Loop Semi Join (actual rows=3D1 loops=3D1)
   Buffers: local hit=3D6
   ->  Seq Scan on ta (actual rows=3D3 loops=3D1)
         Buffers: local hit=3D1
   ->  Nested Loop (actual rows=3D0 loops=3D3)
         Buffers: local hit=3D5
         ->  Index Only Scan using tb_pkey on tb (actual rows=3D0 loops=
=3D3)
               Index Cond: (id =3D ta.id)
               Heap Fetches: 1
               Buffers: local hit=3D4
         ->  Seq Scan on tc (actual rows=3D1 loops=3D1)
               Buffers: local hit=3D1
 Planning:
   Buffers: shared hit=3D67 read=3D12
(14 rows)

but it doesn't work if it is written through the outside condition.

alena@postgres=3D# EXPLAIN (ANALYZ=
E, COSTS OFF, SUMMARY OFF, TIMING OFF)
 SELECT *
   FROM ta
  WHERE EXISTS (SELECT *
                  FROM tb JOIN tc
                  ON ta.id =
=3D tb.id);
                      QUERY PLAN                     =20
------------------------------------------------------
 Seq Scan on ta (actual rows=3D1 loops=3D1)
   Filter: EXISTS(SubPlan 1)
   Rows Removed by Filter: 2
   Buffers: local hit=3D5
   SubPlan 1
     ->  Nested Loop (actual rows=3D0 loops=3D3)
           Buffers: local hit=3D4
           ->  Seq Scan on tb (actual rows=3D0 loops=3D3)
                 Filter: (ta.id<=
/a> =3D id)
                 Rows Removed by Filter: 3
                 Buffers: local hit=3D3
           ->  Seq Scan on tc (actual rows=3D1 loops=3D1)
                 Buffers: local hit=3D1
 Planning:
   Buffers: shared hit=3D16 read=3D9
(15 rows)

I have written a patch to add this functionality and now it gives an query plan:

alena@postgres=3D# EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF)
=C2=A0SELECT *
=C2=A0=C2=A0 FROM ta
=C2=A0 WHERE EXISTS (SELECT *
=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=C2=A0 FROM tb JOIN tc
=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=C2=A0 ON
ta.id =3D tb.id); =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=C2=A0=C2=A0=C2=A0=C2=A0 QUERY PLAN=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=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=A0Nested Loop Semi Join (actual rows=3D1 loops=3D1)
=C2=A0=C2=A0 Buffers: local hit=3D6
=C2=A0=C2=A0 ->=C2=A0 Seq Scan on ta (actual rows=3D3 loops=3D1) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Buffers: local hit= =3D1
=C2=A0=C2=A0 ->=C2=A0 Nested Loop (actual rows=3D0 loops=3D3)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Buffers: local hit= =3D5
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ->=C2=A0 Index On= ly Scan using tb_pkey on tb (actual rows=3D0 loops=3D3)
=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 Index Cond: (id =3D ta.id)
=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 Heap Fetches: 1
=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 Buffers: local hit=3D4
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ->=C2=A0 Seq Scan= on tc (actual rows=3D1 loops=3D1)
=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 Buffers: local hit=3D1
(12 rows)

tb and tc form a Cartesian product, but in the case of the intersection condition with tuples from the table ta (ta.id =3D tb.id). So, according= to the join condition, tb intersects only with 1, and only it gets into the result, but at the same time they appear twice - this is because of the Cartesian product of tb with tc

How it works:

I rewrote the code a bit so that it considers not only the quals in jointree->quals, but also those in join expression (subselect->jointree->fromlist). If they satisfy the conditions for using pull up, I add them to the list of clauses and form a "Bool" expression from them, joined by an "= AND" operation.

I took a look at this patch= and I did a little polishing on it.

And I believe that in testing, = you need to set it to BUFFERS OFF,
because of the recent change made to = ANALYZE.

The tests are failing, like this:=C2=A0
QUERY PLA= N
=C2=A0----------------------------------------------------------------= ---------
=C2=A0Nested Loop Semi Join (actual rows=3D2 loops=3D1)
+ B= uffers: local hit=3D7
=C2=A0-> Seq Scan on ta (actual rows=3D2 loops= =3D1)
+ Buffers: local hit=3D1
=C2=A0-> Nested Loop (actual rows= =3D1 loops=3D2)
+ Buffers: local hit=3D6
=C2=A0-> Index Only Scan = using tb_pkey on tb (actual rows=3D1 loops=3D2)
=C2=A0Index Cond: (id = =3D ta.id)
=C2=A0Heap Fetches: 2
+ Buffe= rs: local hit=3D4
=C2=A0-> Seq Scan on tc (actual rows=3D1 loops=3D2)=
-(7 rows)
+ Buffers: local hit=3D2
+(12 rows)

=
best regards,
Ranier Vilela
--000000000000459142062a018969-- --000000000000459143062a01896b Content-Type: application/octet-stream; name="v1-0001-Add-EXISTS-pull-up-if-subquery-join-expressions.patch" Content-Disposition: attachment; filename="v1-0001-Add-EXISTS-pull-up-if-subquery-join-expressions.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_m52bld0n0 ZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL29wdGltaXplci9wbGFuL3N1YnNlbGVjdC5jIGIvc3Jj L2JhY2tlbmQvb3B0aW1pemVyL3BsYW4vc3Vic2VsZWN0LmMKaW5kZXggZWQ2MmUzYTBmYy4uZjUw NDJiNjk1MiAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvb3B0aW1pemVyL3BsYW4vc3Vic2VsZWN0 LmMKKysrIGIvc3JjL2JhY2tlbmQvb3B0aW1pemVyL3BsYW4vc3Vic2VsZWN0LmMKQEAgLTEzNzYs NiArMTM3NiwxMSBAQCBjb252ZXJ0X0VYSVNUU19zdWJsaW5rX3RvX2pvaW4oUGxhbm5lckluZm8g KnJvb3QsIFN1YkxpbmsgKnN1YmxpbmssCiAJaW50CQkJdmFybm87CiAJUmVsaWRzCQljbGF1c2Vf dmFybm9zOwogCVJlbGlkcwkJdXBwZXJfdmFybm9zOworCUxpc3RDZWxsCSpsYzsKKwlMaXN0CQkq Y2xhdXNlczsKKwlMaXN0CQkqYWxsX2NsYXVzZXMgPSBOSUw7CisJQ29uc3QJCSpjb25zdF92YXI7 CisJYm9vbAkJZmlyc3RfZWxlbTsKIAogCUFzc2VydChzdWJsaW5rLT5zdWJMaW5rVHlwZSA9PSBF WElTVFNfU1VCTElOSyk7CiAKQEAgLTE0MDUsMTIgKzE0MTAsODAgQEAgY29udmVydF9FWElTVFNf c3VibGlua190b19qb2luKFBsYW5uZXJJbmZvICpyb290LCBTdWJMaW5rICpzdWJsaW5rLAogCWlm ICghc2ltcGxpZnlfRVhJU1RTX3F1ZXJ5KHJvb3QsIHN1YnNlbGVjdCkpCiAJCXJldHVybiBOVUxM OwogCisJaWYgKHN1YnNlbGVjdC0+am9pbnRyZWUtPnF1YWxzKQorCQlhbGxfY2xhdXNlcyA9IGxh cHBlbmQoYWxsX2NsYXVzZXMsIHN1YnNlbGVjdC0+am9pbnRyZWUtPnF1YWxzKTsKKworCXN1YnNl bGVjdC0+am9pbnRyZWUtPnF1YWxzID0gTlVMTDsKKworCS8qIEdhdGhlciBhbGwgY2xhdXNlcyBp biBtYWluIGxpc3QgZm9yIHRoZSBmdXJ0aGVyIGNvbnNpZGVyYXRpb24gKi8KKwlhbGxfY2xhdXNl cyA9IGxpc3RfY29uY2F0KGFsbF9jbGF1c2VzLCBzdWJzZWxlY3QtPmpvaW50cmVlLT5mcm9tbGlz dCk7CisKIAkvKgotCSAqIFNlcGFyYXRlIG91dCB0aGUgV0hFUkUgY2xhdXNlLiAgKFdlIGNvdWxk IHRoZW9yZXRpY2FsbHkgYWxzbyByZW1vdmUKLQkgKiB0b3AtbGV2ZWwgcGxhaW4gSk9JTi9PTiBj bGF1c2VzLCBidXQgaXQncyBwcm9iYWJseSBub3Qgd29ydGggdGhlCi0JICogdHJvdWJsZS4pCisJ ICogV2Ugd2lsbCBhYmxlIHRvIHJlbW92ZSB0b3AtbGV2ZWwgcGxhaW4gSk9JTi9PTiBjbGF1c2Vz IGlmIHRoZXkgYXJlIG5vdCBvdXRlciBqb2luLgogCSAqLwotCXdoZXJlQ2xhdXNlID0gc3Vic2Vs ZWN0LT5qb2ludHJlZS0+cXVhbHM7CisJY2xhdXNlcyA9IE5JTDsKKwlmaXJzdF9lbGVtID0gdHJ1 ZTsKKwljb25zdF92YXIgPSBtYWtlQ29uc3QoQk9PTE9JRCwKKwkJCQkJCQkJLTEsCisJCQkJCQkJ CUludmFsaWRPaWQsCisJCQkJCQkJCXNpemVvZihib29sKSwKKwkJCQkJCQkJKERhdHVtKSAxLAor CQkJCQkJCQlmYWxzZSwKKwkJCQkJCQkJdHJ1ZSk7CisJZm9yZWFjaCAobGMsIGFsbF9jbGF1c2Vz KQorCXsKKwkJTm9kZSAqamUgPSAoKE5vZGUgKikgbGZpcnN0KGxjKSk7CisKKwkJd2hlcmVDbGF1 c2UgPSBqZTsKKwkJaWYgKElzQShqZSwgUmFuZ2VUYmxSZWYpKQorCQkJZ290byBlbmQ7CisKKwkJ aWYgKChJc0EoamUsIEpvaW5FeHByKSAmJiAoKEpvaW5FeHByICopamUpLT5qb2ludHlwZSAhPSBK T0lOX0lOTkVSKSkKKwkJCWdvdG8gZW5kOworCisJCWlmIChJc0EoamUsIEpvaW5FeHByKSAmJiAo KEpvaW5FeHByICopamUpLT5xdWFscyAhPSBOVUxMKQorCQkJd2hlcmVDbGF1c2UgPSAoKEpvaW5F eHByICopamUpLT5xdWFsczsKKworCQkvKgorCQkgKiBPbiB0aGUgb3RoZXIgaGFuZCwgdGhlIFdI RVJFIGNsYXVzZSBtdXN0IGNvbnRhaW4gc29tZSBWYXJzIG9mIHRoZQorCQkgKiBwYXJlbnQgcXVl cnksIGVsc2UgaXQncyBub3QgZ29ubmEgYmUgYSBqb2luLgorCQkgKi8KKwkJaWYgKCFjb250YWlu X3ZhcnNfb2ZfbGV2ZWwod2hlcmVDbGF1c2UsIDEpKQorCQkJZ290byBlbmQ7CisKKwkJLyoKKwkJ ICogV2UgZG9uJ3QgcmlzayBvcHRpbWl6aW5nIGlmIHRoZSBXSEVSRSBjbGF1c2UgaXMgdm9sYXRp bGUsIGVpdGhlci4KKwkJICovCisJCWlmIChjb250YWluX3ZvbGF0aWxlX2Z1bmN0aW9ucyh3aGVy ZUNsYXVzZSkpCisJCQlnb3RvIGVuZDsKKworCQkvKgorCQkgKiBJbiBjYXNlIG9mIGEgc3VjY2Vz c2Z1bCBhdHRlbXB0LCByZXBsYWNlcyBpdCB3aXRoIHRoZSBjb3JyZWN0IGNvbmRpdGlvbgorCQkg Ki8KKwkJaWYgKElzQShqZSwgSm9pbkV4cHIpKQorCQkJKChKb2luRXhwciAqKWplKS0+cXVhbHMg PSAoTm9kZSAqKSBjb25zdF92YXI7CisKKwkJY2xhdXNlcyA9IGxhcHBlbmQoY2xhdXNlcywgd2hl cmVDbGF1c2UpOworCisJCWZpcnN0X2VsZW0gPSBmYWxzZTsKKwkJc3Vic2VsZWN0LT5qb2ludHJl ZS0+ZnJvbWxpc3QgPSBsaXN0X2RlbGV0ZV9wdHIoc3Vic2VsZWN0LT5qb2ludHJlZS0+ZnJvbWxp c3QsIGxjKTsKKworCQllbmQ6CisJCQlpZiAoZmlyc3RfZWxlbSkKKwkJCQlyZXR1cm4gTlVMTDsK Kwl9CisKKwlsaXN0X2ZyZWUoYWxsX2NsYXVzZXMpOworCisJLyogV2UgZG9uJ3QgaGF2ZSBhbnkg dXNlcyBmb3IgcHVsbC11cCBjcmVhdGlvbiAqLworCWlmIChjbGF1c2VzID09IE5JTCkKKwkJcmV0 dXJuIE5VTEw7CisJZWxzZQorCQkvKiBXZSBjYW4gZWFzaWx5IGNvbWJpbmUgY2xhdXNlcyB0aHJv dWdoIEFORCBvcGVyYXRvciBiZWNhdXNlIHRoZXkgYXJlIGluZGVwZW5kZW50ICovCisJCXdoZXJl Q2xhdXNlID0gbGlzdF9sZW5ndGgoY2xhdXNlcykgPiAxID8KKwkJCQkJCQkoTm9kZSAqKSBtYWtl Qm9vbEV4cHIoQU5EX0VYUFIsIGNsYXVzZXMsIC0xKSA6CisJCQkJCQkJKE5vZGUgKikgbGluaXRp YWwoY2xhdXNlcyk7CisKIAlzdWJzZWxlY3QtPmpvaW50cmVlLT5xdWFscyA9IE5VTEw7CiAKIAkv KgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVncmVzcy9leHBlY3RlZC9zdWJzZWxlY3Qub3V0IGIv c3JjL3Rlc3QvcmVncmVzcy9leHBlY3RlZC9zdWJzZWxlY3Qub3V0CmluZGV4IGViYzU0NWUyNDYu LmFiMGQ3MTZhNzAgMTAwNjQ0Ci0tLSBhL3NyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvc3Vic2Vs ZWN0Lm91dAorKysgYi9zcmMvdGVzdC9yZWdyZXNzL2V4cGVjdGVkL3N1YnNlbGVjdC5vdXQKQEAg LTgxMiw2ICs4MTIsMTU3IEBAIHdoZXJlIGV4aXN0cyAoCiAgICAgICBmcm9tIHRleHRfdGJsICkg c3MKICAgd2hlcmUgcm9hZC5uYW1lID0gc3MuZjEgKTsKIHJvbGxiYWNrOworLS0gVGVzdCBjYXNl IGZvciBleGlzdCBzdWJsaW5rIHdoZXJlIHdlIGNhbiBjb25zaWRlciBzb21lIHVuZGVwZW5kZW50 IGV4cHJlc3Npb24KKy0tIHdpdGggb3V0ZXIgbGluaworLS0KK0VYUExBSU4gKEFOQUxZWkUsIENP U1RTIE9GRiwgU1VNTUFSWSBPRkYsIFRJTUlORyBPRkYsIEJVRkZFUlMgT0ZGKQorIFNFTEVDVCAx CisgICBGUk9NIHRhCisgIFdIRVJFIEVYSVNUUyAoU0VMRUNUIDEKKyAgICAgICAgICAgICAgICAg IEZST00gdGIKKyAgICAgICAgICAgICAgICAgIEpPSU4gdGMKKyAgICAgICAgICAgICAgICAgICAg T04gdGEuaWQgPSB0Yi5pZCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUVVFUlkg UExBTiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisg TmVzdGVkIExvb3AgU2VtaSBKb2luIChhY3R1YWwgcm93cz0yIGxvb3BzPTEpCisgICAtPiAgU2Vx IFNjYW4gb24gdGEgKGFjdHVhbCByb3dzPTIgbG9vcHM9MSkKKyAgIC0+ICBOZXN0ZWQgTG9vcCAo YWN0dWFsIHJvd3M9MSBsb29wcz0yKQorICAgICAgICAgLT4gIEluZGV4IE9ubHkgU2NhbiB1c2lu ZyB0Yl9wa2V5IG9uIHRiIChhY3R1YWwgcm93cz0xIGxvb3BzPTIpCisgICAgICAgICAgICAgICBJ bmRleCBDb25kOiAoaWQgPSB0YS5pZCkKKyAgICAgICAgICAgICAgIEhlYXAgRmV0Y2hlczogMgor ICAgICAgICAgLT4gIFNlcSBTY2FuIG9uIHRjIChhY3R1YWwgcm93cz0xIGxvb3BzPTIpCisoNyBy b3dzKQorCitFWFBMQUlOIChBTkFMWVpFLCBDT1NUUyBPRkYsIFNVTU1BUlkgT0ZGLCBUSU1JTkcg T0ZGLCBCVUZGRVJTIE9GRikKKyBTRUxFQ1QgMQorICAgRlJPTSB0YQorICBXSEVSRSBFWElTVFMg KFNFTEVDVCAxCisgICAgICAgICAgICAgICAgICBGUk9NIHRiCisgICAgICAgICAgICAgICAgICBK T0lOIHRjCisgICAgICAgICAgICAgICAgICAgIE9OIHRhLmlkID0gdGMuaWQpOworICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIE5lc3RlZCBMb29wIFNlbWkgSm9pbiAoYWN0dWFs IHJvd3M9MiBsb29wcz0xKQorICAgLT4gIFNlcSBTY2FuIG9uIHRhIChhY3R1YWwgcm93cz0yIGxv b3BzPTEpCisgICAtPiAgTmVzdGVkIExvb3AgKGFjdHVhbCByb3dzPTEgbG9vcHM9MikKKyAgICAg ICAgIC0+ICBJbmRleCBPbmx5IFNjYW4gdXNpbmcgdGNfcGtleSBvbiB0YyAoYWN0dWFsIHJvd3M9 MSBsb29wcz0yKQorICAgICAgICAgICAgICAgSW5kZXggQ29uZDogKGlkID0gdGEuaWQpCisgICAg ICAgICAgICAgICBIZWFwIEZldGNoZXM6IDIKKyAgICAgICAgIC0+ICBTZXEgU2NhbiBvbiB0YiAo YWN0dWFsIHJvd3M9MSBsb29wcz0yKQorKDcgcm93cykKKworLS0gSm9pbiBjb21wb3VuZCBleHBy ZXNzaW9uCitFWFBMQUlOIChBTkFMWVpFLCBDT1NUUyBPRkYsIFNVTU1BUlkgT0ZGLCBUSU1JTkcg T0ZGLCBCVUZGRVJTIE9GRikKKyBTRUxFQ1QgMQorICAgRlJPTSB0YQorICBXSEVSRSBFWElTVFMg KFNFTEVDVCAxCisgICAgICAgICAgICAgICAgICBGUk9NIHRiCisgICAgICAgICAgICAgICAgICBK T0lOIHRjCisgICAgICAgICAgICAgICAgICAgIE9OIHRhLmlkID0gdGMuaWQgYW5kCisgICAgICAg ICAgICAgICAgICAgICAgIHRhLmlkID0gdGIuaWQpOworICAgICAgICAgICAgICAgICAgICAgICAg IFFVRVJZIFBMQU4gICAgICAgICAgICAgICAgICAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIEhhc2ggUmlnaHQg U2VtaSBKb2luIChhY3R1YWwgcm93cz0yIGxvb3BzPTEpCisgICBIYXNoIENvbmQ6ICh0Yy5pZCA9 IHRhLmlkKQorICAgLT4gIEhhc2ggSm9pbiAoYWN0dWFsIHJvd3M9MiBsb29wcz0xKQorICAgICAg ICAgSGFzaCBDb25kOiAodGIuaWQgPSB0Yy5pZCkKKyAgICAgICAgIC0+ICBTZXEgU2NhbiBvbiB0 YiAoYWN0dWFsIHJvd3M9NCBsb29wcz0xKQorICAgICAgICAgLT4gIEhhc2ggKGFjdHVhbCByb3dz PTIgbG9vcHM9MSkKKyAgICAgICAgICAgICAgIEJ1Y2tldHM6IDQwOTYgIEJhdGNoZXM6IDEgIE1l bW9yeSBVc2FnZTogMzNrQgorICAgICAgICAgICAgICAgLT4gIFNlcSBTY2FuIG9uIHRjIChhY3R1 YWwgcm93cz0yIGxvb3BzPTEpCisgICAtPiAgSGFzaCAoYWN0dWFsIHJvd3M9MiBsb29wcz0xKQor ICAgICAgICAgQnVja2V0czogNDA5NiAgQmF0Y2hlczogMSAgTWVtb3J5IFVzYWdlOiAzM2tCCisg ICAgICAgICAtPiAgU2VxIFNjYW4gb24gdGEgKGFjdHVhbCByb3dzPTIgbG9vcHM9MSkKKygxMSBy b3dzKQorCitFWFBMQUlOIChBTkFMWVpFLCBDT1NUUyBPRkYsIFNVTU1BUlkgT0ZGLCBUSU1JTkcg T0ZGLCBCVUZGRVJTIE9GRikKKyBTRUxFQ1QgMQorICAgRlJPTSB0YQorICBXSEVSRSBFWElTVFMg KFNFTEVDVCAxCisgICAgICAgICAgICAgICAgICBGUk9NIHRiCisgICAgICAgICAgICAgICAgICBK T0lOIHRjCisgICAgICAgICAgICAgICAgICAgIE9OIHRhLmlkID0gdGMuaWQgYW5kCisgICAgICAg ICAgICAgICAgICAgICAgIHRhLmlkID0gdGIuaWQpOworICAgICAgICAgICAgICAgICAgICAgICAg IFFVRVJZIFBMQU4gICAgICAgICAgICAgICAgICAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIEhhc2ggUmlnaHQg U2VtaSBKb2luIChhY3R1YWwgcm93cz0yIGxvb3BzPTEpCisgICBIYXNoIENvbmQ6ICh0Yy5pZCA9 IHRhLmlkKQorICAgLT4gIEhhc2ggSm9pbiAoYWN0dWFsIHJvd3M9MiBsb29wcz0xKQorICAgICAg ICAgSGFzaCBDb25kOiAodGIuaWQgPSB0Yy5pZCkKKyAgICAgICAgIC0+ICBTZXEgU2NhbiBvbiB0 YiAoYWN0dWFsIHJvd3M9NCBsb29wcz0xKQorICAgICAgICAgLT4gIEhhc2ggKGFjdHVhbCByb3dz PTIgbG9vcHM9MSkKKyAgICAgICAgICAgICAgIEJ1Y2tldHM6IDQwOTYgIEJhdGNoZXM6IDEgIE1l bW9yeSBVc2FnZTogMzNrQgorICAgICAgICAgICAgICAgLT4gIFNlcSBTY2FuIG9uIHRjIChhY3R1 YWwgcm93cz0yIGxvb3BzPTEpCisgICAtPiAgSGFzaCAoYWN0dWFsIHJvd3M9MiBsb29wcz0xKQor ICAgICAgICAgQnVja2V0czogNDA5NiAgQmF0Y2hlczogMSAgTWVtb3J5IFVzYWdlOiAzM2tCCisg ICAgICAgICAtPiAgU2VxIFNjYW4gb24gdGEgKGFjdHVhbCByb3dzPTIgbG9vcHM9MSkKKygxMSBy b3dzKQorCistLSBDb21wb3VuZCBleHByZXNzaW9uIHdpdGggY29uc3QgdHlwZQorRVhQTEFJTiAo QU5BTFlaRSwgQ09TVFMgT0ZGLCBTVU1NQVJZIE9GRiwgVElNSU5HIE9GRiwgQlVGRkVSUyBPRkYp CisgU0VMRUNUIDEKKyAgIEZST00gdGEKKyAgV0hFUkUgRVhJU1RTIChTRUxFQ1QgMQorICAgICAg ICAgICAgICAgICAgRlJPTSB0YgorICAgICAgICAgICAgICAgICAgSk9JTiB0YworICAgICAgICAg ICAgICAgICAgICBPTiB0YS5pZCA9IHRjLmlkIGFuZAorICAgICAgICAgICAgICAgICAgICAgICB0 YS5pZCA9IDEpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIE5lc3RlZCBM b29wIFNlbWkgSm9pbiAoYWN0dWFsIHJvd3M9MSBsb29wcz0xKQorICAgLT4gIEluZGV4IE9ubHkg U2NhbiB1c2luZyB0YV9wa2V5IG9uIHRhIChhY3R1YWwgcm93cz0xIGxvb3BzPTEpCisgICAgICAg ICBJbmRleCBDb25kOiAoaWQgPSAxKQorICAgICAgICAgSGVhcCBGZXRjaGVzOiAxCisgICAtPiAg TmVzdGVkIExvb3AgKGFjdHVhbCByb3dzPTEgbG9vcHM9MSkKKyAgICAgICAgIC0+ICBJbmRleCBP bmx5IFNjYW4gdXNpbmcgdGNfcGtleSBvbiB0YyAoYWN0dWFsIHJvd3M9MSBsb29wcz0xKQorICAg ICAgICAgICAgICAgSW5kZXggQ29uZDogKGlkID0gMSkKKyAgICAgICAgICAgICAgIEhlYXAgRmV0 Y2hlczogMQorICAgICAgICAgLT4gIFNlcSBTY2FuIG9uIHRiIChhY3R1YWwgcm93cz0xIGxvb3Bz PTEpCisoOSByb3dzKQorCitFWFBMQUlOIChBTkFMWVpFLCBDT1NUUyBPRkYsIFNVTU1BUlkgT0ZG LCBUSU1JTkcgT0ZGLCBCVUZGRVJTIE9GRikKKyBTRUxFQ1QgMQorICAgRlJPTSB0YQorICBXSEVS RSBFWElTVFMgKFNFTEVDVCAxCisgICAgICAgICAgICAgICAgICBGUk9NIHRiCisgICAgICAgICAg ICAgICAgICBKT0lOIHRjCisgICAgICAgICAgICAgICAgICAgIE9OIHRiLmlkID0gMSBhbmQKKyAg ICAgICAgICAgICAgICAgICAgICAgdGEuaWQgPSAxKTsKKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBRVUVSWSBQTEFOICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKy0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0KKyBOZXN0ZWQgTG9vcCBTZW1pIEpvaW4gKGFjdHVhbCByb3dzPTEgbG9vcHM9 MSkKKyAgIC0+ICBJbmRleCBPbmx5IFNjYW4gdXNpbmcgdGFfcGtleSBvbiB0YSAoYWN0dWFsIHJv d3M9MSBsb29wcz0xKQorICAgICAgICAgSW5kZXggQ29uZDogKGlkID0gMSkKKyAgICAgICAgIEhl YXAgRmV0Y2hlczogMQorICAgLT4gIE5lc3RlZCBMb29wIChhY3R1YWwgcm93cz0xIGxvb3BzPTEp CisgICAgICAgICAtPiAgSW5kZXggT25seSBTY2FuIHVzaW5nIHRiX3BrZXkgb24gdGIgKGFjdHVh bCByb3dzPTEgbG9vcHM9MSkKKyAgICAgICAgICAgICAgIEluZGV4IENvbmQ6IChpZCA9IDEpCisg ICAgICAgICAgICAgICBIZWFwIEZldGNoZXM6IDEKKyAgICAgICAgIC0+ICBTZXEgU2NhbiBvbiB0 YyAoYWN0dWFsIHJvd3M9MSBsb29wcz0xKQorKDkgcm93cykKKworLS0gRGlzYWJsZWQgcHVsbCB1 cCBiZWNhdXNlIGl0IGlzIGFwcGxjYXBhYmxlIGZvciBJTk5FUiBKT0lOIGNvbm5lY3Rpb24KK0VY UExBSU4gKEFOQUxZWkUsIENPU1RTIE9GRiwgU1VNTUFSWSBPRkYsIFRJTUlORyBPRkYsIEJVRkZF UlMgT0ZGKQorIFNFTEVDVCAxCisgICBGUk9NIHRhCisgIFdIRVJFIEVYSVNUUyAoU0VMRUNUIDEK KyAgICAgICAgICAgICAgICAgIEZST00gdGIKKyAgICAgICAgICAgICAgICAgIFJJR0hUIEpPSU4g dGMKKyAgICAgICAgICAgICAgICAgICAgT04gdGEuaWQgPSB0Yy5pZCk7CisgICAgICAgICAgICAg ICAgICAgICAgICAgUVVFUlkgUExBTiAgICAgICAgICAgICAgICAgICAgICAgICAKKy0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIFNl cSBTY2FuIG9uIHRhIChhY3R1YWwgcm93cz0yIGxvb3BzPTEpCisgICBGaWx0ZXI6IEVYSVNUUyhT dWJQbGFuIDEpCisgICBTdWJQbGFuIDEKKyAgICAgLT4gIE5lc3RlZCBMb29wIExlZnQgSm9pbiAo YWN0dWFsIHJvd3M9MSBsb29wcz0yKQorICAgICAgICAgICBKb2luIEZpbHRlcjogKHRhLmlkID0g dGMuaWQpCisgICAgICAgICAgIFJvd3MgUmVtb3ZlZCBieSBKb2luIEZpbHRlcjogMgorICAgICAg ICAgICAtPiAgU2VxIFNjYW4gb24gdGMgKGFjdHVhbCByb3dzPTEgbG9vcHM9MikKKyAgICAgICAg ICAgLT4gIE1hdGVyaWFsaXplIChhY3R1YWwgcm93cz0yIGxvb3BzPTIpCisgICAgICAgICAgICAg ICAgIFN0b3JhZ2U6IE1lbW9yeSAgTWF4aW11bSBTdG9yYWdlOiAxN2tCCisgICAgICAgICAgICAg ICAgIC0+ICBTZXEgU2NhbiBvbiB0YiAoYWN0dWFsIHJvd3M9NCBsb29wcz0xKQorKDEwIHJvd3Mp CisKIC0tCiAtLSBUZXN0IGNhc2UgZm9yIHN1YmxpbmtzIHB1c2hlZCBkb3duIGludG8gc3Vic2Vs ZWN0cyB2aWEgam9pbiBhbGlhcyBleHBhbnNpb24KIC0tCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9y ZWdyZXNzL3NxbC9zdWJzZWxlY3Quc3FsIGIvc3JjL3Rlc3QvcmVncmVzcy9zcWwvc3Vic2VsZWN0 LnNxbAppbmRleCA2ZWQzNjM2YTllLi5iZDg0MmQ2MjdjIDEwMDY0NAotLS0gYS9zcmMvdGVzdC9y ZWdyZXNzL3NxbC9zdWJzZWxlY3Quc3FsCisrKyBiL3NyYy90ZXN0L3JlZ3Jlc3Mvc3FsL3N1YnNl bGVjdC5zcWwKQEAgLTQzOSw2ICs0MzksNzEgQEAgd2hlcmUgZXhpc3RzICgKIAogcm9sbGJhY2s7 CiAKKy0tIFRlc3QgY2FzZSBmb3IgZXhpc3Qgc3VibGluayB3aGVyZSB3ZSBjYW4gY29uc2lkZXIg c29tZSB1bmRlcGVuZGVudCBleHByZXNzaW9uCistLSB3aXRoIG91dGVyIGxpbmsKKy0tCitFWFBM QUlOIChBTkFMWVpFLCBDT1NUUyBPRkYsIFNVTU1BUlkgT0ZGLCBUSU1JTkcgT0ZGLCBCVUZGRVJT IE9GRikKKyBTRUxFQ1QgMQorICAgRlJPTSB0YQorICBXSEVSRSBFWElTVFMgKFNFTEVDVCAxCisg ICAgICAgICAgICAgICAgICBGUk9NIHRiCisgICAgICAgICAgICAgICAgICBKT0lOIHRjCisgICAg ICAgICAgICAgICAgICAgIE9OIHRhLmlkID0gdGIuaWQpOworCitFWFBMQUlOIChBTkFMWVpFLCBD T1NUUyBPRkYsIFNVTU1BUlkgT0ZGLCBUSU1JTkcgT0ZGLCBCVUZGRVJTIE9GRikKKyBTRUxFQ1Qg MQorICAgRlJPTSB0YQorICBXSEVSRSBFWElTVFMgKFNFTEVDVCAxCisgICAgICAgICAgICAgICAg ICBGUk9NIHRiCisgICAgICAgICAgICAgICAgICBKT0lOIHRjCisgICAgICAgICAgICAgICAgICAg IE9OIHRhLmlkID0gdGMuaWQpOworCistLSBKb2luIGNvbXBvdW5kIGV4cHJlc3Npb24KK0VYUExB SU4gKEFOQUxZWkUsIENPU1RTIE9GRiwgU1VNTUFSWSBPRkYsIFRJTUlORyBPRkYsIEJVRkZFUlMg T0ZGKQorIFNFTEVDVCAxCisgICBGUk9NIHRhCisgIFdIRVJFIEVYSVNUUyAoU0VMRUNUIDEKKyAg ICAgICAgICAgICAgICAgIEZST00gdGIKKyAgICAgICAgICAgICAgICAgIEpPSU4gdGMKKyAgICAg ICAgICAgICAgICAgICAgT04gdGEuaWQgPSB0Yy5pZCBhbmQKKyAgICAgICAgICAgICAgICAgICAg ICAgdGEuaWQgPSB0Yi5pZCk7CisKK0VYUExBSU4gKEFOQUxZWkUsIENPU1RTIE9GRiwgU1VNTUFS WSBPRkYsIFRJTUlORyBPRkYsIEJVRkZFUlMgT0ZGKQorIFNFTEVDVCAxCisgICBGUk9NIHRhCisg IFdIRVJFIEVYSVNUUyAoU0VMRUNUIDEKKyAgICAgICAgICAgICAgICAgIEZST00gdGIKKyAgICAg ICAgICAgICAgICAgIEpPSU4gdGMKKyAgICAgICAgICAgICAgICAgICAgT04gdGEuaWQgPSB0Yy5p ZCBhbmQKKyAgICAgICAgICAgICAgICAgICAgICAgdGEuaWQgPSB0Yi5pZCk7CisKKy0tIENvbXBv dW5kIGV4cHJlc3Npb24gd2l0aCBjb25zdCB0eXBlCitFWFBMQUlOIChBTkFMWVpFLCBDT1NUUyBP RkYsIFNVTU1BUlkgT0ZGLCBUSU1JTkcgT0ZGLCBCVUZGRVJTIE9GRikKKyBTRUxFQ1QgMQorICAg RlJPTSB0YQorICBXSEVSRSBFWElTVFMgKFNFTEVDVCAxCisgICAgICAgICAgICAgICAgICBGUk9N IHRiCisgICAgICAgICAgICAgICAgICBKT0lOIHRjCisgICAgICAgICAgICAgICAgICAgIE9OIHRh LmlkID0gdGMuaWQgYW5kCisgICAgICAgICAgICAgICAgICAgICAgIHRhLmlkID0gMSk7CisKK0VY UExBSU4gKEFOQUxZWkUsIENPU1RTIE9GRiwgU1VNTUFSWSBPRkYsIFRJTUlORyBPRkYsIEJVRkZF UlMgT0ZGKQorIFNFTEVDVCAxCisgICBGUk9NIHRhCisgIFdIRVJFIEVYSVNUUyAoU0VMRUNUIDEK KyAgICAgICAgICAgICAgICAgIEZST00gdGIKKyAgICAgICAgICAgICAgICAgIEpPSU4gdGMKKyAg ICAgICAgICAgICAgICAgICAgT04gdGIuaWQgPSAxIGFuZAorICAgICAgICAgICAgICAgICAgICAg ICB0YS5pZCA9IDEpOworLS0gRGlzYWJsZWQgcHVsbCB1cCBiZWNhdXNlIGl0IGlzIGFwcGxjYXBh YmxlIGZvciBJTk5FUiBKT0lOIGNvbm5lY3Rpb24KK0VYUExBSU4gKEFOQUxZWkUsIENPU1RTIE9G RiwgU1VNTUFSWSBPRkYsIFRJTUlORyBPRkYsIEJVRkZFUlMgT0ZGKQorIFNFTEVDVCAxCisgICBG Uk9NIHRhCisgIFdIRVJFIEVYSVNUUyAoU0VMRUNUIDEKKyAgICAgICAgICAgICAgICAgIEZST00g dGIKKyAgICAgICAgICAgICAgICAgIFJJR0hUIEpPSU4gdGMKKyAgICAgICAgICAgICAgICAgICAg T04gdGEuaWQgPSB0Yy5pZCk7CisKIC0tCiAtLSBUZXN0IGNhc2UgZm9yIHN1YmxpbmtzIHB1c2hl ZCBkb3duIGludG8gc3Vic2VsZWN0cyB2aWEgam9pbiBhbGlhcyBleHBhbnNpb24KIC0tCg== --000000000000459143062a01896b--