Attn: Development Editor, Latest OCaml Weekly News
Alan Schmitt <[email protected]> Tue, 30 Jun 2026 15:25:21 +0200
| Newsgroups | gmane.comp.lang.caml.inria |
|---|---|
| Message-ID | <[email protected]> |
--===-=-=
Content-Type: multipart/mixed; boundary="=-=-="
--=-=-=
Content-Type: multipart/alternative; boundary="==-=-="
--==-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
SGVsbG8NCg0KSGVyZSBpcyB0aGUgbGF0ZXN0IE9DYW1sIFdlZWtseSBOZXdzLCBmb3IgdGhlIHdl
ZWsgb2YgSnVuZSAyMyB0byAzMCwNCjIwMjYuDQoNClRhYmxlIG9mIENvbnRlbnRzDQrilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KTmV3IHJlbGVh
c2Ugb2YgU2VrDQpKc19vZl9vY2FtbCAvIFdhc21fb2Zfb2NhbWwgNi40DQpPY3NpcGVyc2lzdCAy
LjEuMDogdHlwZS1zYWZlIHBlcnNpc3RlbnQgcmVmZXJlbmNlcyB3aXRoIERlcml2aW5nDQpNb2R1
bGFyIGV4cGxpY2l0cyBpbiBwcmUtT0NhbWwgNS41DQpMUmdyZXAgMC45OiBCZXR0ZXIgc3ludGF4
IGVycm9ycyBmb3IgT0NhbWwgYW5kIE1lbmhpcg0KU3RhdGljIEFuYWx5c2lzIGZvciBPQ2FtbA0K
bmV3IHJlbGVhc2VzOiBNZXJsaW4gNS44IGFuZCBPQ2FtbC1MU1AgMS4yNy4wIHdpdGggc3VwcG9y
dCBmb3IgT0NhbWwgNS41DQpkdXJhcyAyLjEuMSDigJQgZGFpbHkgbm90ZXMgYXMgcGxhaW4gdGV4
dCBmaWxlcw0KU29mdHdhcmUgRW5naW5lZXIgYXQgTGV4aUZpIChQYXJpcykNCk93ZWJ2aWV3IDog
T0NhbWwgYmluZGluZyB0byB0aGUgd2VidmlldyBsaWJyYXJ5DQpPQ2FtbCBSdW50aW1lIE1lZXRp
bmc6IE1vbiwgSnVseSA2IEAgMTA6MDAgVVRDICgxMDowMCBMb25kb24vQ2FtYnJpZGdlLCAxMTow
MCBQYXJpcywgN3BtIFN5ZG5leSkNCk9sZCBDV04NCg0KDQpOZXcgcmVsZWFzZSBvZiBTZWsNCuKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkA0KDQog
IEFyY2hpdmU6IDxodHRwczovL2Rpc2N1c3Mub2NhbWwub3JnL3QvbmV3LXJlbGVhc2Utb2Ytc2Vr
LzE4MjgxLzE+DQoNCg0KRnJhbsOnb2lzIFBvdHRpZXIgYW5ub3VuY2VkDQrilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIANCg0KICBXZSBhcmUgcGxlYXNlZCB0byBhbm5vdW5jZSBhIG5ldyByZWxlYXNlIG9m
IFtTZWtdLCBhIGxpYnJhcnkgdGhhdA0KICBvZmZlcnMgZWZmaWNpZW50IGVwaGVtZXJhbCAobXV0
YWJsZSkgYW5kIHBlcnNpc3RlbnQgKGltbXV0YWJsZSkNCiAgL3NlcXVlbmNlLyBkYXRhIHN0cnVj
dHVyZXMsIHBsdXMgZWZmaWNpZW50IGNvbnZlcnNpb25zIGJldHdlZW4gdGhlc2UNCiAgdHdvIGZv
cm1zLg0KDQogIFRoaXMgbmV3IHJlbGVhc2UgaW50cm9kdWNlcyBvcHRpbWl6YXRpb25zIHRoYXQg
c3BlZWQgdXAgc2V2ZXJhbA0KICBvcGVyYXRpb25zLCBpbmNsdWRpbmcgcmFuZG9tIGFjY2VzcyAo
YGdldCcsIGBzZXQnKSwgc3BsaXR0aW5nLCBhbmQNCiAgY29uY2F0ZW5hdGlvbi4gRm9yIGRldGFp
bHMsIHBsZWFzZSBzZWUgdGhlIFtjaGFuZ2UgbG9nXS4NCg0KICDilIzilIDilIDilIDilIANCiAg
4pSCIG9wYW0gdXBkYXRlICYmIG9wYW0gaW5zdGFsbCBzZWsNCiAg4pSU4pSA4pSA4pSA4pSADQoN
CiAgSGFwcHkgaGFja2luZywgQXJ0aHVyIENoYXJndcOpcmF1ZCAmIEZyYW7Dp29pcyBQb3R0aWVy
Lg0KDQoNCltTZWtdIDxodHRwczovL2dpdGxhYi5pbnJpYS5mci9mcG90dGllci9zZWs+DQoNCltj
aGFuZ2UgbG9nXQ0KPGh0dHBzOi8vZ2l0bGFiLmlucmlhLmZyL2Zwb3R0aWVyL3Nlay8tL2Jsb2Iv
bWFzdGVyL0NIQU5HRVMubWQ/cmVmX3R5cGU9aGVhZHM+DQoNCg0KRnJhbsOnb2lzIFBvdHRpZXIg
bGF0ZXIgYWRkZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU
gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIExldCBtZSBhZGQg
dGhpcyBsaW5rIHRvIFt0aGUgZG9jdW1lbnRhdGlvbl0uDQoNCg0KW3RoZSBkb2N1bWVudGF0aW9u
XQ0KPGh0dHBzOi8vY2FtYml1bS5pbnJpYS5mci9+ZnBvdHRpZXIvc2VrL2RvYy9zZWsvU2VrLz4N
Cg0KDQpKc19vZl9vY2FtbCAvIFdhc21fb2Zfb2NhbWwgNi40DQrilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZlOg0KICA8aHR0cHM6Ly9kaXNjdXNzLm9jYW1s
Lm9yZy90L2Fubi1qcy1vZi1vY2FtbC13YXNtLW9mLW9jYW1sLTYtNC8xODI4Mi8xPg0KDQoNCkho
dWdvIGFubm91bmNlZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSADQoNCiAgSSdtIHBsZWFzZWQgdG8gYW5ub3VuY2UgdGhlIGpvaW50IHJlbGVhc2Ugb2YgKmpz
X29mX29jYW1sKiBhbmQNCiAgKndhc21fb2Zfb2NhbWwgNi40LjAqLg0KDQogIEpzX29mX29jYW1s
IGlzIGEgY29tcGlsZXIgZnJvbSBPQ2FtbCBieXRlY29kZSB0byBKYXZhU2NyaXB0LiBJdCBtYWtl
cw0KICBpdCBwb3NzaWJsZSB0byBydW4gcHVyZSBPQ2FtbCBwcm9ncmFtcyBpbiBKYXZhU2NyaXB0
IGVudmlyb25tZW50cyBsaWtlDQogIGJyb3dzZXJzIGFuZCBOb2RlLmpzLg0KDQogIFdhc21fb2Zf
b2NhbWwgaXMgYSBjb21waWxlciBmcm9tIE9DYW1sIGJ5dGVjb2RlIHRvIFdlYkFzc2VtYmx5LiBJ
dCBpcw0KICBoaWdobHkgY29tcGF0aWJsZSB3aXRoIGpzX29mX29jYW1sLCBzbyB5b3UgY2FuIGNv
bXBpbGUgeW91ciBwcm9ncmFtcw0KICB3aXRoIHdhc21fb2Zfb2NhbWwgaW5zdGVhZCBvZiBqc19v
Zl9vY2FtbCBhbmQgZXhwZXJpZW5jZSBvdmVyYWxsDQogIGJldHRlciBwZXJmb3JtYW5jZS4NCg0K
ICBNb3N0IHNpZ25pZmljYW50IGNoYW5nZXMgc2luY2UgdmVyc2lvbiA2LjM6DQoNCg0KVG9vbGNo
YWluDQrilYzilYzilYzilYzilYzilYzilYzilYzilYwNCg0KICDigKIgKk9DYW1sIDUuNS4wIHN1
cHBvcnQqLg0KICDigKIgKk94Q2FtbCBzdXBwb3J0Ki4NCg0KDQp3YXNtX29mX29jYW1sDQrilYzi
lYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYwNCg0KICDigKIgKldBU0kgMC4xIHN1
cHBvcnQqIOKAlCB0YXJnZXQgc3RhbmRhbG9uZSBXQVNJIHJ1bnRpbWVzICh3YXNtdGltZSBhbmQN
CiAgICAgZnJpZW5kcyksIG5vIEphdmFTY3JpcHQgaG9zdCByZXF1aXJlZC4NCiAg4oCiICpEeW5s
aW5rIGFuZCB0b3BsZXZlbCBzdXBwb3J0KiDigJQgdGhlIE9DYW1sIHRvcGxldmVsIG5vdyBydW5z
IG9uIHRoZQ0KICAgICBXYXNtIGJhY2tlbmQuDQogIOKAoiBBbiAqYWx0ZXJuYXRpdmUgZWZmZWN0
cyBiYWNrZW5kKiBiYXNlZCBvbiB0aGUgW1N0YWNrIFN3aXRjaGluZw0KICAgIHByb3Bvc2FsXS4N
CiAg4oCiICpQdXJlLVdhc20genN0ZCBhbmQgQkxBS0UyYiog4oCUIHVubWFyc2hhbGxpbmcgY29t
cHJlc3NlZCB2YWx1ZXMgYW5kDQogICAgIGBEaWdlc3QuQkxBS0UyezUxMiwyNTYsMTI4fScgbm8g
bG9uZ2VyIG5lZWQgdGhlIEphdmFTY3JpcHQgc2hpbXMsDQogICAgIHNvIHRoZXkgd29yayB1bmRl
ciBXQVNJIHRvby4NCiAg4oCiIFRoZSBsZWdhY3kgYG51bScgbGlicmFyeSBub3cgd29ya3Mgb24g
V2FzbSAodGhlIGBuYXQnIHByaW1pdGl2ZXMNCiAgICB3ZXJlIG5vLW9wIHN0dWJzKS4NCg0KDQpb
U3RhY2sgU3dpdGNoaW5nIHByb3Bvc2FsXQ0KPGh0dHBzOi8vZ2l0aHViLmNvbS9XZWJBc3NlbWJs
eS9zdGFjay1zd2l0Y2hpbmc+DQoNCg0KTGlicmFyeSDigJQgbmV3IHdlYiBBUElzDQrilYzilYzi
lYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzi
lYwNCg0KICDigKIgKmBQcm9taXNlJyBtb2R1bGUqIOKAlCB0eXBlLXNhZmUgYmluZGluZ3MgdG8g
SlMgcHJvbWlzZXMsIHdpdGggKkx3dA0KICAgICBpbnRlcm9wKiAoYEpzX29mX29jYW1sX2x3dC5Q
cm9taXNlLnt0b19sd3Qsb2ZfbHd0fScpIGFuZA0KICAgICBQcm9taXNlLXR5cGVkIGBEb21faHRt
bCcgYmluZGluZ3MuDQogIOKAoiAqYEZldGNoJyArIGBBYm9ydCcgbW9kdWxlcyog4oCUIHRoZSBG
ZXRjaCBBUEkgd2l0aCB0eXBlZA0KICAgICBgQWJvcnRDb250cm9sbGVyfi9+QWJvcnRTaWduYWwn
IGNhbmNlbGxhdGlvbi4NCiAg4oCiICpgRG9tX3N2ZycgYWxpZ25lZCB3aXRoIFNWRyAyKiwgdGhl
ICpwb3BvdmVyIEFQSSosDQogICAgICpgSW50bC5SZWxhdGl2ZVRpbWVGb3JtYXQnKiwgYSBuZXcg
KmBQZXJmb3JtYW5jZScgbW9kdWxlKiwNCiAgICAgYWRkaXRpb25hbCBgQ29uc29sZScgYmluZGlu
Z3MsIGFuZCBtYW55IG1vcmUgYERvbV9odG1sJyBiaW5kaW5ncy4NCg0KDQpCdWcgZml4ZXMNCuKV
jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjA0KDQogIOKAoiBBIGxhcmdlIG51bWJlciBvZiBidWcg
Zml4ZXMgYWNyb3NzIHRoZSBjb21waWxlciwgcnVudGltZSwgbGlicmFyeQ0KICAgIGJpbmRpbmdz
LCBhbmQgUFBYLg0KDQoNCuKaoO+4jyBCcmVha2luZyBjaGFuZ2VzDQrilYzilYzilYzilYzilYzi
lYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYwNCg0KICBBIGZldyBjaGFuZ2Vz
IGFyZSBzb3VyY2UtaW5jb21wYXRpYmxlIOKAlCBtb3N0bHkgdG8gZml4IGluY29ycmVjdA0KICBi
aW5kaW5ncyBhbmQgYmVoYXZpb3Ig4oCUIGFuZCBtYXkgcmVxdWlyZSB1cGRhdGluZyBleGlzdGlu
ZyBjb2RlLiBTZWUNCiAgdGhlIFttaWdyYXRpb24gZ3VpZGVdLg0KDQogIFNlZSB0aGUgW2RvY3Vt
ZW50YXRpb25dIGFuZCB0aGUgW2Z1bGwgY2hhbmdlbG9nXS4NCg0KDQpbbWlncmF0aW9uIGd1aWRl
XQ0KPGh0dHBzOi8vZ2l0aHViLmNvbS9vY3NpZ2VuL2pzX29mX29jYW1sL3dpa2kvVXBncmFkZS1m
cm9tLTYuMy4wLXRvLTYuNC4wPg0KDQpbZG9jdW1lbnRhdGlvbl0gPGh0dHBzOi8vb2NzaWdlbi5v
cmcvanNfb2Zfb2NhbWwvPg0KDQpbZnVsbCBjaGFuZ2Vsb2ddDQo8aHR0cHM6Ly9naXRodWIuY29t
L29jc2lnZW4vanNfb2Zfb2NhbWwvYmxvYi9tYXN0ZXIvQ0hBTkdFUy5tZD4NCg0KDQpWaW5jZW50
IEJhbGF0IHRoZW4gYWRkZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU
gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIFdlIHJlbGVhc2VkIEVsaW9t
IDEyLjEgYXQgdGhlIHNhbWUgdGltZSwgYnJpbmdpbmcgY29tcGF0aWJpbGl0eSB3aXRoDQogIGJv
dGgganNfb2Zfb2NhbWwgNi40IGFuZCBPQ2FtbCA1LjUuDQoNCg0KT2NzaXBlcnNpc3QgMi4xLjA6
IHR5cGUtc2FmZSBwZXJzaXN0ZW50IHJlZmVyZW5jZXMgd2l0aCBEZXJpdmluZw0K4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2ZToNCiAgPGh0dHBzOi8vZGlzY3Vzcy5vY2FtbC5vcmcv
dC9hbm4tb2NzaXBlcnNpc3QtMi0xLTAtdHlwZS1zYWZlLXBlcnNpc3RlbnQtcmVmZXJlbmNlcy13
aXRoLWRlcml2aW5nLzE4MjgzLzE+DQoNCg0KVmluY2VudCBCYWxhdCBhbm5vdW5jZWQNCuKUgOKU
gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU
gOKUgOKUgA0KDQogIFtPY3NpcGVyc2lzdF0gMi4xLjAgaXMgb3V0LiBQZXJzaXN0ZW50IHJlZmVy
ZW5jZXMsIHN0b3JlcyBhbmQgdGFibGVzDQogIGNhbiBub3cgYmUgc2VyaWFsaXNlZCB3aXRoIGBE
ZXJpdmluZ19Kc29uJyBpbnN0ZWFkIG9mIGBNYXJzaGFsJzogdGhlDQogIGRhdGEgaXMgaHVtYW4t
cmVhZGFibGUgaW4gdGhlIGRhdGFiYXNlIGFuZCBzdGFibGUgYWNyb3NzIE9DYW1sDQogIHZlcnNp
b25zLiBUaGUgbmV3IEFQSSBpcyBmdWxseSBiYWNrd2FyZCBjb21wYXRpYmxlLCBhbmQgT2NzaXBl
cnNpc3QNCiAgd29ya3MgYXMgYSBzdGFuZGFsb25lIGxpYnJhcnkgZm9yIGFueSBPQ2FtbCBwcm9n
cmFtIChubyBFbGlvbSBvcg0KICBPY3NpZ2VuIFNlcnZlciByZXF1aXJlZCkuDQoNCiAg4pSM4pSA
4pSA4pSA4pSADQogIOKUgiB0eXBlIHVzZXIgPSB7IG5hbWUgOiBzdHJpbmc7IGFnZSA6IGludCB9
IFtAQGRlcml2aW5nIGpzb25dDQogIOKUgiANCiAg4pSCICgqIGEgcGVyc2lzdGVudCByZWZlcmVu
Y2UsIHN0b3JlZCBhcyByZWFkYWJsZSBKU09OICopDQogIOKUgiBsZXQgdmlzaXRzID0gT2NzaXBl
cnNpc3QuUmVmX2pzb24ucmVmIH5wZXJzaXN0ZW50OiJ2aXNpdHMiIFslanNvbjogaW50XSAwDQog
IOKUgiANCiAg4pSCIGxldCBjb3VudF92aXNpdCAoKSA9DQogIOKUgiAgIGxldCVsd3QgbiA9IE9j
c2lwZXJzaXN0LlJlZl9qc29uLmdldCB2aXNpdHMgaW4NCiAg4pSCICAgT2NzaXBlcnNpc3QuUmVm
X2pzb24uc2V0IHZpc2l0cyAobiArIDEpDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIEZ1bGwgYW5u
b3VuY2VtZW50Og0KICA8aHR0cHM6Ly9vY3NpZ2VuLm9yZy9ibG9nL3Bvc3RzL29jc2lwZXJzaXN0
LTIuMS4wLmh0bWw+DQoNCg0KW09jc2lwZXJzaXN0XSA8aHR0cHM6Ly9vY3NpZ2VuLm9yZy9vY3Np
cGVyc2lzdC8+DQoNCg0KTW9kdWxhciBleHBsaWNpdHMgaW4gcHJlLU9DYW1sIDUuNQ0K4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2ZToNCiAg
PGh0dHBzOi8vaW5ib3guY2kuZGV2L2NhbWwtbGlzdC82ZDVmMTE1Yy04NjZkLTRjYzAtYTEwMi03
MzY1Nzc3OGEwZTJAaW5yaWEuZnIvVC8+DQoNCg0Kb2xlZyBzYWlkDQrilIDilIDilIDilIDilIDi
lIDilIDilIDilIANCg0KICBPbmUgb2YgdGhlIG5vdGFibGUgZmVhdHVyZXMgb2YgdGhlIGp1c3Qg
YW5ub3VuY2VkIE9DYW1sIDUuNSBhcmUNCiAgbW9kdWxlLWRlcGVuZGVudCBmdW5jdGlvbnMsIGEu
ay5hLiBtb2R1bGFyIGV4cGxpY2l0cy4gSXQgaXMgYSB3ZWxjb21lDQogIGFkZGl0aW9uOiBpdCBs
ZXRzIHVzIGV4cHJlc3MgaGlnaGVyLXJhbmtlZCB0eXBlcyBpbiB0aGUgc2ltcGxlc3Qgd2F5LA0K
ICBhbmQgaXMgcGFydGljdWxhcmx5IGdvb2QgZm9yIHR5cGVkIHRhZ2xlc3MtZmluYWwgY29kZS4N
Cg0KICBJdCBzaG91bGQgYmUgbWVudGlvbmVkIGhvd2V2ZXIgdGhhdCBtb2R1bGFyIGV4cGxpY2l0
cyBjb3VsZCBiZSBkb25lDQogIGJlZm9yZSwgd2l0aCBsaXR0bGUgb3Igbm8gaGFzc2xlLiBQZXJo
YXBzIHRoZXJlIGlzIG1lcml0IHRvIHJlbWluZCBvZg0KICB0aGF0IG9sZCB0cmlja37igJMgZXNw
ZWNpYWxseSBiZWNhdXNlIGl0IHdvcmtzIGFsc28gd2l0aCBzdGF0aWNhbGx5DQogIHVua25vd24g
bW9kdWxlcyAod2hpY2ggYXJlIG91dCBvZiBzY29wZSBmb3IgT0NhbWwgNS41IG1vZHVsYXINCiAg
ZXhwbGljaXRzKS4NCg0KICBBcyB0aGUgcnVubmluZyBleGFtcGxlIHdlIHJlLXVzZSB0aGUgcHJl
dHR5LXByaW50aW5nIGV4YW1wbGUgaW4gdGhlDQogIE9DYW1sIDUuNSBhbm5vdW5jZW1lbnQgKGhl
cmVhZnRlciwgQW5uNTUpLg0KDQogIFdlIHN0YXJ0IGhvd2V2ZXIgd2l0aCBhIHNpbXBsZXIgZXhh
bXBsZTogcHJldHR5LXByaW50aW5nIGEgc2V0DQogIGdlbmVyYXRlZCBieSB0aGUgYFNldC5NYWtl
JyBmdW5jdG9yLiBUaGUgZXhhbXBsZSBmb2xsb3dzIHRoZSBwYXR0ZXJuDQogIG9mIHRoZSBwcF9t
YXAgZnVuY3Rpb24gZnJvbSBBbm41NS4gSXQgaXMgc2ltcGxlciB0aGFuIHByaW50aW5nIGEgbWFw
DQogIGJlY2F1c2UgaXQgaW52b2x2ZXMgbm8gaGlnaGVyLXJhbmsgdHlwZXMuDQoNCiAg4pSM4pSA
4pSA4pSA4pSADQogIOKUgiBsZXQgcHBfc2V0ICh0eXBlIGEgcykgDQogIOKUgiAgICAgICAobW9k
dWxlIE06IFNldC5TIHdpdGggdHlwZSBlbHQgPSBhIGFuZCB0eXBlIHQgPSBzKSANCiAg4pSCICAg
ICAgIChwcF9lbHQ6Rm9ybWF0LmZvcm1hdHRlci0+YS0+dW5pdCkgKHBwZjpGb3JtYXQuZm9ybWF0
dGVyKSAoc2V0OnMpID0gDQogIOKUgiAgIGlmIE0uaXNfZW1wdHkgc2V0IHRoZW4gRm9ybWF0LmZw
cmludGYgcHBmICLDuCIgZWxzZSANCiAg4pSCICAgbGV0IHBwX3NlcCBwcGYgKCkgPSBGb3JtYXQu
ZnByaW50ZiBwcGYgIixAICIgaW4gDQogIOKUgiAgIEZvcm1hdC5mcHJpbnRmIHBwZiAiQFt7QCAl
YUAgfUBdIiANCiAg4pSCICAgICAoRm9ybWF0LnBwX3ByaW50X3NlcSB+cHBfc2VwIHBwX2VsdCkg
KE0udG9fc2VxIHNldCkgDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIEl0IGlzIGFsbW9zdCBsaXRl
cmFsbHkgdGhlIHBwX21hcCBleGFtcGxlIGZyb20gQW5uNTUsIHdpdGggc2V0DQogIHN1YnN0aXR1
dGVkIGZvciBtYXAuIFRoZSBtYWluIGRpZmZlcmVuY2UgaXMgdHlwZSBhbm5vdGF0aW9ucy4gVGhp
cyBpcw0KICBub3QgYSBidWc6IEkgaW5zaXN0IG9uIHdyaXRpbmcgc2lnbmF0dXJlcyBvciBleHBs
aWNpdCB0eXBlIGFubm90YXRpb25zDQogIGZvciBhbGwgdG9wLWxldmVsIGRlZmluaXRpb25zIChl
eGNlcHQsIHBlcmhhcHMsIHRoZSBtb3N0IHRyaXZpYWwpLg0KDQogIFRoZSBhbm5vdGF0aW9ucyBj
b3VsZCBiZSBzaW1wbGlmaWVkIGlmIHdlIGludHJvZHVjZQ0KDQogIOKUjOKUgOKUgOKUgOKUgA0K
ICDilIIgdHlwZSAoJ2UsJ3MpIHNldCA9IChtb2R1bGUgU2V0LlMgd2l0aCB0eXBlIGVsdCA9ICdl
IGFuZCB0eXBlIHQgPSAncykNCiAg4pSCIHR5cGUgJ2EgcHJpbnRlciA9IEZvcm1hdC5mb3JtYXR0
ZXItPidhLT51bml0DQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIFRoZSBleGFtcGxlIHRoZW4gcmVh
ZHMNCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIGxldCBwcF9zZXQgOiB0eXBlIGUgcy4gKGUs
cykgc2V0IC0+IGUgcHJpbnRlciAtPiBzIHByaW50ZXIgPSANCiAg4pSCICAgZnVuIChtb2R1bGUg
TSkgcHBfZWx0IHBwZiBzZXQgLT4gKCogLi4uIGFzIGJlZm9yZSAuLi4gKikNCiAg4pSU4pSA4pSA
4pSA4pSADQoNCiAgVGhlIHNpZ25hdHVyZSB0ZWxscyBhdCBhIGdsYW5jZSB3aGF0IHBwX3NldCBp
cyBkb2luZyAod2hpY2ggaXMgb25lIG9mDQogIHRoZSBiZW5lZml0cyBvZiBzaWduYXR1cmVzOiBp
dCBpcyBub3QganVzdCBmb3IsIGFuZCBub3QgbWFpbmx5IGZvciwNCiAgdGhlIGNvbXBpbGVyLikN
Cg0KICBXZSBjYW4gdXNlIHBwX3NldCBqdXN0IGxpa2UgcHBfbWFwIHdhcyB1c2VkIGluIHRoZSBB
bm41NSBleGFtcGxlOg0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgbW9kdWxlIFN0cmluZ19z
ZXQgPSBTZXQuTWFrZShTdHJpbmcpIA0KICDilIIgDQogIOKUgiBsZXQgKCkgPSANCiAg4pSCICAg
bGV0IG0gPSBTdHJpbmdfc2V0Lm9mX2xpc3QgWyJaZXJvIjsgIlplcm8iOyAiT25lIjsgIlVuIl0g
aW4gDQogIOKUgiAgIGxldCBwcF9zdHIgPSBGb3JtYXQucHBfcHJpbnRfc3RyaW5nIGluIA0KICDi
lIIgICBGb3JtYXQucHJpbnRmICIlYUAuIiAocHBfc2V0IChtb2R1bGUgU3RyaW5nX3NldCkgcHBf
c3RyKSBtIA0KICDilJTilIDilIDilIDilIANCg0KICBPdXIgcmVuZGl0aW9uIG9mIG1vZHVsYXIg
ZXhwbGljaXRzIGV4dGVuZHMgYmV5b25kIHN0YXRpY2FsbHkga25vd24NCiAgbW9kdWxlcyBsaWtl
IFN0cmluZ19zZXQuIEZvciBleGFtcGxlLA0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgKCog
QWJzdHJhY3Qgc2V0IG9mIGVsZW1lbnRzIG9mIHR5cGVzICdlLiBUaGUgaW1wbGVtZW50YXRpb24g
aXMgYWJzdHJhY3QgKikNCiAg4pSCIA0KICDilIIgdHlwZSAnZSBhc2V0ID0gKG1vZHVsZSBTZXQu
UyB3aXRoIHR5cGUgZWx0ID0gJ2UpDQogIOKUgiANCiAg4pSCIGxldCBmIDogdW5pdCAtPiBpbnQg
YXNldCA9IGZ1biAoKSAtPiANCiAg4pSCICAgaWYgUmFuZG9tLmJvb2wgKCkgdGhlbiANCiAg4pSC
ICAgICAobW9kdWxlIFNldC5NYWtlKEludCkpIA0KICDilIIgICBlbHNlIA0KICDilIIgICAgICht
b2R1bGUgU2V0Lk1ha2Uoc3RydWN0IHR5cGUgdCA9IGludCANCiAg4pSCICAgICAgIGxldCBjb21w
YXJlIHggeSA9IC0gSW50LmNvbXBhcmUgeCB5IGVuZCkpDQogIOKUlOKUgOKUgOKUgOKUgA0KDQog
IFRoZSBmdW5jdGlvbiBmIHJhbmRvbWx5IHJldHVybnMgb25lIG9mIHR3byBkaXN0aW5jdCBTZXQN
CiAgaW1wbGVtZW50YXRpb25zICh0aGUgU2V0LnQgdHlwZXMgYXJlIG5vdCBjb21wYXRpYmxlKS4g
QXMgYW4NCiAgYXBwbGljYXRpb24sIHdlIHByaW50IGEgbGlzdCBvZiBpbnRlZ2VycyBhcyBhIHNl
dCAoYXV0b21hdGljYWxseQ0KICBzb3J0aW5nIGFuZCByZW1vdmluZyBkdXBsaWNhdGVzKToNCg0K
ICDilIzilIDilIDilIDilIANCiAg4pSCIGxldCBwcmludF9hc19zZXQgOiB0eXBlIGEuIGEgYXNl
dCAtPiBhIHByaW50ZXIgLT4gYSBsaXN0IHByaW50ZXIgID0gDQogIOKUgiAgIGZ1biAobW9kdWxl
IE0pIHBwIHBwZiBsc3QgLT4gDQogIOKUgiAgICAgcHBfc2V0IChtb2R1bGUgTSkgcHAgcHBmIChN
Lm9mX2xpc3QgbHN0KQ0KICDilIIgDQogIOKUgiBsZXQgXyA9IEZvcm1hdC5wcmludGYgIiVhQC4i
IA0KICDilIIgICAgIChwcmludF9hc19zZXQgKGYgKCkpIEZvcm1hdC5wcF9wcmludF9pbnQpIFsx
OzI7MzsxXQ0KICDilJTilIDilIDilIDilIANCg0KICBUaGUgcmVzdWx0IGlzIGluZGVlZCBlaXRo
ZXIgInsgMSwgMiwgMyB9IiBvciAieyAzLCAyLCAxIH0iLCBkZXBlbmRpbmcNCiAgb24gaG93IGRp
ZSBpcyBjYXN0Lg0KDQogIExldCB1cyBub3cgdGFja2xlIHRoZSBwcF9tYXAgZXhhbXBsZSBmcm9t
IEFubjU1LiBJdCBpcyBjaGFsbGVuZ2luZw0KICBiZWNhdXNlIG9mIHRoZSBoaWdoZXItcmFuayB0
eXBlIG9mIHRoZSBtYXAgdHlwZSAnYSBNYXAuUy50Lg0KDQogIEl0IGlzIHRlbXB0aW5nIHRvIGRl
ZmluZSB0aGUgbW9kdWxlIHR5cGUgYXMNCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIHR5cGUg
KCdrLCd2LCdtKSBtYXAgPSANCiAg4pSCICAgICAobW9kdWxlIE1hcC5TIHdpdGggdHlwZSBrZXkg
PSAnayBhbmQgdHlwZSAnYSB0ID0gJ20gY29uc3RyYWludCAnYSA9ICd2KQ0KICDilJTilIDilIDi
lIDilIANCg0KICBBbGFzLCBpdCBkb2Vzbid0IHdvcms6DQoNCiAg4pSM4pSA4pSA4pSA4pSADQog
IOKUgiAyIHwgICAgIChtb2R1bGUgTWFwLlMgd2l0aCB0eXBlIGtleSA9ICdrIGFuZCB0eXBlICdh
IHQgPSAnbSBjb25zdHJhaW50ICdhID0gJ3YpDQogIOKUgiAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICBeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl4N
CiAg4pSCIEVycm9yOiBTeW50YXggZXJyb3I6IGludmFsaWQgcGFja2FnZSB0eXBlOiBwYXJhbWV0
cml6ZWQgdHlwZXMgYXJlIG5vdCBzdXBwb3J0ZWQNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgUGFj
a2FnZSB0eXBlcyBhbmQgdGhlaXIgYHdpdGgnIGNvbnN0cmFpbnRzIGNvbWUgd2l0aCBtYW55DQog
IHJlc3RyaWN0aW9ucywgd2hpY2ggaXMgZGVlcGx5IHVuZm9ydHVuYXRlLg0KDQogIFdlIGhhdmUg
dG8gcmVzb3J0IHRvIGFuIGVuY29kaW5nOg0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgbW9k
dWxlIHR5cGUgbWFwcyA9IHNpZw0KICDilIIgICBpbmNsdWRlIE1hcC5TDQogIOKUgiAgIHR5cGUg
dg0KICDilIIgICB0eXBlIG10DQogIOKUgiAgIHZhbCBvZl9tdCA6IG10IC0+IHYgdA0KICDilIIg
ICB2YWwgdG9fbXQgOiB2IHQgLT4gbXQgDQogIOKUgiBlbmQNCiAg4pSCIHR5cGUgKCdrLCd2LCdt
KSBtYXAgPSANCiAg4pSCICAgICAobW9kdWxlIG1hcHMgd2l0aCB0eXBlIGtleSA9ICdrIGFuZCB0
eXBlIHYgPSAndiBhbmQgdHlwZSBtdCA9ICdtKQ0KICDilJTilIDilIDilIDilIANCg0KICBPbmUg
c2hvdWxkIG1lbnRpb24gdGhhdCB0aGlzIGlzIGEgc3RyaWN0bHkgbW9yZSBnZW5lcmFsIHR5cGUg
b2YgbWFwczoNCiAgaXQgc3VwcG9ydHMgc3BlY2lhbGl6ZWQgaW1wbGVtZW50YXRpb25zIGZvciBw
YXJ0aWN1bGFyIGNvbWJpbmF0aW9uIG9mDQogIGtleXMgYW5kIHZhbHVlcyAoZS5nLiwgaWYgJ3Yg
aXMgYm9vbCwgd2UgY2FuIHVzZSBTZXQgYXMgdGhlIHVuZGVybHlpbmcNCiAgc3RydWN0dXJlLikN
Cg0KICBUaGUgcHJldHR5LXByaW50ZXIgb2YgbWFwcyBpcyB0aGUgc2FtZSBhcyBpbiB0aGUgQW5u
NTUsIHdpdGggdHdvDQogIGFkZGl0aW9uczogdHdvIG9jY3VycmVuY2VzIG9mIE0ub2ZfdC4NCg0K
ICDilIzilIDilIDilIDilIANCiAg4pSCIGxldCBwcF9tYXAgOiB0eXBlIGsgdiBtLiAoayx2LG0p
IG1hcCAtPiBrIHByaW50ZXIgLT4gdiBwcmludGVyIC0+IG0gcHJpbnRlciA9IA0KICDilIIgICAg
IGZ1biAobW9kdWxlIE0pIHBwX2tleSBwcF92IHBwZiBzZXQgLT4gDQogIOKUgiAgIGlmIE0uaXNf
ZW1wdHkgKE0ub2ZfbXQgc2V0KSB0aGVuIEZvcm1hdC5mcHJpbnRmIHBwZiAiw7giIGVsc2UgDQog
IOKUgiAgIGxldCBwcF9zZXAgcHBmICgpID0gRm9ybWF0LmZwcmludGYgcHBmICIsQCAiIGluIA0K
ICDilIIgICBsZXQgcHBfYmluZGluZyBwcGYgKGssdikgPSBGb3JtYXQuZnByaW50ZiBwcGYgIkBb
JWFAID1AICVhQF0iIHBwX2tleSBrIHBwX3YgdiANCiAg4pSCICAgaW4gDQogIOKUgiAgIEZvcm1h
dC5mcHJpbnRmIHBwZiAiQFt7QCAlYUAgfUBdIiANCiAg4pSCICAgICAoRm9ybWF0LnBwX3ByaW50
X3NlcSB+cHBfc2VwIHBwX2JpbmRpbmcpIChNLnRvX3NlcSAoTS5vZl9tdCBzZXQpKSANCiAg4pSU
4pSA4pSA4pSA4pSADQoNCiAgSXQgYXBwbGllcyB0byBzdGF0aWNhbGx5ICp1bmtub3duKiBtb2R1
bGVzIGhvd2V2ZXIsIHVubGlrZSBwcF9tYXAgaW4NCiAgQW5uNTUNCg0KICDilIzilIDilIDilIDi
lIANCiAg4pSCIHR5cGUgKCdrLCd2KSBhbWFwID0gKG1vZHVsZSBtYXBzIHdpdGggdHlwZSBrZXkg
PSAnayBhbmQgdHlwZSB2ID0gJ3YpDQogIOKUgiANCiAg4pSCIGxldCBzdHJpbmdfbWFwIDogdHlw
ZSBhLiB1bml0IC0+IChzdHJpbmcsYSkgYW1hcCA9IGZ1biAoKSAtPiANCiAg4pSCICAgKG1vZHVs
ZSBzdHJ1Y3QNCiAg4pSCICAgICBpbmNsdWRlIE1hcC5NYWtlKFN0cmluZykgDQogIOKUgiAgICAg
dHlwZSB2ID0gYQ0KICDilIIgICAgIHR5cGUgbXQgPSB2IHQNCiAg4pSCICAgICBsZXQgb2ZfbXQg
PSBGdW4uaWQNCiAg4pSCICAgICBsZXQgdG9fbXQgPSBGdW4uaWQNCiAg4pSCICAgZW5kKQ0KICDi
lIIgDQogIOKUgiBsZXQgKCkgPSANCiAg4pSCICAgbGV0IG1kID0gc3RyaW5nX21hcCAoKSBpbg0K
ICDilIIgICBsZXQgbW9kdWxlIE0gPSAodmFsIChtZCA6IChzdHJpbmcsaW50KSBhbWFwKSkgaW4N
CiAg4pSCICAgbGV0IG0gPSBNLm9mX2xpc3QgWyJaZXJvIiwgMDsgIk9uZSIsIDFdIGluIA0KICDi
lIIgICBsZXQgcHBfc3RyID0gRm9ybWF0LnBwX3ByaW50X2ludCBpbiANCiAg4pSCICAgRm9ybWF0
LnByaW50ZiAiJWFALiIgDQogIOKUgiAgICAgKHBwX21hcCAobW9kdWxlIE0pIEZvcm1hdC5wcF9w
cmludF9zdHJpbmcgcHBfc3RyKSAoTS50b19tdCBtKQ0KICDilJTilIDilIDilIDilIANCg0KICBJ
IHNob3VsZCBtZW50aW9uIHRoYXQgdGhlIGZ1bmN0aW9ucyBsaWtlIHRvX210IGNvbWUgbmF0dXJh
bGx5IGluIGNhc2UNCiAgb2YgdGFnbGVzcy1maW5hbCBpbnRlcnByZXRlcnM6IHRoZXNlIGFyZSB0
aGUgb2JzZXJ2YXRpb24gZnVuY3Rpb25zLg0KICBGb3IgZXhhbXBsZToNCg0KICDilIzilIDilIDi
lIDilIANCiAg4pSCIG1vZHVsZSB0eXBlIGxjID0gc2lnDQogIOKUgiAgIHR5cGUgJ2EgcmVwcg0K
ICDilIIgICB2YWwgaW50IDogaW50IC0+IGludCByZXByDQogIOKUgiAgIHZhbCBsYW0gIDogKCdh
IHJlcHIgLT4gJ2IgcmVwcikgLT4gKCdhIC0+ICdiKSByZXByDQogIOKUgiAgIHZhbCBhcHAgOiAo
J2EgLT4gJ2IpIHJlcHIgLT4gKCdhIHJlcHIgLT4gJ2IgcmVwcikNCiAg4pSCICAgdHlwZSBvYnN0
DQogIOKUgiAgIHR5cGUgb2JzDQogIOKUgiAgIHZhbCBvYnNlcnZlIDogb2JzdCByZXByIC0+IG9i
cw0KICDilIIgZW5kDQogIOKUgiANCiAg4pSCIHR5cGUgKCdhLCdvYnMpIGxjID0gKG1vZHVsZSAo
bGMgd2l0aCB0eXBlIG9icyA9ICdvYnMgYW5kIHR5cGUgb2JzdCA9ICdhKSkNCiAg4pSCIA0KICDi
lIIgbGV0IGV4MSA6IHR5cGUgb2JzLiAoaW50LG9icykgbGMgLT4gb2JzID0gZnVuIChtb2R1bGUg
TSkgLT4gbGV0IG9wZW4gTSBpbg0KICDilIIgICBsZXQgdDEgPSBhcHAgKGxhbSAoZnVuIHggLT4g
eCkpIChpbnQgMSkNCiAg4pSCICAgaW4gb2JzZXJ2ZSB0MQ0KICDilJTilIDilIDilIDilIANCg0K
ICBJbiBjb25jbHVzaW9uLCBpdCB3b3VsZCBiZSBncmVhdCBpZiBvbmUgZGF5IHRoZSByZXN0cmlj
dGlvbnMgb24NCiAgcGFja2FnZSB0eXBlcyB3ZXJlIHJlbGF4ZWQuDQoNCg0KT2xpdmllciBOaWNv
bGUgYXNrZWQgYW5kIFNhbXVlbCBWaXZpZW4gcmVwbGllZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSADQoNCiAgICAgICAgVGhhbmtzIGZvciBwb2ludGluZyB0aGlzIG91dC4gRG9lcyB0aGlzIG1l
YW4gdGhhdCBtb2R1bGFyDQogICAgICAgIGV4cGxpY2l0cywgc3RyaWN0bHkgc3BlYWtpbmcsIGJy
aW5nIG5vIGFkZGl0aW9uYWwNCiAgICAgICAgZXhwcmVzc2l2aXR5IGJ1dCBvbmx5IGEgc2ltcGxl
ciB3YXkgdG8gZG8gdGhlc2UgdGhpbmdzPyBPcg0KICAgICAgICBhcmUgdGhlcmUgcHJvZ3JhbXMg
dGhhdCBjb3VsZCBiZSBleHByZXNzZWQgd2l0aCBtb2R1bGFyDQogICAgICAgIGV4cGxpY2l0cyBi
dXQgbm90IHdpdGggY29uc3RyYWluZWQgbW9kdWxlIHR5cGVzPw0KDQogIEluZGVlZC4gTW9kdWxh
ciBleHBsaWNpdCBkb2VzIG5vdCBhZGQgYW55IGV4cHJlc3NpdmVuZXNzIHRvIHRoZQ0KICBsYW5n
dWFnZSAoYW5kIGRvZXMgbm90IGltcGFjdCB0aGUgc291bmRuZXNzIG9mIHRoZSB0eXBlIHN5c3Rl
bSkuIEV2ZXJ5DQogIHByb2dyYW0gdGhhdCBjYW4gYmUgd3JpdHRlbiB1c2luZyBtb2R1bGFyIGV4
cGxpY2l0cyBjb3VsZCBoYXZlIGJlZW4NCiAgd3JpdHRlbiB3aXRoIGEgZnVuY3RvciBlbmNvZGVk
IGFzIGEgZmlyc3QtY2xhc3MgbW9kdWxlLg0KDQogIFdlIHByZXNlbnRlZCB0aGlzIGVuY29kaW5n
IGluIHNlY3Rpb24gMS41IG9mIHRoaXMgcGFwZXIgYWJvdXQgbW9kdWxhcg0KICBleHBsaWNpdHMg
OiA8aHR0cHM6Ly9oYWwuc2NpZW5jZS9oYWwtMDU0MjgxMzYvZG9jdW1lbnQ+DQoNCg0KTFJncmVw
IDAuOTogQmV0dGVyIHN5bnRheCBlcnJvcnMgZm9yIE9DYW1sIGFuZCBNZW5oaXINCuKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkA0KDQogIEFyY2hpdmU6DQogIDxo
dHRwczovL2Rpc2N1c3Mub2NhbWwub3JnL3QvbHJncmVwLTAtOS1iZXR0ZXItc3ludGF4LWVycm9y
cy1mb3Itb2NhbWwtYW5kLW1lbmhpci8xODI4Ni8xPg0KDQoNCkZyw6lkw6lyaWMgQm91ciBhbm5v
dW5jZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU
gOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIEhpIGV2ZXJ5b25lLA0KDQogIEkndmUganVzdCByZWxl
YXNlZCAqTFJncmVwIDAuOSosIGEgdG9vbCB0byBjdXN0b21pemUgdGhlIGVycm9yDQogIG1lc3Nh
Z2VzIG9mIE1lbmhpci1nZW5lcmF0ZWQgTFIgcGFyc2VycyBieSByZWFzb25pbmcgYWJvdXQgZmFp
bHVyZQ0KICBwYXRocy4NCg0KICBUaGUgZ29hbCBpcyB0byBtb3ZlIGZyb20gZ2VuZXJpYyAiU3lu
dGF4IGVycm9yIGF0IGxpbmUgWCIgbWVzc2FnZXMgdG8NCiAgbW9yZSBpbnR1aXRpdmUgZGlhZ25v
c3RpY3MgdGhhdCBwb2ludCB0byB0aGUgYWN0dWFsIHJvb3QgY2F1c2UuIEZvcg0KICBleGFtcGxl
LCBpZiB5b3UgYWNjaWRlbnRhbGx5IHB1dCBhIHNlbWljb2xvbiBpbiBhIGxvY2FsLWxldCBjaGFp
bjoNCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIGxldCB4ID0gNTsNCiAg4pSCIA0KICDilIIg
bGV0IHkgPSA2DQogIOKUgiANCiAg4pSCIGxldCB6ID0gNw0KICDilIIgXl5eDQogIOKUgiBFcnJv
cjogRXhwZWN0aW5nICdpbicgdG8gY29tcGxldGUgbG9jYWwtbGV0IGJpbmRpbmcuIA0KICDilIIg
SGludDogdGhpcyBtaWdodCBiZSBkdWUgdG8gdGhlIHNlbWljb2xvbiBsaW5lIDEsIGNoYXJhY3Rl
ciA5DQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIFdpdGhvdXQgTFJncmVwLCBPQ2FtbCB0eXBpY2Fs
bHkgcmVwb3J0cyBvbmx5IGEgc3ludGF4IGVycm9yIG9uIHRoZQ0KICBzdWJzZXF1ZW50IGBsZXQn
IGJpbmRpbmcuIFRoZSBjdXN0b21pemVkIHBhcnNlciBjYW4gaWRlbnRpZnkgdGhhdCB0aGUNCiAg
c2VtaWNvbG9uIGlzIHRoZSBsaWtlbHkgY3VscHJpdC4NCg0KICAqSG93IHlvdSBjYW4gaGVscCAo
ZmVlZGJhY2sgd2FudGVkISkqDQoNCiAgSSBhbSBsb29raW5nIGZvciB1c2VycyB0byBoZWxwIHN0
cmVzcy10ZXN0IHRoZSBjdXJyZW50IHNwZWNpZmljYXRpb25zDQogIGFuZCBpZGVudGlmeSB3aGVy
ZSBlcnJvciBtZXNzYWdlcyBhcmUgc3RpbGwgbGFja2luZy4NCg0KICAxLiAqSWYgeW91IHVzZSBP
Q2FtbDoqIEkndmUgcGF0Y2hlZCB0aGUgY29tcGlsZXIgdG8gdXNlIExSZ3JlcC4gUGxlYXNlDQog
ICAgIHRyeSBpdCB2aWEgb3BhbTogYG9wYW0gc3dpdGNoIGNyZWF0ZSA1LjQuMStscmdyZXAnICpQ
bGVhc2UgcmVwb3J0DQogICAgIGNhc2VzIHdoZXJlIHRoZSBlcnJvciBtZXNzYWdlcyBhcmUgY29u
ZnVzaW5nIG9yIHdoZXJlIHlvdSB3b3VsZA0KICAgICBsaWtlIHRvIHNlZSBhIG1vcmUgaGVscGZ1
bCBoaW50LioNCg0KICAyLiAqSWYgeW91IHVzZSBNZW5oaXI6KiBHaXZlIExSZ3JlcCBhIHRyeSBv
biB5b3VyIG93biBncmFtbWFycyBpZiB5b3UNCiAgICAgIHdhbnQgdG8gY3VzdG9taXplIGVycm9y
IG1lc3NhZ2VzLg0KDQogICAgIOKAoyBbR2VuZXJhbCBFeGFtcGxlc10NCiAgICAg4oCjIFtPQ2Ft
bCBFcnJvciBTcGVjaWZpY2F0aW9uc10NCg0KICBJbnRlZ3JhdGlvbiB3aXRoIE1lcmxpbiBpcyBh
bHNvIGNvbWluZyBzb29uIChbUFIgIzIwNzJdKS4NCg0KICBIdWdlIHRoYW5rcyB0byBAZnBvdHRp
ZXIsIEBqbWlkLCBUYXJpZGVzLCBhbmQgSmFuZSBTdHJlZXQgZm9yIHRoZWlyDQogIHN1cHBvcnQu
DQoNCiAgSGFwcHkgdGVzdGluZyENCg0KDQpbR2VuZXJhbCBFeGFtcGxlc10gPGh0dHBzOi8vZ2l0
aHViLmNvbS9mcG90dGllci9scmdyZXAtZXhhbXBsZT4NCg0KW09DYW1sIEVycm9yIFNwZWNpZmlj
YXRpb25zXQ0KPGh0dHBzOi8vZ2l0aHViLmNvbS9sZXQtZGVmL2xyZ3JlcC9ibG9iL21haW4vZXhh
bXBsZXMvb2NhbWwvcGFyc2VyL2Vycm9ycy5scmdyZXA+DQoNCltQUiAjMjA3Ml0gPGh0dHBzOi8v
Z2l0aHViLmNvbS9vY2FtbC9tZXJsaW4vcHVsbC8yMDcyPg0KDQoNClN0YXRpYyBBbmFseXNpcyBm
b3IgT0NhbWwNCuKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkA0KDQogIEFyY2hpdmU6DQogIDxodHRwczovL2Rp
c2N1c3Mub2NhbWwub3JnL3QvYmxvZy1zdGF0aWMtYW5hbHlzaXMtZm9yLW9jYW1sLzE4Mjg3LzE+
DQoNCg0KZmFudGF6aW8gYW5ub3VuY2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIANCg0KICBIaSBhbGwsDQoNCiAgSSB3cm90ZSBhIHNob3J0
IChhbmQgc2xpZ2h0bHkgb3BpbmlvbmF0ZWQpIHBpZWNlIG9uIHRoZSBzdGF0ZSBvZg0KICBzdGF0
aWMgYW5hbHlzaXMgdG9vbGluZyBmb3IgT0NhbWwuICBUaGUgZ29hbCBpcyB0byBwcm92aWRlIGFu
IG92ZXJ2aWV3DQogIG9mIGF2YWlsYWJsZSB0b29scywgd29ya3MgaW4gcHJvZ3Jlc3MsIGFuZCBt
aXNzaW5nIHBpZWNlcy4gTGV0IG1lIGtub3cNCiAgaWYgdGhlcmUgaXMgYSBzdGF0aWMgYW5hbHlz
aXMgdG9vbCB5b3UgdXNlIHRoYXQgaXMgbm90IG1lbnRpb25lZCwgb3INCiAgaWYgeW91IHdpc2gg
b25lIGV4aXN0ZWQuDQoNCiAgVGhhbmtzIQ0KDQogIDxodHRwczovL2ZhbnRhemlvLmV1L2FydGlj
bGVzL3N0YXRpY19hbmFseXNpc19vY2FtbC5odG1sPg0KDQoNCm5ldyByZWxlYXNlczogTWVybGlu
IDUuOCBhbmQgT0NhbWwtTFNQIDEuMjcuMCB3aXRoIHN1cHBvcnQgZm9yIE9DYW1sIDUuNQ0K4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2ZToN
CiAgPGh0dHBzOi8vZGlzY3Vzcy5vY2FtbC5vcmcvdC9hbm4tbmV3LXJlbGVhc2VzLW1lcmxpbi01
LTgtYW5kLW9jYW1sLWxzcC0xLTI3LTAtd2l0aC1zdXBwb3J0LWZvci1vY2FtbC01LTUvMTgyOTMv
MT4NCg0KDQp2ZHMgYW5ub3VuY2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIANCg0KICBJIGFtIGdsYWQgdG8gYW5ub3VuY2UgbmV3IHJlbGVhc2VzIG9mIE1lcmxpbiBh
bmQgT0NhbWwtTFNQIPCfp5kgIQ0KDQogIE1lcmxpbiBpcyBhbiBlZGl0b3Igc2VydmljZSB0aGF0
IHByb3ZpZGVzIG1vZGVybiBJREUgZmVhdHVyZXMgZm9yDQogIE9DYW1sIGFuZCBPQ2FtbC1MU1Ag
aXMgYSBmcm9udGVuZCBmb3IgTWVybGluIHRoYXQgc3BlYWtzIHdpdGggTFNQDQogIGNsaWVudHMu
DQoNCiAgVGhlcmUgYXJlIGEgZmV3IGJ1ZyBmaXhlcyBpbiB0aGVzZSBidXQgdGhlIG1haW4gZmVh
dHVyZSBpcyB0aGUgc3RhYmxlDQogIHN1cHBvcnQgZm9yIE9DYW1sIDUuNS4NCg0KICBGdWxsIGNo
YW5nZWxvZ3M6DQogIOKAoiA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL21lcmxpbi9ibG9iL21h
aW4vQ0hBTkdFUy5tZCNtZXJsaW4tNTg+DQogIOKAoiA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1s
L29jYW1sLWxzcC9ibG9iL21hc3Rlci9DSEFOR0VTLm1kIzEyNzA+DQoNCg0KZHVyYXMgMi4xLjEg
4oCUIGRhaWx5IG5vdGVzIGFzIHBsYWluIHRleHQgZmlsZXMNCuKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kA0KDQogIEFyY2hpdmU6DQogIDxodHRwczovL2Rpc2N1c3Mub2NhbWwub3JnL3QvYW5uLWR1cmFz
LTItMS0xLWRhaWx5LW5vdGVzLWFzLXBsYWluLXRleHQtZmlsZXMvMTgyOTkvMT4NCg0KDQpTZXJn
aXkgRHVyYXMgYW5ub3VuY2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KICAqZHVyYXMqIGlzIGEgY29tbWFuZC1s
aW5lIHRvb2wgZm9yIGRhaWx5IG5vdGVzIHN0b3JlZCBhcyBwbGFpbiB0ZXh0DQogICBmaWxlcyAo
YFlZWVkvTU0vWVlZWS1NTS1ERC5kbicpLiBObyBkYXRhYmFzZSwgbm8gZGFlbW9uLCBubw0KICAg
YmFja2dyb3VuZCBzZXJ2aWNlcy4NCg0KICB2Mi4xLjEgYWRkcyBgZHVyYXMgYnVpbGQnLCB3aGlj
aCBjb252ZXJ0cyBhIG5vdGUgY29sbGVjdGlvbiB0byBhDQogIHN0YXRpYyBIVE1MIHdlYnNpdGUu
IDcsMzAwIG5vdGVzIGluIFx+MjIwbXMsIHNpbmdsZS10aHJlYWRlZCwgbm8NCiAgY2FjaGluZy4g
Tm90ZXMgdXNlIFtzaWdsaW5lXSBmb3JtYXQg4oCUIGEgcGxhaW4tdGV4dCBzdHJ1Y3R1cmVkIG5v
dGF0aW9uDQogIHdoZXJlIHRoZSBsZWFkaW5nIGNoYXJhY3RlciBvZiBlYWNoIGxpbmUgZGVjbGFy
ZXMgaXRzIHR5cGUuDQoNCiAg4oCiIFNvdXJjZTogPGh0dHBzOi8vY29kZWJlcmcub3JnL2R1cmFz
L2R1cmFzPg0KICDigKIgSW5zdGFsbDogYG9wYW0gaW5zdGFsbCBkdXJhcycNCiAg4oCiIE1hbiBw
YWdlOiBgbWFuIGR1cmFzJw0KDQoNCltzaWdsaW5lXSA8aHR0cHM6Ly9jb2RlYmVyZy5vcmcvZHVy
YXMvc2lnbGluZT4NCg0KDQpTb2Z0d2FyZSBFbmdpbmVlciBhdCBMZXhpRmkgKFBhcmlzKQ0K4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2
ZToNCiAgPGh0dHBzOi8vZGlzY3Vzcy5vY2FtbC5vcmcvdC9qb2Itc29mdHdhcmUtZW5naW5lZXIt
YXQtbGV4aWZpLXBhcmlzLzE4MzA0LzE+DQoNCg0KTmljb2xhcyBPamVkYSBCYXIgYW5ub3VuY2Vk
DQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KICBEZWFyIGFsbCwNCg0KICBbTGV4aUZpXSBp
cyBoaXJpbmchIFdlIGFyZSBsb29raW5nIGZvciBhIGZ1bGwtdGltZSBTb2Z0d2FyZSBFbmdpbmVl
cg0KICB0byBqb2luIG91ciBjb3JlIGRldmVsb3BtZW50IHRlYW0uDQoNCiAgV2UgYXJlIHBhcnRp
Y3VsYXJseSBpbnRlcmVzdGVkIGluIGNhbmRpZGF0ZXMgd2l0aCBhIHN0cm9uZyBwcm9ncmFtbWlu
Zw0KICBiYWNrZ3JvdW5kLCBmb3IgZXhhbXBsZSB0aHJvdWdoIHByZXZpb3VzIGluZHVzdHJpYWwg
ZXhwZXJpZW5jZSwNCiAgY29udHJpYnV0aW9ucyB0byBvcGVuLXNvdXJjZSBwcm9qZWN0cywgb3Ig
c3Vic3RhbnRpYWwgcGVyc29uYWwNCiAgcHJvamVjdHMuDQoNCiAgTGV4aUZpIGhhcyBiZWVuIHVz
aW5nIE9DYW1sIGZvciBtb3JlIHRoYW4gMjUgeWVhcnPigJR3ZSB3ZXJlIHRoZSBmaXJzdA0KICBz
b2Z0d2FyZSBjb21wYW55IHRvIGJ1aWxkIG91ciBwcm9kdWN0cyBvbiBPQ2FtbOKAlGFuZCB3ZSBz
dGlsbCBpbXBsZW1lbnQNCiAgdGhlIHZhc3QgbWFqb3JpdHkgb2Ygb3VyIHN0YWNrIGluIE9DYW1s
LiBJZiB5b3UncmUgZXhjaXRlZCBhYm91dCB1c2luZw0KICBPQ2FtbCB0byBzb2x2ZSByZWFsLXdv
cmxkIGluZHVzdHJpYWwgcHJvYmxlbXMsIHdlIHdvdWxkIGxvdmUgdG8gaGVhcg0KICBmcm9tIHlv
dS4NCg0KICA8aHR0cHM6Ly93d3cubGV4aWZpLmNvbS9jYXJlZXJzL3NvZnR3YXJlX2VuZ2luZWVy
Lz4NCg0KICBXb3JrIGF0IExleGlGaSBzcGFucyBhIHdpZGUgcmFuZ2Ugb2YgcHJvamVjdHMgYWNy
b3NzIG11bHRpcGxlDQogIGRvbWFpbnMuIFdlIGFsc28gcmVtYWluIGFjdGl2ZWx5IGVuZ2FnZWQg
d2l0aCB0aGUgT0NhbWwgY29tbXVuaXR5IGFuZA0KICBzdHJpdmUgdG8gZ2l2ZSBiYWNrIGluIHZh
cmlvdXMgd2F5cywgaW5jbHVkaW5nIGZ1bmRpbmcgY29tbXVuaXR5DQogIHByb2plY3RzLCBoZWxw
aW5nIG1haW50YWluIHRoZSBPQ2FtbCBjb21waWxlciBhbmQgb3RoZXIgb3Blbi1zb3VyY2UNCiAg
cHJvamVjdHMsIGFuZCBwYXJ0aWNpcGF0aW5nIGluIGNvbmZlcmVuY2VzLg0KDQogIElmIHlvdSBo
YXZlIGFueSBxdWVzdGlvbnMsIHBsZWFzZSBkb24ndCBoZXNpdGF0ZSB0byByZWFjaCBvdXQgdG8g
bWUsDQogIGVpdGhlciBoZXJlIG9yIHByaXZhdGVseS4NCg0KICBDaGVlcnMsIE5pY29sYXMNCg0K
DQpbTGV4aUZpXSA8aHR0cHM6Ly93d3cubGV4aWZpLmNvbS8+DQoNCg0KT3dlYnZpZXcgOiBPQ2Ft
bCBiaW5kaW5nIHRvIHRoZSB3ZWJ2aWV3IGxpYnJhcnkNCuKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkA0KDQogIEFyY2hpdmU6DQogIDxodHRwczovL2Rpc2N1c3Mub2NhbWwub3JnL3Qvb3dlYnZp
ZXctb2NhbWwtYmluZGluZy10by10aGUtd2Vidmlldy1saWJyYXJ5LzE4MzA1LzE+DQoNCg0KS29y
a29ycmFuIGFubm91bmNlZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgSGkgZXZlcnlvbmUhIPCfkYsNCg0KICBJJ2QgbGlrZSB0
byBzaGFyZSBhIHNtYWxsIHByb2plY3QgSSd2ZSBiZWVuIHdvcmtpbmcgb246ICpvd2Vidmlldyos
IGENCiAgc2V0IG9mIE9DYW1sIGJpbmRpbmdzIGZvciBbd2Vidmlld10uDQoNCg0KW3dlYnZpZXdd
IDxodHRwczovL2dpdGh1Yi5jb20vd2Vidmlldy93ZWJ2aWV3Pg0KDQpXaGF0IGlzIHdlYnZpZXc/
DQrilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYzilYwNCg0KICBb
d2Vidmlld10gaXMgYSB0aW55LCBjcm9zcy1wbGF0Zm9ybSBsaWJyYXJ5IGZvciBidWlsZGluZyBk
ZXNrdG9wIEdVSXMNCiAgdXNpbmcgdGhlIG9wZXJhdGluZyBzeXN0ZW0ncyBidWlsdC1pbiB3ZWIg
ZW5naW5lIOKAlCBXZWJLaXQgb24gbWFjT1MsDQogIFdlYktpdEdUSyBvbiBMaW51eCwgYW5kIFdl
YlZpZXcyIG9uIFdpbmRvd3MuIEluc3RlYWQgb2Ygc2hpcHBpbmcgYQ0KICB3aG9sZSBicm93c2Vy
IGxpa2UgRWxlY3Ryb24sIHlvdSByZXVzZSB0aGUgc3lzdGVtIG9uZSwgc28geW91ciBhcHBzDQog
IHN0YXkgc21hbGwuIFlvdSBjcmVhdGUgYSB3aW5kb3csIHBvaW50IGl0IGF0IHNvbWUgSFRNTCAo
b3IgYSBVUkwpLCBhbmQNCiAgeW91IGNhbiBjYWxsIGJhY2sgYW5kIGZvcnRoIGJldHdlZW4gdGhl
IHBhZ2UncyBKYXZhU2NyaXB0IGFuZCB5b3VyDQogIGhvc3QgbGFuZ3VhZ2UuDQoNCg0KW3dlYnZp
ZXddIDxodHRwczovL2dpdGh1Yi5jb20vd2Vidmlldy93ZWJ2aWV3Pg0KDQoNClRoZSBnYXAgb3dl
YnZpZXcgZmlsbHMNCuKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKV
jOKVjOKVjOKVjOKVjOKVjOKVjOKVjA0KDQogIFdoYXQgbWFrZXMgd2VidmlldyByZWFsbHkgYXBw
ZWFsaW5nIGlzIGl0cyBlY29zeXN0ZW06IGl0IGFscmVhZHkgaGFzDQogIGJpbmRpbmdzIGluIGEg
KmxvdCogb2YgbGFuZ3VhZ2VzIOKAlCBHbyAodGhlIHJlZmVyZW5jZSBvbmUpLCBSdXN0LA0KICBQ
eXRob24sIEMjLCBOaW0sIFppZywgYW5kIG1hbnkgbW9yZS4gQXMgZmFyIGFzIEkgY291bGQgdGVs
bCwgdGhvdWdoLA0KICB0aGVyZSB3YXNuJ3Qgb25lIGZvciAqT0NhbWwqLg0KDQogIG93ZWJ2aWV3
IGlzIGFuIGF0dGVtcHQgdG8gZmlsbCB0aGF0IGdhcDogYSB0aGluIGJpbmRpbmcgdGhhdCBsZXRz
IHlvdQ0KICBkcml2ZSB3ZWJ2aWV3IGRpcmVjdGx5IGZyb20gT0NhbWwsIHdpdGggYSBuYXRpdmUg
YnJpZGdlIGJldHdlZW4gdGhlDQogIHBhZ2UncyBKYXZhU2NyaXB0IGFuZCB5b3VyIE9DYW1sIGZ1
bmN0aW9ucy4NCg0KDQpXaGF0IGl0IGxvb2tzIGxpa2UNCuKVjOKVjOKVjOKVjOKVjOKVjOKVjOKV
jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjA0KDQogIEEgY29tcGxldGUgYXBwIGlzIGFi
b3V0IHRlbiBsaW5lczoNCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIGxldCAoKSA9DQogIOKU
giAgIGxldCB3ID0gV2Vidmlldy5jcmVhdGUgKCkgaW4NCiAg4pSCICAgV2Vidmlldy5zZXRfdGl0
bGUgdyAiTXkgZmlyc3Qgb3dlYnZpZXcgYXBwIjsNCiAg4pSCICAgV2Vidmlldy5zZXRfc2l6ZSB3
IFx+d2lkdGg6NDgwIFx+aGVpZ2h0OjMyMCBXZWJ2aWV3LkhpbnRfbm9uZTsNCiAg4pSCICAgV2Vi
dmlldy5zZXRfaHRtbCB3DQogIOKUgiAgIHt8PCFkb2N0eXBlIGh0bWw+DQogIOKUgiAgICAgICA8
aHRtbD48Ym9keSBzdHlsZT0iZm9udC1mYW1pbHk6IHN5c3RlbS11aTsgdGV4dC1hbGlnbjogY2Vu
dGVyIj4NCiAg4pSCICAgICAgICAgPGgxPkhlbGxvIGZyb20gT0NhbWwg8J+RizwvaDE+DQogIOKU
giAgICAgICA8L2JvZHk+PC9odG1sPnx9Ow0KICDilIIgICBXZWJ2aWV3LnJ1biB3Ow0KICDilIIg
ICBXZWJ2aWV3LmRlc3Ryb3kgdw0KICDilJTilIDilIDilIDilIANCg0KICBBbmQgeW91IGNhbiBl
eHBvc2UgT0NhbWwgZnVuY3Rpb25zIHRvIHRoZSBwYWdlIOKAlCBoZXJlIGB3aW5kb3cuYWRkKGEs
DQogIGIpJyByZXR1cm5zIGEgSmF2YVNjcmlwdCBQcm9taXNlIHJlc29sdmVkIGZyb20gT0NhbWw6
DQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBXZWJ2aWV3LmJpbmQgdyAiYWRkIiAoZnVuIGlk
IHJlcSAtPg0KICDilIIgICBsZXQgcmVzdWx0ID0NCiAg4pSCICAgbWF0Y2ggU2NhbmYuc3NjYW5m
X29wdCByZXEgIlxbJWQsJWRcXSIgKGZ1biBhIGIgLT4gYSArIGIpIHdpdGgNCiAg4pSCICAgfCBT
b21lIG4gLT4gc3RyaW5nX29mX2ludCBuDQogIOKUgiAgIHwgTm9uZSAtPiAibnVsbCINCiAg4pSC
ICAgaW4NCiAg4pSCICAgV2Vidmlldy5yZXR1cm4gdyBpZCBcfmVycm9yOmZhbHNlIFx+cmVzdWx0
KQ0KICDilJTilIDilIDilIDilIANCg0KDQpUcnkgaXQNCuKVjOKVjOKVjOKVjOKVjOKVjA0KDQog
IOKUjOKUgOKUgOKUgOKUgA0KICDilIIgIyBSdW4gdGhlIGJ1bmRsZWQgZXhhbXBsZQ0KICDilIIg
Z2l0IGNsb25lIGh0dHBzOi8vZ2l0aHViLmNvbS9rb3Jrb3JyYW4vb3dlYnZpZXcuZ2l0DQogIOKU
giBjZCBvd2Vidmlldw0KICDilIIgZHVuZSBleGVjIGV4YW1wbGVzL2hlbGxvd3YuZXhlDQogIOKU
giANCiAg4pSCICMgT3IgcGluIGl0IGludG8geW91ciBvd24gcHJvamVjdA0KICDilIIgb3BhbSBw
aW4gYWRkIG93ZWJ2aWV3IGh0dHBzOi8vZ2l0aHViLmNvbS9rb3Jrb3JyYW4vb3dlYnZpZXcuZ2l0
DQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIFRoZW4ganVzdCBhZGQgYChsaWJyYXJpZXMgb3dlYnZp
ZXcud2VidmlldyknIHRvIHlvdXIgZHVuZSBmaWxlLiBUaGUNCiAgYHdlYnZpZXcuaCcgaGVhZGVy
IGlzIHZlbmRvcmVkLCBhbmQgdGhlIHBsYXRmb3JtLXNwZWNpZmljIEMrKyBmbGFncw0KICBhcmUg
ZGV0ZWN0ZWQgYXQgYnVpbGQgdGltZSAodmlhIGBwa2ctY29uZmlnJyBvbiBMaW51eCksIHNvIHRo
ZXJlJ3MNCiAgbm90aGluZyB0byB3aXJlIHVwIGJ5IGhhbmQuDQoNCg0KSG9uZXN0IHN0YXR1cyAm
IGEgcmVxdWVzdA0K4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM
4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWMDQoNCiAgVGhpcyBpcyBhICpjb21wYWN0IGJp
bmRpbmcgLyBzdGFydGluZyBwb2ludCosIG5vdCBhIGNvbXBsZXRlIGxpYnJhcnkNCiAgeWV0OiBz
b21lIHBpZWNlcyAoYHVuYmluZCcsIGBkaXNwYXRjaCcsIGZ1bGwgYmluZGluZyBtZW1vcnkNCiAg
bWFuYWdlbWVudCkgYXJlIGludGVudGlvbmFsbHkgbGVmdCBvdXQgZm9yIG5vdy4NCg0KICBJdCdz
IGFsc28gZGV2ZWxvcGVkIGFuZCB0ZXN0ZWQgbWFpbmx5IG9uICoqbWFjT1MqKi4gSSdkIGxvdmUg
ZmVlZGJhY2sNCiAgZnJvbSBwZW9wbGUgcnVubmluZyBpdCBvbiAqKkxpbnV4IGRpc3RyaWJ1dGlv
bnMqKiDigJQgZG9lcyBpdCBjb21waWxlLA0KICBkbyB0aGUgb3BhbSBgZGVwZXh0cycgcmVzb2x2
ZSwgZG9lcyB0aGUgYHdlYmtpdDJndGstNC4xJyBiYWNrZW5kDQogIGJlaGF2ZSBvbiB5b3VyIGRp
c3Rybz8NCg0KICBJc3N1ZXMgYW5kIFBScyBhcmUgdmVyeSB3ZWxjb21lLg0KDQogIFJlcG9zaXRv
cnk6IDxodHRwczovL2dpdGh1Yi5jb20va29ya29ycmFuL293ZWJ2aWV3Pg0KDQogIFRoYW5rcyBm
b3IgcmVhZGluZyDigJQgaGFwcHkgdG8gaGVhciB0aG91Z2h0cywgc3VnZ2VzdGlvbnMsIGFuZA0K
ICBlc3BlY2lhbGx5IExpbnV4IGJ1aWxkIHJlcG9ydHMhDQoNCg0KT0NhbWwgUnVudGltZSBNZWV0
aW5nOiBNb24sIEp1bHkgNiBAIDEwOjAwIFVUQyAoMTA6MDAgTG9uZG9uL0NhbWJyaWRnZSwgMTE6
MDAgUGFyaXMsIDdwbSBTeWRuZXkpDQrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZlOg0KICA8aHR0cHM6Ly9kaXNj
dXNzLm9jYW1sLm9yZy90L29jYW1sLXJ1bnRpbWUtbWVldGluZy1tb24tanVseS02LTEwLTAwLXV0
Yy0xMC0wMC1sb25kb24tY2FtYnJpZGdlLTExLTAwLXBhcmlzLTdwbS1zeWRuZXkvMTgzMTIvMT4N
Cg0KDQpUaW0gTWNHaWxjaHJpc3QgYW5ub3VuY2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KICBU
aGUgbmV4dCBPQ2FtbCBSdW50aW1lIE1lZXRpbmcgaXMgTW9uZGF5IEp1bHkgNnRoICgyMDI2LTA3
LTA2KSBhdA0KICAxMDowMCBVVEMgKDEwOjAwIExvbmRvbi9DYW1icmlkZ2UsIDExOjAwIFBhcmlz
LCA3cG0gU3lkbmV5KS4gVGhlDQogIGFnZW5kYSBub3RlcyBhcmUgaGVyZSA8aHR0cHM6Ly9oYWNr
bWQuaW8vQHRtY2dpbGNocmlzdC9TMVJ0T2J2V0dlPg0KICBlbWFpbCB0aW1AdGFyaWRlcy5jb20g
aWYgeW91IHdhbnQgYSBjYWxlbmRhciBpbnZpdGUuDQoNCiAgQXBwcm94aW1hdGVseSBldmVyeSBt
b250aCB3ZSBoYXZlIGFuIGluZm9ybWFsIG1lZXRpbmcgYmV0d2VlbiBPQ2FtbA0KICBkZXZlbG9w
ZXJzIHdpdGggYSBmb2N1cyBvbiB0aGUgbGFuZ3VhZ2UgcnVudGltZS9nYXJiYWdlIGNvbGxlY3Rv
ci4gVGhlDQogIG1lZXRpbmdzIGFyZSBmb3Igc2hhcmluZyB1bmRlcnN0YW5kaW5nIGFuZCBpZGVh
cywgbm90IGZvciBmb3JtYWwNCiAgcGxhbm5pbmcgcHVycG9zZXMuIFRoZXkgYXJlIG9wZW4gdG8g
YW55IGludGVyZXN0ZWQgZGV2ZWxvcGVyLg0KDQogIFByZXZpb3VzIG1lZXRpbmcgbm90ZXMgYXZh
aWxhYmxlIGluDQogIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvc3Vic3lzdGVtLW1lZXRpbmdz
Pg0KDQoNCk9sZCBDV04NCuKVkOKVkOKVkOKVkOKVkOKVkOKVkA0KDQogIElmIHlvdSBoYXBwZW4g
dG8gbWlzcyBhIENXTiwgeW91IGNhbiBbc2VuZCBtZSBhIG1lc3NhZ2VdIGFuZCBJJ2xsIG1haWwN
CiAgaXQgdG8geW91LCBvciBnbyB0YWtlIGEgbG9vayBhdCBbdGhlIGFyY2hpdmVdIG9yIHRoZSBb
UlNTIGZlZWQgb2YgdGhlDQogIGFyY2hpdmVzXS4NCg0KICBJZiB5b3UgYWxzbyB3aXNoIHRvIHJl
Y2VpdmUgaXQgZXZlcnkgd2VlayBieSBtYWlsLCB5b3UgbWF5IHN1YnNjcmliZQ0KICB0byB0aGUg
W2NhbWwtbGlzdF0uDQoNCiAgW0FsYW4gU2NobWl0dF0NCg0KDQpbc2VuZCBtZSBhIG1lc3NhZ2Vd
IDxtYWlsdG86YWxhbi5zY2htaXR0QHBvbHl0ZWNobmlxdWUub3JnPg0KDQpbdGhlIGFyY2hpdmVd
IDxodHRwczovL2FsYW4ucGV0aXRlcG9tbWUubmV0L2N3bi8+DQoNCltSU1MgZmVlZCBvZiB0aGUg
YXJjaGl2ZXNdIDxodHRwczovL2FsYW4ucGV0aXRlcG9tbWUubmV0L2N3bi9jd24ucnNzPg0KDQpb
Y2FtbC1saXN0XSA8aHR0cHM6Ly9zeW1wYS5pbnJpYS5mci9zeW1wYS9pbmZvL2NhbWwtbGlzdD4N
Cg0KW0FsYW4gU2NobWl0dF0gPGh0dHBzOi8vYWxhbi5wZXRpdGVwb21tZS5uZXQvPg0KDQo=
--==-=-=
Content-Type: text/html; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
<?xml version=3D"1.0" encoding=3D"utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns=3D"http://www.w3.org/1999/xhtml" lang=3D"en" xml:lang=3D"en">
<head>
<!-- 2026-06-30 Tue 14:00 -->
<meta http-equiv=3D"Content-Type" content=3D"text/html;charset=3Dutf-8" />
<meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=3D1"=
/>
<title>OCaml Weekly News</title>
<meta name=3D"generator" content=3D"Org Mode" />
<style type=3D"text/css">
#content { max-width: 60em; margin: auto; }
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #e6e6e6;
border-radius: 3px;
background-color: #f2f2f2;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: auto;
}
pre.src:before {
display: none;
position: absolute;
top: -8px;
right: 12px;
padding: 3px;
color: #555;
background-color: #f2f2f299;
}
pre.src:hover:before { display: inline; margin-top: 14px;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-authinfo::before { content: 'Authinfo'; }
pre.src-c:before { content: 'C'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'JavaScript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr {
font-size: smaller;
@supports (content: attr(data-linenr)) {
visibility: hidden;
&::before { content: attr(data-linenr); visibility: visible; }
}
}
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { }
</style>
<style type=3D"text/css">#table-of-contents h2 { display: none } .title { d=
isplay: none } .authorname { text-align: right }</style>
<style type=3D"text/css">.outline-2 {border-top: 1px solid black;}</style>
</head>
<body>
<div id=3D"content" class=3D"content">
<h1 class=3D"title">OCaml Weekly News</h1>
<p>
<a href=3D"https://alan.petitepomme.net/cwn/2026.06.23.html">Previous Week<=
/a> <a href=3D"https://alan.petitepomme.net/cwn/index.html">Up</a> <a href=
=3D"https://alan.petitepomme.net/cwn/2026.07.07.html">Next Week</a>
</p>
<p>
Hello
</p>
<p>
Here is the latest OCaml Weekly News, for the week of June 23 to 30, 2026.
</p>
<div id=3D"table-of-contents" role=3D"doc-toc">
<h2>Table of Contents</h2>
<div id=3D"text-table-of-contents" role=3D"doc-toc">
<ul>
<li><a href=3D"#1">New release of Sek</a></li>
<li><a href=3D"#2">Js_of_ocaml / Wasm_of_ocaml 6.4</a></li>
<li><a href=3D"#3">Ocsipersist 2.1.0: type-safe persistent references with =
Deriving</a></li>
<li><a href=3D"#4">Modular explicits in pre-OCaml 5.5</a></li>
<li><a href=3D"#5">LRgrep 0.9: Better syntax errors for OCaml and Menhir</a=
></li>
<li><a href=3D"#6">Static Analysis for OCaml</a></li>
<li><a href=3D"#7">new releases: Merlin 5.8 and OCaml-LSP 1.27.0 with suppo=
rt for OCaml 5.5</a></li>
<li><a href=3D"#8">duras 2.1.1 =E2=80=94 daily notes as plain text files</a=
></li>
<li><a href=3D"#9">Software Engineer at LexiFi (Paris)</a></li>
<li><a href=3D"#10">Owebview : OCaml binding to the webview library</a></li>
<li><a href=3D"#11">OCaml Runtime Meeting: Mon, July 6 @ 10:00 UTC (10:00 L=
ondon/Cambridge, 11:00 Paris, 7pm Sydney)</a></li>
<li><a href=3D"#org816b529">Old CWN</a></li>
</ul>
</div>
</div>
<div id=3D"outline-container-1" class=3D"outline-2">
<h2 id=3D"1">New release of Sek</h2>
<div class=3D"outline-text-2" id=3D"text-1">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/new-release-of-sek/18281/1"=
>https://discuss.ocaml.org/t/new-release-of-sek/18281/1</a>
</p>
</div>
<div id=3D"outline-container-org55deb9c" class=3D"outline-3">
<h3 id=3D"org55deb9c">Fran=C3=A7ois Pottier announced</h3>
<div class=3D"outline-text-3" id=3D"text-org55deb9c">
<p>
We are pleased to announce a new release of <a href=3D"https://gitlab.inria=
.fr/fpottier/sek">Sek</a>, a library that offers efficient ephemeral (mutab=
le) and persistent (immutable) <i>sequence</i> data structures, plus effici=
ent conversions between these two forms.
</p>
<p>
This new release introduces optimizations that speed up several operations,=
including random access (<code>get</code>, <code>set</code>), splitting, a=
nd concatenation. For details, please see the <a href=3D"https://gitlab.inr=
ia.fr/fpottier/sek/-/blob/master/CHANGES.md?ref_type=3Dheads">change log</a=
>.
</p>
<pre class=3D"example" id=3D"orgfd071c9">
opam update && opam install sek
</pre>
<p>
Happy hacking,
Arthur Chargu=C3=A9raud & Fran=C3=A7ois Pottier.
</p>
</div>
</div>
<div id=3D"outline-container-org751114b" class=3D"outline-3">
<h3 id=3D"org751114b">Fran=C3=A7ois Pottier later added</h3>
<div class=3D"outline-text-3" id=3D"text-org751114b">
<p>
Let me add this link to <a href=3D"https://cambium.inria.fr/~fpottier/sek/d=
oc/sek/Sek/">the documentation</a>.
</p>
</div>
</div>
</div>
<div id=3D"outline-container-2" class=3D"outline-2">
<h2 id=3D"2">Js_of_ocaml / Wasm_of_ocaml 6.4</h2>
<div class=3D"outline-text-2" id=3D"text-2">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-js-of-ocaml-wasm-of-oca=
ml-6-4/18282/1">https://discuss.ocaml.org/t/ann-js-of-ocaml-wasm-of-ocaml-6=
-4/18282/1</a>
</p>
</div>
<div id=3D"outline-container-orgec9b10c" class=3D"outline-3">
<h3 id=3D"orgec9b10c">Hhugo announced</h3>
<div class=3D"outline-text-3" id=3D"text-orgec9b10c">
<p>
I'm pleased to announce the joint release of <b>js_of_ocaml</b> and <b>wasm=
_of_ocaml 6.4.0</b>.
</p>
<p>
Js_of_ocaml is a compiler from OCaml bytecode to JavaScript. It makes it po=
ssible to run pure OCaml programs in JavaScript environments like browsers =
and Node.js.
</p>
<p>
Wasm_of_ocaml is a compiler from OCaml bytecode to WebAssembly. It is highl=
y compatible with js_of_ocaml, so you can compile your programs with wasm_o=
f_ocaml instead of js_of_ocaml and experience overall better performance.
</p>
<p>
Most significant changes since version 6.3:
</p>
</div>
<div id=3D"outline-container-org0e8d45f" class=3D"outline-4">
<h4 id=3D"org0e8d45f">Toolchain</h4>
<div class=3D"outline-text-4" id=3D"text-org0e8d45f">
<ul class=3D"org-ul">
<li><b>OCaml 5.5.0 support</b>.</li>
<li><b>OxCaml support</b>.</li>
</ul>
</div>
</div>
<div id=3D"outline-container-org846b963" class=3D"outline-4">
<h4 id=3D"org846b963">wasm_of_ocaml</h4>
<div class=3D"outline-text-4" id=3D"text-org846b963">
<ul class=3D"org-ul">
<li><b>WASI 0.1 support</b> =E2=80=94 target standalone WASI runtimes (wasm=
time and friends), no JavaScript host required.</li>
<li><b>Dynlink and toplevel support</b> =E2=80=94 the OCaml toplevel now ru=
ns on the Wasm backend.</li>
<li>An <b>alternative effects backend</b> based on the <a href=3D"https://g=
ithub.com/WebAssembly/stack-switching">Stack Switching proposal</a>.</li>
<li><b>Pure-Wasm zstd and BLAKE2b</b> =E2=80=94 unmarshalling compressed va=
lues and <code>Digest.BLAKE2{512,256,128}</code> no longer need the JavaScr=
ipt shims, so they work under WASI too.</li>
<li>The legacy <code>num</code> library now works on Wasm (the <code>nat</c=
ode> primitives were no-op stubs).</li>
</ul>
</div>
</div>
<div id=3D"outline-container-org5585cf4" class=3D"outline-4">
<h4 id=3D"org5585cf4">Library =E2=80=94 new web APIs</h4>
<div class=3D"outline-text-4" id=3D"text-org5585cf4">
<ul class=3D"org-ul">
<li><b><code>Promise</code> module</b> =E2=80=94 type-safe bindings to JS p=
romises, with <b>Lwt interop</b> (<code>Js_of_ocaml_lwt.Promise.{to_lwt,of_=
lwt}</code>) and Promise-typed <code>Dom_html</code> bindings.</li>
<li><b><code>Fetch</code> + <code>Abort</code> modules</b> =E2=80=94 the Fe=
tch API with typed <code>AbortController~/~AbortSignal</code> cancellation.=
</li>
<li><b><code>Dom_svg</code> aligned with SVG 2</b>, the <b>popover API</b>,=
<b><code>Intl.RelativeTimeFormat</code></b>, a new <b><code>Performance</c=
ode> module</b>, additional <code>Console</code> bindings, and many more <c=
ode>Dom_html</code> bindings.</li>
</ul>
</div>
</div>
<div id=3D"outline-container-org07f36e6" class=3D"outline-4">
<h4 id=3D"org07f36e6">Bug fixes</h4>
<div class=3D"outline-text-4" id=3D"text-org07f36e6">
<ul class=3D"org-ul">
<li>A large number of bug fixes across the compiler, runtime, library bindi=
ngs, and PPX.</li>
</ul>
</div>
</div>
<div id=3D"outline-container-org50ceeb6" class=3D"outline-4">
<h4 id=3D"org50ceeb6">=E2=9A=A0=EF=B8=8F Breaking changes</h4>
<div class=3D"outline-text-4" id=3D"text-org50ceeb6">
<p>
A few changes are source-incompatible =E2=80=94 mostly to fix incorrect bin=
dings and behavior =E2=80=94 and may require updating existing code. See th=
e <a href=3D"https://github.com/ocsigen/js_of_ocaml/wiki/Upgrade-from-6.3.0=
-to-6.4.0">migration guide</a>.
</p>
<p>
See the <a href=3D"https://ocsigen.org/js_of_ocaml/">documentation</a> and =
the <a href=3D"https://github.com/ocsigen/js_of_ocaml/blob/master/CHANGES.m=
d">full changelog</a>.
</p>
</div>
</div>
</div>
<div id=3D"outline-container-orgeea72a6" class=3D"outline-3">
<h3 id=3D"orgeea72a6">Vincent Balat then added</h3>
<div class=3D"outline-text-3" id=3D"text-orgeea72a6">
<p>
We released Eliom 12.1 at the same time, bringing compatibility with both j=
s_of_ocaml 6.4 and OCaml 5.5.
</p>
</div>
</div>
</div>
<div id=3D"outline-container-3" class=3D"outline-2">
<h2 id=3D"3">Ocsipersist 2.1.0: type-safe persistent references with Derivi=
ng</h2>
<div class=3D"outline-text-2" id=3D"text-3">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-ocsipersist-2-1-0-type-=
safe-persistent-references-with-deriving/18283/1">https://discuss.ocaml.org=
/t/ann-ocsipersist-2-1-0-type-safe-persistent-references-with-deriving/1828=
3/1</a>
</p>
</div>
<div id=3D"outline-container-orgbec333a" class=3D"outline-3">
<h3 id=3D"orgbec333a">Vincent Balat announced</h3>
<div class=3D"outline-text-3" id=3D"text-orgbec333a">
<p>
<a href=3D"https://ocsigen.org/ocsipersist/">Ocsipersist</a> 2.1.0 is out. =
Persistent references, stores and tables can now be serialised with <code>D=
eriving_Json</code> instead of <code>Marshal</code>: the data is human-read=
able in the database and stable across OCaml versions. The new API is fully=
backward compatible, and Ocsipersist works as a standalone library for any=
OCaml program (no Eliom or Ocsigen Server required).
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">type</span> <span style=3D"color: #444fcf; font-weight: bold;">u=
ser</span> =3D { name : string; age : int } <span style=3D"color: #a7601f;"=
>[@@deriving json]</span>
<span style=3D"color: #8f6f4a; font-style: italic;">(* </span><span style=
=3D"color: #8f6f4a; font-style: italic;">a persistent reference, stored as =
readable JSON</span><span style=3D"color: #8f6f4a; font-style: italic;"> *)=
</span>
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">visits</span> =3D <span style=3D"color: #557400; font-=
weight: bold;">Ocsipersist.Ref_json.</span><span style=3D"color: #557400; f=
ont-weight: bold;">ref</span> <span style=3D"color: #444fcf; font-weight: b=
old;">~persistent</span>:<span style=3D"color: #ca3400;">"visits"</span> <s=
pan style=3D"color: #a7601f; background-color: #ebebeb;">[%json</span>: int=
<span style=3D"color: #a7601f; background-color: #ebebeb;">]</span> 0
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #a7601f;">count_visit</span> () =3D
<span style=3D"color: #242521; font-weight: bold;">let</span><span style=
=3D"color: #a7601f;">%lwt</span> <span style=3D"color: #007a9f;">n</span> =
=3D <span style=3D"color: #557400; font-weight: bold;">Ocsipersist.Ref_json=
.</span>get visits <span style=3D"color: #242521; font-weight: bold;">in</s=
pan>
<span style=3D"color: #557400; font-weight: bold;">Ocsipersist.Ref_json.<=
/span>set visits (n + 1)
</code></pre>
</div>
<p>
Full announcement: <a href=3D"https://ocsigen.org/blog/posts/ocsipersist-2.=
1.0.html">https://ocsigen.org/blog/posts/ocsipersist-2.1.0.html</a>
</p>
</div>
</div>
</div>
<div id=3D"outline-container-4" class=3D"outline-2">
<h2 id=3D"4">Modular explicits in pre-OCaml 5.5</h2>
<div class=3D"outline-text-2" id=3D"text-4">
<p>
Archive: <a href=3D"https://inbox.ci.dev/caml-list/6d5f115c-866d-4cc0-a102-=
[email protected]/T/">https://inbox.ci.dev/caml-list/6d5f115c-866d-4cc0=
[email protected]/T/</a>
</p>
</div>
<div id=3D"outline-container-org34282a7" class=3D"outline-3">
<h3 id=3D"org34282a7">oleg said</h3>
<div class=3D"outline-text-3" id=3D"text-org34282a7">
<p>
One of the notable features of the just announced OCaml 5.5 are
module-dependent functions, a.k.a. modular explicits. It is a welcome
addition: it lets us express higher-ranked types in the simplest way,
and is particularly good for typed tagless-final code.
</p>
<p>
It should be mentioned however that modular explicits could be done before,
with little or no hassle. Perhaps there is merit to remind of that old
trick~– especially because it works also with statically unknown modu=
les
(which are out of scope for OCaml 5.5 modular explicits).
</p>
<p>
As the running example we re-use the pretty-printing example in the
OCaml 5.5 announcement (hereafter, Ann55).
</p>
<p>
We start however with a simpler example: pretty-printing a set=20
generated by the <code>Set.Make</code> functor. The example follows the=20
pattern of the pp_map function from Ann55. It is simpler than=20
printing a map because it involves no higher-rank types.
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">let</span> <span style=3D"color: #a7601f;">pp_set</span> (<span =
style=3D"color: #006f00; font-weight: bold;">type</span> <span style=3D"col=
or: #444fcf; font-weight: bold;">a</span> <span style=3D"color: #444fcf; fo=
nt-weight: bold;">s</span>)=20
(<span style=3D"color: #006f00; font-weight: bold;">module</span> <sp=
an style=3D"color: #557400; font-weight: bold;">M</span>: <span style=3D"co=
lor: #557400; font-weight: bold;">Set.S with type elt </span>=3D<span style=
=3D"color: #557400; font-weight: bold;"> a and type t </span>=3D<span style=
=3D"color: #557400; font-weight: bold;"> s</span>)=20
(<span style=3D"color: #007a9f;">pp_elt</span>:<span style=3D"color: =
#444fcf; font-weight: bold;">Format.formatter->a->unit</span>) (<span=
style=3D"color: #007a9f;">ppf</span>:<span style=3D"color: #444fcf; font-w=
eight: bold;">Format.formatter</span>) (<span style=3D"color: #007a9f;">set=
</span>:<span style=3D"color: #444fcf; font-weight: bold;">s</span>) =3D=20
<span style=3D"color: #006f00; font-weight: bold;">if</span> <span style=
=3D"color: #557400; font-weight: bold;">M.</span>is_empty set <span style=
=3D"color: #006f00; font-weight: bold;">then</span> <span style=3D"color: #=
557400; font-weight: bold;">Format.</span>fprintf ppf <span style=3D"color:=
#ca3400;">"ø"</span> <span style=3D"color: #006f00; font-weight: bold=
;">else</span>=20
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #a7601f;">pp_sep</span> <span style=3D"color: #007a9f;">ppf</spa=
n> () =3D <span style=3D"color: #557400; font-weight: bold;">Format.</span>=
fprintf ppf <span style=3D"color: #ca3400;">",@ "</span> <span style=3D"col=
or: #242521; font-weight: bold;">in</span>=20
<span style=3D"color: #557400; font-weight: bold;">Format.</span>fprintf =
ppf <span style=3D"color: #ca3400;">"@[{@ %a@ }@]"</span>=20
(<span style=3D"color: #557400; font-weight: bold;">Format.</span>pp_pr=
int_seq ~pp_sep pp_elt) (<span style=3D"color: #557400; font-weight: bold;"=
>M.</span>to_seq set)=20
</code></pre>
</div>
<p>
It is almost literally the pp_map example from Ann55, with set
substituted for map. The main difference is type annotations. This is
not a bug: I insist on writing signatures or explicit type annotations
for all top-level definitions (except, perhaps, the most trivial).
</p>
<p>
The annotations could be simplified if we introduce
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">type</span> <span style=3D"color: #444fcf; font-weight: bold;">(=
'e,'s) set</span> =3D (<span style=3D"color: #242521; font-weight: bold;">m=
odule</span> <span style=3D"color: #557400; font-weight: bold;">Set</span>.=
<span style=3D"color: #242521;">S</span> <span style=3D"color: #242521; fon=
t-weight: bold;">with type</span> <span style=3D"color: #444fcf; font-weigh=
t: bold;">elt</span> =3D 'e <span style=3D"color: #242521; font-weight: bol=
d;">and type</span> <span style=3D"color: #444fcf; font-weight: bold;">t</s=
pan> =3D 's)
<span style=3D"color: #242521; font-weight: bold;">type</span> <span style=
=3D"color: #444fcf; font-weight: bold;">'a printer</span> =3D <span style=
=3D"color: #557400; font-weight: bold;">Format.</span>formatter->'a->=
unit
</code></pre>
</div>
<p>
The example then reads
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">let</span> <span style=3D"color: #007a9f;">pp_set</span> :<span =
style=3D"color: #444fcf; font-weight: bold;"> </span><span style=3D"color: =
#006f00; font-weight: bold;">type</span><span style=3D"color: #444fcf; font=
-weight: bold;"> e s. (e,s) set -> e printer -> s printer </span>=3D=
=20
<span style=3D"color: #006f00; font-weight: bold;">fun</span> (<span styl=
e=3D"color: #006f00; font-weight: bold;">module</span> <span style=3D"color=
: #557400; font-weight: bold;">M</span>) <span style=3D"color: #007a9f;">pp=
_elt</span> <span style=3D"color: #007a9f;">ppf</span> <span style=3D"color=
: #007a9f;">set</span> -> <span style=3D"color: #8f6f4a; font-style: ita=
lic;">(* </span><span style=3D"color: #8f6f4a; font-style: italic;">... as =
before ...</span><span style=3D"color: #8f6f4a; font-style: italic;"> *)</s=
pan>
</code></pre>
</div>
<p>
The signature tells at a glance what pp_set is doing (which is one of
the benefits of signatures: it is not just for, and not mainly for,
the compiler.)
</p>
<p>
We can use pp_set just like pp_map was used in the Ann55 example:
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">module</span> <span style=3D"color: #557400; font-weight: bold;"=
>String_set</span> =3D <span style=3D"color: #557400; font-weight: bold;">S=
et.Make(String)</span>=20
<span style=3D"color: #242521; font-weight: bold;">let</span> () =3D=20
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">m</span> =3D <span style=3D"color: #557400; font-weigh=
t: bold;">String_set.</span>of_list [<span style=3D"color: #ca3400;">"Zero"=
</span>; <span style=3D"color: #ca3400;">"Zero"</span>; <span style=3D"colo=
r: #ca3400;">"One"</span>; <span style=3D"color: #ca3400;">"Un"</span>] <sp=
an style=3D"color: #242521; font-weight: bold;">in</span>=20
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">pp_str</span> =3D <span style=3D"color: #557400; font-=
weight: bold;">Format.</span>pp_print_string <span style=3D"color: #242521;=
font-weight: bold;">in</span>=20
<span style=3D"color: #557400; font-weight: bold;">Format.</span>printf <=
span style=3D"color: #ca3400;">"%a@."</span> (pp_set (<span style=3D"color:=
#006f00; font-weight: bold;">module</span> <span style=3D"color: #557400; =
font-weight: bold;">String_set</span>) pp_str) m=20
</code></pre>
</div>
<p>
Our rendition of modular explicits extends beyond statically known
modules like String_set. For example,
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #8f6f4a; font-styl=
e: italic;">(* </span><span style=3D"color: #8f6f4a; font-style: italic;">A=
bstract set of elements of types 'e. The implementation is abstract</span><=
span style=3D"color: #8f6f4a; font-style: italic;"> *)</span>
<span style=3D"color: #242521; font-weight: bold;">type</span> <span style=
=3D"color: #444fcf; font-weight: bold;">'e aset</span> =3D (<span style=3D"=
color: #242521; font-weight: bold;">module</span> <span style=3D"color: #55=
7400; font-weight: bold;">Set</span>.<span style=3D"color: #242521;">S</spa=
n> <span style=3D"color: #242521; font-weight: bold;">with type</span> <spa=
n style=3D"color: #444fcf; font-weight: bold;">elt</span> =3D 'e)
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #a7601f;">f</span> :<span style=3D"color: #444fcf; font-weight: =
bold;"> unit -> int aset </span>=3D <span style=3D"color: #006f00; font-=
weight: bold;">fun</span> () ->=20
<span style=3D"color: #006f00; font-weight: bold;">if</span> <span style=
=3D"color: #557400; font-weight: bold;">Random.</span>bool () <span style=
=3D"color: #006f00; font-weight: bold;">then</span>=20
(<span style=3D"color: #242521; font-weight: bold;">module</span> <span=
style=3D"color: #557400; font-weight: bold;">Set</span>.<span style=3D"col=
or: #242521;">Make</span>(<span style=3D"color: #242521;">Int</span>))=20
<span style=3D"color: #006f00; font-weight: bold;">else</span>=20
(<span style=3D"color: #242521; font-weight: bold;">module</span> <span=
style=3D"color: #557400; font-weight: bold;">Set</span>.<span style=3D"col=
or: #242521;">Make</span>(<span style=3D"color: #242521; font-weight: bold;=
">struct</span> <span style=3D"color: #242521; font-weight: bold;">type</sp=
an> <span style=3D"color: #444fcf; font-weight: bold;">t</span> =3D int=20
<span style=3D"color: #242521; font-weight: bold;">let</span> <span s=
tyle=3D"color: #a7601f;">compare</span> <span style=3D"color: #007a9f;">x</=
span> <span style=3D"color: #007a9f;">y</span> =3D - <span style=3D"color: =
#557400; font-weight: bold;">Int.</span>compare x y <span style=3D"color: #=
242521; font-weight: bold;">end</span>))
</code></pre>
</div>
<p>
The function f randomly returns one of two distinct Set
implementations (the Set.t types are not compatible). As an
application, we print a list of integers as a set (automatically
sorting and removing duplicates):
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">let</span> <span style=3D"color: #007a9f;">print_as_set</span> :=
<span style=3D"color: #444fcf; font-weight: bold;"> </span><span style=3D"c=
olor: #006f00; font-weight: bold;">type</span><span style=3D"color: #444fcf=
; font-weight: bold;"> a. a aset -> a printer -> a list printer </sp=
an>=3D=20
<span style=3D"color: #006f00; font-weight: bold;">fun</span> (<span styl=
e=3D"color: #006f00; font-weight: bold;">module</span> <span style=3D"color=
: #557400; font-weight: bold;">M</span>) <span style=3D"color: #007a9f;">pp=
</span> <span style=3D"color: #007a9f;">ppf</span> <span style=3D"color: #0=
07a9f;">lst</span> ->=20
pp_set (<span style=3D"color: #006f00; font-weight: bold;">module</span=
> <span style=3D"color: #557400; font-weight: bold;">M</span>) pp ppf (<spa=
n style=3D"color: #557400; font-weight: bold;">M.</span>of_list lst)
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">_</span> =3D <span style=3D"color: #557400; font-weigh=
t: bold;">Format.</span>printf <span style=3D"color: #ca3400;">"%a@."</span=
>=20
(print_as_set (f ()) <span style=3D"color: #557400; font-weight: bold;"=
>Format.</span>pp_print_int) [1;2;3;1]
</code></pre>
</div>
<p>
The result is indeed either "{ 1, 2, 3 }" or "{ 3, 2, 1 }", depending
on how die is cast.
</p>
<p>
Let us now tackle the pp_map example from Ann55. It is challenging because
of the higher-rank type of the map type 'a Map.S.t.
</p>
<p>
It is tempting to define the module type as
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">type</span> <span style=3D"color: #444fcf; font-weight: bold;">(=
'k,'v,'m) map</span> =3D=20
(<span style=3D"color: #242521; font-weight: bold;">module</span> <span=
style=3D"color: #557400; font-weight: bold;">Map</span>.<span style=3D"col=
or: #242521;">S</span> <span style=3D"color: #242521; font-weight: bold;">w=
ith type</span> <span style=3D"color: #444fcf; font-weight: bold;">key</spa=
n> =3D 'k <span style=3D"color: #242521; font-weight: bold;">and type</span=
> <span style=3D"color: #444fcf; font-weight: bold;">'a t</span> =3D 'm <sp=
an style=3D"color: #242521; font-weight: bold;">constraint</span> 'a =3D 'v)
</code></pre>
</div>
<p>
Alas, it doesn't work:
</p>
<pre class=3D"example" id=3D"org5f4afd8">
2 | (module Map.S with type key =3D 'k and type 'a t =3D 'm constraint =
'a =3D 'v)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^=
^^^
Error: Syntax error: invalid package type: parametrized types are not suppo=
rted
</pre>
<p>
Package types and their <code>with</code> constraints come with many restri=
ctions, which
is deeply unfortunate.
</p>
<p>
We have to resort to an encoding:
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">module type</span> <span style=3D"color: #444fcf; font-weight: b=
old;">maps</span> =3D <span style=3D"color: #242521; font-weight: bold;">si=
g</span>
<span style=3D"color: #242521; font-weight: bold;">include</span> <span s=
tyle=3D"color: #557400; font-weight: bold;">Map.S</span>
<span style=3D"color: #242521; font-weight: bold;">type</span> <span styl=
e=3D"color: #444fcf; font-weight: bold;">v</span>
<span style=3D"color: #242521; font-weight: bold;">type</span> <span styl=
e=3D"color: #444fcf; font-weight: bold;">mt</span>
<span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">of_mt</span> : mt -> v t
<span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">to_mt</span> : v t -> mt=20
<span style=3D"color: #242521; font-weight: bold;">end</span>
<span style=3D"color: #242521; font-weight: bold;">type</span> <span style=
=3D"color: #444fcf; font-weight: bold;">('k,'v,'m) map</span> =3D=20
(<span style=3D"color: #242521; font-weight: bold;">module</span> maps =
<span style=3D"color: #242521; font-weight: bold;">with type</span> <span s=
tyle=3D"color: #444fcf; font-weight: bold;">key</span> =3D 'k <span style=
=3D"color: #242521; font-weight: bold;">and type</span> <span style=3D"colo=
r: #444fcf; font-weight: bold;">v</span> =3D 'v <span style=3D"color: #2425=
21; font-weight: bold;">and type</span> <span style=3D"color: #444fcf; font=
-weight: bold;">mt</span> =3D 'm)
</code></pre>
</div>
<p>
One should mention that this is a strictly more general type of maps:
it supports specialized implementations for particular combination of
keys and values (e.g., if 'v is bool, we can use Set as the underlying
structure.)
</p>
<p>
The pretty-printer of maps is the same as in the Ann55, with two additions:
two occurrences of M.of_t.
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">let</span> <span style=3D"color: #007a9f;">pp_map</span> :<span =
style=3D"color: #444fcf; font-weight: bold;"> </span><span style=3D"color: =
#006f00; font-weight: bold;">type</span><span style=3D"color: #444fcf; font=
-weight: bold;"> k v m. (k,v,m) map -> k printer -> v printer -> m=
printer </span>=3D=20
<span style=3D"color: #006f00; font-weight: bold;">fun</span> (<span st=
yle=3D"color: #006f00; font-weight: bold;">module</span> <span style=3D"col=
or: #557400; font-weight: bold;">M</span>) <span style=3D"color: #007a9f;">=
pp_key</span> <span style=3D"color: #007a9f;">pp_v</span> <span style=3D"co=
lor: #007a9f;">ppf</span> <span style=3D"color: #007a9f;">set</span> ->=
=20
<span style=3D"color: #006f00; font-weight: bold;">if</span> <span style=
=3D"color: #557400; font-weight: bold;">M.</span>is_empty (<span style=3D"c=
olor: #557400; font-weight: bold;">M.</span>of_mt set) <span style=3D"color=
: #006f00; font-weight: bold;">then</span> <span style=3D"color: #557400; f=
ont-weight: bold;">Format.</span>fprintf ppf <span style=3D"color: #ca3400;=
">"ø"</span> <span style=3D"color: #006f00; font-weight: bold;">else</=
span>=20
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #a7601f;">pp_sep</span> <span style=3D"color: #007a9f;">ppf</spa=
n> () =3D <span style=3D"color: #557400; font-weight: bold;">Format.</span>=
fprintf ppf <span style=3D"color: #ca3400;">",@ "</span> <span style=3D"col=
or: #242521; font-weight: bold;">in</span>=20
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #a7601f;">pp_binding</span> <span style=3D"color: #007a9f;">ppf<=
/span> (<span style=3D"color: #007a9f;">k</span>,<span style=3D"color: #007=
a9f;">v</span>) =3D <span style=3D"color: #557400; font-weight: bold;">Form=
at.</span>fprintf ppf <span style=3D"color: #ca3400;">"@[%a@ =3D@ %a@]"</sp=
an> pp_key k pp_v v=20
<span style=3D"color: #242521; font-weight: bold;">in</span>=20
<span style=3D"color: #557400; font-weight: bold;">Format.</span>fprintf =
ppf <span style=3D"color: #ca3400;">"@[{@ %a@ }@]"</span>=20
(<span style=3D"color: #557400; font-weight: bold;">Format.</span>pp_pr=
int_seq ~pp_sep pp_binding) (<span style=3D"color: #557400; font-weight: bo=
ld;">M.</span>to_seq (<span style=3D"color: #557400; font-weight: bold;">M.=
</span>of_mt set))=20
</code></pre>
</div>
<p>
It applies to statically <b>unknown</b> modules however, unlike pp_map in A=
nn55
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">type</span> <span style=3D"color: #444fcf; font-weight: bold;">(=
'k,'v) amap</span> =3D (<span style=3D"color: #242521; font-weight: bold;">=
module</span> maps <span style=3D"color: #242521; font-weight: bold;">with =
type</span> <span style=3D"color: #444fcf; font-weight: bold;">key</span> =
=3D 'k <span style=3D"color: #242521; font-weight: bold;">and type</span> <=
span style=3D"color: #444fcf; font-weight: bold;">v</span> =3D 'v)
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #a7601f;">string_map</span> :<span style=3D"color: #444fcf; font=
-weight: bold;"> </span><span style=3D"color: #006f00; font-weight: bold;">=
type</span><span style=3D"color: #444fcf; font-weight: bold;"> a. unit ->=
; (string,a) amap </span>=3D <span style=3D"color: #006f00; font-weight: bo=
ld;">fun</span> () ->=20
(<span style=3D"color: #242521; font-weight: bold;">module</span> <span s=
tyle=3D"color: #242521; font-weight: bold;">struct</span>
<span style=3D"color: #242521; font-weight: bold;">include</span> <span=
style=3D"color: #557400; font-weight: bold;">Map.Make(String)</span>=20
<span style=3D"color: #242521; font-weight: bold;">type</span> <span st=
yle=3D"color: #444fcf; font-weight: bold;">v</span> =3D a
<span style=3D"color: #242521; font-weight: bold;">type</span> <span st=
yle=3D"color: #444fcf; font-weight: bold;">mt</span> =3D v t
<span style=3D"color: #242521; font-weight: bold;">let</span> <span sty=
le=3D"color: #007a9f;">of_mt</span> =3D <span style=3D"color: #557400; font=
-weight: bold;">Fun.</span>id
<span style=3D"color: #242521; font-weight: bold;">let</span> <span sty=
le=3D"color: #007a9f;">to_mt</span> =3D <span style=3D"color: #557400; font=
-weight: bold;">Fun.</span>id
<span style=3D"color: #242521; font-weight: bold;">end</span>)
<span style=3D"color: #242521; font-weight: bold;">let</span> () =3D=20
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">md</span> =3D string_map () <span style=3D"color: #242=
521; font-weight: bold;">in</span>
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #242521; font-weight: bold;">module</span> <span style=3D"color:=
#557400; font-weight: bold;">M</span> =3D (<span style=3D"color: #242521; =
font-weight: bold;">val</span> (md : <span style=3D"color: #444fcf; font-we=
ight: bold;">(string,int) amap</span>)) <span style=3D"color: #242521; font=
-weight: bold;">in</span>
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">m</span> =3D <span style=3D"color: #557400; font-weigh=
t: bold;">M.</span>of_list [<span style=3D"color: #ca3400;">"Zero"</span>, =
0; <span style=3D"color: #ca3400;">"One"</span>, 1] <span style=3D"color: #=
242521; font-weight: bold;">in</span>=20
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">pp_str</span> =3D <span style=3D"color: #557400; font-=
weight: bold;">Format.</span>pp_print_int <span style=3D"color: #242521; fo=
nt-weight: bold;">in</span>=20
<span style=3D"color: #557400; font-weight: bold;">Format.</span>printf <=
span style=3D"color: #ca3400;">"%a@."</span>=20
(pp_map (<span style=3D"color: #006f00; font-weight: bold;">module</spa=
n> <span style=3D"color: #557400; font-weight: bold;">M</span>) <span style=
=3D"color: #557400; font-weight: bold;">Format.</span>pp_print_string pp_st=
r) (<span style=3D"color: #557400; font-weight: bold;">M.</span>to_mt m)
</code></pre>
</div>
<p>
I should mention that the functions like to_mt come naturally in case
of tagless-final interpreters: these are the observation functions.
For example:
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">module type</span> <span style=3D"color: #444fcf; font-weight: b=
old;">lc</span> =3D <span style=3D"color: #242521; font-weight: bold;">sig<=
/span>
<span style=3D"color: #242521; font-weight: bold;">type</span> <span styl=
e=3D"color: #444fcf; font-weight: bold;">'a repr</span>
<span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">int</span> : int -> int repr
<span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">lam</span> : ('a repr -> 'b repr) -> ('a -> =
'b) repr
<span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">app</span> : ('a -> 'b) repr -> ('a repr -> '=
b repr)
<span style=3D"color: #242521; font-weight: bold;">type</span> <span styl=
e=3D"color: #444fcf; font-weight: bold;">obst</span>
<span style=3D"color: #242521; font-weight: bold;">type</span> <span styl=
e=3D"color: #444fcf; font-weight: bold;">obs</span>
<span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">observe</span> : obst repr -> obs
<span style=3D"color: #242521; font-weight: bold;">end</span>
<span style=3D"color: #242521; font-weight: bold;">type</span> <span style=
=3D"color: #444fcf; font-weight: bold;">('a,'obs) lc</span> =3D (<span styl=
e=3D"color: #242521; font-weight: bold;">module</span> (lc <span style=3D"c=
olor: #242521; font-weight: bold;">with type</span> <span style=3D"color: #=
444fcf; font-weight: bold;">obs</span> =3D 'obs <span style=3D"color: #2425=
21; font-weight: bold;">and type</span> <span style=3D"color: #444fcf; font=
-weight: bold;">obst</span> =3D 'a))
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #a7601f;">ex1</span> :<span style=3D"color: #444fcf; font-weight=
: bold;"> </span><span style=3D"color: #006f00; font-weight: bold;">type</s=
pan><span style=3D"color: #444fcf; font-weight: bold;"> obs. (int,obs) lc -=
> obs </span>=3D <span style=3D"color: #006f00; font-weight: bold;">fun<=
/span> (<span style=3D"color: #006f00; font-weight: bold;">module</span> <s=
pan style=3D"color: #557400; font-weight: bold;">M</span>) -> <span styl=
e=3D"color: #242521; font-weight: bold;">let</span> <span style=3D"color: #=
242521; font-weight: bold;">open </span><span style=3D"color: #557400; font=
-weight: bold;">M</span> <span style=3D"color: #242521; font-weight: bold;"=
>in</span>
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">t1</span> =3D app (lam (<span style=3D"color: #006f00;=
font-weight: bold;">fun</span> <span style=3D"color: #007a9f;">x</span> -&=
gt; x)) (int 1)
<span style=3D"color: #242521; font-weight: bold;">in</span> observe t1
</code></pre>
</div>
<p>
In conclusion, it would be great if one day the restrictions on
package types were relaxed.
</p>
</div>
</div>
<div id=3D"outline-container-org321e087" class=3D"outline-3">
<h3 id=3D"org321e087">Olivier Nicole asked and Samuel Vivien replied</h3>
<div class=3D"outline-text-3" id=3D"text-org321e087">
<blockquote>
<p>
Thanks for pointing this out. Does this mean that modular explicits,=20
strictly speaking, bring no additional expressivity but only a simpler=20
way to do these things? Or are there programs that could be expressed=20
with modular explicits but not with constrained module types?
</p>
</blockquote>
<p>
Indeed. Modular explicit does not add any expressiveness to the language=20
(and does not impact the soundness of the type system). Every program=20
that can be written using modular explicits could have been written with=20
a functor encoded as a first-class module.
</p>
<p>
We presented this encoding in section 1.5 of this paper about modular=20
explicits : <a href=3D"https://hal.science/hal-05428136/document">https://h=
al.science/hal-05428136/document</a>
</p>
</div>
</div>
</div>
<div id=3D"outline-container-5" class=3D"outline-2">
<h2 id=3D"5">LRgrep 0.9: Better syntax errors for OCaml and Menhir</h2>
<div class=3D"outline-text-2" id=3D"text-5">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/lrgrep-0-9-better-syntax-er=
rors-for-ocaml-and-menhir/18286/1">https://discuss.ocaml.org/t/lrgrep-0-9-b=
etter-syntax-errors-for-ocaml-and-menhir/18286/1</a>
</p>
</div>
<div id=3D"outline-container-org0f5a33a" class=3D"outline-3">
<h3 id=3D"org0f5a33a">Fr=C3=A9d=C3=A9ric Bour announced</h3>
<div class=3D"outline-text-3" id=3D"text-org0f5a33a">
<p>
Hi everyone,
</p>
<p>
I've just released <b>LRgrep 0.9</b>, a tool to customize the error message=
s of Menhir-generated LR parsers by reasoning about failure paths.
</p>
<p>
The goal is to move from generic "Syntax error at line X" messages to more =
intuitive diagnostics that point to the actual root cause. For example, if =
you accidentally put a semicolon in a local-let chain:
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">let</span> <span style=3D"color: #007a9f;">x</span> =3D 5;
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">y</span> =3D 6
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">z</span> =3D 7
<span style=3D"color: #9f0d0f;">^^^</span>
<span style=3D"color: #242521;">Error</span>: <span style=3D"color: #242521=
;">Expecting</span> 'in' <span style=3D"color: #006f00; font-weight: bold;"=
>to</span> complete local-<span style=3D"color: #242521; font-weight: bold;=
">let</span> <span style=3D"color: #a7601f;">binding</span>.=20
<span style=3D"color: #242521;">Hint</span>: this might be due <span style=
=3D"color: #006f00; font-weight: bold;">to</span> the semicolon line 1, cha=
racter 9
</code></pre>
</div>
<p>
Without LRgrep, OCaml typically reports only a syntax error on the subseque=
nt <code>let</code> binding. The customized parser can identify that the se=
micolon is the likely culprit.
</p>
<p>
<b>How you can help (feedback wanted!)</b>
</p>
<p>
I am looking for users to help stress-test the current specifications and i=
dentify where error messages are still lacking.
</p>
<ol class=3D"org-ol">
<li><b>If you use OCaml:</b> I've patched the compiler to use LRgrep. Pleas=
e try it via opam:
<code>opam switch create 5.4.1+lrgrep</code>
<b>Please report cases where the error messages are confusing or where you =
would like to see a more helpful hint.</b></li>
<li><b>If you use Menhir:</b> Give LRgrep a try on your own grammars if you=
want to customize error messages.
<ul class=3D"org-ul">
<li><a href=3D"https://github.com/fpottier/lrgrep-example">General Examples=
</a></li>
<li><a href=3D"https://github.com/let-def/lrgrep/blob/main/examples/ocaml/p=
arser/errors.lrgrep">OCaml Error Specifications</a></li>
</ul></li>
</ol>
<p>
Integration with Merlin is also coming soon (<a href=3D"https://github.com/=
ocaml/merlin/pull/2072">PR #2072</a>).
</p>
<p>
Huge thanks to @fpottier, @jmid, Tarides, and Jane Street for their support.
</p>
<p>
Happy testing!
</p>
</div>
</div>
</div>
<div id=3D"outline-container-6" class=3D"outline-2">
<h2 id=3D"6">Static Analysis for OCaml</h2>
<div class=3D"outline-text-2" id=3D"text-6">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/blog-static-analysis-for-oc=
aml/18287/1">https://discuss.ocaml.org/t/blog-static-analysis-for-ocaml/182=
87/1</a>
</p>
</div>
<div id=3D"outline-container-orgea70984" class=3D"outline-3">
<h3 id=3D"orgea70984">fantazio announced</h3>
<div class=3D"outline-text-3" id=3D"text-orgea70984">
<p>
Hi all,
</p>
<p>
I wrote a short (and slightly opinionated) piece on the state of static ana=
lysis tooling for OCaml.
The goal is to provide an overview of available tools, works in progress, a=
nd missing pieces. Let me know if there is a static analysis tool you use t=
hat is not mentioned, or if you wish one existed.
</p>
<p>
Thanks!
</p>
<p>
<a href=3D"https://fantazio.eu/articles/static_analysis_ocaml.html">https:/=
/fantazio.eu/articles/static_analysis_ocaml.html</a>
</p>
</div>
</div>
</div>
<div id=3D"outline-container-7" class=3D"outline-2">
<h2 id=3D"7">new releases: Merlin 5.8 and OCaml-LSP 1.27.0 with support for=
OCaml 5.5</h2>
<div class=3D"outline-text-2" id=3D"text-7">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-new-releases-merlin-5-8=
-and-ocaml-lsp-1-27-0-with-support-for-ocaml-5-5/18293/1">https://discuss.o=
caml.org/t/ann-new-releases-merlin-5-8-and-ocaml-lsp-1-27-0-with-support-fo=
r-ocaml-5-5/18293/1</a>
</p>
</div>
<div id=3D"outline-container-org61e92fb" class=3D"outline-3">
<h3 id=3D"org61e92fb">vds announced</h3>
<div class=3D"outline-text-3" id=3D"text-org61e92fb">
<p>
I am glad to announce new releases of Merlin and OCaml-LSP =F0=9F=A7=99 !
</p>
<p>
Merlin is an editor service that provides modern IDE features for OCaml and=
OCaml-LSP is a frontend for Merlin that speaks with LSP clients.
</p>
<p>
There are a few bug fixes in these but the main feature is the stable suppo=
rt for OCaml 5.5.
</p>
<p>
Full changelogs:=20
</p>
<ul class=3D"org-ul">
<li><a href=3D"https://github.com/ocaml/merlin/blob/main/CHANGES.md#merlin-=
58">https://github.com/ocaml/merlin/blob/main/CHANGES.md#merlin-58</a></li>
<li><a href=3D"https://github.com/ocaml/ocaml-lsp/blob/master/CHANGES.md#12=
70">https://github.com/ocaml/ocaml-lsp/blob/master/CHANGES.md#1270</a></li>
</ul>
</div>
</div>
</div>
<div id=3D"outline-container-8" class=3D"outline-2">
<h2 id=3D"8">duras 2.1.1 =E2=80=94 daily notes as plain text files</h2>
<div class=3D"outline-text-2" id=3D"text-8">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-duras-2-1-1-daily-notes=
-as-plain-text-files/18299/1">https://discuss.ocaml.org/t/ann-duras-2-1-1-d=
aily-notes-as-plain-text-files/18299/1</a>
</p>
</div>
<div id=3D"outline-container-org7374af3" class=3D"outline-3">
<h3 id=3D"org7374af3">Sergiy Duras announced</h3>
<div class=3D"outline-text-3" id=3D"text-org7374af3">
<p>
<b>duras</b> is a command-line tool for daily notes stored as plain text fi=
les (<code>YYYY/MM/YYYY-MM-DD.dn</code>). No database, no daemon, no backgr=
ound services.
</p>
<p>
v2.1.1 adds <code>duras build</code>, which converts a note collection to a=
static HTML website. 7,300 notes in \~220ms, single-threaded, no caching. =
Notes use <a href=3D"https://codeberg.org/duras/sigline">sigline</a> format=
=E2=80=94 a plain-text structured notation where the leading character of =
each line declares its type.
</p>
<ul class=3D"org-ul">
<li>Source: <a href=3D"https://codeberg.org/duras/duras">https://codeberg.o=
rg/duras/duras</a></li>
<li>Install: <code>opam install duras</code></li>
<li>Man page: <code>man duras</code></li>
</ul>
</div>
</div>
</div>
<div id=3D"outline-container-9" class=3D"outline-2">
<h2 id=3D"9">Software Engineer at LexiFi (Paris)</h2>
<div class=3D"outline-text-2" id=3D"text-9">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/job-software-engineer-at-le=
xifi-paris/18304/1">https://discuss.ocaml.org/t/job-software-engineer-at-le=
xifi-paris/18304/1</a>
</p>
</div>
<div id=3D"outline-container-orgddf8848" class=3D"outline-3">
<h3 id=3D"orgddf8848">Nicolas Ojeda Bar announced</h3>
<div class=3D"outline-text-3" id=3D"text-orgddf8848">
<p>
Dear all,
</p>
<p>
<a href=3D"https://www.lexifi.com/">LexiFi</a> is hiring! We are looking fo=
r a full-time Software Engineer to join our core development team.
</p>
<p>
We are particularly interested in candidates with a strong programming back=
ground, for example through previous industrial experience, contributions t=
o open-source projects, or substantial personal projects.
</p>
<p>
LexiFi has been using OCaml for more than 25 years=E2=80=94we were the firs=
t software company to build our products on OCaml=E2=80=94and we still impl=
ement the vast majority of our stack in OCaml. If you're excited about usin=
g OCaml to solve real-world industrial problems, we would love to hear from=
you.
</p>
<p>
<a href=3D"https://www.lexifi.com/careers/software_engineer/">https://www.l=
exifi.com/careers/software_engineer/</a>
</p>
<p>
Work at LexiFi spans a wide range of projects across multiple domains. We a=
lso remain actively engaged with the OCaml community and strive to give bac=
k in various ways, including funding community projects, helping maintain t=
he OCaml compiler and other open-source projects, and participating in conf=
erences.
</p>
<p>
If you have any questions, please don't hesitate to reach out to me, either=
here or privately.
</p>
<p>
Cheers,
Nicolas
</p>
</div>
</div>
</div>
<div id=3D"outline-container-10" class=3D"outline-2">
<h2 id=3D"10">Owebview : OCaml binding to the webview library</h2>
<div class=3D"outline-text-2" id=3D"text-10">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/owebview-ocaml-binding-to-t=
he-webview-library/18305/1">https://discuss.ocaml.org/t/owebview-ocaml-bind=
ing-to-the-webview-library/18305/1</a>
</p>
</div>
<div id=3D"outline-container-org0992b5c" class=3D"outline-3">
<h3 id=3D"org0992b5c">Korkorran announced</h3>
<div class=3D"outline-text-3" id=3D"text-org0992b5c">
<p>
Hi everyone! =F0=9F=91=8B
</p>
<p>
I'd like to share a small project I've been working on: <b>owebview</b>, a =
set of OCaml bindings for <a href=3D"https://github.com/webview/webview">we=
bview</a>.
</p>
</div>
<div id=3D"outline-container-org91e9f39" class=3D"outline-4">
<h4 id=3D"org91e9f39">What is webview?</h4>
<div class=3D"outline-text-4" id=3D"text-org91e9f39">
<p>
<a href=3D"https://github.com/webview/webview">webview</a> is a tiny, cross=
-platform library for building desktop GUIs using the operating system's bu=
ilt-in web engine =E2=80=94 WebKit on macOS, WebKitGTK on Linux, and WebVie=
w2 on Windows. Instead of shipping a whole browser like Electron, you reuse=
the system one, so your apps stay small. You create a window, point it at =
some HTML (or a URL), and you can call back and forth between the page's Ja=
vaScript and your host language.
</p>
</div>
</div>
<div id=3D"outline-container-orgfeea64e" class=3D"outline-4">
<h4 id=3D"orgfeea64e">The gap owebview fills</h4>
<div class=3D"outline-text-4" id=3D"text-orgfeea64e">
<p>
What makes webview really appealing is its ecosystem: it already has bindin=
gs in a <b>lot</b> of languages =E2=80=94 Go (the reference one), Rust, Pyt=
hon, C#, Nim, Zig, and many more. As far as I could tell, though, there was=
n't one for <b>OCaml</b>.
</p>
<p>
owebview is an attempt to fill that gap: a thin binding that lets you drive=
webview directly from OCaml, with a native bridge between the page's JavaS=
cript and your OCaml functions.
</p>
</div>
</div>
<div id=3D"outline-container-org07ed693" class=3D"outline-4">
<h4 id=3D"org07ed693">What it looks like</h4>
<div class=3D"outline-text-4" id=3D"text-org07ed693">
<p>
A complete app is about ten lines:
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">let</span> () =3D
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">w</span> =3D <span style=3D"color: #557400; font-weigh=
t: bold;">Webview.</span>create () <span style=3D"color: #242521; font-weig=
ht: bold;">in</span>
<span style=3D"color: #557400; font-weight: bold;">Webview.</span>set_tit=
le w <span style=3D"color: #ca3400;">"My first owebview app"</span>;
<span style=3D"color: #557400; font-weight: bold;">Webview.</span>set_siz=
e w \<span style=3D"color: #444fcf; font-weight: bold;">~width</span>:480 \=
<span style=3D"color: #444fcf; font-weight: bold;">~height</span>:320 <span=
style=3D"color: #557400; font-weight: bold;">Webview.</span><span style=3D=
"color: #242521;">Hint_none</span>;
<span style=3D"color: #557400; font-weight: bold;">Webview.</span>set_htm=
l w
<span style=3D"color: #ca3400;">{|<!doctype html></span>
<span style=3D"color: #ca3400;"> <html><body style=3D"font-fa=
mily: system-ui; text-align: center"></span>
<span style=3D"color: #ca3400;"> <h1>Hello from OCaml 👋=
;</h1></span>
<span style=3D"color: #ca3400;"> </body></html>|}</span>;
<span style=3D"color: #557400; font-weight: bold;">Webview.</span>run w;
<span style=3D"color: #557400; font-weight: bold;">Webview.</span>destroy=
w
</code></pre>
</div>
<p>
And you can expose OCaml functions to the page =E2=80=94 here <code>window.=
add(a, b)</code>
returns a JavaScript Promise resolved from OCaml:
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #557400; font-weig=
ht: bold;">Webview.</span>bind w <span style=3D"color: #ca3400;">"add"</spa=
n> (<span style=3D"color: #006f00; font-weight: bold;">fun</span> <span sty=
le=3D"color: #007a9f;">id</span> <span style=3D"color: #007a9f;">req</span>=
->
<span style=3D"color: #242521; font-weight: bold;">let</span> <span style=
=3D"color: #007a9f;">result</span> =3D
<span style=3D"color: #006f00; font-weight: bold;">match</span> <span sty=
le=3D"color: #557400; font-weight: bold;">Scanf.</span>sscanf_opt req <span=
style=3D"color: #ca3400;">"\[%d,%d\]"</span> (<span style=3D"color: #006f0=
0; font-weight: bold;">fun</span> <span style=3D"color: #007a9f;">a</span> =
<span style=3D"color: #007a9f;">b</span> -> a + b) <span style=3D"color:=
#006f00; font-weight: bold;">with</span>
| <span style=3D"color: #242521;">Some</span> n -> string_of_int n
| <span style=3D"color: #242521;">None</span> -> <span style=3D"color:=
#ca3400;">"null"</span>
<span style=3D"color: #242521; font-weight: bold;">in</span>
<span style=3D"color: #557400; font-weight: bold;">Webview.</span>return =
w id \<span style=3D"color: #444fcf; font-weight: bold;">~error</span>:<spa=
n style=3D"color: #00824f;">false</span> \~result)
</code></pre>
</div>
</div>
</div>
<div id=3D"outline-container-org5dbc3ad" class=3D"outline-4">
<h4 id=3D"org5dbc3ad">Try it</h4>
<div class=3D"outline-text-4" id=3D"text-org5dbc3ad">
<div class=3D"org-src-container">
<pre class=3D"src src-shell"><code><span style=3D"color: #8f6f4a; font-styl=
e: italic;"># </span><span style=3D"color: #8f6f4a; font-style: italic;">Ru=
n the bundled example</span>
git clone https://github.com/korkorran/owebview.git
<span style=3D"color: #557400; font-weight: bold;">cd</span> owebview
dune exec examples/hellowv.exe
<span style=3D"color: #8f6f4a; font-style: italic;"># </span><span style=3D=
"color: #8f6f4a; font-style: italic;">Or pin it into your own project</span>
opam pin add owebview https://github.com/korkorran/owebview.git
</code></pre>
</div>
<p>
Then just add <code>(libraries owebview.webview)</code> to your dune file. =
The <code>webview.h</code> header is vendored, and the platform-specific C+=
+ flags are detected at build time (via <code>pkg-config</code> on Linux), =
so there's nothing to wire up by hand.
</p>
</div>
</div>
<div id=3D"outline-container-orgb57962e" class=3D"outline-4">
<h4 id=3D"orgb57962e">Honest status & a request</h4>
<div class=3D"outline-text-4" id=3D"text-orgb57962e">
<p>
This is a <b>compact binding / starting point</b>, not a complete library y=
et:
some pieces (<code>unbind</code>, <code>dispatch</code>, full binding memor=
y management) are intentionally left out for now.
</p>
<p>
It's also developed and tested mainly on <b><b>macOS</b></b>. I'd love feed=
back from people running it on <b><b>Linux distributions</b></b> =E2=80=94 =
does it compile, do the opam <code>depexts</code> resolve, does the <code>w=
ebkit2gtk-4.1</code> backend behave on your distro?
</p>
<p>
Issues and PRs are very welcome.
</p>
<p>
Repository: <a href=3D"https://github.com/korkorran/owebview">https://githu=
b.com/korkorran/owebview</a>
</p>
<p>
Thanks for reading =E2=80=94 happy to hear thoughts, suggestions, and espec=
ially Linux build reports!
</p>
</div>
</div>
</div>
</div>
<div id=3D"outline-container-11" class=3D"outline-2">
<h2 id=3D"11">OCaml Runtime Meeting: Mon, July 6 @ 10:00 UTC (10:00 London/=
Cambridge, 11:00 Paris, 7pm Sydney)</h2>
<div class=3D"outline-text-2" id=3D"text-11">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ocaml-runtime-meeting-mon-j=
uly-6-10-00-utc-10-00-london-cambridge-11-00-paris-7pm-sydney/18312/1">http=
s://discuss.ocaml.org/t/ocaml-runtime-meeting-mon-july-6-10-00-utc-10-00-lo=
ndon-cambridge-11-00-paris-7pm-sydney/18312/1</a>
</p>
</div>
<div id=3D"outline-container-orgbed18bc" class=3D"outline-3">
<h3 id=3D"orgbed18bc">Tim McGilchrist announced</h3>
<div class=3D"outline-text-3" id=3D"text-orgbed18bc">
<p>
The next OCaml Runtime Meeting is Monday July 6th (2026-07-06) at 10:00 UTC=
(10:00 London/Cambridge, 11:00 Paris, 7pm Sydney). The agenda notes are he=
re <a href=3D"https://hackmd.io/@tmcgilchrist/S1RtObvWGe">https://hackmd.io=
/@tmcgilchrist/S1RtObvWGe</a> email [email protected] if you want a calendar =
invite.
</p>
<p>
Approximately every month we have an informal meeting between OCaml develop=
ers with a focus on the language runtime/garbage collector. The meetings ar=
e for sharing understanding and ideas, not for formal planning purposes. Th=
ey are open to any interested developer.
</p>
<p>
Previous meeting notes available in <a href=3D"https://github.com/ocaml/sub=
system-meetings">https://github.com/ocaml/subsystem-meetings</a>
</p>
</div>
</div>
</div>
<div id=3D"outline-container-org816b529" class=3D"outline-2">
<h2 id=3D"org816b529">Old CWN</h2>
<div class=3D"outline-text-2" id=3D"text-org816b529">
<p>
If you happen to miss a CWN, you can <a href=3D"mailto:alan.schmitt@polytec=
hnique.org">send me a message</a> and I'll mail it to you, or go take a loo=
k at <a href=3D"https://alan.petitepomme.net/cwn/">the archive</a> or the <=
a href=3D"https://alan.petitepomme.net/cwn/cwn.rss">RSS feed of the archive=
s</a>.
</p>
<p>
If you also wish to receive it every week by mail, you may subscribe to the=
<a href=3D"https://sympa.inria.fr/sympa/info/caml-list">caml-list</a>.
</p>
<div class=3D"authorname" id=3D"orgd1ab7cc">
<p>
<a href=3D"https://alan.petitepomme.net/">Alan Schmitt</a>
</p>
</div>
</div>
</div>
</div>
</body>
</html>
--==-=-=--
--=-=-=--
--===-=-=
Content-Type: application/pgp-signature; name="signature.asc"
-----BEGIN PGP SIGNATURE-----
iQFvBAEBCABZFiEE6lXof/BsSVW56ZmGBA0KO07S5ccFAmpDw8EbFIAAAAAABAAO
bWFudTIsMi41KzEuMTIsMCwzHxxhbGFuLnNjaG1pdHRAcG9seXRlY2huaXF1ZS5v
cmcACgkQBA0KO07S5cc8tAf+MJGm8rY29TpInnF601tWdXa3xzrMPABHX3JY3YZi
HjFaZ3ZD4YmrNiN8BnqC3SV/mbbCvMVqsGwrPtbkRwfCL4L9wjF3anpaadhWoks6
TpytkkSdJyjIFSevhYIRUV44wLBH6dWWeeNyZdoUEEetF7W7+kvbYUqooTtuCHV7
s1I67lY54Qg3+E9XK7OEcgjpbsHwQpqnHkv2g20fmk8cauo8yZBfeUWdt0aT1ftz
CYumyVJ33lfBQYrYGd0ocgtteVnsuW+xg6+135NKRYAlI/4cuyO7/U+ASW/KLKBd
DDw+tidF77U2BaclnmLfXcyDvHMt2t2PlRu7Ey4Z6TlODQ==
=5VYK
-----END PGP SIGNATURE-----
--===-=-=--