<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">
<br id="lineBreakAtBeginningOfMessage">
<div><br>
<blockquote type="cite">
<div>On Mar 14, 2024, at 9:05 PM, Guy Steele <guy.steele@oracle.com> wrote:</div>
<br class="Apple-interchange-newline">
<div>
<div style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">
Thanks for these derails,</div>
</div>
</blockquote>
<div><br>
</div>
<div>Sorry: “details"</div>
<br>
<blockquote type="cite">
<div>
<div style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">
but they don’t quite answer my question: how does the compiler makes the decision to require the prefix? Specifically, is it done purely by examining the types of the literals (in which case the existing story, about how method overloading decides which of
several methods with the same name to call, is adequate), or are you imagining some additional ad-hoc mechanism that is somehow examining the syntax of method arguments (in which case some care will be needed to ensure that it interacts properly with the rest
of the method overloading resolution mechanism)? I ask because, given your explanation below, I am not seeing how types alone can do the job—but maybe I am missing something.
<div><br>
</div>
<div>—Guy<br id="lineBreakAtBeginningOfMessage">
<div><br>
<blockquote type="cite">
<div>On Mar 14, 2024, at 6:15 PM, Maurizio Cimadamore <maurizio.cimadamore@oracle.com> wrote:</div>
<br class="Apple-interchange-newline">
<div>
<div>
<p><br>
</p>
<div class="moz-cite-prefix">On 14/03/2024 22:05, Guy Steele wrote:<br>
</div>
<blockquote type="cite" cite="mid:E65EA9D5-312B-4A39-99F7-013D70C6E62C@oracle.com">
<div>Is your intent that a string interpolation literal would have a type other than String? If so, I agree that this is a third option—with the consequence that each API designer now needs to contemplate three-way overloading.</div>
<div><br>
</div>
<div>If that is not your intent, then I am not seeing how the prefix helps—so please explain?</div>
</blockquote>
<p>Let's go back to the example I mentioned:</p>
<div class="markdown-here-wrapper" data-md-url="">
<pre style="font-family: Consolas, Inconsolata, Courier, monospace; font-size: 1em; line-height: 1.2em; margin-top: 1.2em; margin-bottom: 1.2em;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0px 0.15em; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">String.format("Hello, my name is %s\{name}"); // can you spot the bug?
</code></pre>
</div>
<div class="markdown-here-wrapper" data-md-url="">There's a string with an embedded expression here. The compiler might require a prefix here (e.g. do you want a string, or a string template?). If no prefix is added (as in the above code) it might just be an
error, and this won't compile.</div>
<div class="markdown-here-wrapper" data-md-url=""><br>
</div>
<div class="markdown-here-wrapper" data-md-url="">This means that if I do:</div>
<div class="markdown-here-wrapper" data-md-url="">
<div class="markdown-here-wrapper" data-md-url="">
<pre style="font-family: Consolas, Inconsolata, Courier, monospace; font-size: 1em; line-height: 1.2em; margin-top: 1.2em; margin-bottom: 1.2em;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0px 0.15em; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">String.format(INTERPOLATED"Hello, my name is %s\{name}");
</code></pre>
</div>
</div>
<div><br class="webkit-block-placeholder">
</div>
<p>I will select String.format(String, Object...) - but I will do so deliberately - it's not just what happens "by default" (as was the case before).</p>
<p>Or, if I want the template version, I do:</p>
<pre style="font-family: Consolas, Inconsolata, Courier, monospace; font-size: 1em; line-height: 1.2em; margin-top: 1.2em; margin-bottom: 1.2em;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0px 0.15em; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">String.format(TEMPLATE"Hello, my name is %s\{name}");</code></pre>
<div><br class="webkit-block-placeholder">
</div>
<p>Basically, requiring all literals that have embedded expression to have a prefix removes the problem of defaulting on the String side of the fence. Then, personally I'd also prefer if the default was actually on the StringTemplate side of the fence, so that
the above was actually identical to this:</p>
<pre style="font-family: Consolas, Inconsolata, Courier, monospace; font-size: 1em; line-height: 1.2em; margin-top: 1.2em; margin-bottom: 1.2em;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0px 0.15em; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">String.format("Hello, my name is %s\{name}"); // ok, this is a template</code></pre>
<div><br class="webkit-block-placeholder">
</div>
<p>Note that these two prefixes might also come in handy when disambiguating a literal with no embedded expressions. Only, in that case the default would point the other way.</p>
<p>To summarize:</p>
<ul>
<li>template literal with arguments -> defaults to StringTemplate. User can ask interpolation explicitly, by adding a prefix</li><li>template literal w/o arguments -> defaults to String. User can ask a degenerate template explicitly, by adding a prefix</li></ul>
<p>This doesn't sound too bad, and it feels like it has the defaults pointing the right way?<br>
</p>
<p>Maurizio<br>
</p>
<blockquote type="cite" cite="mid:E65EA9D5-312B-4A39-99F7-013D70C6E62C@oracle.com">
<div></div>
<div>Thanks,</div>
<div>Guy</div>
<div><br>
<blockquote type="cite">
<div>On Mar 14, 2024, at 6:00 PM, Maurizio Cimadamore <a class="moz-txt-link-rfc2396E" href="mailto:maurizio.cimadamore@oracle.com">
<maurizio.cimadamore@oracle.com></a> wrote:</div>
<br class="Apple-interchange-newline">
<div>
<div>
<p><br>
</p>
<div class="moz-cite-prefix">On 14/03/2024 19:39, Guy Steele wrote:<br>
</div>
<blockquote type="cite" cite="mid:F217B131-C5FD-4587-B251-06760F08DD36@oracle.com">
This is a very important example to consider. I observe, however, that there are at least two possible ways to avoid the unpleasant surprise:
<div><br>
</div>
<div>(1) Don't have string interpolation literals, because accidentally using a string interpolation literal instead of a string template literals can result in invoking the wrong overload of a method.</div>
<div>
<div><br>
</div>
<div>(2) Don’t overload methods so as to accept either a string or a string template.</div>
</div>
</blockquote>
<p>I agree with your analysis, but note that there is also a third option:</p>
<p>(3) make it so that both string interpolation literal and string template literal have a prefix.</p>
<p>I believe that is enough to solve the issue (because the program I wrote would no longer compile: the compiler would require an explicit prefix).<br>
</p>
<p>Maurizio<br>
</p>
<blockquote type="cite" cite="mid:F217B131-C5FD-4587-B251-06760F08DD36@oracle.com">
<div>
<div><br>
</div>
<div>If we were to take approach (2), then:</div>
<div><br>
</div>
<div>(a) We would keep `println` as is, and not allow it to accept a template, but that’s okay—if you thought you wanted a template, what you really want is plan old string interpolation, and the type checking will make sure you don't use the wrong one.</div>
<div><br>
</div>
<div>
<div>(b) A SQL processor would accept a template but not a string—if you thought you wanted string interpolation, what you really want is a template, and the type checking will make sure you don't use the wrong one.</div>
<div><br>
</div>
<div>(c) I think `format` is a special case that we tend to get hung up on, and I think that, in this particular branch of the design space we are exploring, perhaps a name other than `String.format` should be chosen for the method that does string formatting
on templates. Possible names are `StringTemplate.format` and `String.format$`, but I will leave further bikeshedding on this to others. I do recognize that this move will not enable the type system per se to absolutely prevent programmers from writing</div>
<div class="markdown-here-wrapper" data-md-url="">
<pre style="font-family: Consolas, Inconsolata, Courier, monospace; font-size: 1em; line-height: 1.2em; margin-top: 1.2em; margin-bottom: 1.2em;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace; margin: 0px 0.15em; background-color: rgb(248, 248, 248); overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">String.format("Hello, my name is %s{name}"); // can you spot the bug?
</code></pre>
</div>
<div>but, as Clement has observed, such cases will probably provoke a warning about a mismatch between the number of arguments and the number of %-specifiers that require parameters, so maybe overloading would be okay anyway for `String.format`.</div>
</div>
<div><br>
</div>
<div>Anyway, my point is that whether to overload a method to accept either a string or a string template can be evaluated on a case-by-case basis according to a small number of principles that I think we could enumerate and explain pretty easily.</div>
<div><br>
</div>
<div>—Guy</div>
<div>
<div><br>
<blockquote type="cite">
<div>On Mar 14, 2024, at 1:40 PM, Maurizio Cimadamore <a class="moz-txt-link-rfc2396E" href="mailto:maurizio.cimadamore@oracle.com" moz-do-not-send="true">
<maurizio.cimadamore@oracle.com></a> wrote:</div>
<br class="Apple-interchange-newline">
<div>
<div>
<div class="markdown-here-wrapper" data-md-url="" style="">
<p style="margin: 0px 0px 1.2em !important;">Not to pour too much cold water on the idea of having string interpolation literal, but I’d like to mention a few points here.</p>
<p style="margin: 0px 0px 1.2em !important;">First, it was a deliberate design goal of the string template feature to make interpolation an explicit act. Note that, if we had the syntax you describe, we actually achieve the opposite effect: string interpolation
is now the default, and implicit, and actually <em>cheaper</em> (to type) than the safer template alternative. This is a bit of a red herring, I think.</p>
<p style="margin: 0px 0px 1.2em !important;">The second problem is that interpolation literals can sometimes be deceiving. Consider this example:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">String.format("Hello, my name is %s{name}"); // can you spot the bug?
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">Where <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">
String::format</code> has a new overload which accepts a StringTemplate.</p>
<p style="margin: 0px 0px 1.2em !important;">Basically, since here we forgot the leading “$” (or whatever char that is), the whole thing is just a big interpolation. Semantically equivalent to:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;"> String.format("Hello, my name is %s" + name); // whoops!
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">This will fail, as <code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;">
String::format</code> will be waiting for an argument (a string), but none is provided. So:</p>
<pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">| Exception java.util.MissingFormatArgumentException: Format specifier '%s'
| at Formatter.format (Formatter.java:2672)
| at Formatter.format (Formatter.java:2609)
| at String.format (String.java:2897)
| at (#2:1)
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">This is a very odd (and new!) failure mode, that I’m sure is gonna surprise developers.</p>
<p style="margin: 0px 0px 1.2em !important;">Maurizio</p>
<p style="margin: 0px 0px 1.2em !important;">On 14/03/2024 15:08, Guy Steele wrote:</p>
<div style="margin: 0px 0px 1.2em !important;"><br class="webkit-block-placeholder">
</div>
<div class="markdown-here-exclude">
<div><br class="webkit-block-placeholder">
</div>
<blockquote type="cite" cite="mid:3F8C64A7-BEB8-4BA2-A9B1-E00C14578B28@oracle.com">
<pre class="moz-quote-pre" wrap="">Second thoughts about how to explain a string interpolation literal:
</pre>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">On Mar 13, 2024, at 2:02 PM, Guy Steele <a class="moz-txt-link-rfc2396E" href="mailto:guy.steele@oracle.com" moz-do-not-send="true"><guy.steele@oracle.com></a> wrote:
. . .
—————————
String is not a subtype of StringTemplate; they are disjoint types.
$”foo” is a (trivial) string template literal
“foo” is a string literal
$”Hello, \{x}” is a (nontrivial) string template literal
“Hello, \{x}” is a shorthand (expanded by the compiler) for `String.of($“Hello, \{x}”)`
—————————
</pre>
</blockquote>
<pre class="moz-quote-pre" wrap="">Given that the intent is that String.of (or whatever we want to call it—possibly the `interpolation` instance method of class `StringTemplate` rather than a static method `String.of`) should just do standard string concatenation, we might be better off just saying that a string interpolation literal is expanded by the compiler into uses of “+”; for example,
“Hello, \{x}.”
(I have added a period to the example to make the point clearer) is expanded into
“Hello, “ + x + “.”
and in general
“c0\{e1}c1\{e2}c2…\{en}cn”
(where each ck is a possibly empty sequence of string characters and each ek is an expression) is expanded into
“c0” + (e1) + “c1” + (e2) + “c2” + … + (en) + “cn”
The point is that, with this definition, “c0\{e1}c1\{e2}c2…\{en}cn” is a constant expression iff every ek is a constant expression. This is handy for interpolating constant variables into a string that is itself intended to be constant.
—Guy
</pre>
</blockquote>
<div><br class="webkit-block-placeholder">
</div>
</div>
<div style="margin: 0px 0px 1.2em !important;"><br class="webkit-block-placeholder">
</div>
<div title="MDH:PHA+Tm90IHRvIHBvdXIgdG9vIG11Y2ggY29sZCB3YXRlciBvbiB0aGUgaWRlYSBvZiBoYXZpbmcg
c3RyaW5nIGludGVycG9sYXRpb24gbGl0ZXJhbCwgYnV0IEknZCBsaWtlIHRvIG1lbnRpb24gYSBm
ZXcgcG9pbnRzIGhlcmUuPC9wPjxwPkZpcnN0LCBpdCB3YXMgYSBkZWxpYmVyYXRlIGRlc2lnbiBn
b2FsIG9mIHRoZSBzdHJpbmcgdGVtcGxhdGUgZmVhdHVyZSB0byBtYWtlIGludGVycG9sYXRpb24g
YW4gZXhwbGljaXQgYWN0LiBOb3RlIHRoYXQsIGlmIHdlIGhhZCB0aGUgc3ludGF4IHlvdSBkZXNj
cmliZSwgd2UgYWN0dWFsbHkgYWNoaWV2ZSB0aGUgb3Bwb3NpdGUgZWZmZWN0OiBzdHJpbmcgaW50
ZXJwb2xhdGlvbiBpcyBub3cgdGhlIGRlZmF1bHQsIGFuZCBpbXBsaWNpdCwgYW5kIGFjdHVhbGx5
IF9jaGVhcGVyXyAodG8gdHlwZSkgdGhhbiB0aGUgc2FmZXIgdGVtcGxhdGUgYWx0ZXJuYXRpdmUu
IFRoaXMgaXMgYSBiaXQgb2YgYSByZWQgaGVycmluZywgSSB0aGluay48L3A+PHA+VGhlIHNlY29u
ZCBwcm9ibGVtIGlzIHRoYXQgaW50ZXJwb2xhdGlvbiBsaXRlcmFscyBjYW4gc29tZXRpbWVzIGJl
IGRlY2VpdmluZy4gQ29uc2lkZXIgdGhpcyBleGFtcGxlOjwvcD48cD5gYGA8YnI+U3RyaW5nLmZv
cm1hdCgiSGVsbG8sIG15IG5hbWUgaXMgJXN7bmFtZX0iKTsgLy8gY2FuIHlvdSBzcG90IHRoZSBi
dWc/PGJyPmBgYDwvcD48cD5XaGVyZSBgU3RyaW5nOjpmb3JtYXRgIGhhcyBhIG5ldyBvdmVybG9h
ZCB3aGljaCBhY2NlcHRzIGEgU3RyaW5nVGVtcGxhdGUuPC9wPjxwPkJhc2ljYWxseSwgc2luY2Ug
aGVyZSB3ZSBmb3Jnb3QgdGhlIGxlYWRpbmcgIiQiIChvciB3aGF0ZXZlciBjaGFyIHRoYXQgaXMp
LCB0aGUgd2hvbGUgdGhpbmcgaXMganVzdCBhIGJpZyBpbnRlcnBvbGF0aW9uLiBTZW1hbnRpY2Fs
bHkgZXF1aXZhbGVudCB0bzo8L3A+PHA+YGBgPGJyPgpTdHJpbmcuZm9ybWF0KCJIZWxsbywgbXkg
bmFtZSBpcyAlcyIgKyBuYW1lKTsgLy8gd2hvb3BzITxicj4KYGBgPC9wPgo8cD5UaGlzIHdpbGwg
ZmFpbCwgYXMgYFN0cmluZzo6Zm9ybWF0YCB3aWxsIGJlIHdhaXRpbmcgZm9yIGFuIGFyZ3VtZW50
IChhIHN0cmluZyksIGJ1dCBub25lIGlzIHByb3ZpZGVkLiBTbzo8L3A+PHA+YGBgPGJyPnwmbmJz
cDsgRXhjZXB0aW9uIGphdmEudXRpbC5NaXNzaW5nRm9ybWF0QXJndW1lbnRFeGNlcHRpb246IEZv
cm1hdCBzcGVjaWZpZXIgJyVzJzxicj58Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i
c3A7Jm5ic3A7IGF0IEZvcm1hdHRlci5mb3JtYXQgKEZvcm1hdHRlci5qYXZhOjI2NzIpPGJyPnwm
bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgYXQgRm9ybWF0dGVyLmZv
cm1hdCAoRm9ybWF0dGVyLmphdmE6MjYwOSk8YnI+fCZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu
YnNwOyZuYnNwOyZuYnNwOyBhdCBTdHJpbmcuZm9ybWF0IChTdHJpbmcuamF2YToyODk3KTxicj58
Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IGF0ICgjMjoxKTxicj5g
YGA8L3A+PHA+VGhpcyBpcyBhIHZlcnkgb2RkIChhbmQgbmV3ISkgZmFpbHVyZSBtb2RlLCB0aGF0
IEknbSBzdXJlIGlzIGdvbm5hIHN1cnByaXNlIGRldmVsb3BlcnMuPC9wPjxwPk1hdXJpemlvPGJy
PjwvcD48cD48YnI+PC9wPjxwPjwvcD48cD48YnI+PC9wPjxkaXYgY2xhc3M9Im1vei1jaXRlLXBy
ZWZpeCI+T24gMTQvMDMvMjAyNCAxNTowOCwgR3V5IFN0ZWVsZSB3cm90ZTo8YnI+PC9kaXY+PGJs
b2NrcXVvdGUgdHlwZT0iY2l0ZSIgY2l0ZT0ibWlkOjNGOEM2NEE3LUJFQjgtNEJBMi1BOUIxLUUw
MEMxNDU3OEIyOEBvcmFjbGUuY29tIj48cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIi
PlNlY29uZCB0aG91Z2h0cyBhYm91dCBob3cgdG8gZXhwbGFpbiBhIHN0cmluZyBpbnRlcnBvbGF0
aW9uIGxpdGVyYWw6Cgo8L3ByZT48YmxvY2txdW90ZSB0eXBlPSJjaXRlIj48cHJlIGNsYXNzPSJt
b3otcXVvdGUtcHJlIiB3cmFwPSIiPk9uIE1hciAxMywgMjAyNCwgYXQgMjowMuKAr1BNLCBHdXkg
U3RlZWxlICZsdDtndXkuc3RlZWxlQG9yYWNsZS5jb20mZ3Q7IHdyb3RlOgouIC4gLgoK4oCU4oCU
4oCU4oCU4oCU4oCU4oCU4oCU4oCUClN0cmluZyBpcyBub3QgYSBzdWJ0eXBlIG9mIFN0cmluZ1Rl
bXBsYXRlOyB0aGV5IGFyZSBkaXNqb2ludCB0eXBlcy4KCgkk4oCdZm9v4oCdICAgICAgICAgICAg
ICBpcyBhICh0cml2aWFsKSBzdHJpbmcgdGVtcGxhdGUgbGl0ZXJhbAoJ4oCcZm9v4oCdICAgICAg
ICAgICAgICAgIGlzIGEgc3RyaW5nIGxpdGVyYWwKICAgICAgICAk4oCdSGVsbG8sIFx7eH3igJ0g
ICAgIGlzIGEgKG5vbnRyaXZpYWwpIHN0cmluZyB0ZW1wbGF0ZSBsaXRlcmFsCiAgICAgICAg4oCc
SGVsbG8sIFx7eH3igJ0gICAgICBpcyBhIHNob3J0aGFuZCAoZXhwYW5kZWQgYnkgdGhlIGNvbXBp
bGVyKSBmb3IgYFN0cmluZy5vZigk4oCcSGVsbG8sIFx7eH3igJ0pYArigJTigJTigJTigJTigJTi
gJTigJTigJTigJQKPC9wcmU+PC9ibG9ja3F1b3RlPjxwcmUgY2xhc3M9Im1vei1xdW90ZS1wcmUi
IHdyYXA9IiI+CkdpdmVuIHRoYXQgdGhlIGludGVudCBpcyB0aGF0IFN0cmluZy5vZiAob3Igd2hh
dGV2ZXIgd2Ugd2FudCB0byBjYWxsIGl04oCUcG9zc2libHkgdGhlIGBpbnRlcnBvbGF0aW9uYCBp
bnN0YW5jZSBtZXRob2Qgb2YgY2xhc3MgYFN0cmluZ1RlbXBsYXRlYCByYXRoZXIgdGhhbiBhIHN0
YXRpYyBtZXRob2QgYFN0cmluZy5vZmApIHNob3VsZCBqdXN0IGRvIHN0YW5kYXJkIHN0cmluZyBj
b25jYXRlbmF0aW9uLCB3ZSBtaWdodCBiZSBiZXR0ZXIgb2ZmIGp1c3Qgc2F5aW5nIHRoYXQgYSBz
dHJpbmcgaW50ZXJwb2xhdGlvbiBsaXRlcmFsIGlzIGV4cGFuZGVkIGJ5IHRoZSBjb21waWxlciBp
bnRvIHVzZXMgb2Yg4oCcK+KAnTsgZm9yIGV4YW1wbGUsCgogICAgICAgICDigJxIZWxsbywgXHt4
fS7igJ0KCihJIGhhdmUgYWRkZWQgYSBwZXJpb2QgdG8gdGhlIGV4YW1wbGUgdG8gbWFrZSB0aGUg
cG9pbnQgY2xlYXJlcikgaXMgZXhwYW5kZWQgaW50bwoKICAgICAgICDigJxIZWxsbywg4oCcICsg
eCArIOKAnC7igJ0KCmFuZCBpbiBnZW5lcmFsCgogICAgICAgIOKAnGMwXHtlMX1jMVx7ZTJ9YzLi
gKZce2VufWNu4oCdCgood2hlcmUgZWFjaCBjayBpcyBhIHBvc3NpYmx5IGVtcHR5IHNlcXVlbmNl
IG9mIHN0cmluZyBjaGFyYWN0ZXJzIGFuZCBlYWNoIGVrIGlzIGFuIGV4cHJlc3Npb24pICBpcyBl
eHBhbmRlZCBpbnRvCgogICAgICAgIOKAnGMw4oCdICsgKGUxKSArIOKAnGMx4oCdICsgKGUyKSAr
IOKAnGMy4oCdICsg4oCmICsgKGVuKSArIOKAnGNu4oCdCgpUaGUgcG9pbnQgaXMgdGhhdCwgd2l0
aCB0aGlzIGRlZmluaXRpb24sIOKAnGMwXHtlMX1jMVx7ZTJ9YzLigKZce2VufWNu4oCdIGlzIGEg
Y29uc3RhbnQgZXhwcmVzc2lvbiBpZmYgZXZlcnkgZWsgaXMgYSBjb25zdGFudCBleHByZXNzaW9u
LiBUaGlzIGlzIGhhbmR5IGZvciBpbnRlcnBvbGF0aW5nIGNvbnN0YW50IHZhcmlhYmxlcyBpbnRv
IGEgc3RyaW5nIHRoYXQgaXMgaXRzZWxmIGludGVuZGVkIHRvIGJlIGNvbnN0YW50LgoK4oCUR3V5
Cgo8L3ByZT48L2Jsb2NrcXVvdGU+" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;">
</div>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
<br>
</blockquote>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</body>
</html>