[Zope-PTK] First shot, class tree viewer for python/zope (using wxPython...)

Alexander Schonfeld alex@garage.co.jp
Thu, 15 Jun 2000 17:35:49 +0900


--VGh1LCAxNSBKdW4gMjAwMCAxNzozNTo0OSArMDkwMA==
Content-Transfer-Encoding: 7bit
Content-Type: text/plain

Hi,

I wrote (I mean hacked a demo...) to show class trees of bunches of
python files.  You can then move them around and take screen shots and
bask in the glory that is your zope classes.

To use:
	python pyinherit.py
d:\cvs\Zope2\lib\python\Products\LoginManager

It requires wxPython (a gui lib) from:
	http://wxpython.org/

Please expand on this if it looks interesting, and email me a copy.

Thanks,

Alex.

1010011010101001101010100110101010011010
0  Digital Garage
1  Alexander Schonfeld
0  alex@garage.co.jp - pear - 03-5454-7219
1  http://www.zope.ne.jp/



--VGh1LCAxNSBKdW4gMjAwMCAxNzozNTo0OSArMDkwMA==
Content-Type: application/octet-stream; name="pyinherit.py"
Content-Disposition: attachment;
 filename="pyinherit.py"
Content-Transfer-Encoding: base64

IiIiR2VuZXJhdGUgaW5oZXJpdGFuY2UgdHJlZSBvZiBhbGwgY2xhc3NlcyBkb2luZyByZWN1cnNp
dmUgZGlyIHNlYXJjaC4iIiINCg0KX192ZXJzaW9uX18gPSAiMC4xIEFsZXhhbmRlciBTY2hvbmZl
bGQgPGFsZXhAZ2FyYWdlLmNvLmpwPiwgMjkgTWF5IDIwMDAiDQoNCiMjIyMjIyMjIyMjIFVTQUdF
DQojIHB5dGhvbiBweWluaGVyaXQucHkgL215ZGlyIC9teWRpci9mdW4vYWZpbGUucHkgL2Fub3Ro
ZXJmaWxlLnB5IC9hZGlyMi8NCiMgQzpcUHJvamVjdHNcaW5oZXJpdD5weXRob24gcHlpbmhlcml0
LnB5IGQ6XGN2c1xab3BlMlxsaWJccHl0aG9uXFByb2R1Y3RzXExvZ2luTWFuYWdlciBkOlxjdnNc
Wm9wZTJcbGliXHB5dGhvblxQcm9kdWN0c1xaUGF0dGVybnMgDQoNCiMjIyMjIyMjIyMjIFJFUVVJ
UkVNRU5UUw0KIyAxLiBjb21wdXRlciAob3IgdmVyeSBiaWcgbGlnaHQtYnJpZ2h0LCBtYXliZSBh
YmFjdXMpDQojIDIuIHB5dGhvbiAtIGh0dHA6Ly93d3cucHl0aG9uLm9yZw0KIyAzLiB3eFB5dGhv
biAtIGh0dHA6Ly93eHB5dGhvbi5vcmcNCg0KIyMjIyMjIyMjIyMgTk9URVMNCiMgSSdtIHRyeWlu
ZyB0byBidWlsZCBhIHRvb2wgdG8gdmlzdWFsaXplIGNsYXNzIHN0cnVjdHVyZXMgZnJvbSBzb3Vy
Y2UgZmlsZXMuDQojIA0KIyBTdHVmZiBsZWZ0IHRvIGRvOg0KIwkJMS4gb3JnYW5pemUgdHJlZSBi
ZXR0ZXIsIG1pbmltaXplIG92ZXJsYXBwaW5nIGJyYW5jaGVzDQojCQkyLiBzaG93IG1vcmUgY2xh
c3MgaW5mbw0KIwkJMy4gbGluayB0byBhY3R1YWwgZmlsZXMNCiMJCTQuIHByaW50aW5nL3NhdmUv
bG9hZC9ldGMgc3VwcG9ydA0KIwkJNS4gZ2FpbiB1bmRlcnN0YW5kaW5nIG9mIHd4T0dMLi4uIChv
Z2wgemVuKQ0KIwkJNi4gYWN0dWFsbHkgc2VhcmNoIHRoZSBjbGFzcyBwYXRoIGZvciBjcmF6eSBb
c3R1ZmZdIGxpa2UgdGhpczogY2xhc3MgREIoU2hhcmVkLkRDLlpSREIuVEhVTksuVEhVTktFRF9U
TSk6DQojCQk3LiBvcHRpbWl6ZT8NCiMJCTguIGJldHRlciB3aW5kb3cgc2l6aW5nIGV0Yy4NCiMN
CiMgV2hhdCdzIGhlcmUgbm93OiBhIGhhY2tlZCB2ZXIgb2YgdGhlIG9nbGRlbW8ucHkgYW5kIHNv
bWUgc2ltcGxlIHRyZWUgc3R1ZmYsIHBsdXMgZGlyZWN0b3J5IHdhbGtpbmcgdG8gZmluZCBjbGFz
c2VzLg0KIw0KIyBRdWVzdGlvbnM/ICBDb21tZW50cz8gIEZpeGVkIHRoaXMgbWVzcz8gIFBsZWFz
ZSBkcm9wIG1lIGEgbGluZSBhdDogYWxleEBnYXJhZ2UuY28uanANCg0KIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCmltcG9ydCBzeXMsIHN0cmluZywgcmUNCmZyb20gd3hQ
eXRob24ud3ggaW1wb3J0ICoNCmZyb20gd3hQeXRob24ub2dsIGltcG9ydCAqDQoNCiMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KY2xhc3MgdHJlZU5vZGU6DQoJZGVmIF9faW5p
dF9fKHNlbGYsIGNsYXNzbmFtZSwgZmlsZW5hbWU9JycsIGRlcHRoPTApOg0KCQlzZWxmLmNsYXNz
bmFtZSA9IGNsYXNzbmFtZQ0KCQlzZWxmLmZpbGVuYW1lID0gZmlsZW5hbWUNCgkJc2VsZi5jaGls
ZHJlbiA9IFtdICNhY3R1YWwgb2JqZWN0cw0KCQlzZWxmLnBhcmVudHMgPSBbXSAjanVzdCBzdHJp
bmcgY2xhc3NuYW1lcywgbGF0ZXIgY29udmVydGVkIHRvIG9ianMNCgkJc2VsZi5kZXB0aCA9IDAg
I2xldmVsIGluIHRyZWUNCgkJc2VsZi5zaGFwZSA9IDANCglkZWYgX19yZXByX18oc2VsZik6DQoJ
CXJldHVybiBzZWxmLmNsYXNzbmFtZQ0KCWRlZiBfX2NtcF9fKHNlbGYsIG90aGVyKToNCgkJaWYg
c3RyKHNlbGYuY2xhc3NuYW1lKSA+IHN0cihvdGhlcik6DQoJCQlyZXR1cm4gMQ0KCQllbGlmIHN0
cihzZWxmLmNsYXNzbmFtZSkgPCBzdHIob3RoZXIpOg0KCQkJcmV0dXJuIC0xDQoJCWVsc2U6DQoJ
CQlyZXR1cm4gMA0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCmRlZiBn
ZXRDaGlsZE5vZGVDbnQobm9kZSk6ICMgc2VhcmNoZXMgdXAgdGhyb3VnaCBwYXJlbnRzDQoJc3Vt
ID0gMA0KCXN1bSA9IGxlbihub2RlLmNoaWxkcmVuKQ0KCWZvciBjaGlsZCBpbiBub2RlLmNoaWxk
cmVuOg0KCQlzdW0gPSBzdW0gKyBnZXRDaGlsZE5vZGVDbnQoY2hpbGQpDQoJcmV0dXJuIHN1bQ0K
DQpkZWYgZ2V0UGFyZW50Tm9kZUNudChub2RlKTogIyBzZWFyY2hlcyB1cCB0aHJvdWdoIHBhcmVu
dHMNCglzdW0gPSAwDQoJc3VtID0gbGVuKG5vZGUucGFyZW50cykNCglmb3IgcGFyZW50IGluIG5v
ZGUucGFyZW50czoNCgkJc3VtID0gc3VtICsgZ2V0UGFyZW50Tm9kZUNudChwYXJlbnQpDQoJcmV0
dXJuIHN1bQ0KDQpkZWYgcm93U29ydEZ1bmMobm9kZTEsIG5vZGUyKToNCgluMWNudCA9IGdldENo
aWxkTm9kZUNudChub2RlMSkrZ2V0UGFyZW50Tm9kZUNudChub2RlMSkNCgluMmNudCA9IGdldENo
aWxkTm9kZUNudChub2RlMikrZ2V0UGFyZW50Tm9kZUNudChub2RlMikNCglpZiBuMWNudCA+IG4y
Y250Og0KCQlyZXR1cm4gLTENCgllbGlmIG4xY250IDwgbjJjbnQ6DQoJCXJldHVybiAxDQoJZWxz
ZToNCgkJcmV0dXJuIDANCiMJCW4xY250ID0gZ2V0Q2hpbGROb2RlQ250KG5vZGUxKQ0KIwkJbjJj
bnQgPSBnZXRDaGlsZE5vZGVDbnQobm9kZTIpDQojCQlpZiBuMWNudCA+IG4yY250Og0KIwkJCXJl
dHVybiAtMQ0KIwkJZWxpZiBuMWNudCA8IG4yY250Og0KIwkJCXJldHVybiAxDQojCQllbHNlOg0K
IwkJCXJldHVybiAwDQoNCmRlZiBhZGRGaWxlcyhmaWxlbmFtZXMsIGRpcm5hbWUsIG5hbWVzKToN
Cglmb3IgZmlsZW5hbWUgaW4gbmFtZXM6DQoJCWZpbGVuYW1lID0gb3MucGF0aC5qb2luKG9zLnBh
dGgubm9ybXBhdGgoZGlybmFtZSksZmlsZW5hbWUpDQoJCWlmIChvcy5wYXRoLmlzZmlsZShmaWxl
bmFtZSkgYW5kIChmaWxlbmFtZVstMzpdID09ICcucHknKSk6DQoJCQlmaWxlbmFtZXMuYXBwZW5k
KG9zLnBhdGguYWJzcGF0aChmaWxlbmFtZSkpDQogDQpjbGFzc1JFID0gcmUuY29tcGlsZShyIlxz
K2NsYXNzXHMrKFx3KylccyooXChccyooLis/KVxzKlwpXHMqfClccyo6IixyZS5ET1RBTEwpICMg
YnJlYWtzICJjbGFzcyBmcmVkKGEsc2RmKSIgaW50byB0d28gZ3JvdXBzICJmcmVkIiBhbmQgImEs
c2RmIiB0aGUgImEsc2RmIiBoYXMgdG8gYmUgcGFyc2VkIHNlcGFyYXRlbHkNCmRlZiBnZXRDbGFz
c0luZm8oZmlsZW5hbWUpOg0KCWYgPSBvcGVuKGZpbGVuYW1lLCAncicpDQoJbGluZXMgPSBmLnJl
YWQoKQ0KCWYuY2xvc2UoKQ0KCW1hdGNoZXMgPSBjbGFzc1JFLmZpbmRhbGwobGluZXMpDQoJZm9y
IG0gaW4gbWF0Y2hlczoNCgkJbmV3Tm9kZSA9IHRyZWVOb2RlKG1bMF0sZmlsZW5hbWUpDQoJCWFs
bFRyZWVOb2Rlcy5hcHBlbmQobmV3Tm9kZSkNCgkJaWYgbVsyXTogIyBjbGFzcyBpbmhlcml0cyBm
cm9tIHNvbWV0aGluZyAiYSxzZGYiDQoJCQlwcmludCBzdHIobVsyXSkNCgkJCXByaW50IGZpbGVu
YW1lDQoJCQlmb3IgcGFyZW50IGluIHJlLnNwbGl0KHIiXHMqLFxzKiIsbVsyXSk6DQoJCQkJaWYg
cGFyZW50ICE9ICcnOg0KCQkJCQluZXdOb2RlLnBhcmVudHMuYXBwZW5kKHBhcmVudCkNCg0KZGVm
IGdldE1heERlcHRoKG5vZGUsIGRlcHRoKTogIyBzZWFyY2hlcyB1cCB0aHJvdWdoIHBhcmVudHMN
CglkZWVwZXN0ID0gZGVwdGgNCglmb3IgcGFyZW50IGluIG5vZGUucGFyZW50czoNCgkJbmV3RGVw
dGggPSBnZXRNYXhEZXB0aChwYXJlbnQsIGRlcHRoKzEpDQoJCWlmIChuZXdEZXB0aCA+IGRlZXBl
c3QpOg0KCQkJZGVlcGVzdCA9IG5ld0RlcHRoDQoJcmV0dXJuIGRlZXBlc3QNCg0KZGVmIGRvU2Nh
bihkaXJuYW1lcywgZmlsZW5hbWVzKToNCglnbG9iYWwgYWxsVHJlZU5vZGVzLCBhbGxUcmVlUm93
cw0KCWFsbFRyZWVOb2RlcyA9IFtdDQoJYWxsVHJlZVJvd3MgPSBbXQ0KDQoJZm9yIGRpcm5hbWUg
aW4gZGlybmFtZXM6DQoJCW9zLnBhdGgud2FsayhkaXJuYW1lLCBhZGRGaWxlcywgZmlsZW5hbWVz
KQ0KCWZvciBmaWxlbmFtZSBpbiBmaWxlbmFtZXM6DQoJCSNwcmludCBmaWxlbmFtZQ0KCQlnZXRD
bGFzc0luZm8oZmlsZW5hbWUpDQoJYWRkZWQgPSAxDQoJd2hpbGUgYWRkZWQ6DQoJCWFkZGVkID0g
MA0KCQlmb3Igbm9kZSBpbiBhbGxUcmVlTm9kZXM6DQoJCQlmb3IgcGFyZW50IGluIG5vZGUucGFy
ZW50czoNCgkJCQl0cnk6DQoJCQkJCWlmIGFsbFRyZWVOb2Rlcy5pbmRleChwYXJlbnQpIDwgMDoN
CgkJCQkJCXByaW50ICJzaG91bGRuJ3QgYmUgaGVyZT8iDQoJCQkJZXhjZXB0IFZhbHVlRXJyb3I6
CQ0KCQkJCQlhZGRlZCA9IDEgDQoJCQkJCSMgYWRkaW5nIGEgcGFyZW50LCBidXQgZG9uJ3Qga25v
dyB3aGF0IGZpbGUgaXRzIGZyb20sIA0KCQkJCQkjIGNhbiBwYXJzZSBkb3RzIGFuZCBmaW5kIGlu
IHN5cyBwYXRoLCBidXQgbWlnaHQgYmUgdHJpY2t5DQoJCQkJCWFsbFRyZWVOb2Rlcy5hcHBlbmQo
dHJlZU5vZGUocGFyZW50LCc/Pz8nK25vZGUuZmlsZW5hbWUpKQ0KDQoJZm9yIG5vZGUgaW4gYWxs
VHJlZU5vZGVzOiAjIG1ha2UgY2hpbGRyZW4NCgkJZm9yIHBhcmVudCBpbiBub2RlLnBhcmVudHM6
DQoJCQlhbGxUcmVlTm9kZXNbYWxsVHJlZU5vZGVzLmluZGV4KHBhcmVudCldLmNoaWxkcmVuLmFw
cGVuZChub2RlKQ0KDQoJZm9yIG5vZGUgaW4gYWxsVHJlZU5vZGVzOiAjIGZpeCBwYXJlbnRzIChp
ZS4gZ2V0IGFjdHVhbCBvYmplY3RzLCBub3QganVzdCBzdHJpbmdzKQ0KCQlmb3IgbmR4IGluIHJh
bmdlKGxlbihub2RlLnBhcmVudHMpKToNCgkJCW5vZGUucGFyZW50c1tuZHhdID0gYWxsVHJlZU5v
ZGVzW2FsbFRyZWVOb2Rlcy5pbmRleChub2RlLnBhcmVudHNbbmR4XSldDQoNCglmb3Igbm9kZSBp
biBhbGxUcmVlTm9kZXM6DQoJCW5vZGUuZGVwdGggPSBnZXRNYXhEZXB0aChub2RlLDApDQoNCglt
YXhEZXB0aCA9IDANCglmb3Igbm9kZSBpbiBhbGxUcmVlTm9kZXM6DQoJCWlmIG5vZGUuZGVwdGgg
PiBtYXhEZXB0aDogbWF4RGVwdGggPSBub2RlLmRlcHRoDQoJZm9yIGNudCBpbiByYW5nZShtYXhE
ZXB0aCsxKTogI2luaXQgYWxsVHJlZVJvd3MNCgkJYWxsVHJlZVJvd3MuYXBwZW5kKFtdKQ0KCWZv
ciBub2RlIGluIGFsbFRyZWVOb2RlczoNCgkJYWxsVHJlZVJvd3Nbbm9kZS5kZXB0aF0uYXBwZW5k
KG5vZGUpDQoJZm9yIG5keCBpbiByYW5nZShsZW4oYWxsVHJlZVJvd3MpKToNCgkJYWxsVHJlZVJv
d3NbbmR4XS5zb3J0KHJvd1NvcnRGdW5jKQ0KCQ0KCXJldHVybiBhbGxUcmVlTm9kZXMsIGFsbFRy
ZWVSb3dzDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KaWYgX19uYW1l
X18gPT0gIl9fbWFpbl9fIjoNCglpbXBvcnQgb3MNCg0KCWRpcnMgPSBbXQ0KCWZpbGVzID0gW10N
Cglmb3IgYXJnIGluIHN5cy5hcmd2WzE6XToNCgkJaWYgb3MucGF0aC5pc2RpcihhcmcpOg0KCQkJ
ZGlycy5hcHBlbmQoYXJnKQ0KCQllbGlmIG9zLnBhdGguaXNmaWxlKGFyZyk6DQoJCQlpZiBhcmdb
LTM6XSA9PSAiLnB5IjoNCgkJCQlmaWxlcy5hcHBlbmQob3MucGF0aC5hYnNwYXRoKGFyZykpDQoJ
ZG9TY2FuKGRpcnMsIGZpbGVzKQ0KDQoJIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjI0RFQlVHIFNUUlVDVFMNCglmb3Igcm93IGluIGFsbFRyZWVSb3dzOg0KCQlwcmludCBz
dHIocm93KQ0KCWZvciBub2RlIGluIGFsbFRyZWVOb2RlczoNCgkJcHJpbnQgc3RyKG5vZGUuZGVw
dGgpKycgJytzdHIobm9kZSkrc3RyKG5vZGUucGFyZW50cykrc3RyKG5vZGUuY2hpbGRyZW4pDQoJ
CQ0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBUaGlzIGNyZWF0ZXMgc29tZSBwZW5zIGFuZCBicnVzaGVz
IHRoYXQgdGhlIE9HTCBsaWJyYXJ5IHVzZXMuDQoNCnd4T0dMSW5pdGlhbGl6ZSgpDQoNCiMtLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tDQoNCmNsYXNzIERpYW1vbmRTaGFwZSh3eFBvbHlnb25TaGFwZSk6DQoJZGVmIF9f
aW5pdF9fKHNlbGYsIHc9MC4wLCBoPTAuMCk6DQoJCXd4UG9seWdvblNoYXBlLl9faW5pdF9fKHNl
bGYpDQoJCWlmIHcgPT0gMC4wOg0KCQkJdyA9IDYwLjANCgkJaWYgaCA9PSAwLjA6DQoJCQloID0g
NjAuMA0KDQoJCSMjIEVpdGhlciB3eFJlYWxQb2ludHMgb3IgMi10dXBsZXMgb2YgZmxvYXRzICB3
b3Jrcy4NCg0KCQkjcG9pbnRzID0gWyB3eFJlYWxQb2ludCgwLjAsICAgIC1oLzIuMCksDQoJCSMg
ICAgICAgICAgd3hSZWFsUG9pbnQody8yLjAsICAwLjApLA0KCQkjICAgICAgICAgIHd4UmVhbFBv
aW50KDAuMCwgICAgaC8yLjApLA0KCQkjICAgICAgICAgIHd4UmVhbFBvaW50KC13LzIuMCwgMC4w
KSwNCgkJIyAgICAgICAgICBdDQoJCXBvaW50cyA9IFsgKDAuMCwgICAgLWgvMi4wKSwNCgkJCQkg
ICAody8yLjAsICAwLjApLA0KCQkJCSAgICgwLjAsICAgIGgvMi4wKSwNCgkJCQkgICAoLXcvMi4w
LCAwLjApLA0KCQkJCSAgIF0NCg0KCQlzZWxmLkNyZWF0ZShwb2ludHMpDQoNCiMtLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tDQoNCmNsYXNzIFJvdW5kZWRSZWN0YW5nbGVTaGFwZSh3eFJlY3RhbmdsZVNoYXBlKToNCglk
ZWYgX19pbml0X18oc2VsZiwgdz0wLjAsIGg9MC4wKToNCgkJd3hSZWN0YW5nbGVTaGFwZS5fX2lu
aXRfXyhzZWxmLCB3LCBoKQ0KCQlzZWxmLlNldENvcm5lclJhZGl1cygtMC4zKQ0KDQojLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLQ0KDQpjbGFzcyBNeUV2dEhhbmRsZXIod3hTaGFwZUV2dEhhbmRsZXIpOg0KCWRlZiBf
X2luaXRfXyhzZWxmLCBmcmFtZSk6DQoJCXd4U2hhcGVFdnRIYW5kbGVyLl9faW5pdF9fKHNlbGYp
DQoJCSNzZWxmLmxvZyA9IGxvZw0KCQlzZWxmLnN0YXRiYXJGcmFtZSA9IGZyYW1lDQoNCglkZWYg
VXBkYXRlU3RhdHVzQmFyKHNlbGYsIHNoYXBlKToNCgkJbm9kZSA9IGFsbFRyZWVOb2Rlc1tzaGFw
ZS5HZXRJZCgpXQ0KCQl4LHkgPSBzaGFwZS5HZXRYKCksIHNoYXBlLkdldFkoKQ0KCQl3aWR0aCwg
aGVpZ2h0ID0gc2hhcGUuR2V0Qm91bmRpbmdCb3hNYXgoKQ0KCQlzZWxmLnN0YXRiYXJGcmFtZS5T
ZXRTdGF0dXNUZXh0KCJOYW1lOiAlcyBGaWxlOiAlcyIgJSAoc3RyKG5vZGUpLCBub2RlLmZpbGVu
YW1lKSkNCg0KCWRlZiBPbkxlZnRDbGljayhzZWxmLCB4LCB5LCBrZXlzID0gMCwgYXR0YWNobWVu
dCA9IDApOg0KCQlzaGFwZSA9IHNlbGYuR2V0U2hhcGUoKQ0KCQljYW52YXMgPSBzaGFwZS5HZXRD
YW52YXMoKQ0KCQlkYyA9IHd4Q2xpZW50REMoY2FudmFzKQ0KCQljYW52YXMuUHJlcGFyZURDKGRj
KQ0KDQoJCWlmIHNoYXBlLlNlbGVjdGVkKCk6DQoJCQlzaGFwZS5TZWxlY3QoZmFsc2UsIGRjKQ0K
CQkJY2FudmFzLlJlZHJhdyhkYykNCgkJZWxzZToNCgkJCXNoYXBlTGlzdCA9IGNhbnZhcy5HZXRE
aWFncmFtKCkuR2V0U2hhcGVMaXN0KCkNCgkJCXJlZHJhdyA9IGZhbHNlDQoJCQl0b1Vuc2VsZWN0
ID0gW10NCgkJCWZvciBzIGluIHNoYXBlTGlzdDoNCgkJCQlpZiBzLlNlbGVjdGVkKCk6DQoJCQkJ
CSMgSWYgd2UgdW5zZWxlY3QgaXQgbm93IHRoZW4gc29tZSBvZiB0aGUgb2JqZWN0cyBpbg0KCQkJ
CQkjIHNoYXBlTGlzdCB3aWxsIGJlY29tZSBpbnZhbGlkICh0aGUgY29udHJvbCBwb2ludHMgYXJl
DQoJCQkJCSMgc2hhcGVzIHRvbyEpIGFuZCBiYWQgdGhpbmdzIHdpbGwgaGFwcGVuLi4uDQoJCQkJ
CXRvVW5zZWxlY3QuYXBwZW5kKHMpDQoJCQlzaGFwZS5TZWxlY3QodHJ1ZSwgZGMpDQoJCQlpZiB0
b1Vuc2VsZWN0Og0KCQkJCWZvciBzIGluIHRvVW5zZWxlY3Q6DQoJCQkJCXMuU2VsZWN0KGZhbHNl
LCBkYykNCgkJCQljYW52YXMuUmVkcmF3KGRjKQ0KCQkJCQ0KCQlzZWxmLlVwZGF0ZVN0YXR1c0Jh
cihzaGFwZSkNCg0KCWRlZiBPbkVuZERyYWdMZWZ0KHNlbGYsIHgsIHksIGtleXMgPSAwLCBhdHRh
Y2htZW50ID0gMCk6DQoJCXNoYXBlID0gc2VsZi5HZXRTaGFwZSgpDQoJCXNlbGYuYmFzZV9PbkVu
ZERyYWdMZWZ0KHgsIHksIGtleXMsIGF0dGFjaG1lbnQpDQoJCWlmIG5vdCBzaGFwZS5TZWxlY3Rl
ZCgpOg0KCQkJc2VsZi5PbkxlZnRDbGljayh4LCB5LCBrZXlzLCBhdHRhY2htZW50KQ0KCQlzZWxm
LlVwZGF0ZVN0YXR1c0JhcihzaGFwZSkNCg0KCWRlZiBPblNpemUoc2VsZiwgeCwgeSk6DQoJCXNl
bGYuYmFzZV9PblNpemUoeCwgeSkNCgkJc2VsZi5VcGRhdGVTdGF0dXNCYXIoc2VsZi5HZXRTaGFw
ZSgpKQ0KDQojICAgIGRlZiBPbk1vdmVQb3N0KHNlbGYsIGRjLCB4LCB5LCBvbGRYLCBvbGRZLCBk
aXNwbGF5KToNCiMgICAgICAgIHNlbGYuYmFzZV9Pbk1vdmVQb3N0KGRjLCB4LCB5LCBvbGRYLCBv
bGRZLCBkaXNwbGF5KQ0KIyAgICAgICAgc2VsZi5VcGRhdGVTdGF0dXNCYXIoc2VsZi5HZXRTaGFw
ZSgpKQ0KDQojICAgIGRlZiBPblJpZ2h0Q2xpY2soc2VsZiwgKmRvbnRjYXJlKToNCiMgICAgICAg
IHNlbGYubG9nLldyaXRlVGV4dCgiJXNcbiIgJSBzZWxmLkdldFNoYXBlKCkpDQoNCiMtLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tDQoNCmNsYXNzIFNoYXBlV2luZG93KHd4U2hhcGVDYW52YXMpOg0KCWRlZiBNeUFkZFNo
YXBlKHNlbGYsIHNoYXBlLCB4LCB5LCBwZW4sIGJydXNoLCBub2RlKToNCgkJc2hhcGUuU2V0RHJh
Z2dhYmxlKHRydWUpDQoJCXNoYXBlLlNldENhbnZhcyhzZWxmKQ0KCQlzaGFwZS5TZXRYKHgpDQoJ
CXNoYXBlLlNldFkoeSkNCgkJc2hhcGUuU2V0UGVuKHBlbikNCgkJc2hhcGUuU2V0QnJ1c2goYnJ1
c2gpDQoJCXNoYXBlLkFkZFRleHQoc3RyKG5vZGUpKQ0KCQkjc2hhcGUuU2V0U2hhZG93TW9kZShT
SEFET1dfUklHSFQpDQoJCXNlbGYuZGlhZ3JhbS5BZGRTaGFwZShzaGFwZSkNCgkJc2hhcGUuU2hv
dyh0cnVlKQ0KDQoJCWV2dGhhbmRsZXIgPSBNeUV2dEhhbmRsZXIoc2VsZi5mcmFtZSkNCgkJZXZ0
aGFuZGxlci5TZXRTaGFwZShzaGFwZSkNCgkJZXZ0aGFuZGxlci5TZXRQcmV2aW91c0hhbmRsZXIo
c2hhcGUuR2V0RXZlbnRIYW5kbGVyKCkpDQoJCXNoYXBlLlNldEV2ZW50SGFuZGxlcihldnRoYW5k
bGVyKQ0KCQlzaGFwZS5TZXRJZChhbGxUcmVlTm9kZXMuaW5kZXgobm9kZSkpDQoNCgkJbm9kZS5z
aGFwZSA9IHNoYXBlDQoJCQ0KCQlzZWxmLnNoYXBlcy5hcHBlbmQobm9kZS5zaGFwZSkNCg0KCWRl
ZiBfX2luaXRfXyhzZWxmLCBwYXJlbnQsIGZyYW1lLCBpZCA9IC0xLCBzaXplID0gd3hEZWZhdWx0
U2l6ZSk6DQoJCXd4U2hhcGVDYW52YXMuX19pbml0X18oc2VsZiwgcGFyZW50LCBpZCwgd3hQb2lu
dCgwLCAwKSwgc2l6ZSwgd3hTVU5LRU5fQk9SREVSKQ0KDQoJCSNzZWxmLmxvZyA9IGxvZw0KCQlz
ZWxmLmZyYW1lID0gZnJhbWUNCgkJc2VsZi5TZXRCYWNrZ3JvdW5kQ29sb3VyKHd4V0hJVEUpDQoJ
CXNlbGYuZGlhZ3JhbSA9IHd4RGlhZ3JhbSgpDQoJCXNlbGYuU2V0RGlhZ3JhbShzZWxmLmRpYWdy
YW0pDQoJCXNlbGYuZGlhZ3JhbS5TZXRDYW52YXMoc2VsZikNCgkJc2VsZi5zaGFwZXMgPSBbXQ0K
DQoJCXJSZWN0QnJ1c2ggPSB3eEJydXNoKHd4TmFtZWRDb2xvdXIoIk1FRElVTSBUVVJRVU9JU0Ui
KSwgd3hTT0xJRCkNCg0KCQkjaW1wb3J0IHBkYjsgcGRiLnNldF90cmFjZSgpDQoJCXdpZHRoID0g
c2VsZi5mcmFtZS5HZXRTaXplKCkuR2V0V2lkdGgoKQ0KCQloZWlnaHQgPSBzZWxmLmZyYW1lLkdl
dFNpemUoKS5HZXRIZWlnaHQoKQ0KCQl4U3RhcnQgPSA1MA0KCQl5U3RhcnQgPSA1MA0KCQl4ID0g
eFN0YXJ0DQoJCXhPZnMgPSAxMDANCgkJeSA9IHlTdGFydA0KCQl5T2ZzID0gaGVpZ2h0IC8gbGVu
KGFsbFRyZWVSb3dzKQ0KCQlmb3Igcm93IGluIGFsbFRyZWVSb3dzOg0KCQkJeE9mcyA9IHdpZHRo
IC8gbGVuKHJvdykNCgkJCWZvciBub2RlIGluIHJvdzoNCgkJCQlzZWxmLk15QWRkU2hhcGUod3hS
ZWN0YW5nbGVTaGFwZSg4NSwgNTApLCB4LCB5LCB3eEJMQUNLX1BFTiwgd3hMSUdIVF9HUkVZX0JS
VVNILCBub2RlKQ0KCQkJCXggPSB4ICsgeE9mcw0KCQkJeSA9IHkgKyB5T2ZzDQoJCQl4ID0geFN0
YXJ0DQoNCgkJI3NlbGYuTXlBZGRTaGFwZSh3eENpcmNsZVNoYXBlKDgwKSwgMTAwLCAxMDAsIHd4
UGVuKHd4QkxVRSwgMyksIHd4R1JFRU5fQlJVU0gsICJDaXJjbGUiKQ0KCQkjc2VsZi5NeUFkZFNo
YXBlKHd4UmVjdGFuZ2xlU2hhcGUoODUsIDUwKSwgMzA1LCA2MCwgd3hCTEFDS19QRU4sIHd4TElH
SFRfR1JFWV9CUlVTSCwgIlJlY3RhbmdsZSIpDQoJCSNzZWxmLk15QWRkU2hhcGUoRGlhbW9uZFNo
YXBlKDkwLCA5MCksIDM0NSwgMjM1LCB3eFBlbih3eEJMVUUsIDMsIHd4RE9UKSwgd3hSRURfQlJV
U0gsICJQb2x5Z29uIikNCgkJI3NlbGYuTXlBZGRTaGFwZShSb3VuZGVkUmVjdGFuZ2xlU2hhcGUo
OTUsNzApLCAxNDAsIDI1NSwgd3hQZW4od3hSRUQsIDEpLCByUmVjdEJydXNoLCAiUm91bmRlZCBS
ZWN0IikNCg0KCQlkYyA9IHd4Q2xpZW50REMoc2VsZikNCgkJc2VsZi5QcmVwYXJlREMoZGMpDQoJ
CQ0KCQlmb3Igbm9kZSBpbiBhbGxUcmVlTm9kZXM6DQoJCQlmcm9tU2hhcGUgPSBub2RlLnNoYXBl
DQoJCQlmb3IgY2hpbGQgaW4gbm9kZS5jaGlsZHJlbjoNCgkJCQl0b1NoYXBlID0gY2hpbGQuc2hh
cGUJCQkNCgkJCQlsaW5lID0gd3hMaW5lU2hhcGUoKQ0KCQkJCWxpbmUuU2V0Q2FudmFzKHNlbGYp
DQoJCQkJbGluZS5TZXRQZW4od3hCTEFDS19QRU4pDQoJCQkJbGluZS5TZXRCcnVzaCh3eEJMQUNL
X0JSVVNIKQ0KCQkJCWxpbmUuQWRkQXJyb3coQVJST1dfQVJST1cpDQoJCQkJbGluZS5NYWtlTGlu
ZUNvbnRyb2xQb2ludHMoMikNCgkJCQlmcm9tU2hhcGUuQWRkTGluZShsaW5lLCB0b1NoYXBlKQ0K
CQkJCXNlbGYuZGlhZ3JhbS5BZGRTaGFwZShsaW5lKQ0KCQkJCWxpbmUuU2hvdyh0cnVlKQ0KCQkJ
CSMgZm9yIHNvbWUgcmVhc29uLCB0aGUgc2hhcGVzIGhhdmUgdG8gYmUgbW92ZWQgZm9yIHRoZSBs
aW5lIHRvIHNob3cgdXAuLi4NCgkJCQlmcm9tU2hhcGUuTW92ZShkYywgZnJvbVNoYXBlLkdldFgo
KSwgZnJvbVNoYXBlLkdldFkoKSkNCg0KCWRlZiBfX2RlbF9fKHNlbGYpOg0KCQlmb3Igc2hhcGUg
aW4gc2VsZi5kaWFncmFtLkdldFNoYXBlTGlzdCgpOg0KCQkJaWYgc2hhcGUuR2V0UGFyZW50KCkg
PT0gTm9uZToNCgkJCQlzaGFwZS5TZXRDYW52YXMoTm9uZSkNCgkJCQlzaGFwZS5EZXN0cm95KCkN
CgkJCQkNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCmNsYXNzIE15RnJhbWUod3hGcmFtZSk6DQoJZGVmIF9f
aW5pdF9fKHNlbGYsIHBhcmVudCwgSUQsIHRpdGxlLCBzaXplID0gd3hEZWZhdWx0U2l6ZSk6DQoJ
CXd4RnJhbWUuX19pbml0X18oc2VsZiwgcGFyZW50LCBJRCwgdGl0bGUsIHd4RGVmYXVsdFBvc2l0
aW9uLCBzaXplKQ0KCQkJCQkJIA0KCQlzZWxmLkNyZWF0ZVN0YXR1c0JhcigpDQoJCXNlbGYuU2V0
U3RhdHVzVGV4dCgiIikNCg0KCQlzZWxmLnNoYXBld2luID0gU2hhcGVXaW5kb3coc2VsZixzZWxm
KQ0KDQpjbGFzcyBNeUFwcCh3eEFwcCk6DQoJZGVmIE9uSW5pdChzZWxmKToNCgkJZnJhbWUgPSBN
eUZyYW1lKE5VTEwsIC0xLCAiUHl0aG9uIENsYXNzIFRyZWUiKQ0KCQlmcmFtZS5TaG93KHRydWUp
DQoJCXNlbGYuU2V0VG9wV2luZG93KGZyYW1lKQ0KCQkNCgkJcmV0dXJuIHRydWUNCg0KYXBwID0g
TXlBcHAoMCkNCmFwcC5NYWluTG9vcCgpDQoNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCmNsYXNzIF9fQ2xl
YW51cDoNCgljbGVhbnVwID0gd3hPR0xDbGVhblVwDQoJZGVmIF9fZGVsX18oc2VsZik6DQoJCXNl
bGYuY2xlYW51cCgpDQoNCiMgd2hlbiB0aGlzIG1vZHVsZSBnZXRzIGNsZWFuZWQgdXAgdGhlbiB3
eE9HTENsZWFuVXAoKSB3aWxsIGdldCBjYWxsZWQNCl9fY3UgPSBfX0NsZWFudXAoKQ0K

--VGh1LCAxNSBKdW4gMjAwMCAxNzozNTo0OSArMDkwMA==--