From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by c5ff346549e7 (Postfix) with ESMTPS id 421445D5 for ; Tue, 30 Nov 2021 10:52:09 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.87,275,1631570400"; d="scan'208,217";a="7161092" Received: from prod-listesu18.inria.fr (HELO sympa.inria.fr) ([128.93.162.160]) by mail2-relais-roc.national.inria.fr with ESMTP; 30 Nov 2021 11:52:08 +0100 Received: by sympa.inria.fr (Postfix, from userid 20132) id 2F159E7A9E; Tue, 30 Nov 2021 11:52:07 +0100 (CET) Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 96D82E7A96 for ; Tue, 30 Nov 2021 11:52:00 +0100 (CET) Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=Pass smtp.pra=alan.schmitt@polytechnique.org; spf=Pass smtp.mailfrom=SRS0=L1VU=QR=polytechnique.org=alan.schmitt@bounces.m4x.org; spf=Pass smtp.helo=postmaster@mx1.polytechnique.org IronPort-PHdr: =?us-ascii?q?A9a23=3AL5F8ZxyGNTkxY9rXCzIzzFBlVkEcU1XcAAcZ59I?= =?us-ascii?q?dhq5Udez7ptK+ZhWZu6wm1geBdL6YwsoMs/DRvaHkVD5Iyre6m1dGTqZxUQQYg?= =?us-ascii?q?94dhQ0qDZ3NI0T6KPn3c35yR5waBxdq8H6hLEdaBtv1aUHMrX2u9z4SHQj0ORZ?= =?us-ascii?q?oKujvFYPekdm72/qz9pHObAlEmiaxaq5uIRurqgncqtMYipZ4JKYrzRvJrHpIe?= =?us-ascii?q?+BIym5tOFmegRXy6Nqu8ZB66yhftO4v+MBGUaXhYqQ3VqdYAyg8M2A0/8Lkqx/?= =?us-ascii?q?ORhaS63QGU2UWlh1IAxXZ7Bz/Q5z8vDf2uvZ71SKHOsL4UK00WS+676h1VBDol?= =?us-ascii?q?CkJNzk88G7Ni8xwir9QrBauqhF7xoLZZoGZOvl4fqPDfNMaXmtBUd1VVyNfH4i?= =?us-ascii?q?9YYwPD/AcMuZDsoLxo1UDoQe7CQSqGejhyCJHhmXu0KM6zeovDA/I0g8vEN0Sq?= =?us-ascii?q?3nbtsn5Ob0IXOyp0KXFzzPOZO5W1zfn74jIdwgsrO2IXb1qd8ra1FQhGB/FjlW?= =?us-ascii?q?VqIzlIy+V3fkKvmeB6+pvT+Svh3Q8qw5tojivw8YsipXVho8O0lDE8iF5wYYpJ?= =?us-ascii?q?dKmVEF7YdikEJpJtyGHKYR6WMQiQ3tnuCsjzLANpJG0cjQQxps92x7fd+KIc5K?= =?us-ascii?q?O4h/7SuufISt0iGxrdb+7mxu/71Wsx+L9W8So31tGsjZJn8XOu30OyhHd6saKR?= =?us-ascii?q?/p/80qv3TuB2R3f5+9EL002l6fVJZgsyaM+mJoUtETMBC72mEPuga+OaEok5um?= =?us-ascii?q?o6/j5bbX+oZ+cMop0hR/kPqQohMO/Hfw0Mg8SUGeB/OS80Kfv/UrjQLVFlvE2n?= =?us-ascii?q?ajZsIzaJcQGvaG1GRNa0oEm6xqnEjipzsgXnXgCLF1ffBKLlZTpO1bWLPD5C/e?= =?us-ascii?q?/mVWsny1xy/DIJL3tGo/NIWbZn7j8eLZy9VRQyA8uwtxH6JJUC60BIPLuWkDqr?= =?us-ascii?q?tDYDxg5PxS6wubmC9V915seVnySDa+YKqzeq1iI5vggI+WUa48VuSr9K/g45/H?= =?us-ascii?q?1l3M1g14dfa6x0ZsWdX+5HvBmI0GDbXrrmNcBHn8Gvwo/TOP0jF2NTCRfZ3euX?= =?us-ascii?q?64k+D47EpimDYDZRoy3jryOxia7HplQa2tbCV6MCW/le5iaV/oIci6eP9NtnzM?= =?us-ascii?q?eWbWvV4Mtzx+juQDix7Z6IOfY5zcUuYzj2dV6/eHfixE/+SJuA8iA0myAT2d5l?= =?us-ascii?q?X4SSTAsxqBwu0l9x0+D0admh/xYEsRe5/ZGUwsnL5Lc1+t6C9TyWwLdYNiGVFa?= =?us-ascii?q?mQtOnATEoU9I+3cUCY0FnG9WtlhzD3iyqDKEJl7GTGZA47KbR02LsK8phxHvKz?= =?us-ascii?q?qcsg0U8TsZBOmCqnqt/+BLSB47NnUWZjaGqdaEE0SDQ6GmN0HaCsVleXgJtXqr?= =?us-ascii?q?KU2gSaFDKo9nh/kPCSLuuCLQ7MgRf1cGCKq1KatzwjVVbWvjvItPeY3i+m2qoH?= =?us-ascii?q?xmIwqmDbIzwd2UGwCrdCE0EkwEP/XaaLgUxHSCho3/YDDNyC13veFng8exxpXK?= =?us-ascii?q?0VEM0yBuKb0J527qv5hEVneCcS+8U3r8cpCgusTB0HFKk09LSCtqAvBZhcb5HY?= =?us-ascii?q?dI95VdHzXjWuxZ8PpymNaBih0QRfx55v0P0hF1LDdAKldcs5jt+yBV0AaaH1hV?= =?us-ascii?q?Hei/Omdi6MaLRYCG6qBuwbYbS20rCy5CX9rYL7LI/sVq1+EmiH08mtnFmyMV90?= =?us-ascii?q?n2G55yMAhBBf4j2VxMe8xF874rRYiw8+5+cgXRoOK/yqTTC3tM1GMM9zRKxY9p?= =?us-ascii?q?UMKWFDRL/VcoACJ79e6QRh1G1Y0dcb6hp/6kuMpb5JpNuOYauLL8mhDWinHhK6?= =?us-ascii?q?4B701uR+mx7UOGahv7tJtmA2Q+WSzr3jFGgq93634deamNLdoJQ4SLjGYhaa7Y?= =?us-ascii?q?0eNobT2C0LJ/urug=3D?= IronPort-Data: =?us-ascii?q?A9a23=3AK4T9xa0Kd8W/lMg+JvbD5fZwkn2cJEfYwER7XOP?= =?us-ascii?q?LsXnJgT501mNUnWEWDGyOOq2CYmr0KNp/YY/loB9TsZTVm4ISHQtv/xmBbVoa8?= =?us-ascii?q?JufXYzxwmTYZn7JcJWbFCqL1yivAzX5BJhcokT0+1H9bdANkVEmjfvRH+OnULa?= =?us-ascii?q?dUsxMbVYMpBkJ2UoLd9ER2dYAbeiRW2thiPuqyyHtEAfNNw1cbgr435m+RCZH5?= =?us-ascii?q?5wejt+3UmsWPpintHeG/5Uc4Ql2yauZdxMUSaEMdgK2qnqq8V23wo/Z109F5tK?= =?us-ascii?q?Nl6aiNFUNRq/OMAOOjHtPRqXkhQJNzsAw+v9hZbxFMRsR0G3PxIwZJNZl7fRcT?= =?us-ascii?q?S8SBJaUzcBEbSQNKhsrJapC6aPKKni5sNWOwgvBaXS5yvFnCgctNo0d+/prKWt?= =?us-ascii?q?J6PoTJStLa0yTweWsz9pXT8Ez35p6dJG6VG8Ykis5l26JXKxOrYr4a67D4Nsd2?= =?us-ascii?q?DYrmuhVDPPGbowYbyBuZVLOeXVy1v0/HMprx6H1kiCqK3sAvAjA/extvjaN2Fc?= =?us-ascii?q?kiP6wJIWAU8KsbsBzska8h2vgw37fFkhCYYTbkS7tHmmEg/+W2zv8XJMOGba48?= =?us-ascii?q?P9znVDVwXYcYCD6nGCT+ZGR4nNSkfoFQ6DVxsYvkUT23Em7F5/lWBmpvHOPvhg?= =?us-ascii?q?dQsddVeog52lhD4LKth2BCDFsoiFpMbQbWA0eHFTGFWNlW/vjAiFpu7COD3fB5?= =?us-ascii?q?vGTtzza1e09NncMP2lcJecay4CLnWzw5y4jiv57F6qkktD+GTfx2i2H6i8kiN3?= =?us-ascii?q?/SOYQz6vhuwivby2E//D0c+L+2ukbsq9JIO+0iE5JqrFEMWTm0Ms=3D?= IronPort-HdrOrdr: =?us-ascii?q?A9a23=3AeJBr36ke8o+tMjtXX2S/2i8DvwTpDfIn3DAb?= =?us-ascii?q?v31ZSRFFG/FwWfrOoB19726RtN9xYgBEpTnuAsO9qB/nhP1ICMwqTNWftWrd1V?= =?us-ascii?q?dATrsI0WKK+VSJJ8S9zI5gPMxbHJSWZuefMbE3t6rH3DU=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0BkBAAuAaZhhyIeaIFaFoJOgR8bAjdHA?= =?us-ascii?q?WRXOjEChAc+jm6CJYEWghWGFoZsiBGEFYEPVBABAwENKgEOBQECBAEBhD9egmc?= =?us-ascii?q?CHgYBBTMTAQIEFQEBBQEBAQIBAwMEARMBAQEBDQsOCDQihWgNQAEQAYFjDAwDA?= =?us-ascii?q?4N0AwEKDgEICkAlIwMJCwEGAwIEDQEXARQKFwESFAUBAYJWAYMHBQqTcJwMgTG?= =?us-ascii?q?BAYNOAQMDBAlBg3KBYw0CFIEVAgEBhgpUSgGCfwmDBHkCJxCBVUSBFYIpSgdug?= =?us-ascii?q?kwMCwEBAQEBgRYlAQEGWYJZgmUEkDAOGR8GFyccCAIYEwsJEAYBAQQFRwgFIwU?= =?us-ascii?q?HBAsCFw8CIwMaCAcBHQUGOgORTB8YDQOMaopGglmREhReMweDPoE0BguHe4EVj?= =?us-ascii?q?FqICYNtgUqQepEDIZV1H4IjhmcIgQ2CO5NgKggwhHuBTiqBagwHMxowQ4JpCWE?= =?us-ascii?q?PjiwWg1CBDDKBJoF1MgmCQYMKQDMCAQEDMQIGAQoBAQMJhWMBAQUTCwGCKIsEA?= =?us-ascii?q?QE?= X-IPAS-Result: =?us-ascii?q?A0BkBAAuAaZhhyIeaIFaFoJOgR8bAjdHAWRXOjEChAc+jm6?= =?us-ascii?q?CJYEWghWGFoZsiBGEFYEPVBABAwENKgEOBQECBAEBhD9egmcCHgYBBTMTAQIEF?= =?us-ascii?q?QEBBQEBAQIBAwMEARMBAQEBDQsOCDQihWgNQAEQAYFjDAwDA4N0AwEKDgEICkA?= =?us-ascii?q?lIwMJCwEGAwIEDQEXARQKFwESFAUBAYJWAYMHBQqTcJwMgTGBAYNOAQMDBAlBg?= =?us-ascii?q?3KBYw0CFIEVAgEBhgpUSgGCfwmDBHkCJxCBVUSBFYIpSgdugkwMCwEBAQEBgRY?= =?us-ascii?q?lAQEGWYJZgmUEkDAOGR8GFyccCAIYEwsJEAYBAQQFRwgFIwUHBAsCFw8CIwMaC?= =?us-ascii?q?AcBHQUGOgORTB8YDQOMaopGglmREhReMweDPoE0BguHe4EVjFqICYNtgUqQepE?= =?us-ascii?q?DIZV1H4IjhmcIgQ2CO5NgKggwhHuBTiqBagwHMxowQ4JpCWEPjiwWg1CBDDKBJ?= =?us-ascii?q?oF1MgmCQYMKQDMCAQEDMQIGAQoBAQMJhWMBAQUTCwGCKIsEAQE?= X-IronPort-AV: E=Sophos;i="5.87,275,1631570400"; d="scan'208,217";a="7161009" X-MGA-submission: =?us-ascii?q?MDEheqosdqd58UkWJXHMWKAnt7ZFXU/PgYbKDp?= =?us-ascii?q?q62U0FqUWkKu7V5dsOrtHMeWrEhidw/yIAtrhEDyG8SFXUv6a5HST5V4?= =?us-ascii?q?Ic6jpRCrRwqNJuH0Al6KL5IGfrsiExBoxCwaA0umlwqvvjLtpSbGUZ2f?= =?us-ascii?q?wt31NVcQrB8RBoosePqJJn9A=3D=3D?= Received: from mx1.polytechnique.org ([129.104.30.34]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Nov 2021 11:52:00 +0100 Received: from set (unknown [131.254.252.165]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ssl.polytechnique.org (Postfix) with ESMTPSA id 5E6DF564C4A; Tue, 30 Nov 2021 11:51:57 +0100 (CET) From: Alan Schmitt To: "lwn" , "cwn" , caml-list@inria.fr Date: Tue, 30 Nov 2021 11:51:47 +0100 Message-ID: <87o8613oho.fsf@m4x.org> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-=-=" X-AV-Checked: ClamAV using ClamSMTP at svoboda.polytechnique.org (Tue Nov 30 11:51:57 2021 +0100 (CET)) X-Spam-Flag: No, tests=bogofilter, spamicity=0.217355, queueID=BF82B564C4C X-Org-Mail: alan.schmitt.1995@polytechnique.org Subject: [Caml-list] Attn: Development Editor, Latest OCaml Weekly News Reply-To: Alan Schmitt X-Loop: caml-list@inria.fr X-Sequence: 18620 Errors-To: caml-list-owner@inria.fr Precedence: list Precedence: bulk Sender: caml-list-request@inria.fr X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: base64 SGVsbG8NCg0KSGVyZSBpcyB0aGUgbGF0ZXN0IE9DYW1sIFdlZWtseSBOZXdzLCBmb3IgdGhlIHdl ZWsgb2YgTm92ZW1iZXIgMjMgdG8gMzAsDQoyMDIxLg0KDQpUYWJsZSBvZiBDb250ZW50cw0K4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCm9wYW0g Mi4xLjEsIG9wYW0gMi4wLjEwLCBhbmQgb3BhbS1kZXBleHQgMS4yDQpPVE9NTCAwLjkuMCDigJQg YSBjb21wbGlhbnQgYW5kIGZsZXhpYmxlIFRPTUwgcGFyc2luZywgbWFuaXB1bGF0aW9uLCBhbmQg cHJldHR5LXByaW50aW5nIGxpYnJhcnkNCk5ldyByZWxlYXNlIG9mIEZpeA0KTmV3IHJlbGVhc2Ug b2YgTWVuaGlyICgyMDIxMTEyNSkNCkx3dCA1LjUuMCwgTHd0X2RvbWFpbiAwLjEuMCwgTHd0X3Jl YWN0LjEuMS41DQpPQ2FtbCdzIENJIGlzIGdyYWR1YWxseSBtb3ZpbmcgdG8gR2l0SHViIEFjdGlv bnMNCkhvdyB0byBjb21iaW5lIDMgbW9uYWRzOiBBc3luYy9Md3QsIEVycm9yIGFuZCBTdGF0ZT8N Ck9sZCBDV04NCg0KDQpvcGFtIDIuMS4xLCBvcGFtIDIuMC4xMCwgYW5kIG9wYW0tZGVwZXh0IDEu Mg0K4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2ZToNCiAgPGh0dHBzOi8vZGlzY3Vzcy5v Y2FtbC5vcmcvdC9hbm4tb3BhbS0yLTEtMS1vcGFtLTItMC0xMC1vcGFtLWRlcGV4dC0xLTIvODg3 Mi8xPg0KDQoNClIuIEJvdWpiZWwgYW5ub3VuY2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KICBXZSBhcmUgcGxlYXNlZCB0 byBhbm5vdW5jZSBzZXZlcmFsIG1pbm9yIHJlbGVhc2VzOiBbb3BhbSAyLjAuMTBdLA0KICBbb3Bh bSAyLjEuMV0sIGFuZCBbb3BhbS1kZXBleHQgMS4yXS4NCg0KICBUaGUgb3BhbSByZWxlYXNlcyBj b25zaXN0IG9mIGJhY2twb3J0ZWQgZml4ZXMsIHdoaWxlIGBvcGFtLWRlcGV4dCcgaGFzDQogIGJl ZW4gYWRhcHRlZCB0byBiZSBjb21wYXRpYmxlIHdpdGggb3BhbSAyLjEsIHRvIGFsbG93IGZvciB3 b3JrZmxvd3MNCiAgd2hpY2ggbmVlZCB0byBtYWludGFpbiBjb21wYXRpYmlsaXR5IHdpdGggb3Bh bSAyLjAuIFdpdGggb3BhbSAyLjEuMSwNCiAgaWYgeW91IGV4cG9ydCBgT1BBTUNMST0yLjAnIGlu dG8geW91ciBlbnZpcm9ubWVudCB0aGVuIHdvcmtmbG93cw0KICBleHBlY3Rpbmcgb3BhbSAyLjAg c2hvdWxkIG5vdyBiZWhhdmUgZXZlbiBtb3JlIGVxdWl2YWxlbnRseS4NCg0KICBZb3UnbGwgZmlu ZCBtb3JlIGluZm9ybWF0aW9uIGluIHRoZSBbYmxvZyBwb3N0IF0uDQoNCg0KW29wYW0gMi4wLjEw XSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL29wYW0vcmVsZWFzZXMvdGFnLzIuMC4xMD4NCg0K W29wYW0gMi4xLjFdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvb3BhbS9yZWxlYXNlcy90YWcv Mi4xLjE+DQoNCltvcGFtLWRlcGV4dCAxLjJdDQo8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sLW9w YW0vb3BhbS1kZXBleHQvcmVsZWFzZXMvdGFnLzEuMj4NCg0KW2Jsb2cgcG9zdCBdIDxodHRwczov L29wYW0ub2NhbWwub3JnL2Jsb2cvb3BhbS0yLTAtMTAtMi0xLTEtZGVwZXh0Lz4NCg0KDQpPVE9N TCAwLjkuMCDigJQgYSBjb21wbGlhbnQgYW5kIGZsZXhpYmxlIFRPTUwgcGFyc2luZywgbWFuaXB1 bGF0aW9uLCBhbmQgcHJldHR5LXByaW50aW5nIGxpYnJhcnkNCuKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkA0KDQogIEFyY2hpdmU6DQogIDxodHRw czovL2Rpc2N1c3Mub2NhbWwub3JnL3QvYW5uLW90b21sLTAtOS0wLWEtY29tcGxpYW50LWFuZC1m bGV4aWJsZS10b21sLXBhcnNpbmctbWFuaXB1bGF0aW9uLWFuZC1wcmV0dHktcHJpbnRpbmctbGli cmFyeS84MTUyLzEwPg0KDQoNCkRhbmlpbCBCYXR1cmluIGFubm91bmNlZA0K4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSADQoNCiAgQSBuZXcgMC45LjMgcmVsYXNlIGlzIGF2YWlsYWJsZS4gU3RpbGwgbm90IDEuMC4w IGp1c3QgaW4gY2FzZS4gVGhlDQogIGNoYW5nZSBJJ20gbW9zdCBnbGFkIEkgbWFuYWdlZCB0byBt YWtlIGlzIHRoYXQgdGhlIGxleGVyIGlzIG5vdw0KICByZS1lbnRyYW50IGFuZCBkb2Vzbid0IHVz ZSBhbnkgbXV0YWJsZSBzdGF0ZS4gV2hlcmUgY2FuIEkgYXBwbHkgZm9yDQogIHRoZSAiRGVzaWdu ZWQgZm9yIG11bHRpY29yZSBPQ2FtbCIgY2VydGlmaWNhdGlvbiBzdGlja2VyPyA7KQ0KDQoNCkJy ZWFraW5nIGNoYW5nZSBpbiB0aGUgZnVuY3RvciBpbnRlcmZhY2UNCuKVjOKVjOKVjOKVjOKVjOKV jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKV jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjA0KDQogIEkgZm91 bmQgYW4gb3ZlcnNpZ2h0IHRoYXQgdG9vayBhIGJyZWFraW5nIGNoYW5nZSB0byBmaXguIEl0IGRp ZG4ndA0KICBicmVhayBhbnkgcGFja2FnZSB0aGF0IHdhcyBhbHJlYWR5IGluIHRoZSBPUEFNIHJl cG9zaXRvcnksIHNvIEknbSBnbGFkDQogIEkgbm90aWNlZCBpdCBiZWZvcmUgaXQgY2F1c2VkIGFu eW9uZSB0cm91YmxlLg0KDQogIE15IGlkZWEgdG8gbWFrZSB0aGUgZnVuY3RvciB0YWtlIHNlcGFy YXRlIGludGVnZXIgYW5kIGZsb2F0IG1vZHVsZXMNCiAgdHVybmVkIG91dCB0byBiZSBtaXNndWlk ZWQ6IGl0IHdvdWxkbid0IGNvbXBvc2Ugd2l0aCBgT3RvbWwuZ2V0X2Zsb2F0DQogIH5zdHJpY3Q6 ZmFsc2UnIGFuZCBzaW1pbGFyIGZ1bmN0aW9ucyB0aGF0IGFwcGx5IHR5cGUgY29udmVyc2lvbnMu DQoNCiAgTG9naWNhbGx5LCBgT3RvbWwuZ2V0X2Zsb2F0IH5zdHJpY3Q6ZmFsc2UgKE90b21sLmlu dGVnZXIgNSknIHNob3VsZA0KICBwcm9kdWNlIGBPdG9tbC5Ub21sRmxvYXQgNS4wJy4gSG93ZXZl ciwgaXQgbWVhbnMgdGhhdCBgZ2V0X2Zsb2F0Jw0KICBuZWVkcyB0byBrbm93IGhvdyB0byBjb252 ZXJ0IGludGVnZXJzIHRvIGZsb2F0LiBJZiBpbnRlZ2VyIGFuZCBmbG9hdA0KICB0eXBlcyBhcmUg aW4gc2VwYXJhdGUgbW9kdWxlcywgdGhhdCBpc24ndCBwb3NzaWJsZS4NCg0KICBTbyBJIGNvbWJp bmVkIGJvdGggaW50ZWdlcnMgYW5kIGZsb2F0cyBpbiBhIHNpbmdsZSBgVG9tbE51bWJlcicuIFRo YXQNCiAgd2F5IHBlb3BsZSB3aG8gd2FudCB0byBicmluZyB0aGVpciBvd24gYmlnbnVtIGxpYnJh cmllcyB3aWxsIGhhdmUgdG8NCiAgd3JpdGUgbW9yZSBjb2RlLCBidXQgbnVtYmVycyB3aWxsIGJl aGF2ZSBhcyB0aGV5IGFyZSBleHBlY3RlZCB0byBpbiBhDQogIGR5bmFtaWNhbGx5IHR5cGVkIGZv cm1hdC4NCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIG1vZHVsZSBCaWdOdW1iZXIgPSBzdHJ1 Y3QNCiAg4pSCICAgdHlwZSBpbnQgPSBaLnQNCiAg4pSCICAgdHlwZSBmbG9hdCA9IERlY2ltYWwu dA0KICDilIIgDQogIOKUgiAgIGxldCBpbnRfb2Zfc3RyaW5nID0gWi5vZl9zdHJpbmcNCiAg4pSC ICAgbGV0IGludF90b19zdHJpbmcgPSBaLnRvX3N0cmluZw0KICDilIIgICBsZXQgaW50X29mX2Jv b2xlYW4gYiA9IGlmIGIgdGhlbiBaLm9uZSBlbHNlIFouemVybw0KICDilIIgICBsZXQgaW50X3Rv X2Jvb2xlYW4gbiA9IChuIDw+IFouemVybykNCiAg4pSCIA0KICDilIIgICAoKiBDYW4ndCBqdXN0 IHJldXNlIERlY2ltYWwudG8vb2Zfc3RyaW5nIGJlY2F1c2UgdGhlaXIgb3B0aW9uYWwgYXJndW1l bnRzDQogIOKUgiAgICAgIHdvdWxkIGNhdXNlIGEgc2lnbmF0dXJlIG1pc21hdGNoLiAqKQ0KICDi lIIgICBsZXQgZmxvYXRfb2Zfc3RyaW5nIHMgPSBEZWNpbWFsLm9mX3N0cmluZyBzDQogIOKUgiAN CiAg4pSCICAgKCogRGVjaW1hbC50b19zdHJpbmcgdXNlcyAiTmFOIiBzcGVsbGluZw0KICDilIIg ICAgICB3aGlsZSBUT01MIHJlcXVpcmVzIGFsbCBzcGVjaWFsIGZsb2F0IHZhbHVlcyB0byBiZSBs b3dlcmNhc2UuICopDQogIOKUgiAgIGxldCBmbG9hdF90b19zdHJpbmcgeCA9IERlY2ltYWwudG9f c3RyaW5nIHggfD4gU3RyaW5nLmxvd2VyY2FzZV9hc2NpaQ0KICDilIIgICBsZXQgZmxvYXRfb2Zf Ym9vbGVhbiBiID0gaWYgYiB0aGVuIERlY2ltYWwub25lIGVsc2UgRGVjaW1hbC56ZXJvDQogIOKU giAgIGxldCBmbG9hdF90b19ib29sZWFuIHggPSAoeCA8PiBEZWNpbWFsLnplcm8pDQogIOKUgiAN CiAg4pSCICAgbGV0IGZsb2F0X29mX2ludCA9IERlY2ltYWwub2ZfYmlnaW50DQogIOKUgiAgIGxl dCBpbnRfb2ZfZmxvYXQgPSBEZWNpbWFsLnRvX2JpZ2ludA0KICDilIIgZW5kDQogIOKUgiANCiAg 4pSCIG1vZHVsZSBPdG9tbCA9IE90b21sLkJhc2UuTWFrZSAoQmlnTnVtYmVyKSAoT3RvbWwuQmFz ZS5TdHJpbmdEYXRlKQ0KICDilJTilIDilIDilIDilIANCg0KICBUaGUgbmV4dCByZWxlYXNlIHdp bGwgbGlrZWx5IGJlIDEuMC4wIGZvciByZWFsLg0KDQoNCk5ldyByZWxlYXNlIG9mIEZpeA0K4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAg QXJjaGl2ZTogPGh0dHBzOi8vZGlzY3Vzcy5vY2FtbC5vcmcvdC9hbm4tbmV3LXJlbGVhc2Utb2Yt Zml4Lzg4OTUvMT4NCg0KDQpGcmFuw6dvaXMgUG90dGllciBhbm5vdW5jZWQNCuKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgA0KDQogIEkgYW0gcGxlYXNlZCB0byBhbm5vdW5jZSBhIG5ldyByZWxlYXNlIG9m IEZpeCwgd2l0aCBzZXZlcmFsIG5ldw0KICBtb2R1bGVzIGNvbnRyaWJ1ZWQgYnkgRnLDqWTDqXJp YyBCb3VyICh0aGFua3MhKS4NCg0KICBJbiBzaG9ydCwgRml4IGlzIGEgdG9vbGtpdCB0aGF0IGhl bHBzIHBlcmZvcm0gbWVtb2l6YXRpb24gYW5kIGZpeGVkDQogIHBvaW50IGNvbXB1dGF0aW9ucyAo aW5jbHVkaW5nIGRhdGEgZmxvdyBhbmFseXNlcykuIE1vcmUgZ2VuZXJhbGx5LCBpdA0KICBvZmZl cnMgYSBudW1iZXIgb2YgYmFzaWMgYWxnb3JpdGhtaWMgYnVpbGRpbmcgYmxvY2tzIHRoYXQgY2Fu IGJlDQogIHVzZWZ1bCBpbiBtYW55IGNpcmN1bXN0YW5jZXMuDQoNCiAg4pSM4pSA4pSA4pSA4pSA DQogIOKUgiBvcGFtIHVwZGF0ZQ0KICDilIIgb3BhbSBpbnN0YWxsIGZpeC4yMDIxMTEyNQ0KICDi lJTilIDilIDilIDilIANCg0KICBEb2N1bWVudGF0aW9uIGNhbiBiZSBmb3VuZCBoZXJlOg0KDQog IOKAoiA8aHR0cHM6Ly9naXRsYWIuaW5yaWEuZnIvZnBvdHRpZXIvZml4Ly0vYmxvYi9tYXN0ZXIv UkVBRE1FLm1kPg0KICDigKIgPGh0dHA6Ly9jYW1iaXVtLmlucmlhLmZyL35mcG90dGllci9maXgv ZG9jL2ZpeC9GaXgvaW5kZXguaHRtbD4NCg0KICBFbmpveSwNCg0KICBGcmFuw6dvaXMgUG90dGll cg0KICBmcmFuY29pcy5wb3R0aWVyQGlucmlhLmZyDQogIDxodHRwOi8vY2FtYml1bS5pbnJpYS5m ci9+ZnBvdHRpZXIvPg0KDQoNCjIwMjEvMTEvMjUNCuKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKV jOKVjA0KDQogIOKAoiBUaGUgbmV3IG1vZHVsZSBgQ29tcGFjdFF1ZXVlJyBvZmZlcnMgYSBtaW5p bWFsaXN0IG11dGFibGUgRklGTw0KICAgIHF1ZXVlLiBJdCBpcyBjb21wYXJhYmxlIHdpdGggT0Nh bWwncyBgUXVldWUnIG1vZHVsZS4gSW4gY29tcGFyaXNvbg0KICAgIHdpdGggYFF1ZXVlJywgaXQg dXNlcyBhIG1vcmUgY29tcGFjdCBpbnRlcm5hbCByZXByZXNlbnRhdGlvbjoNCiAgICBlbGVtZW50 cyBhcmUgc3RvcmVkIGNvbnRpZ3VvdXNseSBpbiBhIGNpcmN1bGFyIGFycmF5LiBUaGlzIGhhcyBh DQogICAgcG9zaXRpdmUgaW1wYWN0IG9uIHBlcmZvcm1hbmNlOiBib3RoIHRpbWUgYW5kIG1lbW9y eSBjb25zdW1wdGlvbiBhcmUNCiAgICByZWR1Y2VkLiBUaGlzIGRhdGEgc3RydWN0dXJlIGlzIG9w dGltaXplZCBmb3IgbWF4aW11bQ0KICAgIHRocm91Z2hwdXQuIChDb250cmlidXRlZCBieSBGcsOp ZMOpcmljIEJvdXIsIHJldmlld2VkIGJ5IEZyYW7Dp29pcw0KICAgIFBvdHRpZXIuKQ0KDQogIOKA oiBUaGUgbmV3IGZ1bmN0b3IgYERhdGFGbG93LkZvckN1c3RvbU1hcHMnIG9mZmVycyBhIGZvcndh cmQgZGF0YSBmbG93DQogICAgYW5hbHlzaXMgdGhhdCBpcyB0dW5lZCBmb3IgZ3JlYXRlciBwZXJm b3JtYW5jZS4gKENvbnRyaWJ1dGVkIGJ5DQogICAgRnLDqWTDqXJpYyBCb3VyLCByZXZpZXdlZCBi eSBGcmFuw6dvaXMgUG90dGllci4pDQoNCiAg4oCiIFRoZSBuZXcgbW9kdWxlIGBJbmRleGluZycg b2ZmZXJzIGEgc2FmZSBBUEkgZm9yIG1hbmlwdWxhdGluZyBpbmRpY2VzDQogICAgaW50byBmaXhl ZC1zaXplIGFycmF5cy4gVGhpcyBBUEkgaW52b2x2ZXMgc29tZSBkeW5hbWljIGNoZWNrcyBhcw0K ICAgIHdlbGwgYXMgc3RhdGljIHR5cGUgY2hlY2tzLCB0aGVyZWJ5IChob3BlZnVsbHkpIGdyZWF0 bHkgcmVkdWNpbmcgdGhlDQogICAgcmlzayBvZiBjb25mdXNpb24gaW4gY29kZSB0aGF0IHVzZXMg bWFueSBhcnJheXMgYW5kIG1hbnkgaW5kaWNlcw0KICAgIGludG8gdGhlc2UgYXJyYXlzLiAoQ29u dHJpYnV0ZWQgYnkgRnLDqWTDqXJpYyBCb3VyLCByZXZpZXdlZCBieQ0KICAgIEZyYW7Dp29pcyBQ b3R0aWVyLikNCg0KICDigKIgSW4gYERhdGFGbG93JywgYWxsb3cgdGhlIGZ1bmN0aW9uIGBmb3Jl YWNoX3Jvb3QnICh3aGljaCBpcyBwYXJ0IG9mDQogICAgdGhlIHNpZ25hdHVyZSBgREFUQV9GTE9X X0dSQVBIJykgdG8gY2FsbCBgY29udHJpYnV0ZSB4IF8nIHNldmVyYWwNCiAgICB0aW1lcyBhdCBh IHNpbmdsZSByb290IGB4Jy4NCg0KDQpOZXcgcmVsZWFzZSBvZiBNZW5oaXIgKDIwMjExMTI1KQ0K 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2ZToNCiAg PGh0dHBzOi8vZGlzY3Vzcy5vY2FtbC5vcmcvdC9hbm4tbmV3LXJlbGVhc2Utb2YtbWVuaGlyLTIw MjExMTI1Lzg4OTYvMT4NCg0KDQpGcmFuw6dvaXMgUG90dGllciBhbm5vdW5jZWQNCuKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgA0KDQogIEkgYW0gcGxlYXNlZCB0byBhbm5vdW5jZSBhIG5ldyByZWxlYXNl IG9mIE1lbmhpciwgd2l0aCBhbiBleGNpdGluZw0KICBjb250cmlidXRpb24gYnkgRnLDqWTDqXJp YyBCb3VyOiBhIGdyb3VuZGJyZWFraW5nIHBlcmZvcm1hbmNlDQogIGltcHJvdmVtZW50IGluIGBt ZW5oaXIgLS1saXN0LWVycm9ycycuIFRoaXMgaXMgbWFkZSBwb3NzaWJsZSBieSBhbg0KICBlbnRp cmVseSBuZXcgcmVhY2hhYmlsaXR5IGFsZ29yaXRobSwgd2hpY2ggaGFzIGJlZW4gZGVzaWduZWQg YW5kDQogIGltcGxlbWVudGVkIGJ5IEZyw6lkw6lyaWMsIGFuZCB3aGljaCBpcyBkZXNjcmliZWQg aW4gb3VyIHBhcGVyICJGYXN0ZXINCiAgUmVhY2hhYmlsaXR5IEFuYWx5c2lzIGZvciBMUigxKSBQ YXJzZXJzIi4gVGhpcyBpcyB0aGUgbGluayB0byB0aGUNCiAgcGFwZXI6DQoNCiAgPGh0dHA6Ly9j YW1iaXVtLmlucmlhLmZyL35mcG90dGllci9wdWJsaXMvYm91ci1wb3R0aWVyLXJlYWNoYWJpbGl0 eS5wZGY+DQoNCiAgVG8gaW5zdGFsbCB0aGUgbmV3IHJlbGVhc2UsIGp1c3QgdHlwZQ0KDQogIOKU jOKUgOKUgOKUgOKUgA0KICDilIIgb3BhbSB1cGRhdGUNCiAg4pSCIG9wYW0gaW5zdGFsbCBtZW5o aXIuMjAyMTExMjUNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgRW5qb3khDQoNCiAgRnJhbsOnb2lz IFBvdHRpZXINCiAgRnJhbmNvaXMuUG90dGllckBpbnJpYS5mcg0KICA8aHR0cDovL2NhbWJpdW0u aW5yaWEuZnIvfmZwb3R0aWVyLz4NCg0KICDigKIgVGhlIGNvbW1hbmQgYG1lbmhpciAtLWxpc3Qt ZXJyb3JzJyBoYXMgYmVlbiBzcGVkIHVwIGJ5IGEgZmFjdG9yIG9mDQogICAgdXAgdG8geDEwMCwg YW5kIHJlcXVpcmVzIHVwIHRvIHgxMDAwIGxlc3MgbWVtb3J5LCB0aGFua3MgdG8gYSBuZXcNCiAg ICBMUigxKSByZWFjaGFiaWxpdHkgYWxnb3JpdGhtLCB3aGljaCBoYXMgYmVlbiBkZXNpZ25lZCBh bmQNCiAgICBpbXBsZW1lbnRlZCBieSBGcsOpZMOpcmljIEJvdXIuDQoNCiAg4oCiIEJldHRlciBk b2N1bWVudCB0aGUgcmVzdHJpY3RlZCB3YXkgaW4gd2hpY2ggdGhlIGBlcnJvcicgdG9rZW4gbXVz dA0KICAgIGJlIHVzZWQgd2hlbiB1c2luZyBgLS1zdHJhdGVneSBzaW1wbGlmaWVkJy4gTWVuaGly IG5vdyBjaGVja3MgdGhhdA0KICAgIHRoaXMgdG9rZW4gaXMgdXNlZCBvbmx5IGF0IHRoZSBlbmQg b2YgYSBwcm9kdWN0aW9uLCBhbmQgd2FybnMgaWYNCiAgICB0aGlzIGlzIG5vdCB0aGUgY2FzZS4g KEJldHRlciB5ZXQsIG91ciBzdWdnZXN0aW9uIGlzIHRvIG5vdCB1c2UgdGhlDQogICAgYGVycm9y JyB0b2tlbiBhdCBhbGwhKQ0KDQogIOKAoiBUaGUgYCRzeW50YXhlcnJvcicga2V5d29yZCBpcyBu b3cgZm9yYmlkZGVuIHdoZW4gdXNpbmcgYC0tc3RyYXRlZ3kNCiAgICBzaW1wbGlmaWVkJy4gVGhp cyBrZXl3b3JkIHdpbGwgYmUgZW50aXJlbHkgcmVtb3ZlZCBpbiB0aGUgbmV4dA0KICAgIHJlbGVh c2UuIEluY2lkZW50YWxseSwgd2UgaGF2ZSBqdXN0IGZvdW5kIG91dCB0aGF0IGl0IGJlaGF2ZXMN CiAgICBkaWZmZXJlbnRseSB1bmRlciB0aGUgY29kZSBiYWNrLWVuZCBhbmQgdW5kZXIgdGhlIHRh YmxlIGJhY2stZW5kLg0KDQogIOKAoiBEaXNhYmxlIE9DYW1sIHdhcm5pbmcgMzkgKHVudXNlZCBy ZWMgZmxhZykgaW4gdGhlIE9DYW1sIGNvZGUNCiAgICBwcm9kdWNlZCBieSBNZW5oaXIncyBjb2Rl IGJhY2stZW5kLiBUaGlzIGRvZXMgbm90IGFmZmVjdCB0aGUgdGFibGUNCiAgICBiYWNrLWVuZC4g IChSZXBvcnRlZCBieSBBcm1hw6tsIEd1w6luZWF1LikNCg0KICDigKIgRml4IGEgYnVnIGluIGAt LXJhbmRvbS0qJyB3aGljaCBjb3VsZCBjYXVzZSBNZW5oaXIgdG8gZGl2ZXJnZSBpZiB0aGUNCiAg ICBncmFtbWFyIHVzZXMgdGhlIGBlcnJvcicgdG9rZW4uDQoNCiAg4oCiIFdhcm4gaWYgYSB0ZXJt aW5hbCBzeW1ib2wgaXMgbmFtZWQgYEVycm9yJy4gVGhpcyBjcmVhdGVzIGEgbmFtZQ0KICAgIGNs YXNoIGluIHRoZSBwdWJsaWMgaW50ZXJmYWNlIG9mIHRoZSBnZW5lcmF0ZWQgcGFyc2VyLg0KDQog IOKAoiBNZW5oaXIgbm93IHJlcXVpcmVzIE9DYW1sIDQuMDMuMCAoaW5zdGVhZCBvZiA0LjAyLjMp IGFuZCBEdW5lIDIuOC4wDQogICAgKGluc3RlYWQgb2YgMi4wLjApLg0KDQoNCkx3dCA1LjUuMCwg THd0X2RvbWFpbiAwLjEuMCwgTHd0X3JlYWN0LjEuMS41DQrilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZANCg0K ICBBcmNoaXZlOg0KICA8aHR0cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90L2Fubi1sd3QtNS01LTAt bHd0LWRvbWFpbi0wLTEtMC1sd3QtcmVhY3QtMS0xLTUvODg5Ny8xPg0KDQoNClJhcGhhw6tsIFBy b3VzdCBhbm5vdW5jZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIEl0IGlzIG15IHBsZWFzdXJlIHRv IGFubm91bmNlIHRoZSByZWxlYXNlIG9mIEx3dCB2ZXJzaW9uIDUuNS4wLA0KICBMd3RfZG9tYWlu IHZlcnNpb24gMC4xLjAsIEx3dF9yZWFjdCB2ZXJzaW9uIDEuMS41LCBMd3RfcHB4IHZlcnNpb24N CiAgMi4wLjMgYW5kIEx3dF9wcHhfbGV0IHZlcnNpb24gNS41LjAuDQoNCiAgPGh0dHBzOi8vZ2l0 aHViLmNvbS9vY3NpZ2VuL2x3dC9yZWxlYXNlcy90YWcvNS41LjA+DQoNCiAgQWxsIHRob3NlIHBh Y2thZ2VzIGNhbiBiZSBpbnN0YWxsZWQgdmlhIG9wYW0gYXMgdXN1YWwuDQoNCg0KOnJvdGF0aW5n X2xpZ2h0OiAgRGVwcmVjYXRpb24NCuKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKV jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjA0KDQog IE9uZSBub3RhYmxlIGNoYW5nZSBpcyB0aGUgZGVwcmVjYXRpb24gb2YgYEx3dF9tYWluLnlpZWxk JyBhbmQNCiAgYEx3dF91bml4LnlpZWxkJy4gSXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlIGBMd3Qu cGF1c2UnIGluc3RlYWQuDQoNCg0KOnJvY2tldDogIEx3dF9kb21haW46IGFuIGludGVyZmFjZSB0 byBtdWx0aWNvcmUgcGFyYWxsZWxpc20NCuKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKV jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKV jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKV jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjA0KDQogIEFub3RoZXIgbm90YWJsZSBjaGFu Z2UgaXMgdGhlIGFkZGl0aW9uIG9mIHRoZSBMd3RfZG9tYWluIHBhY2thZ2UuIFRoaXMNCiAgcGFj a2FnZSBpbmNsdWRlcyBhIHNpbmdsZSBtb2R1bGUgYEx3dF9kb21haW4nIHdpdGggZnVuY3Rpb25z IHRvDQogIGV4ZWN1dGUgc29tZSBjb21wdXRhdGlvbnMgaW4gcGFyYWxsZWwsIHVzaW5nIHRoZSBm ZWF0dXJlcyBvZiBNdWx0aWNvcmUNCiAgT0NhbWwuIFRoZSBwYWNrYWdlIHJlcXVpcmVzIGFuIE9D YW1sIGNvbXBpbGVyIHdpdGggZG9tYWlucyBzdXBwb3J0IHRvDQogIGluc3RhbGwuDQoNCiAgQ29k ZSBmb3IgdGhpcyBwYWNrYWdlIGlzIHRoZSB3b3JrIG9mIEBzdWRoYSB3aXRoIHJldmlld3MgYW5k IHBhY2thZ2luZw0KICBmcm9tIEx3dCBjb250cmlidXRvcnMuDQoNCg0KT3RoZXIgY2hhbmdlcw0K 4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWMDQoNCiAgVGhlIGZ1bGwgbGlz dCBvZiBjaGFuZ2VzIGlzIGF2YWlsYWJsZSBpbiB0aGUgW0NIQU5HRVMgZmlsZV0uDQoNCg0KW0NI QU5HRVMgZmlsZV0gPGh0dHBzOi8vZ2l0aHViLmNvbS9vY3NpZ2VuL2x3dC9ibG9iLzUuNS4wL0NI QU5HRVM+DQoNCg0KT0NhbWwncyBDSSBpcyBncmFkdWFsbHkgbW92aW5nIHRvIEdpdEh1YiBBY3Rp b25zDQrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZlOg0KICA8aHR0 cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90L2Fubi1vY2FtbHMtY2ktaXMtZ3JhZHVhbGx5LW1vdmlu Zy10by1naXRodWItYWN0aW9ucy84OTAyLzE+DQoNCg0KU29yYSBNb3JpbW90byBhbm5vdW5jZWQN CuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgA0KDQogIFRoZSBPQ2FtbCB0ZWFtIHN0YXJ0ZWQgc3dpdGNoaW5nIHRvIEdp dEh1YiBBY3Rpb25zIGxhc3QgeWVhciBmb3Igc29tZQ0KICBvZiB0aGUgb2ZmaWNpYWwgT0NhbWwg cmVwb3NpdG9yaWVzLiBBbHNvLCB3ZSBoYXZlIHJlbGVhc2VkIHNvbWUgQ0kNCiAgcmVsYXRlZCBz dHVmZiwgc3VjaCBhcyBzZXR1cC1vY2FtbCwgdG8gdGhlIGNvbW11bml0eS4gU29tZSBPQ2FtbA0K ICBoYWNrZXJzIGFsc28ga25vdyB0aGF0IENJIGluIHRoZSBPQ2FtbCBjb21tdW5pdHkgaXMgZ3Jh ZHVhbGx5DQogIHN3aXRjaGluZyB0byBHaXRIdWIgQWN0aW9ucyBub3dhZGF5cy4NCg0KICBIb3dl dmVyLCB3aGF0IGdyYWR1YWxseSBiZWNhbWUgYSBwcm9ibGVtIHdoZW4gd2Ugc3RhcnRlZCBzd2l0 Y2hpbmcgd2FzDQogIHRoYXQgdGhlIG51bWJlciBvZiBjb25jdXJyZW50IGpvYnMgdGhhdCBjb3Vs ZCBydW4gaW4gYSBmcmVlIGFjY291bnQgb24NCiAgR2l0SHViIHdhcyBub3QgZW5vdWdoIGZvciBv dXIgYWN0aXZlbmVzcy4NCg0KICBPbmUgb2YgdGhlIG1ham9yIHBhaW4gcG9pbnRzIGZvciBjb21w aWxlciBjb250cmlidXRvcnMgaXMgdGhhdCB0aGUNCiAgd2FpdCB0aW1lIGZvciBDSSB0byBjb21w bGV0ZSwgd2hpY2ggaXMgdW5yZWxhdGVkIHRvIHRoZSBhY3R1YWwgYnVpbGQsDQogIGlzIHRvbyBs b25nLiBIb3dldmVyLCB0aGlzIGhhcyBiZWVuIGEgcGFpbiBwb2ludCBpbiBhbGwgc2VydmljZXMs IGV2ZW4NCiAgYmVmb3JlIEdpdEh1YiBBY3Rpb25zLg0KDQogIFRoZSBHaXRIdWIgdGVhbSBkaWQg dGhlaXIgYmVzdCB0byBoZWxwIHVzIG1ha2UgaXQgYmV0dGVyLiBBcyBhIHJlc3VsdCwNCiAgdGhl eSBvZmZlcmVkIHRvIHVwZ3JhZGUgdGhlIE9DYW1sIG9yZ2FuaXphdGlvbidzIHBsYW4gdG8gdGhl IHRlYW0gcGxhbg0KICBmb3IgZnJlZSwgd2hpY2ggbWVhbnMgdGhhdCB3ZSBjYW4gbm93IGJlbmVm aXQgZnJvbSBhIHJhbmdlIG9mDQogIGZlYXR1cmVzLCBpbmNsdWRpbmcgYWNjZXNzIHRvIDN4IG1v cmUgY29uY3VycmVudCBydW5uZXJzIHRoYW4gYmVmb3JlLg0KDQogIOKAoiBBYm91dCB0ZWFtIHBs YW46DQogICAgPGh0dHBzOi8vZG9jcy5naXRodWIuY29tL2VuL2FjdGlvbnMvbGVhcm4tZ2l0aHVi LWFjdGlvbnMvdXNhZ2UtbGltaXRzLWJpbGxpbmctYW5kLWFkbWluaXN0cmF0aW9uPg0KICDigKIg Q29uY3VycmVuY3kvcGxhbjoNCiAgICA8aHR0cHM6Ly9kb2NzLmdpdGh1Yi5jb20vZW4vZ2V0LXN0 YXJ0ZWQvbGVhcm5pbmctYWJvdXQtZ2l0aHViL2dpdGh1YnMtcHJvZHVjdHMjZ2l0aHViLXRlYW0+ DQoNCiAgV2Ugd291bGQgbGlrZSB0byB0aGFuayBHaXRIdWIgZm9yIHN1cHBvcnRpbmcgb3VyIHRl YW0gYW5kIEFobWVkIEJpbGFsLA0KICB3aG8gc3VwcG9ydGVkIHRoaXMgZWZmb3J0Lg0KDQoNCkhv dyB0byBjb21iaW5lIDMgbW9uYWRzOiBBc3luYy9Md3QsIEVycm9yIGFuZCBTdGF0ZT8NCuKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkA0KDQogIEFyY2hpdmU6DQogIDxo dHRwczovL2Rpc2N1c3Mub2NhbWwub3JnL3QvaG93LXRvLWNvbWJpbmUtMy1tb25hZHMtYXN5bmMt bHd0LWVycm9yLWFuZC1zdGF0ZS84OTA2Lzk+DQoNCg0KRGVlcCBpbiB0aGlzIHRocmVhZCwgSXZh biBHb3RvdmNoaXRzIHNhaWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIFRoZSBtb25hZHMgbGlicmFyeSBwcm92 aWRlcyB0aGUgdHJhbnNmb3JtZXJzIGZvciBzb21lIHdlbGwta25vd24NCiAgbW9uYWRzLiBBbGwg dGhlc2UgbW9uYWRzIGhhdmUgYSBtb3JlIG9yIGxlc3Mgc3RhbmRhcmQgaW1wbGVtZW50YXRpb24s DQogIG9mZmVyaW5nIHRoZSBzYW1lIHBlcmZvcm1hbmNlIGFzIGFueSBvdGhlciBtb25hZGljIGxp YnJhcnkgY2FuDQogIG9mZmVyLiBMaWtlIHRoZXJlIGlzIG5vIGJldHRlciB3YXkgb2YgaW1wbGVt ZW50aW5nIHRoZSBzdGF0ZSBtb25hZA0KICBvdGhlciB0aGFuIGEgZnVuY3Rpb24uIFdlIGhhdmUg ZXhwZXJpbWVudGVkIGEgbG90IHdpdGggZGlmZmVyZW50DQogIHBlcmZvcm1hbmNlIG9wdGltaXph dGlvbnMsIHN1Y2ggYXMgYm94aW5nIGFuZCB1bmJveGluZyBpdCBhbmQgaW5saW5pbmcNCiAgdmFy aW91cyBvcGVyYXRvcnMsIGFuZCBrZWVwIGV4cGVyaW1lbnRpbmcgdG8gZ2V0IHRoZSBtYXhpbXVt IGZyb20gdGhlDQogIGN1cnJlbnQgY29tcGlsZXIuIEluIEJBUCwgd2UgaGVhdmlseSB1c2UgdGhl IG1vbmFkcyBsaWJyYXJ5LCBmaXJzdCBvZg0KICBhbGwgZm9yIG91ciBba25vd2xlZGdlIHJlcHJl c2VudGF0aW9uIGFuZCByZWFzb25pbmcgZW5naW5lXSwgd2hpY2ggaXMNCiAgdGhlIGZvdW5kYXRp b24gZm9yIGFsbCBCQVAgYW5hbHlzZXMuIFdlIGFsc28gdXNlIGl0IGZvciBbZW11bGF0aW5nDQog IGJpbmFyeSBwcm9ncmFtc10uICBUaGUgcmljaCBpbnRlcmZhY2UgaXMgaGVyZSB0byBtYWtlIG91 ciBsaWZlIGVhc2llcg0KICBhbmQgbW9yZSBjb21mb3J0YWJsZSB3aGVuIHdlIHVzZSBtb25hZHMu IEl0IGRlZmluaXRlbHkgY29tZXMgZm9yIGZyZWXCuQ0KICBhcyB0aGUgbnVtYmVyIG9mIGZ1bmN0 aW9ucyBkb2Vzbid0IGFmZmVjdCB0aGUgcGVyZm9ybWFuY2Ugb2YgdGhlDQogIHVuZGVybHlpbmcg bW9uYWQuDQoNCiAgQnV04oCmIHRoZXJlIGlzIGFsd2F5cyBhIGJ1dCA6KSBTdGFja2luZyBtb25h ZHMgdXNpbmcgYSB0cmFuc2Zvcm1lciBkb2VzDQogIGhhdmUgYSBwcmljZS4gRXZlbiB3aXRoIHRo ZSBmbGFtYmRhIGNvbXBpbGVyLiBUaGUgbGF0dGVyIGlzIGRvaW5nIGFuDQogIGV4Y2VsbGVudCBq b2Igb2YgdW5zdGFja2luZyB0aGVtIGFuZCBlbGltaW5hdGluZyB0aGUgb3ZlcmhlYWQgb2YNCiAg aGF2aW5nIGEgY2hhaW4gb2YgbW9uYWRzLiBCdXQgb3VyIGxhdGVzdCBleHBlcmltZW50cyBzaG93 IHRoYXQgYQ0KICBjdXN0b20tbWFkZSBtb25hZCAoc3RpbGwgd2l0aCB0aGUgbW9uYWRzIGxpYnJh cnkpIHBlcmZvcm1zIGJldHRlcg0KICB1bmRlciBlaXRoZXIgYnJhbmNoIG9mIHRoZSBjb21waWxl ci4gV2UgW2hhdmUgcmV3cml0dGVuIG91ciBtYWluDQogIG1vbmFkc10gdGhhdCB3ZXJlIHJlbHlp bmcgb24gdHJhbnNmb3JtZXJzIGFuZCBnb3QgZnJvbSAyMCUgdG8gNTAlDQogIHBlcmZvcm1hbmNl IGltcHJvdmVtZW50LiBCdXQgdGhhdCBpcyBub3QgdG8gc2F5IHRoYXQgdGhlIG1vbmFkcw0KICBs aWJyYXJ5IGl0c2VsZiBpcyBzbG93IG9yIHRoYXQgd2UncmUgbm90IHVzaW5nIGl0LCBpdCBpcyB0 byBzYXkgdGhhdA0KICB0aGVyZSBhcmUgb3RoZXIgb3B0aW9ucyB0byB0cmFuc2Zvcm1lcnMgdGhh dCBtaWdodCB3b3JrIGluIHNvbWUgY2FzZXMuDQogIFNlZSB0aGUgbGlua2VkIFBSIGlmIHlvdSB3 YW50IHRvIGxlYXJuIHRoZSB0cmljay4NCg0KICDCueKBviBQcm92aWRlZCB0aGF0IHdlIGlnbm9y ZSB0aGUgc2l6ZSBvZiB0aGUgZXhlY3V0YWJsZSwgZS5nLiwgbGlua2luZw0KICB0aGUgY29yZV9r ZXJuZWwgbGlicmFyeSByZXN1bHRzIGluIGEgcXVpdGUgbGFyZ2UgYmluYXJ5LCB3aGljaCBtYXkN CiAgaW5jcmVhc2UgdGhlIHN0YXJ0dXAgdGltZS4gSW5zaWduaWZpY2FudGx5LCBidXQgaW4gc29t ZSB1c2UgY2FzZXMsIGl0DQogIG1pZ2h0IGJlIGEgc2lnbmlmaWNhbnQgZmFjdG9yLg0KDQoNCltr bm93bGVkZ2UgcmVwcmVzZW50YXRpb24gYW5kIHJlYXNvbmluZyBlbmdpbmVdDQo8aHR0cHM6Ly9i aW5hcnlhbmFseXNpc3BsYXRmb3JtLmdpdGh1Yi5pby9iYXAvYXBpL21hc3Rlci9iYXAta25vd2xl ZGdlL0JhcF9rbm93bGVkZ2UvS25vd2xlZGdlL2luZGV4Lmh0bWw+DQoNCltlbXVsYXRpbmcgYmlu YXJ5IHByb2dyYW1zXQ0KPGh0dHBzOi8vYmluYXJ5YW5hbHlzaXNwbGF0Zm9ybS5naXRodWIuaW8v YmFwL2FwaS9tYXN0ZXIvYmFwLXByaW11cy9CYXBfcHJpbXVzL1N0ZC9pbmRleC5odG1sPg0KDQpb aGF2ZSByZXdyaXR0ZW4gb3VyIG1haW4gbW9uYWRzXQ0KPGh0dHBzOi8vZ2l0aHViLmNvbS9CaW5h cnlBbmFseXNpc1BsYXRmb3JtL2JhcC9wdWxsLzEzNjE+DQoNCg0KSXZhbiBHb3RvdmNoaXRzIHRo ZW4gc2FpZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgQXMgaXQgd2FzIGFscmVhZHkgc3VnZ2Vz dGVkLCB5b3UgY2FuIHVzZSBbbW9uYWQgdHJhbnNmb3JtZXJzXSwgdG8NCiAgY29tcG9zZSBzZXZl cmFsIG1vbmFkcyBpbnRvIGEgc2luZ2xlIG1vbmFkLiBBcyBhIHNob3ctY2FzZSwgd2Ugd2lsbA0K ICB1c2UgdGhlIFttb25hZHNdIGxpYnJhcnkgKGRpc2NsYWltZXIsIEkgYW0gYW4gYXV0aG9yIG9m IHRoaXMgbGlicmFyeSksDQogIHdoaWNoIHlvdSBjYW4gaW5zdGFsbCB3aXRoDQoNCiAg4pSM4pSA 4pSA4pSA4pSADQogIOKUgiBvcGFtIGluc3RhbGwgbW9uYWRzDQogIOKUlOKUgOKUgOKUgOKUgA0K DQogIEl0IG9mZmVycyBtb3N0IG9mIHRoZSB3ZWxsLWtub3duIG1vbmFkcyBpbiBhIGZvcm0gb2Yg YSBtb25hZA0KICB0cmFuc2Zvcm1lciwgd2hpY2ggaW4gdGVybXMgb2YgT0NhbWwsIGlzIGEgZnVu Y3RvciB0aGF0IHRha2VzIGEgbW9uYWQNCiAgYW5kIHJldHVybnMgYSBuZXcgbW9uYWQgdGhhdCBl bnJpY2hlcyBpdCB3aXRoIHNvbWUgbmV3IGJlaGF2aW9yLiBGb3INCiAgZXhhbXBsZSwgdG8gbWFr ZSBhIG5vbi1kZXRlcm1pbmlzdGljIGVycm9yIG1vbmFkLCB3ZSBjYW4gZG8NCiAgYE1vbmFkLkxp c3QuTWFrZShNb25hZC5SZXN1bHQuRXJyb3IpJyBhbmQgZ2V0IGEgbW9uYWRpYyBzdHJ1Y3R1cmUN CiAgKGkuZS4sIGEgbW9kdWxlIHRoYXQgaW1wbGVtZW50cyB0aGUgW01vbmFkLlNdIGludGVyZmFj ZSkgdGhhdCBpcyBib3RoDQogIGEgbGlzdCBtb25hZCBhbmQgYW4gZXJyb3IgbW9uYWQuICBUaGUg c21hbGwgY2F2ZWF0IGlzIHRoYXQgdGhlDQogIG9wZXJhdGlvbnMgb2YgdGhlIHdyYXBwZWQgbW9u YWQsIHRoZSBlcnJvciBtb25hZCBpbiBvdXIgY2FzZSwgYXJlIG5vdA0KICBhdmFpbGFibGUgZGly ZWN0bHksIHNvIHdlIGhhdmUgdG8gX2xpZnRfIHRoZW0sIGUuZy4sDQogIOKUjOKUgOKUgOKUgOKU gA0KICDilIIgbGV0IGZhaWwgcCA9IGxpZnQgQEAgTW9uYWQuUmVzdWx0LkVycm9yLmZhaWwgcA0K ICDilJTilIDilIDilIDilIANCiAgU28gdGhhdCBpbiB0aGUgZW5kLCB0aGUgZnVsbCBpbXBsZW1l bnRhdGlvbiBvZiB0aGUgdHJhbnNmb3JtZWQgbW9uYWQNCiAgc3RpbGwgcmVxdWlyZXMgc29tZSBi b2lsZXJwbGF0ZSBjb2RlLA0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgbW9kdWxlIExpc3RF ID0gc3RydWN0DQogIOKUgiAgIHR5cGUgJ2EgdCA9ICdhIGxpc3QgTW9uYWQuUmVzdWx0LkVycm9y LnQNCiAg4pSCICAgaW5jbHVkZSBNb25hZC5MaXN0Lk1ha2UoTW9uYWQuUmVzdWx0LkVycm9yKQ0K ICDilIIgICBsZXQgZmFpbCBwID0gbGlmdEBATW9uYWQuUmVzdWx0LkVycm9yLmZhaWwgcA0KICDi lIIgICAoKiBhbmQgc28gb24gZm9yIGVhY2ggb3BlcmF0aW9uIHRoYXQgaXMgc3BlY2lmaWMgdG8g dGhlIHdyYXBwZWQgbW9uYWQgKikNCiAg4pSCIGVuZA0KICDilJTilIDilIDilIDilIANCg0KICBO b3csIGxldCdzIHRyeSB3cmFwcGluZyB0aGUgTHd0IG1vbmFkIGludG8gdGhlIHN0YXRlLiBXZSBk b24ndCB3YW50IHRvDQogIGFkZCB0aGUgRXJyb3IgbW9uYWQgYmVjYXVzZSBMd3QgaXMgYWxyZWFk eSB0aGUgZXJyb3IgbW9uYWQgYW5kIGFkZGluZw0KICBhbiBleHRyYSBsYXllciBvZiBlcnJvcnMg bW9uYWQgaXMgbm90IHdoYXQgd2Ugd2FudC4gRmlyc3Qgb2YgYWxsLCB3ZQ0KICBuZWVkIHRvIGFk YXB0IHRoZSBgTHd0JyBtb25hZCB0byB0aGUgYE1vbmFkLlMnIGludGVyZmFjZSwgZS5nLiwNCiAg 4pSM4pSA4pSA4pSA4pSADQogIOKUgiBtb2R1bGUgTHd0TSA9IHN0cnVjdA0KICDilIIgICB0eXBl ICdhIHQgPSAnYSBMd3QudA0KICDilIIgICBpbmNsdWRlIE1vbmFkLk1ha2Uoc3RydWN0DQogIOKU giAgICAgICB0eXBlICdhIHQgPSAnYSBMd3QudA0KICDilIIgICAgICAgbGV0IHJldHVybiA9IEx3 dC5yZXR1cm4NCiAg4pSCICAgICAgIGxldCBiaW5kID0gTHd0LmJpbmQNCiAg4pSCICAgICAgIGxl dCBtYXAgeCB+ZiA9IEx3dC5tYXAgZiB4DQogIOKUgiAgICAgICBsZXQgbWFwID0gYEN1c3RvbSBt YXANCiAg4pSCICAgICBlbmQpDQogIOKUgiBlbmQNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgSWYg d2Ugd2FudCB0byBrZWVwIHRoZSBzdGF0ZSB0eXBlIG1vbm9tb3JwaGljLCB0aGVuIHdlIHdpbGwg bmVlZCBhDQogIG1vZHVsZSBmb3IgaXQuIFN1cHBvc2UgeW91ciBzdGF0ZSBpcyByZXByZXNlbnRl ZCBhcywNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBtb2R1bGUgU3RhdGUgPSBzdHJ1Y3QNCiAg 4pSCICAgdHlwZSB0ID0gc3RyaW5nIE1hcC5NKFN0cmluZykudA0KICDilIIgZW5kDQogIOKUlOKU gOKUgOKUgOKUgA0KDQogIE5vdywgd2UgY2FuIHVzZSBpdCB0byBidWlsZCBvdXIgYFN0YXRlKEx3 dCknIFJ1c3NpYW4gZG9sbCwNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBtb2R1bGUgSU8gPSBz dHJ1Y3QNCiAg4pSCICAgaW5jbHVkZSBNb25hZC5TdGF0ZS5UMShTdGF0ZSkoTHd0TSkNCiAg4pSC ICAgaW5jbHVkZSBNb25hZC5TdGF0ZS5NYWtlKFN0YXRlKShMd3RNKQ0KICDilIIgDQogIOKUgiAg ICgqIGxldCdzIGxpZnQgW3JlYWRdIGFzIGFuIGV4YW1wbGUgKikNCiAg4pSCICAgbGV0IHJlYWQg ZmQgYnVmIG9mcyBsZW4gPQ0KICDilIIgICAgIGxpZnQgKEx3dF91bml4LnJlYWQgZmQgYnVmIG9m cyBsZW4pDQogIOKUgiBlbmQNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgVGhlIGBNb25hZC5TdGF0 ZS5UMScgZnVuY3RvciBpcyB1c2VkIHRvIGNyZWF0ZSB0aGUgdHlwZXMgZm9yIHRoZQ0KICBnZW5l cmF0ZWQgbW9uYWQuIFlvdSBjYW4gd3JpdGUgdGhlbSBtYW51YWxseSwgb2YgY291cnNlLCBsaWtl IGFzIHdlDQogIGRpZCBpbiB0aGUgTGlzdChFcnJvcikgZXhhbXBsZSwgYnV0IHRoZSB0eXBlIGdl bmVyYXRpbmcgbW9kdWxlcyBhcmUNCiAgaGVyZSBmb3IgdGhlIGNvbnZlbmllbmNlwrkNCg0KICBO b3csIGxldCdzIGdldCBiYWNrIHRvIHRoZSBwcm9ibGVtIG9mIHRoZSBsaWZ0aW5nLiBJdCBsb29r cyB0ZWRpb3VzIHRvDQogIGltcG9zc2libGUgdG8gbGlmdCBldmVyeSBvcGVyYXRpb24gZnJvbSBM d3QuICBDb21tb25seSwgd2UgdHJ5IHRvIHB1dA0KICB0aGUgc21hbGxlciBtb25hZCBpbnNpZGUs IHRvIG1pbmltaXplIHRoZSB3b3JrLCBidXQgaXQgZG9lc24ndCB3b3JrDQogIHdpdGggTHd0IGFz IHRoZSBsYXR0ZXIgaXMgbm90IGEgdHJhbnNmb3JtZXIuIFNvIHdoYXQgaXMgdGhlIHNvbHV0aW9u Pw0KICBGb3IgbWUsIHRoZSBzb2x1dGlvbiBpcyB0byBub3QgbGlmdCB0aGUgb3BlcmF0aW9ucyBh dCBhbGwsIGJ1dA0KICBpbnN0ZWFkLCBkZWZpbmUgeW91ciBJTyBhYnN0cmFjdGlvbiBhbmQgaGlk ZSB0aGF0IGl0IGlzIHVzaW5nIEx3dA0KICB1bmRlcm5lYXRoIHRoZSBob29kLiBUaGlzIHdpbGwg bWFrZSB0aGUgY29kZSB0aGF0IHVzZXMgdGhpcyBuZXcNCiAgYWJzdHJhY3Rpb24gbW9yZSBnZW5l cmljIGFuZCBsZXNzIGVycm9yLXByb25lIHNvIHRoYXQgaXQgY2FuIGZvY3VzIG9uDQogIHRoZSBi dXNpbmVzcyBsb2dpYyBhbmQgdGhlIGltcGxlbWVudGF0aW9uIGRldGFpbHMgY291bGQgYmUgaGlk ZGVuDQogIGluc2lkZSB0aGUgbW9uYWQgaW1wbGVtZW50YXRpb24uIFRoaXMgaXMgd2hhdCB0aGUg bW9uYWRzIGFyZSBmb3IsDQogIGFueXdheS4NCg0KICDCueKBviBXZSBvbWl0IHRoZSB0eXBlcyBm cm9tIHRoZSBvdXRwdXQgb2YgdGhlIGBNYWtlJyBmdW5jdG9yIHNpbmNlIGZvciBhDQogIGxvbmcg dGltZSBPQ2FtbCBkaWRuJ3QgYWxsb3cgdGhlIHJlcGV0aXRpb24gb2YgdHlwZXMgaW4gYSBzdHJ1 Y3R1cmUgc28NCiAgaGF2aW5nIHRoZSB0eXBlcyBpbiBpdCB3aWxsIHByZXZlbnQgdXMgZnJvbSBj b21wb3NpbmcgdmFyaW91cyBmbGF2b3JzDQogIG9mIG1vbmFkcyB1c2luZyBgaW5jbHVkZScuIEl0 IGlzIGFsc28gYSBsb25nLXRpbWUgY29udmVudGlvbiB3aWRlbHkNCiAgdXNlZCBpbiBtYW55IE9D YW1sIGxpYnJhcmllcywgaW5jbHVkaW5nIENvcmUgYW5kIEFzeW5jLiBBIGNvbnZlbnRpb24NCiAg dGhhdCB3ZSBwcm9iYWJseSBkb24ndCBuZWVkIGFueW1vcmUuDQoNCg0KW21vbmFkIHRyYW5zZm9y bWVyc10gPGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01vbmFkX3RyYW5zZm9ybWVyPg0K DQpbbW9uYWRzXQ0KPGh0dHBzOi8vYmluYXJ5YW5hbHlzaXNwbGF0Zm9ybS5naXRodWIuaW8vYmFw L2FwaS9tYXN0ZXIvbW9uYWRzL01vbmFkcy9TdGQvaW5kZXguaHRtbD4NCg0KW01vbmFkLlNdDQo8 aHR0cHM6Ly9iaW5hcnlhbmFseXNpc3BsYXRmb3JtLmdpdGh1Yi5pby9iYXAvYXBpL21hc3Rlci9t b25hZHMvTW9uYWRzL1N0ZC9Nb25hZC9pbmRleC5odG1sPg0KDQoNCk9sZCBDV04NCuKVkOKVkOKV kOKVkOKVkOKVkOKVkA0KDQogIElmIHlvdSBoYXBwZW4gdG8gbWlzcyBhIENXTiwgeW91IGNhbiBb c2VuZCBtZSBhIG1lc3NhZ2VdIGFuZCBJJ2xsIG1haWwNCiAgaXQgdG8geW91LCBvciBnbyB0YWtl IGEgbG9vayBhdCBbdGhlIGFyY2hpdmVdIG9yIHRoZSBbUlNTIGZlZWQgb2YgdGhlDQogIGFyY2hp dmVzXS4NCg0KICBJZiB5b3UgYWxzbyB3aXNoIHRvIHJlY2VpdmUgaXQgZXZlcnkgd2VlayBieSBt YWlsLCB5b3UgbWF5IHN1YnNjcmliZQ0KICBbb25saW5lXS4NCg0KICBbQWxhbiBTY2htaXR0XQ0K DQoNCltzZW5kIG1lIGEgbWVzc2FnZV0gPG1haWx0bzphbGFuLnNjaG1pdHRAcG9seXRlY2huaXF1 ZS5vcmc+DQoNClt0aGUgYXJjaGl2ZV0gPGh0dHBzOi8vYWxhbi5wZXRpdGVwb21tZS5uZXQvY3du Lz4NCg0KW1JTUyBmZWVkIG9mIHRoZSBhcmNoaXZlc10gPGh0dHBzOi8vYWxhbi5wZXRpdGVwb21t ZS5uZXQvY3duL2N3bi5yc3M+DQoNCltvbmxpbmVdIDxodHRwOi8vbGlzdHMuaWR5bGwub3JnL2xp c3RpbmZvL2NhbWwtbmV3cy13ZWVrbHkvPg0KDQpbQWxhbiBTY2htaXR0XSA8aHR0cHM6Ly9hbGFu LnBldGl0ZXBvbW1lLm5ldC8+DQoNCg== --=-=-= Content-Type: text/html; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable OCaml Weekly News

OCaml Weekly News

Previous Week<= /a> Up Next Week

Hello

Here is the latest OCaml Weekly News, for the week of November 23 to 30, 20= 21.

opam 2.1.1, opam 2.0.10, and opam-depext 1.2

R. Boujbel announced

We are pleased to announce several minor releases: opam 2.0.10, opam 2.1.1= , and opam-depext 1.2.

The opam releases consist of backported fixes, while opam-depext has been adapted to be compatible with opam 2.1, to allow for workflows which need to maintain compatibility with opam 2.0. = With opam 2.1.1, if you export OPAMCLI=3D2.0 into your environment then workflows expecting o= pam 2.0 should now behave even more equivalently.

You'll find more information in the blog post .

OTOML 0.9.0 =E2=80=94 a compliant and flexible TOML parsing, m= anipulation, and pretty-printing library

Archive:

Daniil Baturin announced

A new 0.9.3 relase is available. Still not 1.0.0 just in case. The change I= 'm most glad I managed to make is that the lexer is now re-entrant and doesn't use any mutable state. Where can I appl= y for the "Designed for multicore OCaml" certification sticker? ;)

Breaking change in the functor interface

I found an oversight that took a breaking change to fix. It didn't break an= y package that was already in the OPAM repository, so I'm glad I noticed it before it caused anyone trouble.

My idea to make the functor take separate integer and float modules turned = out to be misguided: it wouldn't compose with Otoml.get_float ~strict:false and similar functions that = apply type conversions.

Logically, Otoml.get_float ~strict:false (Otoml.integer 5) sho= uld produce Otoml.TomlFloat 5.0. However, it means that get_float needs to know how to convert integers to float.= If integer and float types are in separate modules, that isn't possible.

So I combined both integers and floats in a single TomlNumber.= That way people who want to bring their own bignum libraries will have to write more code, but numbers will behave as they are= expected to in a dynamically typed format.

module BigNumber =3D struct
  type int =3D Z.t
  type float =3D Deci=
mal.t

  let int_of_string =3D Z.of_string
  let int_to_string =3D Z.to_string
  let int_of_boolean =
b =3D if b then Z.one else Z.<=
/span>zero
  let int_to_boolean =
n =3D (n <> Z.zero)

  (* Can't just reuse Decimal.to/of_string because their optional arguments
     would cause a signature mismatch. *)
  let float_of_string s =3D Decimal.of_string s

  (* Decimal.to_string uses "NaN" spelling
     while TOML requires all special float =
values to be lowercase. *)
  let float_to_string x =3D Decimal.to_string x |> =
String.lowercase_ascii
  let float_of_boolean if b then Decimal.=
one else Decimal.zero
  let float_to_boolean Decimal.z=
ero)

  let float_of_int =3D let int_of_float =3D end

module Otoml =3D Otom=
l.Base.Make (BigNumber) (Otoml.Base.StringDate)

The next release will likely be 1.0.0 for real.

New release of Fix

Fran=C3=A7ois Pottier announced

I am pleased to announce a new release of Fix, with several new modules contribued by Fr=C3=A9d=C3=A9ric Bour (thanks!).

In short, Fix is a toolkit that helps perform memoization and fixed point computations (including data flow analyses). More generally, it offers a number of basic algorithmic building blocks that can be useful in many circumstances.

opam update
opam install fix.20211125

Documentation can be found here:

Enjoy,

Fran=C3=A7ois Pottier
francois.pottier@inria.fr
http://cambium.inria.fr/~fpo= ttier/

2021/11/25

  • The new module CompactQueue offers a minimalist mutable FI= FO queue. It is comparable with OCaml's Queue module. In comparison with Queue, it uses a more compact internal representation: elements are stored contiguously in a circular array. This has a positive impact on performance: both time and memory consumption are reduced. This data structure is optimized for maximum throughput. (Contributed by Fr=C3=A9d=C3=A9ric Bour, reviewed by Fran=C3=A7= ois Pottier.)
  • The new functor DataFlow.ForCustomMaps offers a forward da= ta flow analysis that is tuned for greater performance. (Contributed by Fr=C3=A9d=C3=A9ric B= our, reviewed by Fran=C3=A7ois Pottier.)
  • The new module Indexing offers a safe API for manipulating= indices into fixed-size arrays. This API involves some dynamic checks as well as static type checks, thereby (hopefully) greatly reducing the risk of confusion in code that uses many arrays and many indices into these arrays. (Contributed by Fr=C3=A9d=C3=A9ric Bour, reviewed by Fran=C3=A7ois Pottier.)
  • In DataFlow, allow the function foreach_root (which is part of the signature DATA_FLOW_GRAPH) to call contribute x _ several times at a single root x<= /code>.

New release of Menhir (20211125)

Fran=C3=A7ois Pottier announced

I am pleased to announce a new release of Menhir, with an exciting contribution by Fr=C3=A9d=C3=A9ric Bour: a groundbreaking performance impro= vement in menhir --list-errors. This is made possible by an entirely new= reachability algorithm, which has been designed and implemented by Fr=C3=A9d=C3=A9ric, a= nd which is described in our paper "Faster Reachability Analysis for LR(1) Parsers". Th= is is the link to the paper:

http://cambium.inria.fr/~fpottier/publis/bour-pottier-reachability.= pdf

To install the new release, just type

opam update
opam install menhir.20211125

Enjoy!

Fran=C3=A7ois Pottier
Francois.Pottier@inria.fr
http://cambium.inria.fr/~fpo= ttier/

  • The command menhir --list-errors has been sped up by a fac= tor of up to x100, and requires up to x1000 less memory, thanks to a new LR(1) reachability algorithm, which has been designed and implemented by Fr=C3=A9d=C3=A9ric Bour.
  • Better document the restricted way in which the error toke= n must be used when using --strategy simplified. Menhir now checks that = this token is used only at the end of a production, and warns if this is not the case. (Better yet, our suggestion is to not use the error token at all!)
  • The $syntaxerror keyword is now forbidden when using --strategy simplified. This keyword will be entirely removed in the next release. Incidentally, we have just found out that it behaves differently under the code back-end and under the table back-end.
  • Disable OCaml warning 39 (unused rec flag) in the OCaml code produced by Menhir's code back-end. This does not affect the table back-end. (Reported by Arma=C3=ABl Gu=C3=A9neau.)
  • Fix a bug in --random-* which could cause Menhir to diverg= e if the grammar uses the error token.
  • Warn if a terminal symbol is named Error. This creates a n= ame clash in the public interface of the generated parser.
  • Menhir now requires OCaml 4.03.0 (instead of 4.02.3) and Dune 2.8.0 (instead of 2.0.0).

Lwt 5.5.0, Lwt_domain 0.1.0, Lwt_react.1.1.5

Rapha=C3=ABl Proust announced

It is my pleasure to announce the release of Lwt version 5.5.0, Lwt_domain = version 0.1.0, Lwt_react version 1.1.5, Lwt_ppx version 2.0.3 and Lwt_ppx_let version 5.5.0.

https://githu= b.com/ocsigen/lwt/releases/tag/5.5.0

All those packages can be installed via opam as usual.

:rotating_light: Deprecation

One notable change is the deprecation of Lwt_main.yield and Lwt_unix.yield. It is recommended to use Lwt.pause instead.

:rocket: Lwt_domain: an interface to multicore paral= lelism

Another notable change is the addition of the Lwt_domain package. This pack= age includes a single module Lwt_domain with functions to execute some computations in parallel, using the features= of Multicore OCaml. The package requires an OCaml compiler with domains support to install.

Code for this package is the work of @sudha with reviews and packaging from= Lwt contributors.

Other changes

The full list of changes is available in the CHANGES file.

OCaml's CI is gradually moving to GitHub Actions

Sora Morimoto announced

The OCaml team started switching to GitHub Actions last year for some of th= e official OCaml repositories. Also, we have released some CI related stuff, such as setup-ocaml, to the community.= Some OCaml hackers also know that CI in the OCaml community is gradually switching to GitHub Actions nowadays.

However, what gradually became a problem when we started switching was that= the number of concurrent jobs that could run in a free account on GitHub was not enough for our activeness.

One of the major pain points for compiler contributors is that the wait tim= e for CI to complete, which is unrelated to the actual build, is too long. However, this has been a pain point in al= l services, even before GitHub Actions.

The GitHub team did their best to help us make it better. As a result, they= offered to upgrade the OCaml organization's plan to the team plan for free, which means that we can now = benefit from a range of features, including access to 3x more concurrent runners than before.

We would like to thank GitHub for supporting our team and Ahmed Bilal, who = supported this effort.

How to combine 3 monads: Async/Lwt, Error and State?

Deep in this thread, Ivan Gotovchits said

The monads library provides the transformers for some well-known monads. Al= l these monads have a more or less standard implementation, offering the same performance as any other monadic= library can offer. Like there is no better way of implementing the state monad other than a function. We have e= xperimented a lot with different performance optimizations, such as boxing and unboxing it and inlining vari= ous operators, and keep experimenting to get the maximum from the current compiler. In BAP, we heavily use the monad= s library, first of all for our k= nowledge representation and reasoning engine, which is the foundation for all BA= P analyses. We also use it for emulating binary programs. The rich interface is here to make our life easier an= d more comfortable when we use monads. It definitely comes for free=C2=B9 as the number of functions doesn't affect t= he performance of the underlying monad.

But… there is always a but :) Stacking monads using a transformer do= es have a price. Even with the flambda compiler. The latter is doing an excellent job of unstacking them and elimi= nating the overhead of having a chain of monads. But our latest experiments show that a custom-made monad (still wit= h the monads library) performs better under either branch of the compiler. We have rewritten our main monads that we= re relying on transformers and got from 20% to 50% performance improvement. But that is not to say that the mo= nads library itself is slow or that we're not using it, it is to say that there are other options to transformers tha= t might work in some cases. See the linked PR if you want to learn the trick.

=C2=B9=E2=81=BE Provided that we ignore the size of the executable, e.g., l= inking the core_kernel library results in a quite large binary, which may increase the startup time. Insignificantly, b= ut in some use cases, it might be a significant factor.

Ivan Gotovchits then said

As it was already suggested, you can use monad transformers, to compose several monads= into a single monad. As a show-case, we will use the monads library (discla= imer, I am an author of this library), which you can install with

opam install monads

It offers most of the well-known monads in a form of a monad transformer, w= hich in terms of OCaml, is a functor that takes a monad and returns a new monad that enriches it with some new behavi= or. For example, to make a non-deterministic error monad, we can do Monad.List.Make(Monad.Result= .Error) and get a monadic structure (i.e., a module that implements the Monad.S interfac= e) that is both a list monad and an error monad. The small caveat is that the operations of the wrapped monad, the error monad in our case, are= not available directly, so we have to lift them, e.g.,

let fail p =3D lift @@ Monad.Result.Error.fail p

So that in the end, the full implementation of the transformed monad still = requires some boilerplate code,

module ListE =3D struct
  type 'a t =3D 'a list Monad.Result.Error.t
  include Monad.List.Make(Monad.Result.Error)
  let fail p =
=3D lift@@Monad.Result.Error.fail p
  (* and so on for each operation that is specific to the wrapped monad =
*)
end

Now, let's try wrapping the Lwt monad into the state. We don't want to add = the Error monad because Lwt is already the error monad and adding an extra layer of errors monad is not what we want. = First of all, we need to adapt the Lwt monad to the Monad.S interface, e.g.,

module LwtM =3D struct
  type 'a t =3D 'a Lw=
t.t
  include Monad.Make(struct
      type 'a t =3D 'a let return =3D =
Lwt.return
      let bind =3D Lw=
t.bind
      let map x ~f =3D Lwt.map f x
      let map =3D `Custom map
    end)
end

If we want to keep the state type monomorphic, then we will need a module f= or it. Suppose your state is represented as,

module State =3D struct
  type t =3D string M=
ap.M(String=
).t
end

Now, we can use it to build our State(Lwt) Russian doll,

module IO =3D struct
  include Monad.State.T1(State)(LwtM)
  include Monad.State.Make(State)(LwtM)

  (* let's lift [read] as an example *)<=
/span>
  let read fd =
buf =
ofs len =3D
    lift (Lwt_unix.read fd buf ofs l=
en)
end

The Monad.State.T1 functor is used to create the types for the= generated monad. You can write them manually, of course, like as we did in the List(Error) example, but the type generating = modules are here for the convenience=C2=B9

Now, let's get back to the problem of the lifting. It looks tedious to impo= ssible to lift every operation from Lwt. Commonly, we try to put the smaller monad inside, to minimize the work, but= it doesn't work with Lwt as the latter is not a transformer. So what is the solution? For me, the solution is to not = lift the operations at all, but instead, define your IO abstraction and hide that it is using Lwt underneath the hoo= d. This will make the code that uses this new abstraction more generic and less error-prone so that it can focus on t= he business logic and the implementation details could be hidden inside the monad implementation. This is what the m= onads are for, anyway.

=C2=B9=E2=81=BE We omit the types from the output of the Make = functor since for a long time OCaml didn't allow the repetition of types in a structure so having the types in it will prevent u= s from composing various flavors of monads using include. It is also a long-time convention widely used i= n many OCaml libraries, including Core and Async. A convention that we probably don't need anymore.

Old CWN

If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a loo= k at the archive or the <= a href=3D"https://alan.petitepomme.net/cwn/cwn.rss">RSS feed of the archive= s.

If you also wish to receive it every week by mail, you may subscribe online.

--=-=-=--