From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp47.i.mail.ru (smtp47.i.mail.ru [94.100.177.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 7C25E445320 for ; Thu, 9 Jul 2020 16:57:52 +0300 (MSK) References: <20200629121118.21596-1-arkholga@tarantool.org> <20200629121118.21596-2-arkholga@tarantool.org> <20200701213447.GE5559@tarantool.org> <16d471e3-d578-7b12-6a4f-08814a2f1b64@tarantool.org> <20200709010804.7kejojfasvu7o7oj@tkn_work_nb> From: Olga Arkhangelskaia Message-ID: Date: Thu, 9 Jul 2020 16:57:50 +0300 MIME-Version: 1.0 In-Reply-To: <20200709010804.7kejojfasvu7o7oj@tkn_work_nb> Content-Type: multipart/alternative; boundary="------------91F1EA528D9989A937B2A8B3" Content-Language: en-GB Subject: Re: [Tarantool-patches] [PATCH 1/1] box: fixed box.info:memory() List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexander Turenko Cc: tarantool-patches@dev.tarantool.org This is a multi-part message in MIME format. --------------91F1EA528D9989A937B2A8B3 Content-Type: text/plain; charset="utf-8"; format="flowed" Content-Transfer-Encoding: 8bit Hi Alexandr! Thanks for the review! I have fixed all nits and rewrite the commit message. Fix the return value of box.info:memory(). It used to return the same table as the box.info(). | box.info.memory() = box.info[“memory”]() | box.info.memory() -> getmetatable(box.info.memory).__call(box.info.memory) | box.info:memory() = box.info[“memory”](box.info) | box.info:memory() -> getmetatable(box.info...).__call(box.info.., box.info) See https://www.lua.org/manual/5.1/manual.html#2.8.An extra argument on Lua stack in the second case is box.info table with __serialize metamethod. When all internal functions are over, memory table is pushed on the stack. When console prints the output (converts lua table to yaml format and prints) __serialize metamethod of box.info is called. __serilize metamethod of box.info shows only some predefined fields and completely ignores memory table. To avoid this call, patch pushes an extra empty table on Lua stack. When console calls ymal.serializer to print lua table, box.info will be ignored. Closes #4688 09.07.2020 4:08, Alexander Turenko пишет: > Pasted the actual patch to comment in-place. > >> commit ad00de576ab0300a3e48be2cdda2bef5938eb40e >> Author: Olga Arkhangelskaia >> Date: Mon Jun 29 12:14:24 2020 +0300 >> >> box: fix box.info:memory() >> >> Fix the output of box.info:memory(). It used to return the same table as the >> box.info(). > Nit: 72 symbols at max. Here and below. > > Nit: I would say 'the return value', because 'the output' looks more fixed > >> >> Any box.info.xxx() is the same as box.info[“xxx”](). >> E.g. box.info.memory() -> >> getmetatable(box.info.memory).__call(box.info.memory)[1] > It is ambiguous: whether [1] is first element or an array or a reference > for the link below. fixed > >> After __index and __call metamethods, the final function that fills xxx-table, >> has the only argument - empty table to fill. >> When box.info:xxx() is invoked it automatically passes one argument: >> box.info[“xxx”](box.info). So the resulting call has 2 arguments on the stack. >> box.info:xxx()->getmetatable(box.info.xxx).__call(box.info.xxx, box.info) > Nit: I would surround '->' with spaces for readability. fixed >> When function tries to fill box.info table - __call metamethod of box.info is >> trigged. > It is not correct. It would be __newindex metamethod, but it is not > defined on the table. I guess you was misguided by a console output, > because of __serialize method. In fact table will be filled > with 'cache', 'lua', 'data' and other box.info.memory() fields. You can > verify it youself: fixed > > | tarantool> setmetatable(box.info:memory(), nil) > | --- > | - cache: 0 > | lua: 1076262 > | data: 37816 > | index: 1097728 > | net: 589824 > | tx: 0 > | version: 2.5.0-208-gcf6975793 > | package: Tarantool > | ... > > Despite changes I requested above I appecitate the intention to clarify > the change. > >> >> box.info.gc does not have this problem because of an extra table that is >> created in the beginning of the bottom function. box.info.memory follows >> the same way. >> >> [1] https://www.lua.org/manual/5.1/manual.html#2.8 Changed > Nit: Markdown provides '[1]: https://' syntax for reference style links, > but mayble there are others markups, where syntax is the same as above. > I don't know for sure. Personally I use markdown (but sometimes with > asciidoc titles) for texts with several simple markup elements like > hyperlinks. Many developers aware of this syntax. > >> >> Closes 4688 > Typo: no hash symbol. Fixed >> diff --git a/src/box/lua/info.c b/src/box/lua/info.c >> index d0e553b1d..3d515ae9e 100644 >> --- a/src/box/lua/info.c >> +++ b/src/box/lua/info.c >> @@ -322,6 +322,7 @@ lbox_info_memory_call(struct lua_State *L) >> struct engine_memory_stat stat; >> engine_memory_stat(&stat); >> >> + lua_newtable(L); > Nit: Six same structured blocks are below. But after the change the > first one will differs. Please, add an empty line after lua_newtable(). added an epmty line. > > BTW, we can use lua_createtable() to allocate a hashmap of necessary > size before inserting elements. It is to avoid resizing of the table > (don't know whether it is actual for small map sizes like 6). > > The change itself is okay for me. > >> lua_pushstring(L, "data"); >> luaL_pushuint64(L, stat.data); >> lua_settable(L, -3); >> diff --git a/test/box-tap/gh-4688-box-info-memory.test.lua b/test/box-tap/gh-4688-box-info-memory.test.lua >> new file mode 100755 >> index 000000000..63dcdab8f >> --- /dev/null >> +++ b/test/box-tap/gh-4688-box-info-memory.test.lua >> @@ -0,0 +1,15 @@ >> +#!/usr/bin/env tarantool >> +-- >> +-- gh-4688: box.info:memory() displayed full content of box.info >> +-- >> +local tap = require('tap') >> +local test = tap.test("Tarantool 4688") > Nit: Single and double quotes are used without any system. > > Nit: See how other top level test cases are named: `grep tap.test > test/*/gh-*`. >> +test:plan(1) >> + >> +box.cfg() >> + >> +a = box.info.memory() >> +b = box.info:memory() >> + >> +test:is(table.concat(a), table.concat(b), "box.info:memory") > First, 'lua' values likely will be different. Second, table.concat() > concatenates elements of an array like {'x', 'y', 'z'}. It is not for > maps (it just gives an empty string). The result is that the test passes > ever without the fix. > > Most obvious way would be using of test:is_deeply(), but since 'lua' > field may vary, we can do one of the following ways: > > | a.lua = a.lua and '' or nil > | b.lua = b.lua and '' or nil > | > | test:is_deeply(a, b, 'box.info:memory() is the same as box.info.memory()') > > Or > > | local function get_keys(t) > | local keys = {} > | for k, v in pairs(t) do > | table.insert(keys, k) > | end > | return keys > | end > | > | local keys_1 = get_keys(box.info.memory()) > | local keys_2 = get_keys(box.info:memory()) > | test:is_deeply(keys_1, keys_2, <...>) New test:  --  -- gh-4688: box.info:memory() displayed full content of box.info  --  local tap = require('tap') -local test = tap.test("Tarantool 4688") -test:plan(1) ~  box.cfg() ~ -a = box.info.memory() -b = box.info:memory() +local test = tap.test('gh-4688-box.info:memory-wrong-result') +test:plan(1) + +local a = box.info.memory() +local b = box.info:memory() + +local function get_keys(t) +    local keys = {} +    for k, v in pairs(t) do +        table.insert(keys, k) + end +    return keys +end + +local keys_1 = get_keys(box.info.memory()) +local keys_2 = get_keys(box.info:memory()) +test:is_deeply(keys_1, keys_2, "box.info:memory coincide with box.info.memory") ~ -test:is(table.concat(a), table.concat(b), "box.info:memory") -os.exit(0) +os.exit(test:check() and 0 or 1) > > Feel free to use any variant or provide your own. > >> +os.exit(0) > Please, set exit code appropriately (see [1]). > > [1]: https://github.com/tarantool/doc/issues/1004 --------------91F1EA528D9989A937B2A8B3 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: base64 PGh0bWw+CiAgPGhlYWQ+CiAgICA8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNv bnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCI+CiAgPC9oZWFkPgogIDxib2R5Pgog ICAgPHA+SGkgQWxleGFuZHIhPC9wPgogICAgPHA+VGhhbmtzIGZvciB0aGUgcmV2aWV3ISBJ IGhhdmUgZml4ZWQgYWxsIG5pdHMgYW5kIHJld3JpdGUgdGhlCiAgICAgIGNvbW1pdCBtZXNz YWdlLjwvcD4KICAgIDxwPjxzcGFuIHN0eWxlPSJib3gtc2l6aW5nOiBpbmhlcml0OyB1c2Vy LXNlbGVjdDogdGV4dDsgY3Vyc29yOiB0ZXh0OyBjb2xvcjogcmdiKDM2LCA0MSwgNDYpOyBm b250LWZhbWlseTogTWVubG8sIE1vbmFjbywgQ29uc29sYXMsICZxdW90O0xpYmVyYXRpb24g TW9ubyZxdW90OywgJnF1b3Q7Q291cmllciBOZXcmcXVvdDssIG1vbm9zcGFjZTsgZm9udC1z aXplOiAxMXB4OyBmb250LXN0eWxlOiBub3JtYWw7IGZvbnQtdmFyaWFudC1saWdhdHVyZXM6 IG5vcm1hbDsgZm9udC12YXJpYW50LWNhcHM6IG5vcm1hbDsgZm9udC13ZWlnaHQ6IDQwMDsg bGV0dGVyLXNwYWNpbmc6IG5vcm1hbDsgb3JwaGFuczogMjsgdGV4dC1hbGlnbjogc3RhcnQ7 IHRleHQtaW5kZW50OiAwcHg7IHRleHQtdHJhbnNmb3JtOiBub25lOyB3aGl0ZS1zcGFjZTog cHJlLWxpbmU7IHdpZG93czogMjsgd29yZC1zcGFjaW5nOiAwcHg7IC13ZWJraXQtdGV4dC1z dHJva2Utd2lkdGg6IDBweDsgYmFja2dyb3VuZC1jb2xvcjogcmdiKDI1NSwgMjU1LCAyNTUp OyB0ZXh0LWRlY29yYXRpb24tc3R5bGU6IGluaXRpYWw7IHRleHQtZGVjb3JhdGlvbi1jb2xv cjogaW5pdGlhbDsiPkZpeCB0aGUgcmV0dXJuIHZhbHVlIG9mIGJveC5pbmZvOm1lbW9yeSgp LiBJdCB1c2VkIHRvIHJldHVybiB0aGUgc2FtZSB0YWJsZQphcyB0aGUgYm94LmluZm8oKS4K CnwgYm94LmluZm8ubWVtb3J5KCkgPSBib3guaW5mb1vigJxtZW1vcnnigJ1dKCkKfCBib3gu aW5mby5tZW1vcnkoKSAtJmd0OyBnZXRtZXRhdGFibGUoYm94LmluZm8ubWVtb3J5KS5fX2Nh bGwoYm94LmluZm8ubWVtb3J5KQp8IGJveC5pbmZvOm1lbW9yeSgpID0gYm94LmluZm9b4oCc bWVtb3J54oCdXShib3guaW5mbykKfCBib3guaW5mbzptZW1vcnkoKSAtJmd0OyBnZXRtZXRh dGFibGUoYm94LmluZm8uLi4pLl9fY2FsbChib3guaW5mby4uLCBib3guaW5mbykKU2VlIDwv c3Bhbj48YSBjbGFzcz0ibGluay1idXR0b24tY29tcG9uZW50IiBocmVmPSJodHRwczovL3d3 dy5sdWEub3JnL21hbnVhbC81LjEvbWFudWFsLmh0bWwjMi44LiIgdGl0bGU9Imh0dHBzOi8v d3d3Lmx1YS5vcmcvbWFudWFsLzUuMS9tYW51YWwuaHRtbCMyLjguIiBzdHlsZT0iYm94LXNp emluZzogaW5oZXJpdDsgdXNlci1zZWxlY3Q6IHRleHQ7IGN1cnNvcjogcG9pbnRlcjsgY29s b3I6IHZhcigtLWxpbmstYnV0dG9uLWNvbG9yKTsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyBk aXNwbGF5OiBpbmxpbmUtZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZm9udC1mYW1pbHk6 IE1lbmxvLCBNb25hY28sIENvbnNvbGFzLCAmcXVvdDtMaWJlcmF0aW9uIE1vbm8mcXVvdDss ICZxdW90O0NvdXJpZXIgTmV3JnF1b3Q7LCBtb25vc3BhY2U7IGZvbnQtc2l6ZTogMTFweDsg Zm9udC1zdHlsZTogbm9ybWFsOyBmb250LXZhcmlhbnQtbGlnYXR1cmVzOiBub3JtYWw7IGZv bnQtdmFyaWFudC1jYXBzOiBub3JtYWw7IGZvbnQtd2VpZ2h0OiA0MDA7IGxldHRlci1zcGFj aW5nOiBub3JtYWw7IG9ycGhhbnM6IDI7IHRleHQtYWxpZ246IHN0YXJ0OyB0ZXh0LWluZGVu dDogMHB4OyB0ZXh0LXRyYW5zZm9ybTogbm9uZTsgd2hpdGUtc3BhY2U6IHByZS1saW5lOyB3 aWRvd3M6IDI7IHdvcmQtc3BhY2luZzogMHB4OyAtd2Via2l0LXRleHQtc3Ryb2tlLXdpZHRo OiAwcHg7IGJhY2tncm91bmQtY29sb3I6IHJnYigyNTUsIDI1NSwgMjU1KTsiPmh0dHBzOi8v d3d3Lmx1YS5vcmcvbWFudWFsLzUuMS9tYW51YWwuaHRtbCMyLjguPC9hPjxzcGFuIHN0eWxl PSJib3gtc2l6aW5nOiBpbmhlcml0OyB1c2VyLXNlbGVjdDogdGV4dDsgY3Vyc29yOiB0ZXh0 OyBjb2xvcjogcmdiKDM2LCA0MSwgNDYpOyBmb250LWZhbWlseTogTWVubG8sIE1vbmFjbywg Q29uc29sYXMsICZxdW90O0xpYmVyYXRpb24gTW9ubyZxdW90OywgJnF1b3Q7Q291cmllciBO ZXcmcXVvdDssIG1vbm9zcGFjZTsgZm9udC1zaXplOiAxMXB4OyBmb250LXN0eWxlOiBub3Jt YWw7IGZvbnQtdmFyaWFudC1saWdhdHVyZXM6IG5vcm1hbDsgZm9udC12YXJpYW50LWNhcHM6 IG5vcm1hbDsgZm9udC13ZWlnaHQ6IDQwMDsgbGV0dGVyLXNwYWNpbmc6IG5vcm1hbDsgb3Jw aGFuczogMjsgdGV4dC1hbGlnbjogc3RhcnQ7IHRleHQtaW5kZW50OiAwcHg7IHRleHQtdHJh bnNmb3JtOiBub25lOyB3aGl0ZS1zcGFjZTogcHJlLWxpbmU7IHdpZG93czogMjsgd29yZC1z cGFjaW5nOiAwcHg7IC13ZWJraXQtdGV4dC1zdHJva2Utd2lkdGg6IDBweDsgYmFja2dyb3Vu ZC1jb2xvcjogcmdiKDI1NSwgMjU1LCAyNTUpOyB0ZXh0LWRlY29yYXRpb24tc3R5bGU6IGlu aXRpYWw7IHRleHQtZGVjb3JhdGlvbi1jb2xvcjogaW5pdGlhbDsiPgoKQW4gZXh0cmEgYXJn dW1lbnQgb24gTHVhIHN0YWNrIGluIHRoZSBzZWNvbmQgY2FzZSBpcyBib3guaW5mbyB0YWJs ZSB3aXRoCl9fc2VyaWFsaXplIG1ldGFtZXRob2QuIFdoZW4gYWxsIGludGVybmFsIGZ1bmN0 aW9ucyBhcmUgb3ZlciwgbWVtb3J5IHRhYmxlIGlzCnB1c2hlZCBvbiB0aGUgc3RhY2suIFdo ZW4gY29uc29sZSBwcmludHMgdGhlIG91dHB1dCAoY29udmVydHMgbHVhIHRhYmxlIHRvIHlh bWwKZm9ybWF0IGFuZCBwcmludHMpIF9fc2VyaWFsaXplIG1ldGFtZXRob2Qgb2YgYm94Lmlu Zm8gaXMgY2FsbGVkLgoKX19zZXJpbGl6ZSBtZXRhbWV0aG9kIG9mIGJveC5pbmZvIHNob3dz IG9ubHkgc29tZSBwcmVkZWZpbmVkIGZpZWxkcyBhbmQKY29tcGxldGVseSBpZ25vcmVzIG1l bW9yeSB0YWJsZS4gVG8gYXZvaWQgdGhpcyBjYWxsLCBwYXRjaCBwdXNoZXMgYW4gZXh0cmEK ZW1wdHkgdGFibGUgb24gTHVhIHN0YWNrLiBXaGVuIGNvbnNvbGUgY2FsbHMgeW1hbC5zZXJp YWxpemVyIHRvIHByaW50IGx1YSB0YWJsZSwKYm94LmluZm8gd2lsbCBiZSBpZ25vcmVkLgoK Q2xvc2VzIDwvc3Bhbj48YSBjbGFzcz0ibGluay1idXR0b24tY29tcG9uZW50IiBocmVmPSJo dHRwczovL2dpdGh1Yi5jb20vdGFyYW50b29sL3RhcmFudG9vbC9pc3N1ZXMvNDY4OCIgdGl0 bGU9Imh0dHBzOi8vZ2l0aHViLmNvbS90YXJhbnRvb2wvdGFyYW50b29sL2lzc3Vlcy80Njg4 IiBzdHlsZT0iYm94LXNpemluZzogaW5oZXJpdDsgdXNlci1zZWxlY3Q6IHRleHQ7IGN1cnNv cjogcG9pbnRlcjsgY29sb3I6IHZhcigtLWxpbmstYnV0dG9uLWNvbG9yKTsgdGV4dC1kZWNv cmF0aW9uOiBub25lOyBkaXNwbGF5OiBpbmxpbmUtZmxleDsgYWxpZ24taXRlbXM6IGNlbnRl cjsgZm9udC1mYW1pbHk6IE1lbmxvLCBNb25hY28sIENvbnNvbGFzLCAmcXVvdDtMaWJlcmF0 aW9uIE1vbm8mcXVvdDssICZxdW90O0NvdXJpZXIgTmV3JnF1b3Q7LCBtb25vc3BhY2U7IGZv bnQtc2l6ZTogMTFweDsgZm9udC1zdHlsZTogbm9ybWFsOyBmb250LXZhcmlhbnQtbGlnYXR1 cmVzOiBub3JtYWw7IGZvbnQtdmFyaWFudC1jYXBzOiBub3JtYWw7IGZvbnQtd2VpZ2h0OiA0 MDA7IGxldHRlci1zcGFjaW5nOiBub3JtYWw7IG9ycGhhbnM6IDI7IHRleHQtYWxpZ246IHN0 YXJ0OyB0ZXh0LWluZGVudDogMHB4OyB0ZXh0LXRyYW5zZm9ybTogbm9uZTsgd2hpdGUtc3Bh Y2U6IHByZS1saW5lOyB3aWRvd3M6IDI7IHdvcmQtc3BhY2luZzogMHB4OyAtd2Via2l0LXRl eHQtc3Ryb2tlLXdpZHRoOiAwcHg7IGJhY2tncm91bmQtY29sb3I6IHJnYigyNTUsIDI1NSwg MjU1KTsiPiM0Njg4PC9hPjwvcD4KICAgIDxkaXYgY2xhc3M9Im1vei1jaXRlLXByZWZpeCI+ MDkuMDcuMjAyMCA0OjA4LCBBbGV4YW5kZXIgVHVyZW5rbwogICAgICDQv9C40YjQtdGCOjxi cj4KICAgIDwvZGl2PgogICAgPGJsb2NrcXVvdGUgdHlwZT0iY2l0ZSIKICAgICAgY2l0ZT0i bWlkOjIwMjAwNzA5MDEwODA0LjdrZWpvamZhc3Z1N283b2pAdGtuX3dvcmtfbmIiPgogICAg ICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPlBhc3RlZCB0aGUgYWN0dWFs IHBhdGNoIHRvIGNvbW1lbnQgaW4tcGxhY2UuCgo8L3ByZT4KICAgICAgPGJsb2NrcXVvdGUg dHlwZT0iY2l0ZSI+CiAgICAgICAgPHByZSBjbGFzcz0ibW96LXF1b3RlLXByZSIgd3JhcD0i Ij5jb21taXQgYWQwMGRlNTc2YWIwMzAwYTNlNDhiZTJjZGRhMmJlZjU5MzhlYjQwZQpBdXRo b3I6IE9sZ2EgQXJraGFuZ2Vsc2thaWEgPGEgY2xhc3M9Im1vei10eHQtbGluay1yZmMyMzk2 RSIgaHJlZj0ibWFpbHRvOmFya2hvbGdhQHRhcmFudG9vbC5vcmciPiZsdDthcmtob2xnYUB0 YXJhbnRvb2wub3JnJmd0OzwvYT4KRGF0ZTogICBNb24gSnVuIDI5IDEyOjE0OjI0IDIwMjAg KzAzMDAKCiAgICBib3g6IGZpeCBib3guaW5mbzptZW1vcnkoKQogICAgCiAgICBGaXggdGhl IG91dHB1dCBvZiBib3guaW5mbzptZW1vcnkoKS4gSXQgdXNlZCB0byByZXR1cm4gdGhlIHNh bWUgdGFibGUgYXMgdGhlCiAgICBib3guaW5mbygpLgo8L3ByZT4KICAgICAgPC9ibG9ja3F1 b3RlPgogICAgICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPgpOaXQ6IDcy IHN5bWJvbHMgYXQgbWF4LiBIZXJlIGFuZCBiZWxvdy4KCk5pdDogSSB3b3VsZCBzYXkgJ3Ro ZSByZXR1cm4gdmFsdWUnLCBiZWNhdXNlICd0aGUgb3V0cHV0JyBsb29rcyBtb3JlPC9wcmU+ CiAgICA8L2Jsb2NrcXVvdGU+CiAgICBmaXhlZDxicj4KICAgIDxibG9ja3F1b3RlIHR5cGU9 ImNpdGUiCiAgICAgIGNpdGU9Im1pZDoyMDIwMDcwOTAxMDgwNC43a2Vqb2pmYXN2dTdvN29q QHRrbl93b3JrX25iIj4KICAgICAgPHByZSBjbGFzcz0ibW96LXF1b3RlLXByZSIgd3JhcD0i Ij4KCjwvcHJlPgogICAgICA8YmxvY2txdW90ZSB0eXBlPSJjaXRlIj4KICAgICAgICA8cHJl IGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPiAgICAKICAgIEFueSBib3guaW5mby54 eHgoKSBpcyB0aGUgc2FtZSBhcyBib3guaW5mb1vigJx4eHjigJ1dKCkuCiAgICBFLmcuIGJv eC5pbmZvLm1lbW9yeSgpIC0mZ3Q7CiAgICBnZXRtZXRhdGFibGUoYm94LmluZm8ubWVtb3J5 KS5fX2NhbGwoYm94LmluZm8ubWVtb3J5KVsxXQo8L3ByZT4KICAgICAgPC9ibG9ja3F1b3Rl PgogICAgICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPgpJdCBpcyBhbWJp Z3VvdXM6IHdoZXRoZXIgWzFdIGlzIGZpcnN0IGVsZW1lbnQgb3IgYW4gYXJyYXkgb3IgYSBy ZWZlcmVuY2UKZm9yIHRoZSBsaW5rIGJlbG93LjwvcHJlPgogICAgPC9ibG9ja3F1b3RlPgog ICAgZml4ZWQ8YnI+CiAgICA8YmxvY2txdW90ZSB0eXBlPSJjaXRlIgogICAgICBjaXRlPSJt aWQ6MjAyMDA3MDkwMTA4MDQuN2tlam9qZmFzdnU3bzdvakB0a25fd29ya19uYiI+CiAgICAg IDxwcmUgY2xhc3M9Im1vei1xdW90ZS1wcmUiIHdyYXA9IiI+Cgo8L3ByZT4KICAgICAgPGJs b2NrcXVvdGUgdHlwZT0iY2l0ZSI+CiAgICAgICAgPHByZSBjbGFzcz0ibW96LXF1b3RlLXBy ZSIgd3JhcD0iIj4gICAgQWZ0ZXIgX19pbmRleCBhbmQgX19jYWxsIG1ldGFtZXRob2RzLCB0 aGUgZmluYWwgZnVuY3Rpb24gdGhhdCBmaWxscyB4eHgtdGFibGUsCiAgICBoYXMgdGhlIG9u bHkgYXJndW1lbnQgLSBlbXB0eSB0YWJsZSB0byBmaWxsLgogICAgV2hlbiBib3guaW5mbzp4 eHgoKSBpcyBpbnZva2VkIGl0IGF1dG9tYXRpY2FsbHkgcGFzc2VzIG9uZSBhcmd1bWVudDoK ICAgIGJveC5pbmZvW+KAnHh4eOKAnV0oYm94LmluZm8pLiBTbyB0aGUgcmVzdWx0aW5nIGNh bGwgaGFzIDIgYXJndW1lbnRzIG9uIHRoZSBzdGFjay4KICAgIGJveC5pbmZvOnh4eCgpLSZn dDtnZXRtZXRhdGFibGUoYm94LmluZm8ueHh4KS5fX2NhbGwoYm94LmluZm8ueHh4LCBib3gu aW5mbykKPC9wcmU+CiAgICAgIDwvYmxvY2txdW90ZT4KICAgICAgPHByZSBjbGFzcz0ibW96 LXF1b3RlLXByZSIgd3JhcD0iIj4KTml0OiBJIHdvdWxkIHN1cnJvdW5kICctJmd0Oycgd2l0 aCBzcGFjZXMgZm9yIHJlYWRhYmlsaXR5Lgo8L3ByZT4KICAgIDwvYmxvY2txdW90ZT4KICAg IGZpeGVkPGJyPgogICAgPGJsb2NrcXVvdGUgdHlwZT0iY2l0ZSIKICAgICAgY2l0ZT0ibWlk OjIwMjAwNzA5MDEwODA0LjdrZWpvamZhc3Z1N283b2pAdGtuX3dvcmtfbmIiPgogICAgICA8 cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPgo8L3ByZT4KICAgICAgPGJsb2Nr cXVvdGUgdHlwZT0iY2l0ZSI+CiAgICAgICAgPHByZSBjbGFzcz0ibW96LXF1b3RlLXByZSIg d3JhcD0iIj4gICAgV2hlbiBmdW5jdGlvbiB0cmllcyB0byBmaWxsIGJveC5pbmZvIHRhYmxl IC0gX19jYWxsIG1ldGFtZXRob2Qgb2YgYm94LmluZm8gaXMKICAgIHRyaWdnZWQuCjwvcHJl PgogICAgICA8L2Jsb2NrcXVvdGU+CiAgICAgIDxwcmUgY2xhc3M9Im1vei1xdW90ZS1wcmUi IHdyYXA9IiI+Ckl0IGlzIG5vdCBjb3JyZWN0LiBJdCB3b3VsZCBiZSBfX25ld2luZGV4IG1l dGFtZXRob2QsIGJ1dCBpdCBpcyBub3QKZGVmaW5lZCBvbiB0aGUgdGFibGUuIEkgZ3Vlc3Mg eW91IHdhcyBtaXNndWlkZWQgYnkgYSBjb25zb2xlIG91dHB1dCwKYmVjYXVzZSBvZiBfX3Nl cmlhbGl6ZSBtZXRob2QuIEluIGZhY3QgJmx0O2JveC5pbmZvJmd0OyB0YWJsZSB3aWxsIGJl IGZpbGxlZAp3aXRoICdjYWNoZScsICdsdWEnLCAnZGF0YScgYW5kIG90aGVyIGJveC5pbmZv Lm1lbW9yeSgpIGZpZWxkcy4gWW91IGNhbgp2ZXJpZnkgaXQgeW91c2VsZjo8L3ByZT4KICAg IDwvYmxvY2txdW90ZT4KICAgIGZpeGVkPGJyPgogICAgPGJsb2NrcXVvdGUgdHlwZT0iY2l0 ZSIKICAgICAgY2l0ZT0ibWlkOjIwMjAwNzA5MDEwODA0LjdrZWpvamZhc3Z1N283b2pAdGtu X3dvcmtfbmIiPgogICAgICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPgoK IHwgdGFyYW50b29sJmd0OyBzZXRtZXRhdGFibGUoYm94LmluZm86bWVtb3J5KCksIG5pbCkK IHwgLS0tCiB8IC0gY2FjaGU6IDAKIHwgICBsdWE6IDEwNzYyNjIKIHwgICBkYXRhOiAzNzgx NgogfCAgIGluZGV4OiAxMDk3NzI4CiB8ICAgbmV0OiA1ODk4MjQKIHwgICB0eDogMAogfCAg IHZlcnNpb246IDIuNS4wLTIwOC1nY2Y2OTc1NzkzCiB8ICAgcGFja2FnZTogVGFyYW50b29s CiB8IC4uLgoKRGVzcGl0ZSBjaGFuZ2VzIEkgcmVxdWVzdGVkIGFib3ZlIEkgYXBwZWNpdGF0 ZSB0aGUgaW50ZW50aW9uIHRvIGNsYXJpZnkKdGhlIGNoYW5nZS4KCjwvcHJlPgogICAgICA8 YmxvY2txdW90ZSB0eXBlPSJjaXRlIj4KICAgICAgICA8cHJlIGNsYXNzPSJtb3otcXVvdGUt cHJlIiB3cmFwPSIiPiAgICAKICAgIGJveC5pbmZvLmdjIGRvZXMgbm90IGhhdmUgdGhpcyBw cm9ibGVtIGJlY2F1c2Ugb2YgYW4gZXh0cmEgdGFibGUgdGhhdCBpcwogICAgY3JlYXRlZCBp biB0aGUgYmVnaW5uaW5nIG9mIHRoZSBib3R0b20gZnVuY3Rpb24uIGJveC5pbmZvLm1lbW9y eSBmb2xsb3dzCiAgICB0aGUgc2FtZSB3YXkuCiAgICAKICAgIFsxXSA8YSBjbGFzcz0ibW96 LXR4dC1saW5rLWZyZWV0ZXh0IiBocmVmPSJodHRwczovL3d3dy5sdWEub3JnL21hbnVhbC81 LjEvbWFudWFsLmh0bWwjMi44Ij5odHRwczovL3d3dy5sdWEub3JnL21hbnVhbC81LjEvbWFu dWFsLmh0bWwjMi44PC9hPjwvcHJlPgogICAgICA8L2Jsb2NrcXVvdGU+CiAgICA8L2Jsb2Nr cXVvdGU+CiAgICBDaGFuZ2VkPGJyPgogICAgPGJsb2NrcXVvdGUgdHlwZT0iY2l0ZSIKICAg ICAgY2l0ZT0ibWlkOjIwMjAwNzA5MDEwODA0LjdrZWpvamZhc3Z1N283b2pAdGtuX3dvcmtf bmIiPgogICAgICA8YmxvY2txdW90ZSB0eXBlPSJjaXRlIj4KICAgICAgICA8cHJlIGNsYXNz PSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPgo8L3ByZT4KICAgICAgPC9ibG9ja3F1b3RlPgog ICAgICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPgpOaXQ6IE1hcmtkb3du IHByb3ZpZGVzICdbMV06IGh0dHBzOi8vJyBzeW50YXggZm9yIHJlZmVyZW5jZSBzdHlsZSBs aW5rcywKYnV0IG1heWJsZSB0aGVyZSBhcmUgb3RoZXJzIG1hcmt1cHMsIHdoZXJlIHN5bnRh eCBpcyB0aGUgc2FtZSBhcyBhYm92ZS4KSSBkb24ndCBrbm93IGZvciBzdXJlLiBQZXJzb25h bGx5IEkgdXNlIG1hcmtkb3duIChidXQgc29tZXRpbWVzIHdpdGgKYXNjaWlkb2MgdGl0bGVz KSBmb3IgdGV4dHMgd2l0aCBzZXZlcmFsIHNpbXBsZSBtYXJrdXAgZWxlbWVudHMgbGlrZQpo eXBlcmxpbmtzLiBNYW55IGRldmVsb3BlcnMgYXdhcmUgb2YgdGhpcyBzeW50YXguCgo8L3By ZT4KICAgICAgPGJsb2NrcXVvdGUgdHlwZT0iY2l0ZSI+CiAgICAgICAgPHByZSBjbGFzcz0i bW96LXF1b3RlLXByZSIgd3JhcD0iIj4gICAgCiAgICBDbG9zZXMgNDY4OAo8L3ByZT4KICAg ICAgPC9ibG9ja3F1b3RlPgogICAgICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFw PSIiPgpUeXBvOiBubyBoYXNoIHN5bWJvbC4KPC9wcmU+CiAgICA8L2Jsb2NrcXVvdGU+CiAg ICBGaXhlZDxicj4KICAgIDxibG9ja3F1b3RlIHR5cGU9ImNpdGUiCiAgICAgIGNpdGU9Im1p ZDoyMDIwMDcwOTAxMDgwNC43a2Vqb2pmYXN2dTdvN29qQHRrbl93b3JrX25iIj4KICAgICAg PHByZSBjbGFzcz0ibW96LXF1b3RlLXByZSIgd3JhcD0iIj4KPC9wcmU+CiAgICAgIDxibG9j a3F1b3RlIHR5cGU9ImNpdGUiPgogICAgICAgIDxwcmUgY2xhc3M9Im1vei1xdW90ZS1wcmUi IHdyYXA9IiI+CmRpZmYgLS1naXQgYS9zcmMvYm94L2x1YS9pbmZvLmMgYi9zcmMvYm94L2x1 YS9pbmZvLmMKaW5kZXggZDBlNTUzYjFkLi4zZDUxNWFlOWUgMTAwNjQ0Ci0tLSBhL3NyYy9i b3gvbHVhL2luZm8uYworKysgYi9zcmMvYm94L2x1YS9pbmZvLmMKQEAgLTMyMiw2ICszMjIs NyBAQCBsYm94X2luZm9fbWVtb3J5X2NhbGwoc3RydWN0IGx1YV9TdGF0ZSAqTCkKIAlzdHJ1 Y3QgZW5naW5lX21lbW9yeV9zdGF0IHN0YXQ7CiAJZW5naW5lX21lbW9yeV9zdGF0KCZhbXA7 c3RhdCk7CiAKKwlsdWFfbmV3dGFibGUoTCk7CjwvcHJlPgogICAgICA8L2Jsb2NrcXVvdGU+ CiAgICAgIDxwcmUgY2xhc3M9Im1vei1xdW90ZS1wcmUiIHdyYXA9IiI+Ck5pdDogU2l4IHNh bWUgc3RydWN0dXJlZCBibG9ja3MgYXJlIGJlbG93LiBCdXQgYWZ0ZXIgdGhlIGNoYW5nZSB0 aGUKZmlyc3Qgb25lIHdpbGwgZGlmZmVycy4gUGxlYXNlLCBhZGQgYW4gZW1wdHkgbGluZSBh ZnRlciBsdWFfbmV3dGFibGUoKS48L3ByZT4KICAgIDwvYmxvY2txdW90ZT4KICAgIGFkZGVk IGFuIGVwbXR5IGxpbmUuPGJyPgogICAgPGJsb2NrcXVvdGUgdHlwZT0iY2l0ZSIKICAgICAg Y2l0ZT0ibWlkOjIwMjAwNzA5MDEwODA0LjdrZWpvamZhc3Z1N283b2pAdGtuX3dvcmtfbmIi PgogICAgICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPgoKQlRXLCB3ZSBj YW4gdXNlIGx1YV9jcmVhdGV0YWJsZSgpIHRvIGFsbG9jYXRlIGEgaGFzaG1hcCBvZiBuZWNl c3NhcnkKc2l6ZSBiZWZvcmUgaW5zZXJ0aW5nIGVsZW1lbnRzLiBJdCBpcyB0byBhdm9pZCBy ZXNpemluZyBvZiB0aGUgdGFibGUKKGRvbid0IGtub3cgd2hldGhlciBpdCBpcyBhY3R1YWwg Zm9yIHNtYWxsIG1hcCBzaXplcyBsaWtlIDYpLgoKVGhlIGNoYW5nZSBpdHNlbGYgaXMgb2th eSBmb3IgbWUuCgo8L3ByZT4KICAgICAgPGJsb2NrcXVvdGUgdHlwZT0iY2l0ZSI+CiAgICAg ICAgPHByZSBjbGFzcz0ibW96LXF1b3RlLXByZSIgd3JhcD0iIj4gCWx1YV9wdXNoc3RyaW5n KEwsICJkYXRhIik7CiAJbHVhTF9wdXNodWludDY0KEwsIHN0YXQuZGF0YSk7CiAJbHVhX3Nl dHRhYmxlKEwsIC0zKTsKZGlmZiAtLWdpdCBhL3Rlc3QvYm94LXRhcC9naC00Njg4LWJveC1p bmZvLW1lbW9yeS50ZXN0Lmx1YSBiL3Rlc3QvYm94LXRhcC9naC00Njg4LWJveC1pbmZvLW1l bW9yeS50ZXN0Lmx1YQpuZXcgZmlsZSBtb2RlIDEwMDc1NQppbmRleCAwMDAwMDAwMDAuLjYz ZGNkYWI4ZgotLS0gL2Rldi9udWxsCisrKyBiL3Rlc3QvYm94LXRhcC9naC00Njg4LWJveC1p bmZvLW1lbW9yeS50ZXN0Lmx1YQpAQCAtMCwwICsxLDE1IEBACisjIS91c3IvYmluL2VudiB0 YXJhbnRvb2wKKy0tCistLSBnaC00Njg4OiBib3guaW5mbzptZW1vcnkoKSBkaXNwbGF5ZWQg ZnVsbCBjb250ZW50IG9mIGJveC5pbmZvCistLQorbG9jYWwgdGFwID0gcmVxdWlyZSgndGFw JykKK2xvY2FsIHRlc3QgPSB0YXAudGVzdCgiVGFyYW50b29sIDQ2ODgiKTwvcHJlPgogICAg ICA8L2Jsb2NrcXVvdGU+CiAgICA8L2Jsb2NrcXVvdGU+CiAgICA8YmxvY2txdW90ZSB0eXBl PSJjaXRlIgogICAgICBjaXRlPSJtaWQ6MjAyMDA3MDkwMTA4MDQuN2tlam9qZmFzdnU3bzdv akB0a25fd29ya19uYiI+CiAgICAgIDxwcmUgY2xhc3M9Im1vei1xdW90ZS1wcmUiIHdyYXA9 IiI+Ck5pdDogU2luZ2xlIGFuZCBkb3VibGUgcXVvdGVzIGFyZSB1c2VkIHdpdGhvdXQgYW55 IHN5c3RlbS4KCk5pdDogU2VlIGhvdyBvdGhlciB0b3AgbGV2ZWwgdGVzdCBjYXNlcyBhcmUg bmFtZWQ6IGBncmVwIHRhcC50ZXN0CnRlc3QvKi9naC0qYC4KPC9wcmU+CiAgICA8L2Jsb2Nr cXVvdGU+CiAgICA8YmxvY2txdW90ZSB0eXBlPSJjaXRlIgogICAgICBjaXRlPSJtaWQ6MjAy MDA3MDkwMTA4MDQuN2tlam9qZmFzdnU3bzdvakB0a25fd29ya19uYiI+CiAgICAgIDxwcmUg Y2xhc3M9Im1vei1xdW90ZS1wcmUiIHdyYXA9IiI+CjwvcHJlPgogICAgICA8YmxvY2txdW90 ZSB0eXBlPSJjaXRlIj4KICAgICAgICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFw PSIiPit0ZXN0OnBsYW4oMSkKKworYm94LmNmZygpCisKK2EgPSBib3guaW5mby5tZW1vcnko KQorYiA9IGJveC5pbmZvOm1lbW9yeSgpCisKK3Rlc3Q6aXModGFibGUuY29uY2F0KGEpLCB0 YWJsZS5jb25jYXQoYiksICJib3guaW5mbzptZW1vcnkiKQo8L3ByZT4KICAgICAgPC9ibG9j a3F1b3RlPgogICAgPC9ibG9ja3F1b3RlPgogICAgPGJsb2NrcXVvdGUgdHlwZT0iY2l0ZSIK ICAgICAgY2l0ZT0ibWlkOjIwMjAwNzA5MDEwODA0LjdrZWpvamZhc3Z1N283b2pAdGtuX3dv cmtfbmIiPgogICAgICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPgpGaXJz dCwgJ2x1YScgdmFsdWVzIGxpa2VseSB3aWxsIGJlIGRpZmZlcmVudC4gU2Vjb25kLCB0YWJs ZS5jb25jYXQoKQpjb25jYXRlbmF0ZXMgZWxlbWVudHMgb2YgYW4gYXJyYXkgbGlrZSB7J3gn LCAneScsICd6J30uIEl0IGlzIG5vdCBmb3IKbWFwcyAoaXQganVzdCBnaXZlcyBhbiBlbXB0 eSBzdHJpbmcpLiBUaGUgcmVzdWx0IGlzIHRoYXQgdGhlIHRlc3QgcGFzc2VzCmV2ZXIgd2l0 aG91dCB0aGUgZml4LgoKTW9zdCBvYnZpb3VzIHdheSB3b3VsZCBiZSB1c2luZyBvZiB0ZXN0 OmlzX2RlZXBseSgpLCBidXQgc2luY2UgJ2x1YScKZmllbGQgbWF5IHZhcnksIHdlIGNhbiBk byBvbmUgb2YgdGhlIGZvbGxvd2luZyB3YXlzOgoKIHwgYS5sdWEgPSBhLmx1YSBhbmQgJyZs dDtzdHJpcHBlZCZndDsnIG9yIG5pbAogfCBiLmx1YSA9IGIubHVhIGFuZCAnJmx0O3N0cmlw cGVkJmd0Oycgb3IgbmlsCiB8CiB8IHRlc3Q6aXNfZGVlcGx5KGEsIGIsICdib3guaW5mbzpt ZW1vcnkoKSBpcyB0aGUgc2FtZSBhcyBib3guaW5mby5tZW1vcnkoKScpCgpPcgoKIHwgbG9j YWwgZnVuY3Rpb24gZ2V0X2tleXModCkKIHwgICAgIGxvY2FsIGtleXMgPSB7fQogfCAgICAg Zm9yIGssIHYgaW4gcGFpcnModCkgZG8KIHwgICAgICAgICB0YWJsZS5pbnNlcnQoa2V5cywg aykKIHwgICAgIGVuZAogfCAgICAgcmV0dXJuIGtleXMKIHwgZW5kCiB8CiB8IGxvY2FsIGtl eXNfMSA9IGdldF9rZXlzKGJveC5pbmZvLm1lbW9yeSgpKQogfCBsb2NhbCBrZXlzXzIgPSBn ZXRfa2V5cyhib3guaW5mbzptZW1vcnkoKSkKIHwgdGVzdDppc19kZWVwbHkoa2V5c18xLCBr ZXlzXzIsICZsdDsuLi4mZ3Q7KTwvcHJlPgogICAgPC9ibG9ja3F1b3RlPgogICAgTmV3IHRl c3Q6CsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAKICAgIDxicj4KwqAtLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAKICAgIDxicj4KICAgIMKgLS0gZ2gtNDY4ODogYm94LmluZm86bWVt b3J5KCkgZGlzcGxheWVkIGZ1bGwgY29udGVudCBvZgogICAgYm94LmluZm/CoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgPGJyPgrCoC0twqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoAogICAgPGJyPgogICAgwqBsb2Nh bCB0YXAgPQogICAgcmVxdWlyZSgndGFwJynCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgCiAgICA8YnI+CiAgICAtbG9jYWwgdGVz dCA9IHRhcC50ZXN0KCJUYXJhbnRvb2wKICAgIDQ2ODgiKcKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIDxicj4KLXRlc3Q6cGxhbigxKcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgCiAgICA8YnI+Cn7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoAogICAgPGJyPgrCoGJveC5jZmcoKcKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgCiAgICA8YnI+Cn7CoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoAogICAgPGJyPgogICAg LWEgPQpib3guaW5mby5tZW1vcnkoKcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgCiAgICA8YnI+CiAgICAtYiA9 CmJveC5pbmZvOm1lbW9yeSgpwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAKICAgIDxicj4KICAgICtsb2NhbCB0 ZXN0ID0KICAgIHRhcC50ZXN0KCdnaC00Njg4LWJveC5pbmZvOm1lbW9yeS13cm9uZy1yZXN1 bHQnKcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoAogICAgPGJy PgordGVzdDpwbGFuKDEpwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAKICAgIDxi cj4KK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgCiAgICA8YnI+CiAgICArbG9jYWwgYSA9CiAgICBib3guaW5mby5tZW1vcnkoKcKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg CiAgICA8YnI+CiAgICArbG9jYWwgYiA9CiAgICBib3guaW5mbzptZW1vcnkoKcKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgCiAgICA8 YnI+CivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoAogICAgPGJyPgogICAgK2xvY2FsIGZ1bmN0aW9uCiAgICBnZXRfa2V5cyh0KcKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAKICAgIDxicj4KICAgICvCoMKgwqAgbG9jYWwga2V5cyA9CiAgICB7fcKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCA8YnI+CiAgICArwqDCoMKgIGZvciBrLCB2IGluIHBhaXJzKHQpCiAgICBkb8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IDxicj4KICAgICvCoMKgwqDCoMKgwqDCoCB0YWJsZS5pbnNlcnQoa2V5cywKICAgIGspwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA8YnI+ CiAgICArwqDCoMKgCmVuZMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoAogICAgPGJyPgogICAgK8KgwqDCoCByZXR1cm4KICAgIGtleXPCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoAogICAgPGJyPgorZW5kwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAKICAgIDxicj4KK8KgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgCiAgICA8YnI+CiAgICArbG9j YWwga2V5c18xID0KICAgIGdldF9rZXlzKGJveC5pbmZvLm1lbW9yeSgpKcKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgCiAgICA8YnI+CiAgICArbG9jYWwga2V5c18yID0KICAgIGdldF9r ZXlzKGJveC5pbmZvOm1lbW9yeSgpKcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgCiAgICA8 YnI+CiAgICArdGVzdDppc19kZWVwbHkoa2V5c18xLCBrZXlzXzIsICJib3guaW5mbzptZW1v cnkgY29pbmNpZGUgd2l0aAogICAgYm94LmluZm8ubWVtb3J5IikgPGJyPgp+wqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAKICAgIDxi cj4KICAgIC10ZXN0OmlzKHRhYmxlLmNvbmNhdChhKSwgdGFibGUuY29uY2F0KGIpLAogICAg ImJveC5pbmZvOm1lbW9yeSIpwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgPGJyPgotb3MuZXhpdCgwKcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoAogICAgPGJyPgogICAgK29zLmV4aXQodGVzdDpjaGVjaygpIGFuZCAwIG9yIDEp wqDCoMKgwqDCoCA8YnI+CiAgICA8YmxvY2txdW90ZSB0eXBlPSJjaXRlIgogICAgICBjaXRl PSJtaWQ6MjAyMDA3MDkwMTA4MDQuN2tlam9qZmFzdnU3bzdvakB0a25fd29ya19uYiI+CiAg ICAgIDxwcmUgY2xhc3M9Im1vei1xdW90ZS1wcmUiIHdyYXA9IiI+CgpGZWVsIGZyZWUgdG8g dXNlIGFueSB2YXJpYW50IG9yIHByb3ZpZGUgeW91ciBvd24uCgo8L3ByZT4KICAgICAgPGJs b2NrcXVvdGUgdHlwZT0iY2l0ZSI+CiAgICAgICAgPHByZSBjbGFzcz0ibW96LXF1b3RlLXBy ZSIgd3JhcD0iIj4rb3MuZXhpdCgwKQo8L3ByZT4KICAgICAgPC9ibG9ja3F1b3RlPgogICAg ICA8cHJlIGNsYXNzPSJtb3otcXVvdGUtcHJlIiB3cmFwPSIiPgpQbGVhc2UsIHNldCBleGl0 IGNvZGUgYXBwcm9wcmlhdGVseSAoc2VlIFsxXSkuCgpbMV06IDxhIGNsYXNzPSJtb3otdHh0 LWxpbmstZnJlZXRleHQiIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS90YXJhbnRvb2wvZG9j L2lzc3Vlcy8xMDA0Ij5odHRwczovL2dpdGh1Yi5jb20vdGFyYW50b29sL2RvYy9pc3N1ZXMv MTAwNDwvYT4KPC9wcmU+CiAgICA8L2Jsb2NrcXVvdGU+CiAgPC9ib2R5Pgo8L2h0bWw+Cg== --------------91F1EA528D9989A937B2A8B3--