<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">Hello,</p>
<p style="margin:0px 0px 1.2em!important">I often embed figures as SVG graphics in web pages. As part of this process, I usually do the following</p>
<ol style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px"><p style="margin:0px 0px 1.2em!important;margin:0.5em 0px!important">Set gids on artists and link that gid to a set of data describing that part of a graphic in an external dictionary. This includes things like setting the element’s class, extra contextual information, information that would be good to show in a tooltip, ids of related elements, and so forth.</p>
</li>
<li style="margin:0.5em 0px"><p style="margin:0px 0px 1.2em!important;margin:0.5em 0px!important">Serialize the figure into a file-like object, use an element tree implementation’s <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">XMLID</code> to get an element id map and Element objects</p>
</li>
<li style="margin:0.5em 0px"><p style="margin:0px 0px 1.2em!important;margin:0.5em 0px!important">Iterate over my data dictionary from (1) and set keys in the mapped Element’s <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">attrib</code> dictionary, using the id map from (2)</p>
</li>
<li style="margin:0.5em 0px"><p style="margin:0px 0px 1.2em!important;margin:0.5em 0px!important">Use the element tree implementation’s <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">tostring</code> function to serialize the updated Element objects back into a string and then send the string out as a response to a web request.</p>
</li>
<li style="margin:0.5em 0px"><p style="margin:0px 0px 1.2em!important;margin:0.5em 0px!important">After receiving the SVG string from the server on the client, add the SVG to the page’s DOM and then hang event handlers on it (or pre-specify delegated handlers) that use the added attributes to configure interactive behavior.</p>
</li>
</ol>
<p style="margin:0px 0px 1.2em!important">I looked at the <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">Artist</code> type and saw no good place to store “arbitrary data”. Before I start working on this I wanted to know if anyone else had a better solution. I would also like to know if the devs would be opposed to a PR that adds an extra dictionary/attribute to every <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">Artist</code> instance created.</p>
<p style="margin:0px 0px 1.2em!important">Another alternative solution would be to find a way to push my dictionary mapping gids to extra attributes into the <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">SVGRenderer</code> and have it pass them 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">**extras</code> to <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">XMLWriter.element</code> when it processes individual artists.</p>
<p style="margin:0px 0px 1.2em!important">Here’s a generic example of what I do currently:</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-python" 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;background:rgb(241,239,238);color:rgb(104,97,94);padding:0.5em"><span class="hljs-function" style="color:rgb(64,126,231)"><span class="hljs-keyword" style="color:rgb(102,102,234)">def</span> <span class="hljs-title" style="color:rgb(118,110,107)">plot_with_extras_for_svg</span><span class="hljs-params" style="color:rgb(223,83,32)">(*data, **kwargs)</span>:</span>
    <span class="hljs-comment" style="color:rgb(118,110,107)"># Do the plotting, generating the id-linked data in `id_mapper`</span>
    ax, id_mapper = plot_my_data(*data, **kwargs)
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()

    <span class="hljs-comment" style="color:rgb(118,110,107)"># compute the total space used in both dimensions when dealing with</span>
    <span class="hljs-comment" style="color:rgb(118,110,107)"># negative axis bounds</span>
    x_size = sum(map(abs, xlim))
    y_size = sum(map(abs, ylim))

    <span class="hljs-comment" style="color:rgb(118,110,107)"># Map the used axis space to the drawable region dimensions</span>
    aspect_ratio = x_size / y_size
    canvas_x = <span class="hljs-number" style="color:rgb(223,83,32)">8.</span>
    canvas_y = canvas_x / aspect_ratio

    <span class="hljs-comment" style="color:rgb(118,110,107)"># Configure the artist to draw within the new drawable region bounds</span>
    fig = ax.get_figure()
    fig.tight_layout(pad=<span class="hljs-number" style="color:rgb(223,83,32)">0.2</span>)
    fig.patch.set_visible(<span class="hljs-keyword" style="color:rgb(102,102,234)">False</span>)
    fig.set_figwidth(canvas_x)
    fig.set_figheight(canvas_y)

    ax.patch.set_visible(<span class="hljs-keyword" style="color:rgb(102,102,234)">False</span>)

    <span class="hljs-comment" style="color:rgb(118,110,107)"># Perform the first serialization</span>
    buff = StringIO()
    fig.savefig(buff, format=<span class="hljs-string" style="color:rgb(90,183,56)">'svg'</span>)

    <span class="hljs-comment" style="color:rgb(118,110,107)"># Parse XML buffer from `buff` and configure tag attributes</span>
    root, ids = ET.XMLID(buff.getvalue())
    root.attrib[<span class="hljs-string" style="color:rgb(90,183,56)">'class'</span>] = <span class="hljs-string" style="color:rgb(90,183,56)">'plot-class-svg'</span>
    <span class="hljs-keyword" style="color:rgb(102,102,234)">for</span> id, attributes <span class="hljs-keyword" style="color:rgb(102,102,234)">in</span> id_mapper.items():
        element = ids[id]
        element.attrib.update({(<span class="hljs-string" style="color:rgb(90,183,56)">"data-"</span> + k): str(v)
                               <span class="hljs-keyword" style="color:rgb(102,102,234)">for</span> k, v <span class="hljs-keyword" style="color:rgb(102,102,234)">in</span> attributes.items()})
        element.attrib[<span class="hljs-string" style="color:rgb(90,183,56)">'class'</span>] = id.rsplit(<span class="hljs-string" style="color:rgb(90,183,56)">'-'</span>)[<span class="hljs-number" style="color:rgb(223,83,32)">0</span>]

    <span class="hljs-comment" style="color:rgb(118,110,107)"># More drawable space shenanigans</span>
    min_x, min_y, max_x, max_y = map(int, root.attrib[<span class="hljs-string" style="color:rgb(90,183,56)">"viewBox"</span>].split(<span class="hljs-string" style="color:rgb(90,183,56)">" "</span>))
    min_x += <span class="hljs-number" style="color:rgb(223,83,32)">100</span>
    max_x += <span class="hljs-number" style="color:rgb(223,83,32)">200</span>
    view_box = <span class="hljs-string" style="color:rgb(90,183,56)">' '</span>.join(map(str, (min_x, min_y, max_x, max_y)))
    root.attrib[<span class="hljs-string" style="color:rgb(90,183,56)">"viewBox"</span>] = view_box
    width = float(root.attrib[<span class="hljs-string" style="color:rgb(90,183,56)">"width"</span>][:-<span class="hljs-number" style="color:rgb(223,83,32)">2</span>]) * <span class="hljs-number" style="color:rgb(223,83,32)">1.75</span>
    root.attrib[<span class="hljs-string" style="color:rgb(90,183,56)">"width"</span>] = <span class="hljs-string" style="color:rgb(90,183,56)">"100%"</span>

    height = width / (aspect_ratio)

    root.attrib[<span class="hljs-string" style="color:rgb(90,183,56)">"height"</span>] = <span class="hljs-string" style="color:rgb(90,183,56)">"%dpt"</span> % (height * <span class="hljs-number" style="color:rgb(223,83,32)">1.2</span>)
    root.attrib[<span class="hljs-string" style="color:rgb(90,183,56)">"preserveAspectRatio"</span>] = <span class="hljs-string" style="color:rgb(90,183,56)">"xMinYMin meet"</span>

    <span class="hljs-comment" style="color:rgb(118,110,107)"># Second serialization</span>
    svg = ET.tostring(root)
    plt.close(fig)

    <span class="hljs-keyword" style="color:rgb(102,102,234)">return</span> svg
</code></pre>
<p style="margin:0px 0px 1.2em!important">Thank you</p>
<div title="MDH:SGVsbG8sPGRpdj48YnI+PC9kaXY+PGRpdj5JIG9mdGVuIGVtYmVkIGZpZ3VyZXMgYXMgU1ZHIGdy
YXBoaWNzIGluIHdlYiBwYWdlcy4gQXMgcGFydCBvZiB0aGlzIHByb2Nlc3MsIEkgdXN1YWxseSBk
byB0aGUgZm9sbG93aW5nPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj4xLiBTZXQgZ2lkcyBvbiBh
cnRpc3RzIGFuZCBsaW5rIHRoYXQgZ2lkIHRvIGEgc2V0IG9mIGRhdGEgZGVzY3JpYmluZyB0aGF0
IHBhcnQgb2YgYSBncmFwaGljIGluIGFuIGV4dGVybmFsIGRpY3Rpb25hcnkuIFRoaXMgaW5jbHVk
ZXMgdGhpbmdzIGxpa2Ugc2V0dGluZyB0aGUgZWxlbWVudCdzIGNsYXNzLCBleHRyYSBjb250ZXh0
dWFsIGluZm9ybWF0aW9uLCBpbmZvcm1hdGlvbiB0aGF0IHdvdWxkIGJlIGdvb2QgdG8gc2hvdyBp
biBhIHRvb2x0aXAsIGlkcyBvZiByZWxhdGVkIGVsZW1lbnRzLCBhbmQgc28gZm9ydGguPC9kaXY+
PGRpdj48YnI+PC9kaXY+PGRpdj4yLiBTZXJpYWxpemUgdGhlIGZpZ3VyZSBpbnRvIGEgZmlsZS1s
aWtlIG9iamVjdCwgdXNlIGFuIGVsZW1lbnQgdHJlZSBpbXBsZW1lbnRhdGlvbidzIGBYTUxJRGAg
dG8gZ2V0IGFuIGVsZW1lbnQgaWQgbWFwIGFuZCBFbGVtZW50IG9iamVjdHM8L2Rpdj48ZGl2Pjxi
cj48L2Rpdj48ZGl2PjMuIEl0ZXJhdGUgb3ZlciBteSBkYXRhIGRpY3Rpb25hcnkgZnJvbSAoMSkg
YW5kIHNldCBrZXlzIGluIHRoZSBtYXBwZWQgRWxlbWVudCdzIGBhdHRyaWJgIGRpY3Rpb25hcnks
IHVzaW5nIHRoZSBpZCBtYXAgZnJvbSAoMik8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PjQuIFVz
ZSB0aGUgZWxlbWVudCB0cmVlIGltcGxlbWVudGF0aW9uJ3MgYHRvc3RyaW5nYCBmdW5jdGlvbiB0
byBzZXJpYWxpemUgdGhlIHVwZGF0ZWQgRWxlbWVudCBvYmplY3RzIGJhY2sgaW50byBhIHN0cmlu
ZyBhbmQgdGhlbiBzZW5kIHRoZSBzdHJpbmcgb3V0IGFzIGEgcmVzcG9uc2UgdG8gYSB3ZWIgcmVx
dWVzdC48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PjUuIEFmdGVyIHJlY2VpdmluZyB0aGUgU1ZH
IHN0cmluZyBmcm9tIHRoZSBzZXJ2ZXIgb24gdGhlIGNsaWVudCwgYWRkIHRoZSBTVkcgdG8gdGhl
IHBhZ2UncyBET00gYW5kIHRoZW4gaGFuZyBldmVudCBoYW5kbGVycyBvbiBpdCAob3IgcHJlLXNw
ZWNpZnkgZGVsZWdhdGVkIGhhbmRsZXJzKSB0aGF0IHVzZSB0aGUgYWRkZWQgYXR0cmlidXRlcyB0
byBjb25maWd1cmUgaW50ZXJhY3RpdmUgYmVoYXZpb3IuPC9kaXY+PGRpdj48ZGl2Pjxicj48L2Rp
dj48ZGl2PkkgbG9va2VkIGF0IHRoZSBgQXJ0aXN0YCB0eXBlIGFuZCBzYXcgbm8gZ29vZCBwbGFj
ZSB0byBzdG9yZSAiYXJiaXRyYXJ5IGRhdGEiLiBCZWZvcmUgSSBzdGFydCB3b3JraW5nIG9uIHRo
aXMgSSB3YW50ZWQgdG8ga25vdyBpZiBhbnlvbmUgZWxzZSBoYWQgYSBiZXR0ZXIgc29sdXRpb24u
IEkgd291bGQgYWxzbyBsaWtlIHRvIGtub3cgaWYgdGhlIGRldnMgd291bGQgYmUgb3Bwb3NlZCB0
byBhIFBSIHRoYXQgYWRkcyBhbiBleHRyYSBkaWN0aW9uYXJ5L2F0dHJpYnV0ZSB0byBldmVyeSBg
QXJ0aXN0YCBpbnN0YW5jZSBjcmVhdGVkLjwvZGl2PjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+
QW5vdGhlciBhbHRlcm5hdGl2ZSBzb2x1dGlvbiB3b3VsZCBiZSB0byBmaW5kIGEgd2F5IHRvIHB1
c2ggbXkgZGljdGlvbmFyeSBtYXBwaW5nIGdpZHMgdG8gZXh0cmEgYXR0cmlidXRlcyBpbnRvIHRo
ZSBgU1ZHUmVuZGVyZXJgIGFuZCBoYXZlIGl0IHBhc3MgdGhlbSBhcyBgKipleHRyYXNgIHRvIGBY
TUxXcml0ZXIuZWxlbWVudGAgd2hlbiBpdCBwcm9jZXNzZXMgaW5kaXZpZHVhbCBhcnRpc3RzLjwv
ZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+SGVyZSdzIGEgZ2VuZXJpYyBl
eGFtcGxlIG9mIHdoYXQgSSBkbyBjdXJyZW50bHk6PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5g
YGBweXRob248L2Rpdj48ZGl2PmRlZiBwbG90X3dpdGhfZXh0cmFzX2Zvcl9zdmcoKmRhdGEsICoq
a3dhcmdzKTo8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgIyBEbyB0aGUgcGxvdHRpbmcsIGdlbmVy
YXRpbmcgdGhlIGlkLWxpbmtlZCBkYXRhIGluIGBpZF9tYXBwZXJgPC9kaXY+PGRpdj48ZGl2PiZu
YnNwOyAmbmJzcDsgYXgsIGlkX21hcHBlciA9IHBsb3RfbXlfZGF0YSgqZGF0YSwgKiprd2FyZ3Mp
PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IHhsaW0gPSBheC5nZXRfeGxpbSgpPC9kaXY+PGRpdj4m
bmJzcDsgJm5ic3A7IHlsaW0gPSBheC5nZXRfeWxpbSgpPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRp
dj4mbmJzcDsgJm5ic3A7ICMgY29tcHV0ZSB0aGUgdG90YWwgc3BhY2UgdXNlZCBpbiBib3RoIGRp
bWVuc2lvbnMgd2hlbiBkZWFsaW5nIHdpdGg8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgIyBuZWdh
dGl2ZSBheGlzIGJvdW5kczwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyB4X3NpemUgPSBzdW0obWFw
KGFicywgeGxpbSkpPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IHlfc2l6ZSA9IHN1bShtYXAoYWJz
LCB5bGltKSk8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiZuYnNwOyAm
bmJzcDsgIyBNYXAgdGhlIHVzZWQgYXhpcyBzcGFjZSB0byB0aGUgZHJhd2FibGUgcmVnaW9uIGRp
bWVuc2lvbnM8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgYXNwZWN0X3JhdGlvID0geF9zaXplIC8g
eV9zaXplPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IGNhbnZhc194ID0gOC48L2Rpdj48ZGl2PiZu
YnNwOyAmbmJzcDsgY2FudmFzX3kgPSBjYW52YXNfeCAvIGFzcGVjdF9yYXRpbzwvZGl2PjxkaXY+
PGJyPjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAjIENvbmZpZ3VyZSB0aGUgYXJ0aXN0IHRvIGRy
YXcgd2l0aGluIHRoZSBuZXcgZHJhd2FibGUgcmVnaW9uIGJvdW5kczwvZGl2PjxkaXY+Jm5ic3A7
ICZuYnNwOyBmaWcgPSBheC5nZXRfZmlndXJlKCk8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgZmln
LnRpZ2h0X2xheW91dChwYWQ9MC4yKTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyBmaWcucGF0Y2gu
c2V0X3Zpc2libGUoRmFsc2UpPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IGZpZy5zZXRfZmlnd2lk
dGgoY2FudmFzX3gpPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IGZpZy5zZXRfZmlnaGVpZ2h0KGNh
bnZhc195KTwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyBheC5wYXRjaC5z
ZXRfdmlzaWJsZShGYWxzZSk8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsg
IyBQZXJmb3JtIHRoZSBmaXJzdCBzZXJpYWxpemF0aW9uPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7
IGJ1ZmYgPSBTdHJpbmdJTygpPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IGZpZy5zYXZlZmlnKGJ1
ZmYsIGZvcm1hdD0nc3ZnJyk8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsg
IyBQYXJzZSBYTUwgYnVmZmVyIGZyb20gYGJ1ZmZgIGFuZCBjb25maWd1cmUgdGFnIGF0dHJpYnV0
ZXM8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgcm9vdCwgaWRzID0gRVQuWE1MSUQoYnVmZi5nZXR2
YWx1ZSgpKTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyByb290LmF0dHJpYlsnY2xhc3MnXSA9ICdw
bG90LWNsYXNzLXN2Zyc8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgZm9yIGlkLCBhdHRyaWJ1dGVz
IGluIGlkX21hcHBlci5pdGVtcygpOjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7IGVsZW1lbnQgPSBpZHNbaWRdPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgZWxlbWVudC5hdHRyaWIudXBkYXRlKHsoImRhdGEtIiArIGspOiBzdHIodik8L2Rpdj48ZGl2
PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwO2Zv
ciBrLCB2IGluIGF0dHJpYnV0ZXMuaXRlbXMoKX0pPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgZWxlbWVudC5hdHRyaWJbJ2NsYXNzJ10gPSBpZC5yc3BsaXQoJy0nKVswXTwv
ZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAjIE1vcmUgZHJhd2FibGUgc3Bh
Y2Ugc2hlbmFuaWdhbnM8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgbWluX3gsIG1pbl95LCBtYXhf
eCwgbWF4X3kgPSBtYXAoaW50LCByb290LmF0dHJpYlsidmlld0JveCJdLnNwbGl0KCIgIikpPC9k
aXY+PGRpdj4mbmJzcDsgJm5ic3A7IG1pbl94ICs9IDEwMDwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNw
OyBtYXhfeCArPSAyMDA8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgdmlld19ib3ggPSAnICcuam9p
bihtYXAoc3RyLCAobWluX3gsIG1pbl95LCBtYXhfeCwgbWF4X3kpKSk8L2Rpdj48ZGl2PiZuYnNw
OyAmbmJzcDsgcm9vdC5hdHRyaWJbInZpZXdCb3giXSA9IHZpZXdfYm94PC9kaXY+PGRpdj4mbmJz
cDsgJm5ic3A7IHdpZHRoID0gZmxvYXQocm9vdC5hdHRyaWJbIndpZHRoIl1bOi0yXSkgKiAxLjc1
PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IHJvb3QuYXR0cmliWyJ3aWR0aCJdID0gIjEwMCUiPC9k
aXY+PGRpdj48YnI+PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IGhlaWdodCA9IHdpZHRoIC8gKGFz
cGVjdF9yYXRpbyk8L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgcm9vdC5h
dHRyaWJbImhlaWdodCJdID0gIiVkcHQiICUgKGhlaWdodCAqIDEuMik8L2Rpdj48ZGl2PiZuYnNw
OyAmbmJzcDsgcm9vdC5hdHRyaWJbInByZXNlcnZlQXNwZWN0UmF0aW8iXSA9ICJ4TWluWU1pbiBt
ZWV0IjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAjIFNlY29uZCBzZXJp
YWxpemF0aW9uPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IHN2ZyA9IEVULnRvc3RyaW5nKHJvb3Qp
PGJyPjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyBwbHQuY2xvc2UoZmlnKTwvZGl2PjxkaXY+PGJy
PjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyByZXR1cm4gc3ZnPGJyPjwvZGl2PjwvZGl2PjxkaXY+
YGBgPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5UaGFuayB5b3U8L2Rpdj4=" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0">​</div></div></div>