<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body><div style="font-family: sans-serif;"><div class="plaintext" style="white-space: normal;"><p dir="auto">Thanks, Maurizio.  I find your arguments helpful and persuasive.  They indicate that “autoboxing” is the wrong model, since it would lift ad hoc strings into places that want only STs.</p>
<p dir="auto">The poly-expression move, applied only to string literals, is not so bad, since the only ad hoc strings liftable to STs are those right next to the API points that demand STs.</p>
<p dir="auto">But, if we are going to make ST-demanding APIs the lock and STs the keys, it might be reasonable to demand that all STs look distinctive (with that extra sigil), which is an argument even against the poly-expression move.</p>
<p dir="auto">Guy’s disruptive suggestion, of having both kinds of interpolation expressions, would play out as two tiers of vetting and security.  The lower tier is inhabited by strings.  You have to drive carefully on those streets, where dodgy APIs accept all kinds of strings, and there are no $ sigils to indicate vetted inputs.  The higher tier would be API points that demand STs (and do not welcome plain strings).  To get into that safer tier, you pay a cover charge, the $ sigils (or API points which manufacture STs explicitly).</p>
<p dir="auto">It might seem wrong to ask a cover charge for a tier we want users to prefer, but the IDE will surely help pay it as needed.  (The $ is visible in the code, as a reminder the security is enabled.  Like the wrist band you get when you pay the cover?)</p>
<p dir="auto">On the other hand, if we try to make everything be one tier (everything potentially vettable, but with loopholes for raw strings), the security guarantees get muddier.  If everything is equally secure, and there are loopholes (for string concat and the like) then everything is also equally insecure, in some hand-wavy sense.</p>
<p dir="auto">More hand-waving:  Distinct tiers is a more honest design, allowing for better invariants within the higher tier, and relaxed behavior in the lower tier.  Also, maybe, having the distinct tiers be visibly connected by syntax encourages folks muddling around with string-concat to lift their code to work on STs instead of strings.  Switch the APIs and add the dollar signs.</p>
<p dir="auto">OK, I’ll stop now.  I’m past the point where I need to try the API on some serious project, before I speculate more.</p>
<p dir="auto">On 13 Mar 2024, at 16:47, Maurizio Cimadamore wrote:</p>
</div><blockquote class="embedded" style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><div id="F66EB888-7469-424F-9A37-13301F37DE63">

<div class="markdown-here-wrapper" data-md-url="" style="" markdown-here-wrapper-content-modified="true">
<p style="margin: 0px 0px 1.2em !important;">There is a problem/slippery slope with overloads, which I think should be discussed (and that discussion seems, at least to me, more important than the discussion on how we spell string literals).</p>
<p style="margin: 0px 0px 1.2em !important;">Consider the case of a <em>new</em> API, that perhaps wants to build SQL queries (or any other kind of injection-sensitive factory):</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;">Query makeQuery(???)
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">What should be the natural parameter type for this query? Well, we know that String is flawed here. Easy to reach for, but also too easy to abuse. StringTemplate is a much better type because it allows user-injectable values and constant parts to carried in separate parts of the string template, so that the library has a chance at looking at what’s going on.</p>
<p style="margin: 0px 0px 1.2em !important;">Ok, so let’s say we write the factory as:</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;">Query makeQuery(StringTemplate)
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">As that is clearly the safer option. This obviously works well <em>as long as clients are passing template with arguments</em>.</p>
<p style="margin: 0px 0px 1.2em !important;">No-argument templates might be a corner case, but, sooner or later somebody might want to do this:</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;">makeQuery("SELECT foo FROM bar WHERE foo = 42");
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">Only to discover that this doesn’t compile. What then? There are a couple of alternatives I can think of. The first is to add a String-accepting overload:</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;">Query makeQuery(StringTemplate)
Query makeQuery(String)
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">The second is to use some use-site factory call to turn the string into a degenerate string template:</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;">makeQuery(StringTemplate.fromString("SELECT foo FROM bar WHERE foo = 42"));
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">IMHO, both approaches have problems: they force the user to go from the safer StringTemplate world, to the more unsafe String world. It’s sort of like crossing the Rubicon: once you’re in String-land, it then become easier to introduce potentially very costly mistakes. If we have overloads:</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;">makeQuery("SELECT " + foo + " FROM " + bar + " WHERE " + condition);
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">This would now compile just fine. Effectively, safety-wise we’d be back at square one. The factory case is only marginally better - because using the factory is more convoluted, so it would perhaps be easier to spot that something fishy is going on. That said, as the expression got more complicated, it’s easier for bugs to sneak in:</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;">makeQuery(StringTemplate.fromString("SELECT " + foo + "FROM bar WHERE foo = 42"));
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">So, at least in my opinion, having a string template literal, or some kind of compiler-controlled promotion from string <em>constants</em> to string templates, is not just something we need to type less characters (I honestly couldn’t care less about that, at least not at this stage). These things are needed to allow developers to remain in StringTemplate-land.</p>
<p style="margin: 0px 0px 1.2em !important;">That is, the best <em>overall</em> outcome is for the library <em>not</em> to have an overload, <em>and</em> for the client to either say this:</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;">makeQuery("SELECT foo FROM bar WHERE foo = 42"); // works because of implicit promotion of constant String -> StringTemplate
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">or this:</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;">makeQuery(<insert your favourite "I'M A TEMPLATE" char here>"SELECT foo FROM bar WHERE foo = 42"); // works because it's a string template all along
</code></pre>
<p style="margin: 0px 0px 1.2em !important;">Maurizio</p>
<p style="margin: 0px 0px 1.2em !important;">On 13/03/2024 22:37, John Rose wrote:</p>
<blockquote style="margin: 1.2em 0px;border-left: 4px solid rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119); quotes: none;">
<p style="margin: 0px 0px 1.2em !important;">On 13 Mar 2024, at 15:22, John Rose wrote:</p>
<blockquote style="margin: 1.2em 0px;border-left: 4px solid rgb(221, 221, 221); padding: 0px 1em; color: rgb(119, 119, 119); quotes: none;">
<p style="margin: 0px 0px 1.2em !important;">… OVERLOADS …</p>
<p style="margin: 0px 0px 1.2em !important;">I don’t see (maybe I missed it) a decisive objection to overloading<br>
across ST and String, at least for some processing APIs.<br>
Perhaps it is this: A language processor API that takes STs and<br>
never Strings is making it clear that all inputs should be properly<br>
vetted, nothing taken on trust as a bare string.</p>
</blockquote>
<p style="margin: 0px 0px 1.2em !important;">Doing that MIGHT require a performance model which permits expensive<br>
vetting operations to be memoized on particular OCCURRENCES of inputs<br>
(not just the input strings viewed in and of themselves).</p>
<p style="margin: 0px 0px 1.2em !important;">If that’s true, then I guess that’s support for Guy’s proposal: That<br>
STs (even trivial ones) should never look identical to strings.<br>
Maybe they should always be preceded by a sigil $, or (per my<br>
suggestion) they should always have at least one occurrence of {<br>
inside, even if it’s a trivial nop.</p>
<p style="margin: 0px 0px 1.2em !important;">I kind of like Guy’s offensive-to-everyone suggestion that $ is<br>
required to make a true ST. Then it’s clear how the veteting APIs<br>
mate up with their vetted inputs. And if $ is not placed in front,<br>
we surrender to the string-pasters, but at least the resulting<br>
true-string expressions won’t be accepted by the vetting APIs.</p>
</blockquote>
<div title="MDH:VGhlcmUgaXMgYSBwcm9ibGVtL3NsaXBwZXJ5IHNsb3BlIHdpdGggb3ZlcmxvYWRzLCB3aGljaCBJ IHRoaW5rIHNob3VsZCBiZSBkaXNjdXNzZWQgKGFuZCB0aGF0IGRpc2N1c3Npb24gc2VlbXMsIGF0 IGxlYXN0IHRvIG1lLCBtb3JlIGltcG9ydGFudCB0aGFuIHRoZSBkaXNjdXNzaW9uIG9uIGhvdyB3 ZSBzcGVsbCBzdHJpbmcgbGl0ZXJhbHMpLjxicj48YnI+Q29uc2lkZXIgdGhlIGNhc2Ugb2YgYSBf bmV3XyBBUEksIHRoYXQgcGVyaGFwcyB3YW50cyB0byBidWlsZCBTUUwgcXVlcmllcyAob3IgYW55 IG90aGVyIGtpbmQgb2YgaW5qZWN0aW9uLXNlbnNpdGl2ZSBmYWN0b3J5KTo8YnI+PGJyPmBgYDxi cj5RdWVyeSBtYWtlUXVlcnkoPz8/KTxicj5gYGA8YnI+PGJyPldoYXQgc2hvdWxkIGJlIHRoZSBu YXR1cmFsIHBhcmFtZXRlciB0eXBlIGZvciB0aGlzIHF1ZXJ5PyBXZWxsLCB3ZSBrbm93IHRoYXQg U3RyaW5nIGlzIGZsYXdlZCBoZXJlLiBFYXN5IHRvIHJlYWNoIGZvciwgYnV0IGFsc28gdG9vIGVh c3kgdG8gYWJ1c2UuIFN0cmluZ1RlbXBsYXRlIGlzIGEgbXVjaCBiZXR0ZXIgdHlwZSBiZWNhdXNl IGl0IGFsbG93cyB1c2VyLWluamVjdGFibGUgdmFsdWVzIGFuZCBjb25zdGFudCBwYXJ0cyB0byBj YXJyaWVkIGluIHNlcGFyYXRlIHBhcnRzIG9mIHRoZSBzdHJpbmcgdGVtcGxhdGUsIHNvIHRoYXQg dGhlIGxpYnJhcnkgaGFzIGEgY2hhbmNlIGF0IGxvb2tpbmcgYXQgd2hhdCdzIGdvaW5nIG9uLjxi cj48YnI+T2ssIHNvIGxldCdzIHNheSB3ZSB3cml0ZSB0aGUgZmFjdG9yeSBhczo8YnI+PGJyPmBg YDxicj5RdWVyeSBtYWtlUXVlcnkoU3RyaW5nVGVtcGxhdGUpPGJyPmBgYDxicj48YnI+QXMgdGhh dCBpcyBjbGVhcmx5IHRoZSBzYWZlciBvcHRpb24uIFRoaXMgb2J2aW91c2x5IHdvcmtzIHdlbGwg X2FzIGxvbmcgYXMgY2xpZW50cyBhcmUgcGFzc2luZyB0ZW1wbGF0ZSB3aXRoIGFyZ3VtZW50c18u PGJyPjxicj5ObyBhcmd1bWVudCB0ZW1wbGF0ZSBtaWdodCBiZSBhIGNvcm5lciBjYXNlLCBidXQs IHNvb25lciBvciBsYXRlciBzb21lYm9keSBtaWdodCB3YW50IHRvIGRvIHRoaXM6PGJyPjxicj5g YGA8YnI+bWFrZVF1ZXJ5KCJTRUxFQ1QgZm9vIEZST00gYmFyIFdIRVJFIGZvbyA9IDQyIik7PGJy PmBgYDxicj48YnI+T25seSB0byBkaXNjb3ZlciB0aGF0IHRoaXMgZG9lc24ndCBjb21waWxlLiBX aGF0IHRoZW4/IFRoZXJlIGFyZSBhIGNvdXBsZSBvZiBhbHRlcm5hdGl2ZXMgSSBjYW4gdGhpbmsg b2YuIFRoZSBmaXJzdCBpcyB0byBhZGQgYSBTdHJpbmctYWNjZXB0aW5nIG92ZXJsb2FkOjxicj48 YnI+YGBgPGJyPlF1ZXJ5IG1ha2VRdWVyeShTdHJpbmdUZW1wbGF0ZSk8YnI+UXVlcnkgbWFrZVF1 ZXJ5KFN0cmluZyk8YnI+YGBgPGJyPjxicj5UaGUgc2Vjb25kIGlzIHRvIHVzZSBzb21lIHVzZS1z aXRlIGZhY3RvcnkgY2FsbCB0byB0dXJuIHRoZSBzdHJpbmcgaW50byBhIGRlZ2VuZXJhdGUgc3Ry aW5nIHRlbXBsYXRlOjxicj48YnI+YGBgPGJyPm1ha2VRdWVyeShTdHJpbmdUZW1wbGF0ZS5mcm9t U3RyaW5nKCJTRUxFQ1QgZm9vIEZST00gYmFyIFdIRVJFIGZvbyA9IDQyIikpOzxicj5gYGA8YnI+ PGJyPklNSE8sIGJvdGggYXBwcm9hY2hlcyBoYXZlIHByb2JsZW1zOiB0aGV5IGZvcmNlIHRoZSB1 c2VyIHRvIGdvIGZyb20gdGhlIHNhZmVyIFN0cmluZ1RlbXBsYXRlIHdvcmxkLCB0byB0aGUgbW9y ZSB1bnNhZmUgU3RyaW5nIHdvcmxkLiBJdCdzIHNvcnQgb2YgbGlrZSBjcm9zc2luZyB0aGUgUnVi aWNvbjogb25jZSB5b3UncmUgaW4gU3RyaW5nLWxhbmQsIGl0IHRoZW4gYmVjb21lIGVhc2llciB0 byBpbnRyb2R1Y2UgcG90ZW50aWFsbHkgdmVyeSBjb3N0bHkgbWlzdGFrZXMuIElmIHdlIGhhdmUg b3ZlcmxvYWRzOjxicj48YnI+YGBgPGJyPm1ha2VRdWVyeSgiU0VMRUNUICIgKyBmb28gKyAiIEZS T00gIiArIGJhciArICIgV0hFUkUgIiArIGNvbmRpdGlvbik7PGJyPjxicj5gYGA8YnI+PGJyPlRo aXMgd291bGQgbm93IGNvbXBpbGUganVzdCBmaW5lLiBFZmZlY3RpdmVseSwgc2FmZXR5LXdpc2Ug d2UnZCBiZSBiYWNrIGF0IHNxdWFyZSBvbmUuIFRoZSBmYWN0b3J5IGNhc2UgaXMgb25seSBtYXJn aW5hbGx5IGJldHRlciAtIGJlY2F1c2UgdXNpbmcgdGhlIGZhY3RvcnkgaXMgbW9yZSBjb252b2x1 dGVkLCBzbyBpdCB3b3VsZCBwZXJoYXBzIGJlIGVhc2llciB0byBzcG90IHRoYXQgc29tZXRoaW5n IGZpc2h5IGlzIGdvaW5nIG9uLiBUaGF0IHNhaWQsIGFzIHRoZSBleHByZXNzaW9uIGdvdCBtb3Jl IGNvbXBsaWNhdGVkLCBpdCdzIGVhc2llciBmb3IgYnVncyB0byBzbmVhayBpbjo8YnI+PGJyPmBg YDxicj5tYWtlUXVlcnkoU3RyaW5nVGVtcGxhdGUuZnJvbVN0cmluZygiU0VMRUNUICIgKyBmb28g KyAiRlJPTSBiYXIgV0hFUkUgZm9vID0gNDIiKSk7PGJyPmBgYDxicj48YnI+U28sIGF0IGxlYXN0 IGluIG15IG9waW5pb24sIGhhdmluZyBhIHN0cmluZyB0ZW1wbGF0ZSBsaXRlcmFsLCBvciBzb21l IGtpbmQgb2YgY29tcGlsZXItY29udHJvbGxlZCBwcm9tb3Rpb24gZnJvbSBzdHJpbmcgX2NvbnN0 YW50c18gdG8gc3RyaW5nIHRlbXBsYXRlcywgaXMgbm90IGp1c3Qgc29tZXRoaW5nIHdlIG5lZWQg dG8gdHlwZSBsZXNzIGNoYXJhY3RlcnMgKEkgaG9uZXN0bHkgY291bGRuJ3QgY2FyZSBsZXNzIGFi b3V0IHRoYXQsIGF0IGxlYXN0IG5vdCBhdCB0aGlzIHN0YWdlKS4gVGhlc2UgdGhpbmdzIGFyZSBu ZWVkZWQgdG8gYWxsb3cgZGV2ZWxvcGVycyB0byByZW1haW4gaW4gU3RyaW5nVGVtcGxhdGUtbGFu ZC48YnI+PGJyPlRoYXQgaXMsIHRoZSBiZXN0IF9vdmVyYWxsXyBvdXRjb21lIGlzIGZvciB0aGUg bGlicmFyeSBfbm90XyB0byBoYXZlIGFuIG92ZXJsb2FkLCBfYW5kXyBmb3IgdGhlIGNsaWVudCB0 byBlaXRoZXIgc2F5IHRoaXM6PGJyPjxicj5gYGA8YnI+bWFrZVF1ZXJ5KCJTRUxFQ1QgZm9vIEZS T00gYmFyIFdIRVJFIGZvbyA9IDQyIik7IC8vIHdvcmtzIGJlY2F1c2Ugb2YgaW1wbGljaXQgcHJv bW90aW9uIG9mIGNvbnN0YW50IFN0cmluZyAtJmd0OyBTdHJpbmdUZW1wbGF0ZTxicj5gYGA8YnI+ PGJyPm9yIHRoaXM6PGJyPjxicj5gYGA8YnI+bWFrZVF1ZXJ5KCZsdDtpbnNlcnQgeW91ciBmYXZv dXJpdGUgIkknTSBBIFRFTVBMQVRFIiBjaGFyIGhlcmUmZ3Q7IlNFTEVDVCBmb28gRlJPTSBiYXIg V0hFUkUgZm9vID0gNDIiKTsgLy8gd29ya3MgYmVjYXVzZSBpdCdzIGEgc3RyaW5nIHRlbXBsYXRl IGFsbCBhbG9uZzxicj5gYGA8YnI+PGJyPk1hdXJpemlvPGJyPjxicj48YnI+PGJyPk9uIDEzLzAz LzIwMjQgMjI6MzcsIEpvaG4gUm9zZSB3cm90ZTo8YnI+PHNwYW4gc3R5bGU9IndoaXRlLXNwYWNl OiBwcmUtd3JhcDsgZGlzcGxheTogYmxvY2s7IHdpZHRoOiA5OHZ3OyI+Jmd0OyBPbiAxMyBNYXIg MjAyNCwgYXQgMTU6MjIsIEpvaG4gUm9zZSB3cm90ZTo8YnI+Jmd0OyA8YnI+Jmd0OyZndDsg4oCm IE9WRVJMT0FEUyDigKY8YnI+Jmd0OyZndDsgPGJyPiZndDsmZ3Q7IEkgZG9u4oCZdCBzZWUgKG1h eWJlIEkgbWlzc2VkIGl0KSBhIGRlY2lzaXZlIG9iamVjdGlvbiB0byBvdmVybG9hZGluZzxicj4m Z3Q7Jmd0OyBhY3Jvc3MgU1QgYW5kIFN0cmluZywgYXQgbGVhc3QgZm9yIHNvbWUgcHJvY2Vzc2lu ZyBBUElzLjxicj4mZ3Q7IFBlcmhhcHMgaXQgaXMgdGhpczogIEEgbGFuZ3VhZ2UgcHJvY2Vzc29y IEFQSSB0aGF0IHRha2VzIFNUcyBhbmQ8YnI+Jmd0OyBuZXZlciBTdHJpbmdzIGlzIG1ha2luZyBp dCBjbGVhciB0aGF0IGFsbCBpbnB1dHMgc2hvdWxkIGJlIHByb3Blcmx5PGJyPiZndDsgdmV0dGVk LCBub3RoaW5nIHRha2VuIG9uIHRydXN0IGFzIGEgYmFyZSBzdHJpbmcuPGJyPiZndDsgPGJyPiZn dDsgRG9pbmcgdGhhdCBNSUdIVCByZXF1aXJlIGEgcGVyZm9ybWFuY2UgbW9kZWwgd2hpY2ggcGVy bWl0cyBleHBlbnNpdmU8YnI+Jmd0OyB2ZXR0aW5nIG9wZXJhdGlvbnMgdG8gYmUgbWVtb2l6ZWQg b24gcGFydGljdWxhciBPQ0NVUlJFTkNFUyBvZiBpbnB1dHM8YnI+Jmd0OyAobm90IGp1c3QgdGhl IGlucHV0IHN0cmluZ3Mgdmlld2VkIGluIGFuZCBvZiB0aGVtc2VsdmVzKS48YnI+Jmd0OyA8YnI+ Jmd0OyBJZiB0aGF04oCZcyB0cnVlLCB0aGVuIEkgZ3Vlc3MgdGhhdOKAmXMgc3VwcG9ydCBmb3Ig R3V54oCZcyBwcm9wb3NhbDogVGhhdDxicj4mZ3Q7IFNUcyAoZXZlbiB0cml2aWFsIG9uZXMpIHNo b3VsZCBuZXZlciBsb29rIGlkZW50aWNhbCB0byBzdHJpbmdzLjxicj4mZ3Q7IE1heWJlIHRoZXkg c2hvdWxkIGFsd2F5cyBiZSBwcmVjZWRlZCBieSBhIHNpZ2lsICQsIG9yIChwZXIgbXk8YnI+Jmd0 OyBzdWdnZXN0aW9uKSB0aGV5IHNob3VsZCBhbHdheXMgaGF2ZSBhdCBsZWFzdCBvbmUgb2NjdXJy ZW5jZSBvZiBcezxicj4mZ3Q7IGluc2lkZSwgZXZlbiBpZiBpdOKAmXMgYSB0cml2aWFsIG5vcC48 YnI+Jmd0OyA8YnI+Jmd0OyBJIGtpbmQgb2YgbGlrZSBHdXnigJlzIG9mZmVuc2l2ZS10by1ldmVy eW9uZSBzdWdnZXN0aW9uIHRoYXQgJCBpczxicj4mZ3Q7IHJlcXVpcmVkIHRvIG1ha2UgYSB0cnVl IFNULiAgVGhlbiBpdOKAmXMgY2xlYXIgaG93IHRoZSB2ZXRldGluZyBBUElzPGJyPiZndDsgbWF0 ZSB1cCB3aXRoIHRoZWlyIHZldHRlZCBpbnB1dHMuICBBbmQgaWYgJCBpcyBub3QgcGxhY2VkIGlu IGZyb250LDxicj4mZ3Q7IHdlIHN1cnJlbmRlciB0byB0aGUgc3RyaW5nLXBhc3RlcnMsIGJ1dCBh dCBsZWFzdCB0aGUgcmVzdWx0aW5nPGJyPiZndDsgdHJ1ZS1zdHJpbmcgZXhwcmVzc2lvbnMgd29u 4oCZdCBiZSBhY2NlcHRlZCBieSB0aGUgdmV0dGluZyBBUElzLjwvc3Bhbj48YnI+" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;">​</div>
</div></div></blockquote>
<div class="plaintext" style="white-space: normal;">
</div>
</div></body>

</html>