From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id q2L9fx3K021434 for ; Wed, 21 Mar 2012 10:42:01 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Am0BAFqhaU/RVdS0imdsb2JhbABDDrVteggiAQEBCgkNBxIGI4IJAQEBAwESAhMZARsdAQMBCwYFCzsCIAERAQUBHAYuB4djBZl4CowTgnGFHj+IdgEFC5B2BJVfjkg9g1I4 X-IronPort-AV: E=Sophos;i="4.73,623,1325458800"; d="scan'208";a="137068471" Received: from mail-wi0-f180.google.com ([209.85.212.180]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 21 Mar 2012 10:42:01 +0100 Received: by wibhm17 with SMTP id hm17so1084152wib.9 for ; Wed, 21 Mar 2012 02:42:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=iOg2MU1i9kVurz95hofNcfOezhZF/ZmCNxFdtp8qakw=; b=q/lJT2fYFq0LGTs4+VPhSS/lFXTYQ2U7MU/cINJQZyivKy5J9ntzCtMNDQQhYW0uV7 Y2ZhFzMDNLEdSg5JC6SBBOMTa4NXe6vrq23cbbhgKD6HFTp2AVZWyQurT5I6F6YiXnPd vGBdVim02AOmsDqAXeShdqnYV2SjIIROOBu+/gzbiGhy5Vw8vVjUpBecMRhb2cv/IxhY qDAO9uHp1kNkKNLG1+Nb6C+dpcjHn0dhHNgzd6KbTJggPo7ykqahoD31Tp8MnD1Wnw7t uKmB8VxU18A4asD455TKyL5AHS8qC4yvkF7shtWcVEcjivmsz1Z+0YzGKxJ1UaeVBLEa 7DUQ== Received: by 10.180.103.35 with SMTP id ft3mr7449798wib.0.1332322920985; Wed, 21 Mar 2012 02:42:00 -0700 (PDT) MIME-Version: 1.0 Received: by 10.180.126.68 with HTTP; Wed, 21 Mar 2012 02:41:39 -0700 (PDT) In-Reply-To: <3EB8D30A-FB02-4654-9F95-B7FF029F02FE@math.nagoya-u.ac.jp> References: <3EB8D30A-FB02-4654-9F95-B7FF029F02FE@math.nagoya-u.ac.jp> From: Philippe Veber Date: Wed, 21 Mar 2012 10:41:39 +0100 Message-ID: To: Jacques Garrigue Cc: caml users Content-Type: multipart/alternative; boundary=f46d043bd7e86e72c504bbbd9a73 X-Validation-by: philippe.veber@gmail.com Subject: Re: [Caml-list] Explicitely named type variable and type constraints. --f46d043bd7e86e72c504bbbd9a73 Content-Type: text/plain; charset=ISO-8859-1 Thanks for your answer Jacques! > ([> `quit ] as 'a) screen = (module Screen with type message = > 'a) > > but an expression was expected of type (module Screen) > > Indeed, this is clearly wrong: these two module types are not equivalent. > Right, that one was obvious. > > New attempt: > > > > # let f (screen : 'a screen) = > > let module Screen = (val screen : Screen with type message = 'a) in > > match Screen.(emit init) with > > | Some `quit -> 1 > > | _ -> 0 > > > > ;; > > Error: Unbound type parameter 'a > > Wrong again, as subtyping between module signatures does not > allow free type variables. > At some point, I remember having a message saying that indeed type variables are not allowed while unpacking the module, at least something closer to what you say and more specific than "unbound type parameter 'a". So I'd say it would be more convenient to have a specific message (just like there is for unbound type variables in class definitions for instance). If you don't consider it too futile, I can test it on the SVN head and file a bug report if appropriate. > > > Though here I'm not sure the error is right. New attempt: > > > > > > # let f (type s) (screen : s screen) = > > let module Screen = (val screen : Screen with type message = s) in > > match Screen.(emit init) with > > | Some `quit -> 1 > > | _ -> 0 > > > > ;; > > Error: This type s should be an instance of type [> `quit ] > > > > Which makes sense. So here is my question: is there a way to impose a > constraint on the "newtype" introduced in argument? Let me say that I'm > aware I should write this more simply. For instance in the module type > Screen, emit could have type state -> [`quit | `message of message]. So my > question is only a matter of curiosity. Still, I'd be happy to know :o). > > No, currently there is no way to do that. > One can only create locally abstract types, not locally private types. > Ok. > In theory I see no problem doing that, but with the current approach this > would require new syntax, > and be rather heavy. > > let f (type s = private [> `quit]) (screen : s screen) = ... > > And to be fully general, recursion between those types should be allowed > too... > Probably not worth the trouble. I'm just not used to writing a type and not being able to write a function using values of this type afterwards :o). > > As a side note, writing > type message = private [> unit] > makes the problem clearer. > And solves it in some cases: > > module type Screen = > sig > type state > type message = private [> `quit ] > val init : state > val emit : state -> message option > end > # let f (module Screen : Screen) = > match Screen.(emit init) with > | Some `quit -> 1 > | _ -> 0 > ;; > val f : (module Screen) -> int = > Indeed that works! (with appropriate 3.12 syntax). # module type Screen = sig type state type message = private [> `quit ] val init : state val emit : state -> message option end;; module type Screen = sig type state type message = private [> `quit ] val init : state val emit : state -> message option end # let f screen = let module Screen = (val screen : Screen) in match Screen.emit Screen.init with Some `quit -> 1 | _ -> 0;; val f : (module Screen) -> int = # module Screen1 : Screen = struct type state = unit type message = [`a | `quit] let init = () let emit () = Some `a end;; module Screen1 : Screen # module Screen2 : Screen = struct type state = int type message = [`a | `quit] let init = 0 let emit _ = Some `quit end;; module Screen2 : Screen # [ (module Screen1 : Screen) ; (module Screen2 : Screen) ];; - : (module Screen) list = [; ] This nearly solves my problem: there will be several Screen modules, and those should share a common message type, so that they can communicate. That's why I introduced the 'a screen type. However, it seems that I can't define it anymore: # type 'a screen = (module Screen with type message = 'a) constraint 'a = [> `quit];; Error: In this `with' constraint, the new definition of message does not match its original definition in the constrained signature: Type declarations do not match: type message is not included in type message = private [> `quit ] # type 'a screen = (module Screen with type message = 'a constraint 'a = [> `quit]);; Error: Syntax error It's only logical the first attempt fails. The second, however, seems more reasonable to me (but I guess if type constraints are only allowed in type definition there must be a good reason). Is there a workaround? In the end, I'd want to define a list of Screen modules that share a common message type containing the `quit tag. That said, I remember the work by Romain Bardou and yourself on unions of private polymorphic variants, and I guess we might face difficult problems here. In any case, I have a backup solution, so it's no big deal if it isn't possible. > (using 4.00, but you can also write with (val ...)) > > That remark was unfortunate: now my thread is spoiled for sure :o))) --f46d043bd7e86e72c504bbbd9a73 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: base64 VGhhbmtzIGZvciB5b3VyIGFuc3dlciBKYWNxdWVzITxicj48YnI+PGRpdiBj bGFzcz0iZ21haWxfcXVvdGUiPjxibG9ja3F1b3RlIGNsYXNzPSJnbWFpbF9x dW90ZSIgc3R5bGU9Im1hcmdpbjowIDAgMCAuOGV4O2JvcmRlci1sZWZ0OjFw eCAjY2NjIHNvbGlkO3BhZGRpbmctbGVmdDoxZXgiPjxkaXYgY2xhc3M9Imlt Ij4KJmd0OyCgIKAgoCCgIKAoWyZndDsgYHF1aXQgXSBhcyAmIzM5O2EpIHNj cmVlbiA9IChtb2R1bGUgU2NyZWVuIHdpdGggdHlwZSBtZXNzYWdlID0gJiMz OTthKTxicj4KJmd0OyCgIKAgoCCgYnV0IGFuIGV4cHJlc3Npb24gd2FzIGV4 cGVjdGVkIG9mIHR5cGUgKG1vZHVsZSBTY3JlZW4pPGJyPgo8YnI+CjwvZGl2 PkluZGVlZCwgdGhpcyBpcyBjbGVhcmx5IHdyb25nOiB0aGVzZSB0d28gbW9k dWxlIHR5cGVzIGFyZSBub3QgZXF1aXZhbGVudC48YnI+PC9ibG9ja3F1b3Rl PjxkaXY+UmlnaHQsIHRoYXQgb25lIHdhcyBvYnZpb3VzLjxicj48YnI+PC9k aXY+PGJsb2NrcXVvdGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0ibWFy Z2luOjBwdCAwcHQgMHB0IDAuOGV4O2JvcmRlci1sZWZ0OjFweCBzb2xpZCBy Z2IoMjA0LDIwNCwyMDQpO3BhZGRpbmctbGVmdDoxZXgiPgoKCjxkaXYgY2xh c3M9ImltIj48YnI+CiZndDsgTmV3IGF0dGVtcHQ6PGJyPgomZ3Q7PGJyPgom Z3Q7ICMgbGV0IGYgKHNjcmVlbiA6ICYjMzk7YSBzY3JlZW4pID08YnI+CiZn dDsgoCCgIGxldCBtb2R1bGUgU2NyZWVuID0gKHZhbCBzY3JlZW4gOiBTY3Jl ZW4gd2l0aCB0eXBlIG1lc3NhZ2UgPSAmIzM5O2EpIGluPGJyPgomZ3Q7IKAg oCBtYXRjaCBTY3JlZW4uKGVtaXQgaW5pdCkgd2l0aDxicj4KJmd0OyCgIKAg oCB8IFNvbWUgYHF1aXQgLSZndDsgMTxicj4KJmd0OyCgIKAgoCB8IF8gLSZn dDsgMDxicj4KJmd0Ozxicj4KJmd0OyCgIDs7PGJyPgomZ3Q7IEVycm9yOiBV bmJvdW5kIHR5cGUgcGFyYW1ldGVyICYjMzk7YTxicj4KPGJyPgo8L2Rpdj5X cm9uZyBhZ2FpbiwgYXMgc3VidHlwaW5nIGJldHdlZW4gbW9kdWxlIHNpZ25h dHVyZXMgZG9lcyBub3Q8YnI+CmFsbG93IGZyZWUgdHlwZSB2YXJpYWJsZXMu PGJyPjwvYmxvY2txdW90ZT48ZGl2PkF0IHNvbWUgcG9pbnQsIEkgcmVtZW1i ZXIgaGF2aW5nIGEgbWVzc2FnZSBzYXlpbmcgdGhhdCBpbmRlZWQgdHlwZSB2 YXJpYWJsZXMgYXJlIG5vdCBhbGxvd2VkIHdoaWxlIHVucGFja2luZyB0aGUg bW9kdWxlLCBhdCBsZWFzdCBzb21ldGhpbmcgY2xvc2VyIHRvIHdoYXQgeW91 IHNheSBhbmQgbW9yZSBzcGVjaWZpYyB0aGFuICZxdW90O3VuYm91bmQgdHlw ZSBwYXJhbWV0ZXIgJiMzOTthJnF1b3Q7LiBTbyBJJiMzOTtkIHNheSBpdCB3 b3VsZCBiZSBtb3JlIGNvbnZlbmllbnQgdG8gaGF2ZSBhIHNwZWNpZmljIG1l c3NhZ2UgKGp1c3QgbGlrZSB0aGVyZSBpcyBmb3IgdW5ib3VuZCB0eXBlIHZh cmlhYmxlcyBpbiBjbGFzcyBkZWZpbml0aW9ucyBmb3IgaW5zdGFuY2UpLiBJ ZiB5b3UgZG9uJiMzOTt0IGNvbnNpZGVyIGl0IHRvbyBmdXRpbGUsIEkgY2Fu IHRlc3QgaXQgb24gdGhlIFNWTiBoZWFkIGFuZCBmaWxlIGEgYnVnIHJlcG9y dCBpZiBhcHByb3ByaWF0ZS4gPGJyPgoKoDwvZGl2PjxibG9ja3F1b3RlIGNs YXNzPSJnbWFpbF9xdW90ZSIgc3R5bGU9Im1hcmdpbjowcHQgMHB0IDBwdCAw LjhleDtib3JkZXItbGVmdDoxcHggc29saWQgcmdiKDIwNCwyMDQsMjA0KTtw YWRkaW5nLWxlZnQ6MWV4Ij4KPGRpdiBjbGFzcz0iaW0iPjxicj4KJmd0OyBU aG91Z2ggaGVyZSBJJiMzOTttIG5vdCBzdXJlIHRoZSBlcnJvciBpcyByaWdo dC4gTmV3IGF0dGVtcHQ6PGJyPgomZ3Q7PGJyPgomZ3Q7PGJyPgomZ3Q7ICMg bGV0IGYgKHR5cGUgcykgKHNjcmVlbiA6IHMgc2NyZWVuKSA9PGJyPgomZ3Q7 IKAgoCBsZXQgbW9kdWxlIFNjcmVlbiA9ICh2YWwgc2NyZWVuIDogU2NyZWVu IHdpdGggdHlwZSBtZXNzYWdlID0gcykgaW48YnI+CiZndDsgoCCgIG1hdGNo IFNjcmVlbi4oZW1pdCBpbml0KSB3aXRoPGJyPgomZ3Q7IKAgoCCgIHwgU29t ZSBgcXVpdCAtJmd0OyAxPGJyPgomZ3Q7IKAgoCCgIHwgXyAtJmd0OyAwPGJy PgomZ3Q7PGJyPgomZ3Q7IKAgOzs8YnI+CiZndDsgRXJyb3I6IFRoaXMgdHlw ZSBzIHNob3VsZCBiZSBhbiBpbnN0YW5jZSBvZiB0eXBlIFsmZ3Q7IGBxdWl0 IF08YnI+CiZndDs8YnI+CiZndDsgV2hpY2ggbWFrZXMgc2Vuc2UuIFNvIGhl cmUgaXMgbXkgcXVlc3Rpb246IGlzIHRoZXJlIGEgd2F5IHRvIGltcG9zZSBh IGNvbnN0cmFpbnQgb24gdGhlICZxdW90O25ld3R5cGUmcXVvdDsgaW50cm9k dWNlZCBpbiBhcmd1bWVudD8gTGV0IG1lIHNheSB0aGF0IEkmIzM5O20gYXdh cmUgSSBzaG91bGQgd3JpdGUgdGhpcyBtb3JlIHNpbXBseS4gRm9yIGluc3Rh bmNlIGluIHRoZSBtb2R1bGUgdHlwZSBTY3JlZW4sIGVtaXQgY291bGQgaGF2 ZSB0eXBlIHN0YXRlIC0mZ3Q7IFtgcXVpdCB8IGBtZXNzYWdlIG9mIG1lc3Nh Z2VdLiBTbyBteSBxdWVzdGlvbiBpcyBvbmx5IGEgbWF0dGVyIG9mIGN1cmlv c2l0eS4gU3RpbGwsIEkmIzM5O2QgYmUgaGFwcHkgdG8ga25vdyA6bykuPGJy PgoKCjxicj4KPC9kaXY+Tm8sIGN1cnJlbnRseSB0aGVyZSBpcyBubyB3YXkg dG8gZG8gdGhhdC48YnI+Ck9uZSBjYW4gb25seSBjcmVhdGUgbG9jYWxseSBh YnN0cmFjdCB0eXBlcywgbm90IGxvY2FsbHkgcHJpdmF0ZSB0eXBlcy48YnI+ PC9ibG9ja3F1b3RlPjxkaXY+T2suPGJyPqA8YnI+PC9kaXY+PGJsb2NrcXVv dGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0ibWFyZ2luOjBwdCAwcHQg MHB0IDAuOGV4O2JvcmRlci1sZWZ0OjFweCBzb2xpZCByZ2IoMjA0LDIwNCwy MDQpO3BhZGRpbmctbGVmdDoxZXgiPgoKCkluIHRoZW9yeSBJIHNlZSBubyBw cm9ibGVtIGRvaW5nIHRoYXQsIGJ1dCB3aXRoIHRoZSBjdXJyZW50IGFwcHJv YWNoIHRoaXMgd291bGQgcmVxdWlyZSBuZXcgc3ludGF4LDxicj4KYW5kIGJl IHJhdGhlciBoZWF2eS48YnI+Cjxicj4KIKBsZXQgZiAodHlwZSBzID0gcHJp dmF0ZSBbJmd0OyBgcXVpdF0pIChzY3JlZW4gOiBzIHNjcmVlbikgPSAuLi48 YnI+Cjxicj4KQW5kIHRvIGJlIGZ1bGx5IGdlbmVyYWwsIHJlY3Vyc2lvbiBi ZXR3ZWVuIHRob3NlIHR5cGVzIHNob3VsZCBiZSBhbGxvd2VkIHRvby4uLjxi cj48L2Jsb2NrcXVvdGU+PGRpdj5Qcm9iYWJseSBub3Qgd29ydGggdGhlIHRy b3VibGUuIEkmIzM5O20ganVzdCBub3QgdXNlZCB0byB3cml0aW5nIGEgdHlw ZSBhbmQgbm90IGJlaW5nIGFibGUgdG8gd3JpdGUgYSBmdW5jdGlvbiB1c2lu ZyB2YWx1ZXMgb2YgdGhpcyB0eXBlIGFmdGVyd2FyZHMgOm8pLjxicj4KCqA8 L2Rpdj48YmxvY2txdW90ZSBjbGFzcz0iZ21haWxfcXVvdGUiIHN0eWxlPSJt YXJnaW46MHB0IDBwdCAwcHQgMC44ZXg7Ym9yZGVyLWxlZnQ6MXB4IHNvbGlk IHJnYigyMDQsMjA0LDIwNCk7cGFkZGluZy1sZWZ0OjFleCI+Cjxicj4KQXMg YSBzaWRlIG5vdGUsIHdyaXRpbmc8YnI+CiCgIKAgoCCgdHlwZSBtZXNzYWdl ID0gcHJpdmF0ZSBbJmd0OyB1bml0XTxicj4KbWFrZXMgdGhlIHByb2JsZW0g Y2xlYXJlci48YnI+CkFuZCBzb2x2ZXMgaXQgaW4gc29tZSBjYXNlczo8YnI+ CjxkaXYgY2xhc3M9ImltIj48YnI+Cm1vZHVsZSB0eXBlIFNjcmVlbiA9PGJy PgogoHNpZzxicj4KIKAgoHR5cGUgc3RhdGU8YnI+CjwvZGl2PiCgIKB0eXBl IG1lc3NhZ2UgPSBwcml2YXRlIFsmZ3Q7IGBxdWl0IF08YnI+CiCgIKB2YWwg aW5pdCA6IHN0YXRlPGJyPgo8ZGl2IGNsYXNzPSJpbSI+IKAgoHZhbCBlbWl0 IDogc3RhdGUgLSZndDsgbWVzc2FnZSBvcHRpb248YnI+CiCgZW5kPGJyPgo8 L2Rpdj4jIGxldCBmIChtb2R1bGUgU2NyZWVuIDogU2NyZWVuKSA9PGJyPgo8 ZGl2IGNsYXNzPSJpbSI+IKAgoG1hdGNoIFNjcmVlbi4oZW1pdCBpbml0KSB3 aXRoPGJyPgogoCCgfCBTb21lIGBxdWl0IC0mZ3Q7IDE8YnI+CiCgIKB8IF8g LSZndDsgMDxicj4KIKA7Ozxicj4KPC9kaXY+dmFsIGYgOiAobW9kdWxlIFNj cmVlbikgLSZndDsgaW50ID0gJmx0O2Z1biZndDs8YnI+PC9ibG9ja3F1b3Rl PjxkaXY+SW5kZWVkIHRoYXQgd29ya3MhICh3aXRoIGFwcHJvcHJpYXRlIDMu MTIgc3ludGF4KS4gPGJyPjxicj4jIG1vZHVsZSB0eXBlIFNjcmVlbiA9oKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8YnI+Cgqgc2lnoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8YnI+oKAgdHlwZSBz dGF0ZaCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgPGJyPgoK oKAgdHlwZSBtZXNzYWdlID0gcHJpdmF0ZSBbJmd0OyBgcXVpdCBdoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKAgPGJyPqCgIHZhbCBpbml0IDogc3RhdGWgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgIDxicj4KCqCgIHZhbCBlbWl0IDogc3RhdGUgLSZndDsg bWVzc2FnZSBvcHRpb26goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIDxicj6gZW5kOzugoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8YnI+Cgptb2R1bGUg dHlwZSBTY3JlZW4gPaCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8YnI+ oCBzaWegoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKAgPGJyPgoKoKCgIHR5cGUgc3RhdGWgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKAgPGJyPqCgoCB0eXBlIG1lc3NhZ2UgPSBwcml2YXRlIFsm Z3Q7IGBxdWl0IF08YnI+CgqgoKAgdmFsIGluaXQgOiBzdGF0ZTxicj6goKAg dmFsIGVtaXQgOiBzdGF0ZSAtJmd0OyBtZXNzYWdlIG9wdGlvbjxicj6gIGVu ZDxicj4jIGxldCBmIHNjcmVlbiA9IGxldCBtb2R1bGUgU2NyZWVuID0gKHZh bCBzY3JlZW4gOiBTY3JlZW4pIGluIG1hdGNoIFNjcmVlbi5lbWl0IFNjcmVl bi5pbml0IHdpdGggU29tZSBgcXVpdCAtJmd0OyAxIHwgXyAtJmd0OyAwOzug oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoCA8YnI+Cgp2YWwgZiA6IChtb2R1bGUgU2NyZWVuKSAt Jmd0OyBpbnQgPSAmbHQ7ZnVuJmd0O6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8YnI+IyBtb2R1bGUg U2NyZWVuMSA6IFNjcmVlbiA9IHN0cnVjdCB0eXBlIHN0YXRlID0gdW5pdCB0 eXBlIG1lc3NhZ2UgPSBbYGEgfCBgcXVpdF0gbGV0IGluaXQgPSAoKSBsZXQg ZW1pdCAoKSA9IFNvbWUgYGEgZW5kOzugoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgPGJyPgoK bW9kdWxlIFNjcmVlbjEgOiBTY3JlZW6goKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKAgPGJyPiMgbW9kdWxlIFNjcmVlbjIgOiBTY3JlZW4gPSBzdHJ1Y3QgdHlw ZSBzdGF0ZSA9IGludCB0eXBlIG1lc3NhZ2UgPSBbYGEgfCBgcXVpdF0gbGV0 IGluaXQgPSAwIGxldCBlbWl0IF8gPSBTb21lIGBxdWl0IGVuZDs7oKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgIDxicj4KCm1vZHVsZSBTY3JlZW4yIDogU2NyZWVuoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgIDxicj4jIFsgKG1vZHVsZSBTY3JlZW4xIDog U2NyZWVuKSA7IChtb2R1bGUgU2NyZWVuMiA6IFNjcmVlbikgXTs7oKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8YnI+CgotIDogKG1vZHVsZSBT Y3JlZW4pIGxpc3QgPSBbJmx0O21vZHVsZSZndDs7ICZsdDttb2R1bGUmZ3Q7 XaCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oCA8YnI+PGJyPlRoaXMgbmVhcmx5IHNvbHZlcyBteSBwcm9ibGVtOiB0aGVy ZSB3aWxsIGJlIHNldmVyYWwgU2NyZWVuIG1vZHVsZXMsIGFuZCB0aG9zZSBz aG91bGQgc2hhcmUgYSBjb21tb24gbWVzc2FnZSB0eXBlLCBzbyB0aGF0IHRo ZXkgY2FuIGNvbW11bmljYXRlLiBUaGF0JiMzOTtzIHdoeSBJIGludHJvZHVj ZWQgdGhlICYjMzk7YSBzY3JlZW4gdHlwZS4gSG93ZXZlciwgaXQgc2VlbXMg dGhhdCBJIGNhbiYjMzk7dCBkZWZpbmUgaXQgYW55bW9yZTo8YnI+Cgo8YnI+ IyB0eXBlICYjMzk7YSBzY3JlZW4gPSAobW9kdWxlIFNjcmVlbiB3aXRoIHR5 cGUgbWVzc2FnZSA9ICYjMzk7YSkgY29uc3RyYWludCAmIzM5O2EgPSBbJmd0 OyBgcXVpdF07O6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKAgPGJyPkVycm9yOiBJbiB0aGlzIGB3aXRoJiMz OTsgY29uc3RyYWludCwgdGhlIG5ldyBkZWZpbml0aW9uIG9mIG1lc3NhZ2Wg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8YnI+CgqgoKCgoKAgZG9l cyBub3QgbWF0Y2ggaXRzIG9yaWdpbmFsIGRlZmluaXRpb24gaW4gdGhlIGNv bnN0cmFpbmVkIHNpZ25hdHVyZTqgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8YnI+oKCg oKCgIFR5cGUgZGVjbGFyYXRpb25zIGRvIG5vdCBtYXRjaDqgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAg PGJyPgoKoKCgoKCgoKAgdHlwZSBtZXNzYWdlPGJyPqCgoKCgoCBpcyBub3Qg aW5jbHVkZWQgaW48YnI+oKCgoKCgoKAgdHlwZSBtZXNzYWdlID0gcHJpdmF0 ZSBbJmd0OyBgcXVpdCBdPGJyPjxicj4jIHR5cGUgJiMzOTthIHNjcmVlbiA9 IChtb2R1bGUgU2NyZWVuIHdpdGggdHlwZSBtZXNzYWdlID0gJiMzOTthIGNv bnN0cmFpbnQgJiMzOTthID0gWyZndDsgYHF1aXRdKTs7oKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCA8YnI+ CgpFcnJvcjogU3ludGF4IGVycm9yoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgoCA8YnI+PGJyPkl0JiMzOTtzIG9ubHkgbG9naWNhbCB0aGUgZmlyc3Qg YXR0ZW1wdCBmYWlscy4gVGhlIHNlY29uZCwgaG93ZXZlciwgc2VlbXMgbW9y ZSByZWFzb25hYmxlIHRvIG1lIChidXQgSSBndWVzcyBpZiB0eXBlIGNvbnN0 cmFpbnRzIGFyZSBvbmx5IGFsbG93ZWQgaW4gdHlwZSBkZWZpbml0aW9uIHRo ZXJlIG11c3QgYmUgYSBnb29kIHJlYXNvbikuIElzIHRoZXJlIGEgd29ya2Fy b3VuZD8gSW4gdGhlIGVuZCwgSSYjMzk7ZCB3YW50IHRvIGRlZmluZSBhIGxp c3Qgb2YgU2NyZWVuIG1vZHVsZXMgdGhhdCBzaGFyZSBhIGNvbW1vbiBtZXNz YWdlIHR5cGUgY29udGFpbmluZyB0aGUgYHF1aXQgdGFnLiBUaGF0IHNhaWQs IEkgcmVtZW1iZXIgdGhlIHdvcmsgYnkgUm9tYWluIEJhcmRvdSBhbmQgeW91 cnNlbGYgb24gdW5pb25zIG9mIHByaXZhdGUgcG9seW1vcnBoaWMgdmFyaWFu dHMsIGFuZCBJIGd1ZXNzIHdlIG1pZ2h0IGZhY2UgZGlmZmljdWx0IHByb2Js ZW1zIGhlcmUuIEluIGFueSBjYXNlLCBJIGhhdmUgYSBiYWNrdXAgc29sdXRp b24sIHNvIGl0JiMzOTtzIG5vIGJpZyBkZWFsIGlmIGl0IGlzbiYjMzk7dCBw b3NzaWJsZS48YnI+Cgo8YnI+PGJyPjwvZGl2PjxibG9ja3F1b3RlIGNsYXNz PSJnbWFpbF9xdW90ZSIgc3R5bGU9Im1hcmdpbjowcHQgMHB0IDBwdCAwLjhl eDtib3JkZXItbGVmdDoxcHggc29saWQgcmdiKDIwNCwyMDQsMjA0KTtwYWRk aW5nLWxlZnQ6MWV4Ij4KPGJyPgoodXNpbmcgNC4wMCwgYnV0IHlvdSBjYW4g YWxzbyB3cml0ZSB3aXRoICh2YWwgLi4uKSk8YnI+CjxzcGFuIGNsYXNzPSJI T0VuWmIiPjwvc3Bhbj48YnI+PC9ibG9ja3F1b3RlPjwvZGl2PlRoYXQgcmVt YXJrIHdhcyB1bmZvcnR1bmF0ZTogbm93IG15IHRocmVhZCBpcyBzcG9pbGVk IGZvciBzdXJlIDpvKSkpPGJyPjxicj4K --f46d043bd7e86e72c504bbbd9a73--