<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <div class="markdown-here-wrapper" data-md-url="" style="">
      <p style="margin: 0px 0px 1.2em !important;">On 22/06/2023 08:03,
        Andrii Lomakin wrote:</p>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <div class="markdown-here-exclude">
        <p></p>
        <blockquote type="cite" cite="mid:CAJmD-=4ny8NB1m56sowXZOkPa62B5cPMcfpVBfpcyRkhH2x4hg@mail.gmail.com">
          
          <div dir="ltr">Hi team.
            <div>I am working with foreign API and noticed that offsets
              are treated differently for the "set" and "copy" methods
              of MemorySegment in the case of heap-based segments. </div>
            <div><br clear="all">
              <div>If I create a segment from let's say, byte[] and call
                "set(OfDouble, 0)" on such a segment it doesn't take
                array offset into account during the calculation of the
                applied offset value. So it processes this offset as is,
                and I get an exception about address misalignment. <br>
              </div>
            </div>
          </div>
        </blockquote>
        <p></p>
      </div>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <p style="margin: 0px 0px 1.2em !important;">The alignment
        exception is by design. If you want to work with unaligned
        values (because we can’t really guarantee any alignment when
        working on a byte[]), then you can use the JAVA_DOUBLE_UNALIGNED
        constant.</p>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <div class="markdown-here-exclude">
        <p></p>
        <blockquote type="cite" cite="mid:CAJmD-=4ny8NB1m56sowXZOkPa62B5cPMcfpVBfpcyRkhH2x4hg@mail.gmail.com">
          <div dir="ltr">
            <div>
              <div>But if I pass offsets into the "copy" method, they
                are automatically corrected.</div>
            </div>
          </div>
        </blockquote>
        <p></p>
      </div>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <p style="margin: 0px 0px 1.2em !important;">There are several
        copy methods in memory segments, which all bottom out here:</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 class="hljs language-java" 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;display: block; overflow-x: auto; padding: 0.5em; color: rgb(51, 51, 51); background: rgb(248, 248, 248) none repeat scroll 0% 0%; -moz-text-size-adjust: none;"><span class="hljs-function"><span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">static</span> <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">void</span> <span class="hljs-title" style="color: rgb(153, 0, 0); font-weight: bold;">copy</span><span class="hljs-params">(MemorySegment srcSegment, ValueLayout srcElementLayout, <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">long</span> srcOffset,
                 MemorySegment dstSegment, ValueLayout dstElementLayout, <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">long</span> dstOffset,
                 <span class="hljs-keyword" style="color: rgb(51, 51, 51); font-weight: bold;">long</span> elementCount)</span> </span>{ ... }
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">Now, as you can see
        this method takes two layouts. The layouts are used to determine
        alignment of the copy, as well as byte swap.</p>
      <p style="margin: 0px 0px 1.2em !important;">If you pass
        JAVA_DOUBLE to this copy method you should get exactly the same
        exception you get with the get/set method. But note that the
        copy method that doesn’t take a layout just uses JAVA_BYTE
        underneath, so that might be why you get the impression that the
        copy is working. See below:</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;">jshell> var seg = MemorySegment.allocateNative(10, SegmentScope.auto());
seg ==> MemorySegment{ array: Optional.empty address:140000700364496 limit: 10 }

jshell> var byteSeg = MemorySegment.ofArray(new byte[10]);
byteSeg ==> MemorySegment{ array: Optional[[B@7e6cbb7a] address:0 limit: 10 }

jshell> MemorySegment.copy(byteSeg, 0, seg, 0, 10); // ok, because it uses JAVA_BYTE

jshell> MemorySegment.copy(byteSeg, JAVA_DOUBLE, 0, seg, JAVA_DOUBLE, 0, 1); // fails
|  Exception java.lang.IllegalArgumentException: Source segment incompatible with alignment constraints
|        at MemorySegment.copy (MemorySegment.java:1352)
|        at (#6:1)

jshell> MemorySegment.copy(byteSeg, JAVA_DOUBLE_UNALIGNED, 0, seg, JAVA_DOUBLE_UNALIGNED, 0, 1); // ok again
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">The treatment of
        alignment w.r.t. heap segments is explained in great details
        here:</p>
      <p style="margin: 0px 0px 1.2em !important;"><a href="https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/lang/foreign/MemorySegment.html" class="moz-txt-link-freetext">https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/lang/foreign/MemorySegment.html</a></p>
      <p style="margin: 0px 0px 1.2em !important;">(Java 21 has a
        similar section).</p>
      <p style="margin: 0px 0px 1.2em !important;">Note that this has
        nothing to do with methods not treating offsets uniformly -
        offsets are in fact treated uniformly, and always checked
        against the alignment constraints of the layout being used for
        the dereference operation.</p>
      <p style="margin: 0px 0px 1.2em !important;">If you don’t care
        about alignment, use unaligned layouts (for which constants are
        also provided), or use segments that wrap long[], which allow
        for more alignment.</p>
      <p style="margin: 0px 0px 1.2em !important;">The current behavior
        is kind of a forced move, driven by the fact that heap segments
        have different alignment properties based on platform and JVM
        implementation. So the alignment of heap segment is defined in
        terms of the lowest common denominator. If the API didn’t do
        this, you might write some code using memory segments that would
        work well in one platform and then fail on another because of
        different alignment constraints. While platform-dependent
        behavior is fair game when interacting with native code, in this
        case you would be able to get platform-dependent behavior only
        when accessing memory, and we didn’t want that (as this API will
        likely be used as a replacement for ByteBuffer in many cases,
        e.g. even when no native interop is needed).</p>
      <p style="margin: 0px 0px 1.2em !important;">Cheers<br>
        Maurizio</p>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <div class="markdown-here-exclude">
        <p></p>
        <blockquote type="cite" cite="mid:CAJmD-=4ny8NB1m56sowXZOkPa62B5cPMcfpVBfpcyRkhH2x4hg@mail.gmail.com">
          <div dir="ltr">
            <div>
              <div>Is it done by design? </div>
              <div>IMHO, both methods should treat offsets uniformly,
                and that is not taking into account that such treatments
                of offsets in "set" methods make it very hard to work
                with heap-based segments.</div>
              <div><br>
              </div>
              <div>P.S. I am using JDK 20.</div>
              <span class="gmail_signature_prefix">-- </span><br>
              <div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">
                <div dir="ltr">
                  <div>
                    <div dir="ltr">Best regards,<br>
                      Andrii Lomakin.<br>
                      <br>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </blockquote>
        <p></p>
      </div>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <div title="MDH:PHA+PGJyPjwvcD48ZGl2IGNsYXNzPSJtb3otY2l0ZS1wcmVmaXgiPk9uIDIyLzA2LzIwMjMgMDg6MDMsIEFuZHJpaSBMb21ha2luIHdyb3RlOjxicj48L2Rpdj48YmxvY2txdW90ZSB0eXBlPSJjaXRl
IiBjaXRlPSJtaWQ6Q0FKbUQtPTRueThOQjFtNTZzb3dYWk9rUGE2MkI1Y1BNY2ZwVkJmcGN5Umto
SDJ4NGhnQG1haWwuZ21haWwuY29tIj48bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNv
bnRlbnQ9InRleHQvaHRtbDsgIj48ZGl2IGRpcj0ibHRyIj5IaSB0ZWFtLjxkaXY+SSBhbSB3b3Jr
aW5nIHdpdGggZm9yZWlnbiBBUEkgYW5kIG5vdGljZWQgdGhhdCBvZmZzZXRzIGFyZSB0cmVhdGVk
IGRpZmZlcmVudGx5IGZvciB0aGUgInNldCIgYW5kICJjb3B5IiBtZXRob2RzIG9mIE1lbW9yeVNl
Z21lbnQgaW4gdGhlIGNhc2Ugb2YgaGVhcC1iYXNlZCBzZWdtZW50cy4mbmJzcDs8L2Rpdj48ZGl2
PjxiciBjbGVhcj0iYWxsIj48ZGl2PklmIEkgY3JlYXRlIGEgc2VnbWVudCZuYnNwO2Zyb20gbGV0
J3Mgc2F5LCBieXRlW10gYW5kIGNhbGwgInNldChPZkRvdWJsZSwgMCkiIG9uIHN1Y2ggYSBzZWdt
ZW50Jm5ic3A7aXQgZG9lc24ndCZuYnNwO3Rha2UgYXJyYXkgb2Zmc2V0IGludG8gYWNjb3VudCBk
dXJpbmcgdGhlIGNhbGN1bGF0aW9uIG9mIHRoZSBhcHBsaWVkIG9mZnNldCB2YWx1ZS4gU28gaXQg
cHJvY2Vzc2VzIHRoaXMgb2Zmc2V0IGFzIGlzLCBhbmQgSSBnZXQgYW4gZXhjZXB0aW9uIGFib3V0
IGFkZHJlc3MgbWlzYWxpZ25tZW50LiA8YnI+PC9kaXY+PC9kaXY+PC9kaXY+PC9ibG9ja3F1b3Rl
PlRoZSBhbGlnbm1lbnQgZXhjZXB0aW9uIGlzIGJ5IGRlc2lnbi4gSWYgeW91IHdhbnQgdG8gd29y
ayB3aXRoIHVuYWxpZ25lZCB2YWx1ZXMgKGJlY2F1c2Ugd2UgY2FuJ3QgcmVhbGx5IGd1YXJhbnRl
ZSBhbnkgYWxpZ25tZW50IHdoZW4gd29ya2luZyBvbiBhIGJ5dGVbXSksIHRoZW4geW91IGNhbiB1
c2UgdGhlIEpBVkFfRE9VQkxFX1VOQUxJR05FRCBjb25zdGFudC48YnI+PGJsb2NrcXVvdGUgdHlw
ZT0iY2l0ZSIgY2l0ZT0ibWlkOkNBSm1ELT00bnk4TkIxbTU2c293WFpPa1BhNjJCNWNQTWNmcFZC
ZnBjeVJraEgyeDRoZ0BtYWlsLmdtYWlsLmNvbSI+PGRpdiBkaXI9Imx0ciI+PGRpdj48ZGl2PkJ1
dCBpZiBJIHBhc3Mgb2Zmc2V0cyBpbnRvIHRoZSAiY29weSIgbWV0aG9kLCB0aGV5IGFyZSBhdXRv
bWF0aWNhbGx5IGNvcnJlY3RlZC48L2Rpdj48L2Rpdj48L2Rpdj48L2Jsb2NrcXVvdGU+PHA+VGhl
cmUgYXJlIHNldmVyYWwgY29weSBtZXRob2RzIGluIG1lbW9yeSBzZWdtZW50cywgd2hpY2ggYWxs
IGJvdHRvbSBvdXQgaGVyZTo8L3A+PGRpdiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojZmZmZmZm
O2NvbG9yOiMwMDAwMDA7Zm9udC1mYW1pbHk6J1NvdXJjZSBDb2RlIFBybycsbW9ub3NwYWNlO2Zv
bnQtc2l6ZToxMS4zcHQ7d2hpdGUtc3BhY2U6cHJlOyI+PHNwYW4gc3R5bGU9ImNvbG9yOiMwMDAw
ODA7Zm9udC13ZWlnaHQ6Ym9sZDsiPmBgYGphdmE8YnI+c3RhdGljIHZvaWQgPC9zcGFuPmNvcHko
TWVtb3J5U2VnbWVudCBzcmNTZWdtZW50LCBWYWx1ZUxheW91dCBzcmNFbGVtZW50TGF5b3V0LCA8
c3BhbiBzdHlsZT0iY29sb3I6IzAwMDA4MDtmb250LXdlaWdodDpib2xkOyI+bG9uZyA8L3NwYW4+
c3JjT2Zmc2V0LDxicj4gICAgICAgICAgICAgICAgIE1lbW9yeVNlZ21lbnQgZHN0U2VnbWVudCwg
VmFsdWVMYXlvdXQgZHN0RWxlbWVudExheW91dCwgPHNwYW4gc3R5bGU9ImNvbG9yOiMwMDAwODA7
Zm9udC13ZWlnaHQ6Ym9sZDsiPmxvbmcgPC9zcGFuPmRzdE9mZnNldCw8YnI+ICAgICAgICAgICAg
ICAgICA8c3BhbiBzdHlsZT0iY29sb3I6IzAwMDA4MDtmb250LXdlaWdodDpib2xkOyI+bG9uZyA8
L3NwYW4+ZWxlbWVudENvdW50KSB7IC4uLiB9PGJyPmBgYDxicj48L2Rpdj48ZGl2IHN0eWxlPSJi
YWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmY7Y29sb3I6IzAwMDAwMDtmb250LWZhbWlseTonU291cmNl
IENvZGUgUHJvJyxtb25vc3BhY2U7Zm9udC1zaXplOjExLjNwdDt3aGl0ZS1zcGFjZTpwcmU7Ij48
YnI+PC9kaXY+PHA+Tm93LCBhcyB5b3UgY2FuIHNlZSB0aGlzIG1ldGhvZCB0YWtlcyB0d28gbGF5
b3V0cy4gVGhlIGxheW91dHMgYXJlIHVzZWQgdG8gZGV0ZXJtaW5lIGFsaWdubWVudCBvZiB0aGUg
Y29weSwgYXMgd2VsbCBhcyBieXRlIHN3YXAuPC9wPjxwPklmIHlvdSBwYXNzIEpBVkFfRE9VQkxF
IHRvIHRoaXMgY29weSBtZXRob2QgeW91IHNob3VsZCBnZXQgZXhhY3RseSB0aGUgc2FtZSBleGNl
cHRpb24geW91IGdldCB3aXRoIHRoZSBnZXQvc2V0IG1ldGhvZC4gQnV0IG5vdGUgdGhhdCB0aGUg
Y29weSBtZXRob2QgdGhhdCBkb2Vzbid0IHRha2UgYSBsYXlvdXQganVzdCB1c2VzIEpBVkFfQllU
RSB1bmRlcm5lYXRoLCBzbyB0aGF0IG1pZ2h0IGJlIHdoeSB5b3UgZ2V0IHRoZSBpbXByZXNzaW9u
IHRoYXQgdGhlIGNvcHkgaXMgd29ya2luZy4gU2VlIGJlbG93Ojxicj48L3A+PHA+YGBgPGJyPmpz
aGVsbCZndDsgdmFyIHNlZyA9IE1lbW9yeVNlZ21lbnQuYWxsb2NhdGVOYXRpdmUoMTAsIFNlZ21l
bnRTY29wZS5hdXRvKCkpOzxicj5zZWcgPT0mZ3Q7IE1lbW9yeVNlZ21lbnR7IGFycmF5OiBPcHRp
b25hbC5lbXB0eSBhZGRyZXNzOjE0MDAwMDcwMDM2NDQ5NiBsaW1pdDogMTAgfTxicj48YnI+anNo
ZWxsJmd0OyB2YXIgYnl0ZVNlZyA9IE1lbW9yeVNlZ21lbnQub2ZBcnJheShuZXcgYnl0ZVsxMF0p
Ozxicj5ieXRlU2VnID09Jmd0OyBNZW1vcnlTZWdtZW50eyBhcnJheTogT3B0aW9uYWxbW0JAN2U2
Y2JiN2FdIGFkZHJlc3M6MCBsaW1pdDogMTAgfTxicj48YnI+anNoZWxsJmd0OyBNZW1vcnlTZWdt
ZW50LmNvcHkoYnl0ZVNlZywgMCwgc2VnLCAwLCAxMCk7IC8vIG9rLCBiZWNhdXNlIGl0IHVzZXMg
SkFWQV9CWVRFPGJyPjxicj5qc2hlbGwmZ3Q7IE1lbW9yeVNlZ21lbnQuY29weShieXRlU2VnLCBK
QVZBX0RPVUJMRSwgMCwgc2VnLCBKQVZBX0RPVUJMRSwgMCwgMSk7IC8vIGZhaWxzPGJyPnwmbmJz
cDsgRXhjZXB0aW9uIGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb246IFNvdXJjZSBz
ZWdtZW50IGluY29tcGF0aWJsZSB3aXRoIGFsaWdubWVudCBjb25zdHJhaW50czxicj58Jm5ic3A7
Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IGF0IE1lbW9yeVNlZ21lbnQuY29w
eSAoTWVtb3J5U2VnbWVudC5qYXZhOjEzNTIpPGJyPnwmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm
bmJzcDsmbmJzcDsmbmJzcDsgYXQgKCM2OjEpPGJyPjxicj5qc2hlbGwmZ3Q7IE1lbW9yeVNlZ21l
bnQuY29weShieXRlU2VnLCBKQVZBX0RPVUJMRV9VTkFMSUdORUQsIDAsIHNlZywgSkFWQV9ET1VC
TEVfVU5BTElHTkVELCAwLCAxKTsgLy8gb2sgYWdhaW48YnI+YGBgPGJyPjwvcD48cD5UaGUgdHJl
YXRtZW50IG9mIGFsaWdubWVudCB3LnIudC4gaGVhcCBzZWdtZW50cyBpcyBleHBsYWluZWQgaW4g
Z3JlYXQgZGV0YWlscyBoZXJlOjxicj48YnI+aHR0cHM6Ly9kb2NzLm9yYWNsZS5jb20vZW4vamF2
YS9qYXZhc2UvMjAvZG9jcy9hcGkvamF2YS5iYXNlL2phdmEvbGFuZy9mb3JlaWduL01lbW9yeVNl
Z21lbnQuaHRtbDwvcD48cD4oSmF2YSAyMSBoYXMgYSBzaW1pbGFyIHNlY3Rpb24pLjwvcD48cD5O
b3RlIHRoYXQgdGhpcyBoYXMgbm90aGluZyB0byBkbyB3aXRoIG1ldGhvZHMgbm90IHRyZWF0aW5n
IG9mZnNldHMgdW5pZm9ybWx5IC0gb2Zmc2V0cyBhcmUgaW4gZmFjdCB0cmVhdGVkIHVuaWZvcm1s
eSwgYW5kIGFsd2F5cyBjaGVja2VkIGFnYWluc3QgdGhlIGFsaWdubWVudCBjb25zdHJhaW50cyBv
ZiB0aGUgbGF5b3V0IGJlaW5nIHVzZWQgZm9yIHRoZSBkZXJlZmVyZW5jZSBvcGVyYXRpb24uPC9w
PjxwPklmIHlvdSBkb24ndCBjYXJlIGFib3V0IGFsaWdubWVudCwgdXNlIHVuYWxpZ25lZCBsYXlv
dXRzIChmb3Igd2hpY2ggY29uc3RhbnRzIGFyZSBhbHNvIHByb3ZpZGVkKSwgb3IgdXNlIHNlZ21l
bnRzIHRoYXQgd3JhcCBsb25nW10sIHdoaWNoIGFsbG93IGZvciBtb3JlIGFsaWdubWVudC48YnI+
PC9wPjxwPlRoZSBjdXJyZW50IGJlaGF2aW9yIGlzIGtpbmQgb2YgYSBmb3JjZWQgbW92ZSwgZHJp
dmVuIGJ5IHRoZSBmYWN0IHRoYXQgaGVhcCBzZWdtZW50cyBoYXZlIGRpZmZlcmVudCBhbGlnbm1l
bnQgcHJvcGVydGllcyBiYXNlZCBvbiBwbGF0Zm9ybSBhbmQgSlZNIGltcGxlbWVudGF0aW9uLiBT
byB0aGUgYWxpZ25tZW50IG9mIGhlYXAgc2VnbWVudCBpcyBkZWZpbmVkIGluIHRlcm1zIG9mIHRo
ZSBsb3dlc3QgY29tbW9uIGRlbm9taW5hdG9yLiBJZiB0aGUgQVBJIGRpZG4ndCBkbyB0aGlzLCB5
b3UgbWlnaHQgd3JpdGUgc29tZSBjb2RlIHVzaW5nIG1lbW9yeSBzZWdtZW50cyB0aGF0IHdvdWxk
IHdvcmsgd2VsbCBpbiBvbmUgcGxhdGZvcm0gYW5kIHRoZW4gZmFpbCBvbiBhbm90aGVyIGJlY2F1
c2Ugb2YgZGlmZmVyZW50IGFsaWdubWVudCBjb25zdHJhaW50cy4gV2hpbGUgcGxhdGZvcm0tZGVw
ZW5kZW50IGJlaGF2aW9yIGlzIGZhaXIgZ2FtZSB3aGVuIGludGVyYWN0aW5nIHdpdGggbmF0aXZl
IGNvZGUsIGluIHRoaXMgY2FzZSB5b3Ugd291bGQgYmUgYWJsZSB0byBnZXQgcGxhdGZvcm0tZGVw
ZW5kZW50IGJlaGF2aW9yIG9ubHkgd2hlbiBhY2Nlc3NpbmcgbWVtb3J5LCBhbmQgd2UgZGlkbid0
IHdhbnQgdGhhdCAoYXMgdGhpcyBBUEkgd2lsbCBsaWtlbHkgYmUgdXNlZCBhcyBhIHJlcGxhY2Vt
ZW50IGZvciBCeXRlQnVmZmVyIGluIG1hbnkgY2FzZXMsIGUuZy4gZXZlbiB3aGVuIG5vIG5hdGl2
ZSBpbnRlcm9wIGlzIG5lZWRlZCkuPC9wPjxwPkNoZWVyczxicj5NYXVyaXppbzxicj48L3A+PGJy
PjxibG9ja3F1b3RlIHR5cGU9ImNpdGUiIGNpdGU9Im1pZDpDQUptRC09NG55OE5CMW01NnNvd1ha
T2tQYTYyQjVjUE1jZnBWQmZwY3lSa2hIMng0aGdAbWFpbC5nbWFpbC5jb20iPjxkaXYgZGlyPSJs
dHIiPjxkaXY+PGRpdj5JcyBpdCBkb25lIGJ5IGRlc2lnbj8mbmJzcDs8L2Rpdj48ZGl2PklNSE8s
IGJvdGggbWV0aG9kcyBzaG91bGQmbmJzcDt0cmVhdCBvZmZzZXRzIHVuaWZvcm1seSwgYW5kIHRo
YXQgaXMgbm90IHRha2luZyBpbnRvIGFjY291bnQgdGhhdCBzdWNoIHRyZWF0bWVudHMgb2Ygb2Zm
c2V0cyBpbiAic2V0IiBtZXRob2RzIG1ha2UgaXQgdmVyeSBoYXJkIHRvIHdvcmsgd2l0aCBoZWFw
LWJhc2VkIHNlZ21lbnRzLjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+UC5TLiBJIGFtIHVzaW5n
IEpESyAyMC48L2Rpdj48c3BhbiBjbGFzcz0iZ21haWxfc2lnbmF0dXJlX3ByZWZpeCI+LS0gPC9z
cGFuPjxicj48ZGl2IGRpcj0ibHRyIiBjbGFzcz0iZ21haWxfc2lnbmF0dXJlIiBkYXRhLXNtYXJ0
bWFpbD0iZ21haWxfc2lnbmF0dXJlIj48ZGl2IGRpcj0ibHRyIj48ZGl2PjxkaXYgZGlyPSJsdHIi
PkJlc3QgcmVnYXJkcyw8YnI+QW5kcmlpIExvbWFraW4uPGJyPjxicj48L2Rpdj48L2Rpdj48L2Rp
        dj48L2Rpdj48L2Rpdj48L2Rpdj4KCjwvYmxvY2txdW90ZT4=" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;">​</div>
    </div>
  </body>
</html>