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.96) (envelope-from ) id 1wC5x4-001evJ-31 for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Apr 2026 01:18:59 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wC5x3-003xoy-0s for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Apr 2026 01:18:58 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wC5x2-003xop-2z for pgsql-hackers@lists.postgresql.org; Mon, 13 Apr 2026 01:18:57 +0000 Received: from mail-ot1-x332.google.com ([2607:f8b0:4864:20::332]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wC5x1-00000000kyY-1wMG for pgsql-hackers@lists.postgresql.org; Mon, 13 Apr 2026 01:18:57 +0000 Received: by mail-ot1-x332.google.com with SMTP id 46e09a7af769-7dbcb467f2bso3595127a34.3 for ; Sun, 12 Apr 2026 18:18:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1776043134; cv=none; d=google.com; s=arc-20240605; b=Rf62U90bSGmLXc2Rm8UIbAUaH0Uy3KWMmg4V+sMxplleIRIMUGzd73k4n9R6yzKdaO G9BIfRC1AUd7ixU854BLh42GHVb4+kPvM/WIbpzMURnZ+2pJ4li7j+aCZD+IpBbGAzuf QTVLbxOJuaoS3ey8KHLSbBUNwcdlS/x1fQQqF/eHkOuMNmOYieQBZVi3kUtlm2kDrqME 4lLtaKb5vUO+eI4+z4BxdD4v4Lr19n4fcSq+7KxlQw33FQLEpJVapzdq2UuriJiJKkC+ Do7C1Sp/7/MX4Cwxz20kmA2aKw34yaR3Bztu2TVSM9anfscjCeiJeUF4mZPYNbPnKJVy xsUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=h/a2mAsd3hiIV/Z1zACvFVkF7gAv7sBPYAU7XDduUdE=; fh=pmBMntjmyx6XYOkmIq7jCPL8+6Ex8nEv6KGKxj4+8uc=; b=E7P0KdMVGt6LyRnCJZIsOuEpGh/NMGogb1QWuMZklLOyGzPWsayY24tZVz3a57iyQR E/dZBbm5QoEkrkV/dfjxmoeSIC0BeGqDHYyXGflQCUR2v44xeUvU4uos+e8ShtXhfxSU qkuO3+goLcbd6ASTCPjxaJO6zeqCrvNG4tC8Na/2G6jJa5X4mAv1wG2yakJnoiu3Gamc b/t8eWeBfbtOl1eVgT0vJP8VQtFuUdVgLZ9Fn14nEwKZ9Am2N5Y6E0pEh5eYelyjF+qi VaCiomhnd1C5lPTKMsscJMoHY3tIqBysY5cGRxL/isxU3QsWmcjUKMpluFMYTyCgMkRV 5grw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776043134; x=1776647934; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=h/a2mAsd3hiIV/Z1zACvFVkF7gAv7sBPYAU7XDduUdE=; b=rdA+VLTO4j914+yHbss5wqAYgIpm1rP4qpgcw3rZpmEKZl80PPasTP4AwwdULiJHLq 7YID9g2K0izpGc7xPDWMA8iKde8b/9IP9r4wgABS0Q/5Q3PHLDDn4hv3qP14oNevVqsB xOsbwN1MQygygmO+dj3so2bVAhm60H7fi2Pi4/VEx43pO9ax4DMoBJcegFKxx2fS5HJt jtXDG68VRC4TH9hlSQzDrm7x/d5oGxEXpFBvacnuYW9FbPhIZ14Swd2G4gUGH5MT0Wu9 xTGijyHSYsh4gBtMSrZ6mQOvMeUq4Bn15GhtXEXekQB3vDOhP7kn1dluKNi1mz9cuFwP Rw9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776043134; x=1776647934; h=to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=h/a2mAsd3hiIV/Z1zACvFVkF7gAv7sBPYAU7XDduUdE=; b=do2ttInnM7a+BEW5Wo3N1F6dT10GUF1qmYOFLzbeTBd9QWG7gjJCGfq/bhnVq8JHvZ VjXMjSFj+U4oxAY43HvoB4ZY9PlRsOS+GqL5BPnZ11kVFnfLO/P7dsRyI0qGmQNykQAv /bDbtRh83VKGFpQqQ0kseSZvPxL92vAAUlJyJSGI+JTO+rppKY9juPBr7eFcNUvY4wHE N8e+u0OSoiqSyYx9ileq/Yp8bAohXA2djwwl71Bi6e2QW5wH315G9RrUBd+9KMH0XUAv +5NYf3mLJQdsQZojFxHdpqH4OW2o3Rq4YMzU20ydi8e5fSA4YCtSWnfrmYg5l3D/NdAu D0fA== X-Gm-Message-State: AOJu0YzgMLp4pwDrza5zlFFk5e4oYKxtD3V0nQvGcrAyq/GNaTfPLpD7 VkrTgLjw0ATMq0WtJdc7audyllY4vJHHJlDrUsNuZLdlcp+nrxiODFgrPiC5JC4xkoXFHzrOU6v hS5DP8SwYH9TUE9CwLaFjTIXT00j8D2icACfDkpg= X-Gm-Gg: AeBDieswqSvJ+rnvy7v4sdqeZWlF9rsqCtseHHtp+NI8zIZM3EADPk1OItuF6qurmiD O3gwX5Du+0mjz1Ru698rfWclwqy5Gho28sKwB24rJKKkLtqSQAUBIwsAvyMwgk+LHk97RFhZfyL byg5NHI1yz56YANnTDvkBGiwgMNCc6yt/T7US8EIBvhgavhrRb5LARTv45R0Qwh96ZMXJePdkf3 OnSla+UFJTH/GVozQMr3L/daZVzOUTjyVVozlFkuuBuFMszgqsY4Uu3bl7cpSPhVISjwGFP+eT0 TuSQaMNgq9bKVZD2yl8= X-Received: by 2002:a05:6820:4cc5:b0:685:b094:d304 with SMTP id 006d021491bc7-68be5c5f77amr5514075eaf.9.1776043133410; Sun, 12 Apr 2026 18:18:53 -0700 (PDT) MIME-Version: 1.0 From: Richard Guo Date: Mon, 13 Apr 2026 10:18:42 +0900 X-Gm-Features: AQROBzArF6kbX1hufscECYb1Cf2bj5ITH4kYx1X8yGbfb2o_Q7drKTTs_TroB4Q Message-ID: Subject: Propagate stadistinct through GROUP BY/DISTINCT in subqueries and CTEs To: Pg Hackers Content-Type: multipart/mixed; boundary="00000000000012b9b1064f4d4405" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000012b9b1064f4d4405 Content-Type: text/plain; charset="UTF-8" I complained in [1] that some TPC-DS queries suffer from very poor cardinality estimates on CTE scan filters, to the point that simply disabling nestloop makes some queries run hundreds of times faster. Here's a simple reproduction: create table t (a int, b int, c int); insert into t select i%2, i, i from generate_series(1,1000) i; analyze t; explain analyze with cte as (select a, b, avg(c) as avg from t group by a, b) select * from cte t1, cte t2 where t1.a = 1 and t2.a = 1 and t1.avg = t2.avg; Column 'a' has only 2 distinct values, so the filter a=1 on the 1000-row CTE output should estimate ~500 rows (assuming these values are equally common). Instead, the CTE scan estimates 5 rows (1000 * 1/200) because examine_simple_variable returns early when the subquery has GROUP BY, and selectivity estimation falls back on 1/DEFAULT_NUM_DISTINCT. -> CTE Scan on cte t1 (cost=0.00..22.50 rows=5 width=40) (actual time=4.874..5.053 rows=500.00 loops=1) As a result, this query ends up with a Nested Loop plan, and the Execution Time is 192.907 ms. For DISTINCT or GROUP BY key columns that are simple Vars, I think we can propagate stadistinct from the base table, because the set of distinct values is preserved after grouping. MCV frequencies, histograms, and correlation data are not valid since GROUP BY and DISTINCT change the frequency distribution, but with stadistinct alone, callers like var_eq_const() can use a 1/ndistinct estimate rather than 1/DEFAULT_NUM_DISTINCT. Attached is a patch to do this. With the patch, the example above estimates 500 rows ... -> CTE Scan on cte t1 (cost=0.00..22.50 rows=500 width=40) (actual time=3.785..4.143 rows=500.00 loops=1) ... and chooses a Hash Join, with an Execution Time of 8.238 ms (~20x faster). I tested this patch on TPC-DS query 31: -- on master: Planning Time: 5.207 ms Execution Time: 1536140.258 ms -- on patched: Planning Time: 5.140 ms Execution Time: 1149.482 ms Over 1300x faster. Does this approach make sense? Any thoughts? [1] https://postgr.es/m/CAMbWs4-QU_nkFqFZLdzWRsEsVE8aLWx4qBBVq7g4rXw+cvYDMg@mail.gmail.com - Richard --00000000000012b9b1064f4d4405 Content-Type: application/octet-stream; name="v1-0001-Propagate-stadistinct-through-GROUP-BY-DISTINCT-i.patch" Content-Disposition: attachment; filename="v1-0001-Propagate-stadistinct-through-GROUP-BY-DISTINCT-i.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mnwi7i630 RnJvbSA2YWE3OGRhNjg0YTA0OGU5OWEwMzY2YjkxOGNmOWRlMjU3MmQ5ZjVjIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBSaWNoYXJkIEd1byA8Z3VvZmVuZ2xpbnV4QGdtYWlsLmNvbT4K RGF0ZTogU3VuLCAxMiBBcHIgMjAyNiAxNToxMjoyMCArMDkwMApTdWJqZWN0OiBbUEFUQ0ggdjFd IFByb3BhZ2F0ZSBzdGFkaXN0aW5jdCB0aHJvdWdoIEdST1VQIEJZL0RJU1RJTkNUIGluCiBzdWJx dWVyaWVzIGFuZCBDVEVzCgpQcmV2aW91c2x5LCBleGFtaW5lX3NpbXBsZV92YXJpYWJsZSgpIHdv dWxkIHJldHVybiBlYXJseSB3aGVuIGEKc3VicXVlcnkgb3IgQ1RFIHVzZWQgR1JPVVAgQlkgb3Ig RElTVElOQ1QuICBJdCBjb3VsZCBkZXRlY3QgdW5pcXVlbmVzcwpmb3Igc2luZ2xlLWNvbHVtbiBj YXNlcywgYnV0IGZvciBtdWx0aS1jb2x1bW4gR1JPVVAgQlkgb3IgRElTVElOQ1QsCnNlbGVjdGl2 aXR5IGVzdGltYXRpb24gZmVsbCBiYWNrIG9uIDEvREVGQVVMVF9OVU1fRElTVElOQ1QgKDEvMjAw KS4KVGhpcyBwcm9kdWNlZCB3aWxkbHkgaW5hY2N1cmF0ZSBlc3RpbWF0ZXMgZm9yIGZpbHRlcnMg YW5kIGpvaW5zIG9uCnN1Y2ggY29sdW1ucywgb2Z0ZW4gbGVhZGluZyB0aGUgcGxhbm5lciB0byBj aG9vc2UgbmVzdGVkIGxvb3Agam9pbnMKd2hlcmUgaGFzaCBqb2lucyB3b3VsZCBiZSBmYXIgYmV0 dGVyLiAgVGhpcyB3YXMgYSBzaWduaWZpY2FudCBmYWN0b3IKaW4gcG9vciBUUEMtRFMgYmVuY2ht YXJrIHBlcmZvcm1hbmNlLgoKRm9yIERJU1RJTkNUIG9yIEdST1VQIEJZIGtleSBjb2x1bW5zIHRo YXQgYXJlIHNpbXBsZSBWYXJzLCB3ZSBub3cKcmVjdXJzZSBpbnRvIHRoZSBzdWJxdWVyeSB0byBv YnRhaW4gdGhlIGJhc2UgdGFibGUncyBzdGFkaXN0aW5jdCwKd2hpY2ggcmVtYWlucyB2YWxpZCBh ZnRlciBncm91cGluZyAodGhlIHNldCBvZiBkaXN0aW5jdCB2YWx1ZXMgaXMKcHJlc2VydmVkKS4g IEhvd2V2ZXIsIE1DViBmcmVxdWVuY2llcywgaGlzdG9ncmFtcywgYW5kIGNvcnJlbGF0aW9uCmRh dGEgYXJlIG5vdCB2YWxpZCBiZWNhdXNlIEdST1VQIEJZIGFuZCBESVNUSU5DVCBjaGFuZ2UgdGhl IGZyZXF1ZW5jeQpkaXN0cmlidXRpb24gb2Yga2V5IGNvbHVtbnMuICBTbyB3ZSBzdHJpcCBhbGwg c3RhdHMgc2xvdHMgZnJvbSB0aGUKY29waWVkIHN0YXRzIHR1cGxlLCBjYXVzaW5nIGNhbGxlcnMg bGlrZSB2YXJfZXFfY29uc3QoKSB0byB1c2UgdGhlCjEvbmRpc3RpbmN0IGVzdGltYXRlIGluc3Rl YWQuICBJZiBzdGFkaXN0aW5jdCBpcyBzdG9yZWQgYXMgYSBuZWdhdGl2ZQp2YWx1ZSAoYSBmcmFj dGlvbiBvZiB0aGUgYmFzZSB0YWJsZSdzIHJvdyBjb3VudCksIHdlIGNvbnZlcnQgaXQgdG8gYW4K YWJzb2x1dGUgY291bnQgc28gaXQgaXMgbm90IG1pc2ludGVycHJldGVkIHJlbGF0aXZlIHRvIHRo ZSBzdWJxdWVyeSdzCm91dHB1dCByb3cgY291bnQuCgpOb24ta2V5IGNvbHVtbnMgKGUuZy4sIGFn Z3JlZ2F0ZSBvdXRwdXRzKSBjb250aW51ZSB0byBnZXQgbm8gc3RhdHMsCnNhbWUgYXMgYmVmb3Jl LgotLS0KIHNyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5jcy5jICAgfCAxMDYgKysrKysrKysr KysrKysrKysrKysrKysrKy0tLS0KIHNyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvd2l0aC5vdXQg fCAgOTQgKysrKysrKysrKysrKysrKysrKysrKysrKwogc3JjL3Rlc3QvcmVncmVzcy9zcWwvd2l0 aC5zcWwgICAgICB8ICAzNSArKysrKysrKysrCiAzIGZpbGVzIGNoYW5nZWQsIDIyMSBpbnNlcnRp b25zKCspLCAxNCBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9zcmMvYmFja2VuZC91dGlscy9h ZHQvc2VsZnVuY3MuYyBiL3NyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5jcy5jCmluZGV4IGYy YjU4ZWJmZTFlLi5hZGY2MzhhMzgwYyAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvdXRpbHMvYWR0 L3NlbGZ1bmNzLmMKKysrIGIvc3JjL2JhY2tlbmQvdXRpbHMvYWR0L3NlbGZ1bmNzLmMKQEAgLTI0 Nyw2ICsyNDcsOCBAQCBzdGF0aWMgYm9vbCBjb250YWluX3BsYWNlaG9sZGVyX3dhbGtlcihOb2Rl ICpub2RlLCB2b2lkICpjb250ZXh0KTsKIHN0YXRpYyBOb2RlICpzdHJpcF9hbGxfcGh2c19tdXRh dG9yKE5vZGUgKm5vZGUsIHZvaWQgKmNvbnRleHQpOwogc3RhdGljIHZvaWQgZXhhbWluZV9zaW1w bGVfdmFyaWFibGUoUGxhbm5lckluZm8gKnJvb3QsIFZhciAqdmFyLAogCQkJCQkJCQkJVmFyaWFi bGVTdGF0RGF0YSAqdmFyZGF0YSk7CitzdGF0aWMgdm9pZCBhZGp1c3Rfc3RhdHN0dXBsZV9mb3Jf Z3JvdXBpbmcoUGxhbm5lckluZm8gKnN1YnJvb3QsIFZhciAqdmFyLAorCQkJCQkJCQkJCSAgIFZh cmlhYmxlU3RhdERhdGEgKnZhcmRhdGEpOwogc3RhdGljIHZvaWQgZXhhbWluZV9pbmRleGNvbF92 YXJpYWJsZShQbGFubmVySW5mbyAqcm9vdCwgSW5kZXhPcHRJbmZvICppbmRleCwKIAkJCQkJCQkJ CSAgaW50IGluZGV4Y29sLCBWYXJpYWJsZVN0YXREYXRhICp2YXJkYXRhKTsKIHN0YXRpYyBib29s IGdldF92YXJpYWJsZV9yYW5nZShQbGFubmVySW5mbyAqcm9vdCwgVmFyaWFibGVTdGF0RGF0YSAq dmFyZGF0YSwKQEAgLTYxMDEsNiArNjEwMyw3IEBAIGV4YW1pbmVfc2ltcGxlX3ZhcmlhYmxlKFBs YW5uZXJJbmZvICpyb290LCBWYXIgKnZhciwKIAkJUXVlcnkJICAgKnN1YnF1ZXJ5OwogCQlMaXN0 CSAgICpzdWJ0bGlzdDsKIAkJVGFyZ2V0RW50cnkgKnN0ZTsKKwkJYm9vbAkJaGF2ZV9ncm91cGlu ZyA9IGZhbHNlOwogCiAJCS8qCiAJCSAqIFB1bnQgaWYgaXQncyBhIHdob2xlLXJvdyB2YXIgcmF0 aGVyIHRoYW4gYSBwbGFpbiBjb2x1bW4gcmVmZXJlbmNlLgpAQCAtNjE5MSw5ICs2MTk0LDEyIEBA IGV4YW1pbmVfc2ltcGxlX3ZhcmlhYmxlKFBsYW5uZXJJbmZvICpyb290LCBWYXIgKnZhciwKIAkJ ICogUHVudCBpZiBzdWJxdWVyeSB1c2VzIHNldCBvcGVyYXRpb25zIG9yIGdyb3VwaW5nIHNldHMs IGFzIHRoZXNlCiAJCSAqIHdpbGwgbWFzaCB1bmRlcmx5aW5nIGNvbHVtbnMnIHN0YXRzIGJleW9u ZCByZWNvZ25pdGlvbi4gIChTZXQgb3BzCiAJCSAqIGFyZSBwYXJ0aWN1bGFybHkgbmFzdHk7IGlm IHdlIGZvcmdlZCBhaGVhZCwgd2Ugd291bGQgcmV0dXJuIHN0YXRzCi0JCSAqIHJlbGV2YW50IHRv IG9ubHkgdGhlIGxlZnRtb3N0IHN1YnNlbGVjdC4uLikJRElTVElOQ1QgaXMgYWxzbwotCQkgKiBw cm9ibGVtYXRpYywgYnV0IHdlIGNoZWNrIHRoYXQgbGF0ZXIgYmVjYXVzZSB0aGVyZSBpcyBhIHBv c3NpYmlsaXR5Ci0JCSAqIG9mIGxlYXJuaW5nIHNvbWV0aGluZyBldmVuIHdpdGggaXQuCisJCSAq IHJlbGV2YW50IHRvIG9ubHkgdGhlIGxlZnRtb3N0IHN1YnNlbGVjdC4uLikJRElTVElOQ1QgYW5k IEdST1VQIEJZCisJCSAqIGFyZSBhbHNvIHByb2JsZW1hdGljLCBidXQgd2UgY2hlY2sgdGhvc2Ug bGF0ZXIgYmVjYXVzZSB0aGVyZSBpcyBhCisJCSAqIHBvc3NpYmlsaXR5IG9mIGxlYXJuaW5nIHNv bWV0aGluZyBldmVuIHdpdGggdGhlbTogd2UgY2FuIGRldGVjdAorCQkgKiB1bmlxdWVuZXNzIGZv ciBzaW5nbGUtY29sdW1uIGNhc2VzLCBhbmQgZm9yIGtleSBjb2x1bW5zIHRoYXQgYXJlCisJCSAq IHNpbXBsZSBWYXJzLCB3ZSBjYW4gb2J0YWluIGEgdXNlZnVsIHN0YWRpc3RpbmN0IGZyb20gdGhl IHVuZGVybHlpbmcKKwkJICogYmFzZSB0YWJsZS4KIAkJICovCiAJCWlmIChzdWJxdWVyeS0+c2V0 T3BlcmF0aW9ucyB8fAogCQkJc3VicXVlcnktPmdyb3VwaW5nU2V0cykKQEAgLTYyMTEsMjggKzYy MTcsNDIgQEAgZXhhbWluZV9zaW1wbGVfdmFyaWFibGUoUGxhbm5lckluZm8gKnJvb3QsIFZhciAq dmFyLAogCQl2YXIgPSAoVmFyICopIHN0ZS0+ZXhwcjsKIAogCQkvKgotCQkgKiBJZiBzdWJxdWVy eSB1c2VzIERJU1RJTkNULCB3ZSBjYW4ndCBtYWtlIHVzZSBvZiBhbnkgc3RhdHMgZm9yIHRoZQor CQkgKiBJZiBzdWJxdWVyeSB1c2VzIERJU1RJTkNULCB3ZSBjYW4ndCBtYWtlIGZ1bGwgdXNlIG9m IHN0YXRzIGZvciB0aGUKIAkJICogdmFyaWFibGUgLi4uIGJ1dCwgaWYgaXQncyB0aGUgb25seSBE SVNUSU5DVCBjb2x1bW4sIHdlIGFyZSBlbnRpdGxlZAogCQkgKiB0byBjb25zaWRlciBpdCB1bmlx dWUuICBXZSBkbyB0aGUgdGVzdCB0aGlzIHdheSBzbyB0aGF0IGl0IHdvcmtzCiAJCSAqIGZvciBj YXNlcyBpbnZvbHZpbmcgRElTVElOQ1QgT04uCisJCSAqCisJCSAqIElmIHRoZSB0YXJnZXQgaXMg YSBESVNUSU5DVCBrZXkgdGhhdCBpcyBhIHNpbXBsZSBWYXIsIHdlIGNhbiBzdGlsbAorCQkgKiBv YnRhaW4gYSB1c2VmdWwgc3RhZGlzdGluY3QgZnJvbSB0aGUgYmFzZSB0YWJsZSwgdGhvdWdoIE1D ViBhbmQKKwkJICogaGlzdG9ncmFtIGRhdGEgbXVzdCBiZSBzdHJpcHBlZCBzaW5jZSBESVNUSU5D VCBjaGFuZ2VzIHRoZQorCQkgKiBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uLiAgV2Ugc2V0IGhhdmVf Z3JvdXBpbmcgYW5kIGZhbGwgdGhyb3VnaCB0bworCQkgKiB0aGUgc2ltcGxlLVZhciByZWN1cnNp b24gYmVsb3cuICBOb24ta2V5IGNvbHVtbnMgY2Fubm90IGdvIGZ1cnRoZXIuCiAJCSAqLwogCQlp ZiAoc3VicXVlcnktPmRpc3RpbmN0Q2xhdXNlKQogCQl7Ci0JCQlpZiAobGlzdF9sZW5ndGgoc3Vi cXVlcnktPmRpc3RpbmN0Q2xhdXNlKSA9PSAxICYmCi0JCQkJdGFyZ2V0SXNJblNvcnRMaXN0KHN0 ZSwgSW52YWxpZE9pZCwgc3VicXVlcnktPmRpc3RpbmN0Q2xhdXNlKSkKLQkJCQl2YXJkYXRhLT5p c3VuaXF1ZSA9IHRydWU7Ci0JCQkvKiBjYW5ub3QgZ28gZnVydGhlciAqLwotCQkJcmV0dXJuOwor CQkJaWYgKHRhcmdldElzSW5Tb3J0TGlzdChzdGUsIEludmFsaWRPaWQsIHN1YnF1ZXJ5LT5kaXN0 aW5jdENsYXVzZSkpCisJCQl7CisJCQkJaGF2ZV9ncm91cGluZyA9IHRydWU7CisKKwkJCQlpZiAo bGlzdF9sZW5ndGgoc3VicXVlcnktPmRpc3RpbmN0Q2xhdXNlKSA9PSAxKQorCQkJCQl2YXJkYXRh LT5pc3VuaXF1ZSA9IHRydWU7CisJCQl9CisJCQllbHNlCisJCQkJcmV0dXJuOwogCQl9CiAKIAkJ LyogVGhlIHNhbWUgaWRlYSBhcyB3aXRoIERJU1RJTkNUIGNsYXVzZSB3b3JrcyBmb3IgYSBHUk9V UC1CWSB0b28gKi8KIAkJaWYgKHN1YnF1ZXJ5LT5ncm91cENsYXVzZSkKIAkJewotCQkJaWYgKGxp c3RfbGVuZ3RoKHN1YnF1ZXJ5LT5ncm91cENsYXVzZSkgPT0gMSAmJgotCQkJCXRhcmdldElzSW5T b3J0TGlzdChzdGUsIEludmFsaWRPaWQsIHN1YnF1ZXJ5LT5ncm91cENsYXVzZSkpCi0JCQkJdmFy ZGF0YS0+aXN1bmlxdWUgPSB0cnVlOwotCQkJLyogY2Fubm90IGdvIGZ1cnRoZXIgKi8KLQkJCXJl dHVybjsKKwkJCWlmICh0YXJnZXRJc0luU29ydExpc3Qoc3RlLCBJbnZhbGlkT2lkLCBzdWJxdWVy eS0+Z3JvdXBDbGF1c2UpKQorCQkJeworCQkJCWhhdmVfZ3JvdXBpbmcgPSB0cnVlOworCisJCQkJ aWYgKGxpc3RfbGVuZ3RoKHN1YnF1ZXJ5LT5ncm91cENsYXVzZSkgPT0gMSkKKwkJCQkJdmFyZGF0 YS0+aXN1bmlxdWUgPSB0cnVlOworCQkJfQorCQkJZWxzZSBpZiAoIWhhdmVfZ3JvdXBpbmcpCisJ CQkJcmV0dXJuOwogCQl9CiAKIAkJLyoKQEAgLTYyNjMsNiArNjI4MywxNCBAQCBleGFtaW5lX3Np bXBsZV92YXJpYWJsZShQbGFubmVySW5mbyAqcm9vdCwgVmFyICp2YXIsCiAJCQkgKiBqb2luZWQg dG8gb3RoZXIgdGFibGVzIGluIGEgd2F5IHRoYXQgY3JlYXRlcyBkdXBsaWNhdGVzLgogCQkJICov CiAJCQlleGFtaW5lX3NpbXBsZV92YXJpYWJsZShzdWJyb290LCB2YXIsIHZhcmRhdGEpOworCisJ CQkvKgorCQkJICogSWYgdGhlIHN1YnF1ZXJ5IHVzZXMgRElTVElOQ1Qgb3IgR1JPVVAgQlkgYW5k IHdlIGdvdCBoZXJlCisJCQkgKiBiZWNhdXNlIHRoZSB0YXJnZXQgaXMgYSBrZXkgY29sdW1uLCBz dHJpcCBNQ1YvaGlzdG9ncmFtIHNsb3RzCisJCQkgKiBmcm9tIHRoZSBzdGF0cyB0dXBsZSwga2Vl cGluZyBvbmx5IHN0YWRpc3RpbmN0LgorCQkJICovCisJCQlpZiAoaGF2ZV9ncm91cGluZykKKwkJ CQlhZGp1c3Rfc3RhdHN0dXBsZV9mb3JfZ3JvdXBpbmcoc3Vicm9vdCwgdmFyLCB2YXJkYXRhKTsK IAkJfQogCX0KIAllbHNlCkBAIC02Mjc2LDYgKzYzMDQsNTYgQEAgZXhhbWluZV9zaW1wbGVfdmFy aWFibGUoUGxhbm5lckluZm8gKnJvb3QsIFZhciAqdmFyLAogCX0KIH0KIAorLyoKKyAqIGFkanVz dF9zdGF0c3R1cGxlX2Zvcl9ncm91cGluZworICoJCUFkanVzdCBhIHN0YXRzIHR1cGxlIGZvciB1 c2UgaW4gYSBncm91cGVkIG9yIGRpc3RpbmN0IGNvbnRleHQuCisgKgorICogVGhpcyBpcyB1c2Vk IHdoZW4gdGhlIHN0YXRzIHR1cGxlIHdhcyBvYnRhaW5lZCBieSByZWN1cnNpbmcgaW50byBhIHN1 YnF1ZXJ5LAorICogYnV0IHRoZSBzdWJxdWVyeSdzIG91dHB1dCBpbnZhbGlkYXRlcyBmcmVxdWVu Y3ktcmVsYXRlZCBzdGF0aXN0aWNzIChlLmcuIGR1ZQorICogdG8gR1JPVVAgQlkgb3IgRElTVElO Q1QpLiAgVGhlIHNldCBvZiBkaXN0aW5jdCB2YWx1ZXMgaXMgcHJlc2VydmVkIGJ5IHN1Y2gKKyAq IG9wZXJhdGlvbnMsIHNvIHN0YWRpc3RpbmN0IHJlbWFpbnMgdmFsaWQsIGJ1dCBNQ1YgZnJlcXVl bmNpZXMsIGhpc3RvZ3JhbXMsCisgKiBhbmQgY29ycmVsYXRpb24gZGF0YSBhcmUgbm90LiAgWmVy b2luZyBhbGwgc3RhdHMgc2xvdHMgY2F1c2VzIGNhbGxlcnMgKGUuZy4KKyAqIHZhcl9lcV9jb25z dCkgdG8gZmFsbCB0aHJvdWdoIHRvIHRoZSAxL25kaXN0aW5jdCBlc3RpbWF0ZSBpbnN0ZWFkLgor ICoKKyAqIElmIHN0YWRpc3RpbmN0IGlzIG5lZ2F0aXZlIChhIGZyYWN0aW9uIG9mIHRoZSBiYXNl IHRhYmxlJ3Mgcm93IGNvdW50KSwgd2UKKyAqIGNvbnZlcnQgaXQgdG8gYW4gYWJzb2x1dGUgY291 bnQsIHNpbmNlIGl0IHdvdWxkIG90aGVyd2lzZSBiZSBtaXNpbnRlcnByZXRlZAorICogcmVsYXRp dmUgdG8gdGhlIHN1YnF1ZXJ5IG91dHB1dCdzIHJvdyBjb3VudC4KKyAqLworc3RhdGljIHZvaWQK K2FkanVzdF9zdGF0c3R1cGxlX2Zvcl9ncm91cGluZyhQbGFubmVySW5mbyAqc3Vicm9vdCwgVmFy ICp2YXIsCisJCQkJCQkJICAgVmFyaWFibGVTdGF0RGF0YSAqdmFyZGF0YSkKK3sKKwlIZWFwVHVw bGUJY29weTsKKwlGb3JtX3BnX3N0YXRpc3RpYyBzdGF0czsKKworCWlmICghSGVhcFR1cGxlSXNW YWxpZCh2YXJkYXRhLT5zdGF0c1R1cGxlKSkKKwkJcmV0dXJuOworCisJY29weSA9IGhlYXBfY29w eXR1cGxlKHZhcmRhdGEtPnN0YXRzVHVwbGUpOworCXN0YXRzID0gKEZvcm1fcGdfc3RhdGlzdGlj KSBHRVRTVFJVQ1QoY29weSk7CisKKwkvKiBDb252ZXJ0IG5lZ2F0aXZlIHN0YWRpc3RpbmN0IHRv IGFic29sdXRlIGNvdW50ICovCisJaWYgKHN0YXRzLT5zdGFkaXN0aW5jdCA8IDApCisJeworCQlS ZWxPcHRJbmZvICpiYXNlcmVsID0gZmluZF9iYXNlX3JlbChzdWJyb290LCB2YXItPnZhcm5vKTsK KworCQlpZiAoYmFzZXJlbC0+dHVwbGVzID4gMCkKKwkJeworCQkJc3RhdHMtPnN0YWRpc3RpbmN0 ID0gKGZsb2F0NCkKKwkJCQljbGFtcF9yb3dfZXN0KC1zdGF0cy0+c3RhZGlzdGluY3QgKiBiYXNl cmVsLT50dXBsZXMpOworCQl9CisJfQorCisJLyogWmVybyBvdXQgYWxsIHN0YXRzIHNsb3RzICov CisJZm9yIChpbnQgayA9IDA7IGsgPCBTVEFUSVNUSUNfTlVNX1NMT1RTOyBrKyspCisJCSgmc3Rh dHMtPnN0YWtpbmQxKVtrXSA9IDA7CisKKwkvKiBSZXBsYWNlIG9yaWdpbmFsIHdpdGggb3VyIG1v ZGlmaWVkIGNvcHkgKi8KKwl2YXJkYXRhLT5mcmVlZnVuYyh2YXJkYXRhLT5zdGF0c1R1cGxlKTsK Kwl2YXJkYXRhLT5zdGF0c1R1cGxlID0gY29weTsKKwl2YXJkYXRhLT5mcmVlZnVuYyA9IGhlYXBf ZnJlZXR1cGxlOworfQorCiAvKgogICogYWxsX3Jvd3Nfc2VsZWN0YWJsZQogICoJCVRlc3Qgd2hl dGhlciB0aGUgdXNlciBoYXMgcGVybWlzc2lvbiB0byBzZWxlY3QgYWxsIHJvd3MgZnJvbSBhIGdp dmVuCmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZWdyZXNzL2V4cGVjdGVkL3dpdGgub3V0IGIvc3Jj L3Rlc3QvcmVncmVzcy9leHBlY3RlZC93aXRoLm91dAppbmRleCA3N2RlZDAxYjA0Ni4uYWRkYjI0 ODk2YmUgMTAwNjQ0Ci0tLSBhL3NyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvd2l0aC5vdXQKKysr IGIvc3JjL3Rlc3QvcmVncmVzcy9leHBlY3RlZC93aXRoLm91dApAQCAtMzc2MCwzICszNzYwLDk3 IEBAIHNlbGVjdCAqIGZyb20gd2l0aF90ZXN0OwogKDEgcm93KQogCiBkcm9wIHRhYmxlIHdpdGhf dGVzdDsKKy0tCistLSBUZXN0IHNlbGVjdGl2aXR5IGVzdGltYXRlcyBmb3IgR1JPVVAgQlkgYW5k IERJU1RJTkNUIHN1YnF1ZXJpZXMvQ1RFcy4KKy0tCistLSBXaGVuIGEgc3VicXVlcnkgb3IgQ1RF IGhhcyBHUk9VUCBCWSBvciBESVNUSU5DVCwgdGhlIHBsYW5uZXIgc2hvdWxkIHVzZQorLS0gc3Rh ZGlzdGluY3QgZnJvbSB0aGUgYmFzZSB0YWJsZSBmb3Iga2V5IGNvbHVtbnMsIHJhdGhlciB0aGFu IGZhbGxpbmcgYmFjaworLS0gdG8gREVGQVVMVF9OVU1fRElTVElOQ1QuICBXaXRoIGNvcnJlY3Qg ZXN0aW1hdGVzLCB0aGUgcGxhbm5lciBwaWNrcyBIYXNoCistLSBKb2luOyB3aXRoIHRoZSBvbGQg ZGVmYXVsdCBlc3RpbWF0ZXMgaXQgd291bGQgcGljayBOZXN0ZWQgTG9vcC4KKy0tCistLSBTdWJx dWVyeSB3aXRoIEdST1VQIEJZIChPRkZTRVQgMCBwcmV2ZW50cyBxdWFsIHB1c2hkb3duKQorRVhQ TEFJTiAoQ09TVFMgT0ZGKQorU0VMRUNUICogRlJPTQorICAoU0VMRUNUIHR3bywgdGhvdXNhbmQs IGF2Zyh0ZW4pIEFTIGF2ZyBGUk9NIHRlbmsxIEdST1VQIEJZIHR3bywgdGhvdXNhbmQgT0ZGU0VU IDApIHQxLAorICAoU0VMRUNUIHR3bywgdGhvdXNhbmQsIGF2Zyh0ZW4pIEFTIGF2ZyBGUk9NIHRl bmsxIEdST1VQIEJZIHR3bywgdGhvdXNhbmQgT0ZGU0VUIDApIHQyCitXSEVSRSB0MS50d28gPSAw IEFORCB0Mi50d28gPSAwIEFORCB0MS5hdmcgPSB0Mi5hdmc7CisgICAgICAgICAgICAgICAgICAg ICAgICAgIFFVRVJZIFBMQU4gICAgICAgICAgICAgICAgICAgICAgICAgIAorLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyBIYXNo IEpvaW4KKyAgIEhhc2ggQ29uZDogKHQxLmF2ZyA9IHQyLmF2ZykKKyAgIC0+ICBTdWJxdWVyeSBT Y2FuIG9uIHQxCisgICAgICAgICBGaWx0ZXI6ICh0MS50d28gPSAwKQorICAgICAgICAgLT4gIEhh c2hBZ2dyZWdhdGUKKyAgICAgICAgICAgICAgIEdyb3VwIEtleTogdGVuazEudHdvLCB0ZW5rMS50 aG91c2FuZAorICAgICAgICAgICAgICAgLT4gIFNlcSBTY2FuIG9uIHRlbmsxCisgICAtPiAgSGFz aAorICAgICAgICAgLT4gIFN1YnF1ZXJ5IFNjYW4gb24gdDIKKyAgICAgICAgICAgICAgIEZpbHRl cjogKHQyLnR3byA9IDApCisgICAgICAgICAgICAgICAtPiAgSGFzaEFnZ3JlZ2F0ZQorICAgICAg ICAgICAgICAgICAgICAgR3JvdXAgS2V5OiB0ZW5rMV8xLnR3bywgdGVuazFfMS50aG91c2FuZAor ICAgICAgICAgICAgICAgICAgICAgLT4gIFNlcSBTY2FuIG9uIHRlbmsxIHRlbmsxXzEKKygxMyBy b3dzKQorCistLSBTdWJxdWVyeSB3aXRoIERJU1RJTkNUIChPRkZTRVQgMCBwcmV2ZW50cyBxdWFs IHB1c2hkb3duKQorRVhQTEFJTiAoQ09TVFMgT0ZGKQorU0VMRUNUICogRlJPTQorICAoU0VMRUNU IERJU1RJTkNUIHR3bywgdGhvdXNhbmQgRlJPTSB0ZW5rMSBPRkZTRVQgMCkgdDEsCisgIChTRUxF Q1QgRElTVElOQ1QgdHdvLCB0aG91c2FuZCBGUk9NIHRlbmsxIE9GRlNFVCAwKSB0MgorV0hFUkUg dDEudHdvID0gMCBBTkQgdDIudHdvID0gMCBBTkQgdDEudGhvdXNhbmQgPSB0Mi50aG91c2FuZDsK KyAgICAgICAgICAgICAgICAgICAgICAgICAgUVVFUlkgUExBTiAgICAgICAgICAgICAgICAgICAg ICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLQorIEhhc2ggSm9pbgorICAgSGFzaCBDb25kOiAodDEudGhvdXNhbmQgPSB0 Mi50aG91c2FuZCkKKyAgIC0+ICBTdWJxdWVyeSBTY2FuIG9uIHQxCisgICAgICAgICBGaWx0ZXI6 ICh0MS50d28gPSAwKQorICAgICAgICAgLT4gIEhhc2hBZ2dyZWdhdGUKKyAgICAgICAgICAgICAg IEdyb3VwIEtleTogdGVuazEudHdvLCB0ZW5rMS50aG91c2FuZAorICAgICAgICAgICAgICAgLT4g IFNlcSBTY2FuIG9uIHRlbmsxCisgICAtPiAgSGFzaAorICAgICAgICAgLT4gIFN1YnF1ZXJ5IFNj YW4gb24gdDIKKyAgICAgICAgICAgICAgIEZpbHRlcjogKHQyLnR3byA9IDApCisgICAgICAgICAg ICAgICAtPiAgSGFzaEFnZ3JlZ2F0ZQorICAgICAgICAgICAgICAgICAgICAgR3JvdXAgS2V5OiB0 ZW5rMV8xLnR3bywgdGVuazFfMS50aG91c2FuZAorICAgICAgICAgICAgICAgICAgICAgLT4gIFNl cSBTY2FuIG9uIHRlbmsxIHRlbmsxXzEKKygxMyByb3dzKQorCistLSBDVEUgd2l0aCBHUk9VUCBC WQorRVhQTEFJTiAoQ09TVFMgT0ZGKQorV0lUSCBjdGUgQVMgKFNFTEVDVCB0d28sIHRob3VzYW5k LCBhdmcodGVuKSBBUyBhdmcgRlJPTSB0ZW5rMSBHUk9VUCBCWSB0d28sIHRob3VzYW5kKQorU0VM RUNUICogRlJPTSBjdGUgdDEsIGN0ZSB0MgorV0hFUkUgdDEudHdvID0gMCBBTkQgdDIudHdvID0g MCBBTkQgdDEuYXZnID0gdDIuYXZnOworICAgICAgICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAg ICAgICAgICAgICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0KKyBIYXNoIEpvaW4KKyAgIEhhc2ggQ29uZDogKHQxLmF2ZyA9IHQyLmF2ZykKKyAg IENURSBjdGUKKyAgICAgLT4gIEhhc2hBZ2dyZWdhdGUKKyAgICAgICAgICAgR3JvdXAgS2V5OiB0 ZW5rMS50d28sIHRlbmsxLnRob3VzYW5kCisgICAgICAgICAgIC0+ICBTZXEgU2NhbiBvbiB0ZW5r MQorICAgLT4gIENURSBTY2FuIG9uIGN0ZSB0MQorICAgICAgICAgRmlsdGVyOiAodHdvID0gMCkK KyAgIC0+ICBIYXNoCisgICAgICAgICAtPiAgQ1RFIFNjYW4gb24gY3RlIHQyCisgICAgICAgICAg ICAgICBGaWx0ZXI6ICh0d28gPSAwKQorKDExIHJvd3MpCisKKy0tIENURSB3aXRoIERJU1RJTkNU CitFWFBMQUlOIChDT1NUUyBPRkYpCitXSVRIIGN0ZSBBUyAoU0VMRUNUIERJU1RJTkNUIHR3bywg dGhvdXNhbmQgRlJPTSB0ZW5rMSkKK1NFTEVDVCAqIEZST00gY3RlIHQxLCBjdGUgdDIKK1dIRVJF IHQxLnR3byA9IDAgQU5EIHQyLnR3byA9IDAgQU5EIHQxLnRob3VzYW5kID0gdDIudGhvdXNhbmQ7 CisgICAgICAgICAgICAgICAgICAgUVVFUlkgUExBTiAgICAgICAgICAgICAgICAgICAKKy0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIEhhc2ggSm9pbgor ICAgSGFzaCBDb25kOiAodDEudGhvdXNhbmQgPSB0Mi50aG91c2FuZCkKKyAgIENURSBjdGUKKyAg ICAgLT4gIEhhc2hBZ2dyZWdhdGUKKyAgICAgICAgICAgR3JvdXAgS2V5OiB0ZW5rMS50d28sIHRl bmsxLnRob3VzYW5kCisgICAgICAgICAgIC0+ICBTZXEgU2NhbiBvbiB0ZW5rMQorICAgLT4gIENU RSBTY2FuIG9uIGN0ZSB0MQorICAgICAgICAgRmlsdGVyOiAodHdvID0gMCkKKyAgIC0+ICBIYXNo CisgICAgICAgICAtPiAgQ1RFIFNjYW4gb24gY3RlIHQyCisgICAgICAgICAgICAgICBGaWx0ZXI6 ICh0d28gPSAwKQorKDExIHJvd3MpCisKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3JlZ3Jlc3Mvc3Fs L3dpdGguc3FsIGIvc3JjL3Rlc3QvcmVncmVzcy9zcWwvd2l0aC5zcWwKaW5kZXggMjI1NWJlZmRh ODkuLjBjYjI2MzEyZTIxIDEwMDY0NAotLS0gYS9zcmMvdGVzdC9yZWdyZXNzL3NxbC93aXRoLnNx bAorKysgYi9zcmMvdGVzdC9yZWdyZXNzL3NxbC93aXRoLnNxbApAQCAtMTc2NSwzICsxNzY1LDM4 IEBAIGNyZWF0ZSB0ZW1wIHRhYmxlIHdpdGhfdGVzdCAoaSBpbnQpOwogd2l0aCB3aXRoX3Rlc3Qg YXMgKHNlbGVjdCA0MikgaW5zZXJ0IGludG8gd2l0aF90ZXN0IHNlbGVjdCAqIGZyb20gd2l0aF90 ZXN0Owogc2VsZWN0ICogZnJvbSB3aXRoX3Rlc3Q7CiBkcm9wIHRhYmxlIHdpdGhfdGVzdDsKKwor LS0KKy0tIFRlc3Qgc2VsZWN0aXZpdHkgZXN0aW1hdGVzIGZvciBHUk9VUCBCWSBhbmQgRElTVElO Q1Qgc3VicXVlcmllcy9DVEVzLgorLS0KKy0tIFdoZW4gYSBzdWJxdWVyeSBvciBDVEUgaGFzIEdS T1VQIEJZIG9yIERJU1RJTkNULCB0aGUgcGxhbm5lciBzaG91bGQgdXNlCistLSBzdGFkaXN0aW5j dCBmcm9tIHRoZSBiYXNlIHRhYmxlIGZvciBrZXkgY29sdW1ucywgcmF0aGVyIHRoYW4gZmFsbGlu ZyBiYWNrCistLSB0byBERUZBVUxUX05VTV9ESVNUSU5DVC4gIFdpdGggY29ycmVjdCBlc3RpbWF0 ZXMsIHRoZSBwbGFubmVyIHBpY2tzIEhhc2gKKy0tIEpvaW47IHdpdGggdGhlIG9sZCBkZWZhdWx0 IGVzdGltYXRlcyBpdCB3b3VsZCBwaWNrIE5lc3RlZCBMb29wLgorLS0KKworLS0gU3VicXVlcnkg d2l0aCBHUk9VUCBCWSAoT0ZGU0VUIDAgcHJldmVudHMgcXVhbCBwdXNoZG93bikKK0VYUExBSU4g KENPU1RTIE9GRikKK1NFTEVDVCAqIEZST00KKyAgKFNFTEVDVCB0d28sIHRob3VzYW5kLCBhdmco dGVuKSBBUyBhdmcgRlJPTSB0ZW5rMSBHUk9VUCBCWSB0d28sIHRob3VzYW5kIE9GRlNFVCAwKSB0 MSwKKyAgKFNFTEVDVCB0d28sIHRob3VzYW5kLCBhdmcodGVuKSBBUyBhdmcgRlJPTSB0ZW5rMSBH Uk9VUCBCWSB0d28sIHRob3VzYW5kIE9GRlNFVCAwKSB0MgorV0hFUkUgdDEudHdvID0gMCBBTkQg dDIudHdvID0gMCBBTkQgdDEuYXZnID0gdDIuYXZnOworCistLSBTdWJxdWVyeSB3aXRoIERJU1RJ TkNUIChPRkZTRVQgMCBwcmV2ZW50cyBxdWFsIHB1c2hkb3duKQorRVhQTEFJTiAoQ09TVFMgT0ZG KQorU0VMRUNUICogRlJPTQorICAoU0VMRUNUIERJU1RJTkNUIHR3bywgdGhvdXNhbmQgRlJPTSB0 ZW5rMSBPRkZTRVQgMCkgdDEsCisgIChTRUxFQ1QgRElTVElOQ1QgdHdvLCB0aG91c2FuZCBGUk9N IHRlbmsxIE9GRlNFVCAwKSB0MgorV0hFUkUgdDEudHdvID0gMCBBTkQgdDIudHdvID0gMCBBTkQg dDEudGhvdXNhbmQgPSB0Mi50aG91c2FuZDsKKworLS0gQ1RFIHdpdGggR1JPVVAgQlkKK0VYUExB SU4gKENPU1RTIE9GRikKK1dJVEggY3RlIEFTIChTRUxFQ1QgdHdvLCB0aG91c2FuZCwgYXZnKHRl bikgQVMgYXZnIEZST00gdGVuazEgR1JPVVAgQlkgdHdvLCB0aG91c2FuZCkKK1NFTEVDVCAqIEZS T00gY3RlIHQxLCBjdGUgdDIKK1dIRVJFIHQxLnR3byA9IDAgQU5EIHQyLnR3byA9IDAgQU5EIHQx LmF2ZyA9IHQyLmF2ZzsKKworLS0gQ1RFIHdpdGggRElTVElOQ1QKK0VYUExBSU4gKENPU1RTIE9G RikKK1dJVEggY3RlIEFTIChTRUxFQ1QgRElTVElOQ1QgdHdvLCB0aG91c2FuZCBGUk9NIHRlbmsx KQorU0VMRUNUICogRlJPTSBjdGUgdDEsIGN0ZSB0MgorV0hFUkUgdDEudHdvID0gMCBBTkQgdDIu dHdvID0gMCBBTkQgdDEudGhvdXNhbmQgPSB0Mi50aG91c2FuZDsKLS0gCjIuMzkuNSAoQXBwbGUg R2l0LTE1NCkKCg== --00000000000012b9b1064f4d4405--