-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrapping_array_pcell.lym
More file actions
67 lines (60 loc) · 52.6 KB
/
trapping_array_pcell.lym
File metadata and controls
67 lines (60 loc) · 52.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?xml version="1.0" encoding="utf-8"?>
<!--
Trapping Array PCell Library v1.0.0
Install : Macro > Import... or copy to ~/.klayout/pymacros/
Usage : Libraries panel > "Trapping Array" > drag TrapArray_A or TrapArray_B
Ref : Ruyssen et al., Computers and Fluids 297 (2025) 106643
-->
<klayout-macro>
<description>Trapping Array PCell Library v1.0.0</description>
<version>1.0.0</version>
<category>pymacros</category>
<prolog/>
<epilog/>
<doc/>
<autorun>true</autorun>
<autorun-early>false</autorun-early>
<shortcut/>
<show-in-menu>false</show-in-menu>
<group-name/>
<menu-path/>
<interpreter>python</interpreter>
<dsl-interpreter-name/>
<text>"""
Trapping Array PCell Library v1.0.0
Ref: Ruyssen et al., Computers and Fluids 297 (2025) 106643
Registers "Trapping Array" in the Libraries panel with two PCells:
TrapArray_A - Fixed grid (fixed N_l x N_c)
TrapArray_B - Max traps (maximise count given pitch)
"""
import os, sys, importlib
_pkg = os.path.join(os.path.expanduser("~"), ".klayout",
"pymacros", "trapping_array")
_core = os.path.join(_pkg, "core")
for _d in (_core,):
os.makedirs(_d, exist_ok=True)
_M = {
'core/__init__.py': __import__("base64").b64decode('IiIiCnRyYXBwaW5nX2FycmF5LmNvcmUKPT09PT09PT09PT09PT09PT09PQpQdWJsaWMgQVBJIGZvciB0aGUgVHJhcHBpbmcgQXJyYXkgS0xheW91dCBsaWJyYXJ5LgoKUXVpY2sgc3RhcnQKLS0tLS0tLS0tLS0KICAgIGZyb20gdHJhcHBpbmdfYXJyYXkuY29yZSBpbXBvcnQgbWFrZV9maXhlZF9ncmlkLCBtYWtlX21heF90cmFwcywgZ2VuZXJhdGVfZ2RzCgogICAgIyBNb2RlIEEg4oCTIGZpeGVkIDfDlzE0IGdyaWQsIGRpcmVjdCBJTwogICAgZ3JpZCwgYnVpbGRlciA9IG1ha2VfZml4ZWRfZ3JpZCgKICAgICAgICBMPTE1MDAsIFc9MTIwMCwKICAgICAgICBOX2w9NywgTl9jPTE0LCBnYXBfeD0xMCwgZ2FwX3k9MTAsCiAgICAgICAgbF90cmFwPTMwLCB3X3RyYXA9MjUsIHdhbGxfdD0zLCBiYXNlX3Q9NCwgd19vX2Rvd249OCwKICAgICAgICBpb19tb2RlPSdkaXJlY3QnLCBDPTAuNDQsIHdfaW89MTUwLCBjaGFubmVsX2xlbj0xMDAsCiAgICApCiAgICBwcmludChidWlsZGVyLnN1bW1hcnkoKSkKICAgIGdlbmVyYXRlX2dkcyhncmlkLCBidWlsZGVyLCAiY2hpcF9BLmdkcyIpCgogICAgIyBNb2RlIEIg4oCTIG1heGltaXNlIHRyYXBzLCBkaXZlcmdpbmcgSU8KICAgIGdyaWQsIGJ1aWxkZXIgPSBtYWtlX21heF90cmFwcygKICAgICAgICBMPTE1MDAsIFc9MTIwMCwKICAgICAgICBEZWx0YV94PTQwLCBEZWx0YV95PTM1LAogICAgICAgIGxfdHJhcD0zMCwgd190cmFwPTI1LCB3YWxsX3Q9MywgYmFzZV90PTQsIHdfb19kb3duPTgsCiAgICAgICAgaW9fbW9kZT0nZGl2ZXJnaW5nJywgd19pbz0xNTAsIGxfZGl2PTMwMCwgY2hhbm5lbF9sZW49MTAwLAogICAgKQogICAgZ2VuZXJhdGVfZ2RzKGdyaWQsIGJ1aWxkZXIsICJjaGlwX0IuZ2RzIikKIiIiCgpmcm9tIC5ncmlkICAgIGltcG9ydCBBcnJheUdyaWQKZnJvbSAuYnVpbGRlciBpbXBvcnQgVHJhcHBpbmdBcnJheUJ1aWxkZXIKCmltcG9ydCBweWEKCl9fYWxsX18gPSBbCiAgICAiQXJyYXlHcmlkIiwKICAgICJUcmFwcGluZ0FycmF5QnVpbGRlciIsCiAgICAibWFrZV9maXhlZF9ncmlkIiwKICAgICJtYWtlX21heF90cmFwcyIsCiAgICAiZ2VuZXJhdGVfZ2RzIiwKXQoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ29udmVuaWVuY2UgZmFjdG9yeSBmdW5jdGlvbnMKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmRlZiBtYWtlX2ZpeGVkX2dyaWQoCiAgICAjIENhdml0eQogICAgTCwgVywKICAgICMgR3JpZAogICAgTl9sLCBOX2MsIGdhcF94LCBnYXBfeSwKICAgIGdhcF94X21hcmdpbj1Ob25lLCBnYXBfeV9tYXJnaW49Tm9uZSwKICAgICMgVHJhcCBzaGFwZQogICAgbF90cmFwPTMwLjAsIHdfdHJhcD0yNS4wLCB3YWxsX3Q9My4wLCBiYXNlX3Q9NC4wLCB3X29fZG93bj04LjAsCiAgICAjIElPCiAgICBpb19tb2RlPSdkaXJlY3QnLCBDPTEuMCwgd19pbz0xMDAuMCwgY2hhbm5lbF9sZW49MTAwLjAsIGxfZGl2PTIwMC4wLAogICAgIyBEaXNvcmRlcgogICAgRF9mPTAuMCwgZGlzb3JkZXJfdHlwZT0ndW5pZm9ybScsIHNlZWQ9Tm9uZSwKKToKICAgICIiIgogICAgTW9kZSBBOiBmaXhlZCBOX2wgw5cgTl9jIHRyYXAgZ3JpZC4KCiAgICBSZXR1cm5zCiAgICAtLS0tLS0tCiAgICAoQXJyYXlHcmlkLCBUcmFwcGluZ0FycmF5QnVpbGRlcikKICAgICIiIgogICAgZ3JpZCA9IEFycmF5R3JpZCgKICAgICAgICAnZml4ZWRfZ3JpZCcsIEwsIFcsIGxfdHJhcCwgd190cmFwLAogICAgICAgIE5fbD1OX2wsIE5fYz1OX2MsIGdhcF94PWdhcF94LCBnYXBfeT1nYXBfeSwKICAgICAgICBnYXBfeF9tYXJnaW49Z2FwX3hfbWFyZ2luLCBnYXBfeV9tYXJnaW49Z2FwX3lfbWFyZ2luLAogICAgKQogICAgYnVpbGRlciA9IFRyYXBwaW5nQXJyYXlCdWlsZGVyKAogICAgICAgIGdyaWQsIGxfdHJhcCwgd190cmFwLCB3YWxsX3QsIGJhc2VfdCwgd19vX2Rvd24sCiAgICAgICAgaW9fbW9kZT1pb19tb2RlLCBDPUMsIHdfaW89d19pbywKICAgICAgICBjaGFubmVsX2xlbj1jaGFubmVsX2xlbiwgbF9kaXY9bF9kaXYsCiAgICAgICAgRF9mPURfZiwgZGlzb3JkZXJfdHlwZT1kaXNvcmRlcl90eXBlLCBzZWVkPXNlZWQsCiAgICApCiAgICByZXR1cm4gZ3JpZCwgYnVpbGRlcgoKCmRlZiBtYWtlX21heF90cmFwcygKICAgICMgQ2F2aXR5CiAgICBMLCBXLAogICAgIyBQaXRjaAogICAgRGVsdGFfeCwgRGVsdGFfeSwKICAgIG1hcmdpbl94PU5vbmUsIG1hcmdpbl95PU5vbmUsCiAgICAjIFRyYXAgc2hhcGUKICAgIGxfdHJhcD0zMC4wLCB3X3RyYXA9MjUuMCwgd2FsbF90PTMuMCwgYmFzZV90PTQuMCwgd19vX2Rvd249OC4wLAogICAgIyBJTwogICAgaW9fbW9kZT0nZGlyZWN0JywgQz0xLjAsIHdfaW89MTAwLjAsIGNoYW5uZWxfbGVuPTEwMC4wLCBsX2Rpdj0yMDAuMCwKICAgICMgRGlzb3JkZXIKICAgIERfZj0wLjAsIGRpc29yZGVyX3R5cGU9J3VuaWZvcm0nLCBzZWVkPU5vbmUsCik6CiAgICAiIiIKICAgIE1vZGUgQjogbWF4aW1pc2UgdHJhcCBjb3VudCBnaXZlbiBjYXZpdHkgYW5kIHBpdGNoLgoKICAgIFJldHVybnMKICAgIC0tLS0tLS0KICAgIChBcnJheUdyaWQsIFRyYXBwaW5nQXJyYXlCdWlsZGVyKQogICAgIiIiCiAgICBncmlkID0gQXJyYXlHcmlkKAogICAgICAgICdtYXhfdHJhcHMnLCBMLCBXLCBsX3RyYXAsIHdfdHJhcCwKICAgICAgICBEZWx0YV94PURlbHRhX3gsIERlbHRhX3k9RGVsdGFfeSwKICAgICAgICBtYXJnaW5feD1tYXJnaW5feCwgbWFyZ2luX3k9bWFyZ2luX3ksCiAgICApCiAgICBidWlsZGVyID0gVHJhcHBpbmdBcnJheUJ1aWxkZXIoCiAgICAgICAgZ3JpZCwgbF90cmFwLCB3X3RyYXAsIHdhbGxfdCwgYmFzZV90LCB3X29fZG93biwKICAgICAgICBpb19tb2RlPWlvX21vZGUsIEM9Qywgd19pbz13X2lvLAogICAgICAgIGNoYW5uZWxfbGVuPWNoYW5uZWxfbGVuLCBsX2Rpdj1sX2RpdiwKICAgICAgICBEX2Y9RF9mLCBkaXNvcmRlcl90eXBlPWRpc29yZGVyX3R5cGUsIHNlZWQ9c2VlZCwKICAgICkKICAgIHJldHVybiBncmlkLCBidWlsZGVyCgoKZGVmIGdlbmVyYXRlX2dkcyhncmlkLCBidWlsZGVyLCBmaWxlbmFtZT0idHJhcHBpbmdfYXJyYXkuZ2RzIiwKICAgICAgICAgICAgICAgICBkYnU9MC4wMDEsIGxheWVyX251bWJlcj0xLCBsYXllcl9kYXRhdHlwZT0wKToKICAgICIiIgogICAgQnVpbGQgdGhlIGZ1bGwgY2hpcCBsYXlvdXQgYW5kIHdyaXRlIGEgR0RTIGZpbGUuCgogICAgUGFyYW1ldGVycwogICAgLS0tLS0tLS0tLQogICAgZ3JpZCwgYnVpbGRlciA6IGZyb20gbWFrZV9maXhlZF9ncmlkIC8gbWFrZV9tYXhfdHJhcHMKICAgIGZpbGVuYW1lICAgICAgOiBvdXRwdXQgcGF0aCAoc3RyKQogICAgZGJ1ICAgICAgICAgICA6IGRhdGFiYXNlIHVuaXQgaW4gwrVtIChkZWZhdWx0IDAuMDAxID0gMSBubSkKICAgIGxheWVyX251bWJlciAgOiBHRFMgbGF5ZXIgbnVtYmVyIChkZWZhdWx0IDEpCiAgICBsYXllcl9kYXRhdHlwZTogR0RTIGRhdGF0eXBlIChkZWZhdWx0IDApCgogICAgUmV0dXJucwogICAgLS0tLS0tLQogICAgcHlhLkxheW91dAogICAgIiIiCiAgICBsYXlvdXQgICAgPSBweWEuTGF5b3V0KCkKICAgIGxheW91dC5kYnUgPSBkYnUKICAgIGxheWVyX2lkeCAgPSBsYXlvdXQubGF5ZXIobGF5ZXJfbnVtYmVyLCBsYXllcl9kYXRhdHlwZSkKICAgIGJ1aWxkZXIuYnVpbGQobGF5b3V0LCBsYXllcl9pZHgpCiAgICBsYXlvdXQud3JpdGUoZmlsZW5hbWUpCiAgICBwcmludChmIltUcmFwQXJyYXldIFdyaXR0ZW46IHtmaWxlbmFtZX0iKQogICAgcHJpbnQoYnVpbGRlci5zdW1tYXJ5KCkpCiAgICByZXR1cm4gbGF5b3V0Cg==').decode(),
'core/grid.py': __import__("base64").b64decode('IiIiCmNvcmUvZ3JpZC5weQotLS0tLS0tLS0tLS0KQXJyYXlHcmlkOiByZXNvbHZlcyB0aGUgdHJhcCBhcnJheSBnZW9tZXRyeSBmb3IgYm90aCBvcGVyYXRpbmcgbW9kZXMuClB1cmUgUHl0aG9uIOKAlCBubyBweWEgZGVwZW5kZW5jeSwgZnVsbHkgdGVzdGFibGUgd2l0aG91dCBLTGF5b3V0LgoKTW9kZSBBICBmaXhlZF9ncmlkCiAgICBJbnB1dHMgOiBjYXZpdHkgKEwsIFcpLCBncmlkIChOX2wgw5cgTl9jKSwgZ2FwcyAoZ2FwX3gsIGdhcF95KS4KICAgIERlcml2ZWQ6IM6UeCA9IGxfdHJhcCArIGdhcF94LCAgzpR5ID0gd190cmFwICsgZ2FwX3kuCiAgICBNYXJnaW4gOiBsYXRlcmFsICBtYXJnaW5feSA9IM6UeS8yICAob3ZlcnJpZGFibGUpLgogICAgICAgICAgICAgc3RyZWFtd2lzZSBtYXJnaW5feCA9IGdhcF94IChvdmVycmlkYWJsZSkuCiAgICBBcnJheSBjZW50cmVkIGluIGNhdml0eTsgc3RhZ2dlcmVkIChvZGQgY29sdW1ucyBzaGlmdGVkICvOlHgvMiBpbiB4KS4KCk1vZGUgQiAgbWF4X3RyYXBzCiAgICBJbnB1dHMgOiBjYXZpdHkgKEwsIFcpLCBwaXRjaCAozpR4LCDOlHkpLCBvcHRpb25hbCBtYXJnaW4gb3ZlcnJpZGVzLgogICAgRGVyaXZlZDogTl9jID0gZmxvb3IoKFcgLSAyKm1hcmdpbl95IC0gd190cmFwKSAvIM6UeSkgKyAxCiAgICAgICAgICAgICBOX2wgPSBmbG9vcigoTCAtIDIqbWFyZ2luX3ggLSBsX3RyYXApIC8gzpR4KSArIDEKIiIiCgppbXBvcnQgbWF0aAppbXBvcnQgcmFuZG9tCgoKY2xhc3MgQXJyYXlHcmlkOgogICAgIiIiCiAgICBSZXNvbHZlZCB0cmFwIGFycmF5IGdlb21ldHJ5LgoKICAgIEF0dHJpYnV0ZXMgKGFsbCDCtW0gdW5sZXNzIHN0YXRlZCkKICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIG1vZGUgICAgICAgOiBzdHIgICDigJMgJ2ZpeGVkX2dyaWQnIG9yICdtYXhfdHJhcHMnCiAgICBMLCBXICAgICAgIDogZmxvYXQg4oCTIGNhdml0eSBkaW1lbnNpb25zCiAgICBOX2wsIE5fYyAgIDogaW50ICAg4oCTIGxpbmVzIChzdHJlYW13aXNlKSBhbmQgY29sdW1ucyAobGF0ZXJhbCkKICAgIE5fdHJhcHMgICAgOiBpbnQgICDigJMgTl9sICogTl9jCiAgICBEZWx0YV94ICAgIDogZmxvYXQg4oCTIHN0cmVhbXdpc2UgcGl0Y2gKICAgIERlbHRhX3kgICAgOiBmbG9hdCDigJMgbGF0ZXJhbCBwaXRjaAogICAgbCwgdyAgICAgICA6IGZsb2F0IOKAkyBhcnJheSBib3VuZGluZy1ib3ggc3BhbiAobWFyZ2lucyBpbmNsdWRlZCkKICAgIHgwX2FycmF5ICAgOiBmbG9hdCDigJMgeCBvZiBhcnJheSBCTCBjb3JuZXIgKGNlbnRyZWQgaW4gY2F2aXR5KQogICAgeTBfYXJyYXkgICA6IGZsb2F0IOKAkyB5IG9mIGFycmF5IEJMIGNvcm5lcgogICAgbWFyZ2luX3ggICA6IGZsb2F0IOKAkyBzdHJlYW13aXNlIGNhdml0eS13YWxsIOKGkiBuZWFyZXN0IHRyYXAgZWRnZQogICAgbWFyZ2luX3kgICA6IGZsb2F0IOKAkyBsYXRlcmFsICAgY2F2aXR5LXdhbGwg4oaSIG5lYXJlc3QgdHJhcCBlZGdlICg9IM6UeS8yKQogICAgZmVhc2libGUgICA6IGJvb2wKICAgIHdhcm5pbmdzICAgOiBsaXN0W3N0cl0KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBtb2RlLCBMLCBXLCBsX3RyYXAsIHdfdHJhcCwgKiprdyk6CiAgICAgICAgc2VsZi5tb2RlICAgID0gbW9kZQogICAgICAgIHNlbGYuTCAgICAgICA9IEwKICAgICAgICBzZWxmLlcgICAgICAgPSBXCiAgICAgICAgc2VsZi5sX3RyYXAgID0gbF90cmFwCiAgICAgICAgc2VsZi53X3RyYXAgID0gd190cmFwCiAgICAgICAgc2VsZi53YXJuaW5ncyA9IFtdCiAgICAgICAgc2VsZi5mZWFzaWJsZSA9IFRydWUKCiAgICAgICAgaWYgbW9kZSA9PSAnZml4ZWRfZ3JpZCc6CiAgICAgICAgICAgIHNlbGYuX3NvbHZlX2ZpeGVkKCoqa3cpCiAgICAgICAgZWxpZiBtb2RlID09ICdtYXhfdHJhcHMnOgogICAgICAgICAgICBzZWxmLl9zb2x2ZV9tYXgoKiprdykKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKAogICAgICAgICAgICAgICAgZiJVbmtub3duIG1vZGUgJ3ttb2RlfScuIFVzZSAnZml4ZWRfZ3JpZCcgb3IgJ21heF90cmFwcycuIikKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZGVmIF9zb2x2ZV9maXhlZChzZWxmLCBOX2wsIE5fYywgZ2FwX3gsIGdhcF95LAogICAgICAgICAgICAgICAgICAgICBnYXBfeF9tYXJnaW49Tm9uZSwgZ2FwX3lfbWFyZ2luPU5vbmUpOgogICAgICAgIERlbHRhX3ggID0gc2VsZi5sX3RyYXAgKyBnYXBfeAogICAgICAgIERlbHRhX3kgID0gc2VsZi53X3RyYXAgKyBnYXBfeQogICAgICAgIG1hcmdpbl95ID0gRGVsdGFfeSAvIDIuMCBpZiBnYXBfeV9tYXJnaW4gaXMgTm9uZSBlbHNlIGZsb2F0KGdhcF95X21hcmdpbikKICAgICAgICBtYXJnaW5feCA9IGZsb2F0KGdhcF94KSAgaWYgZ2FwX3hfbWFyZ2luIGlzIE5vbmUgZWxzZSBmbG9hdChnYXBfeF9tYXJnaW4pCgogICAgICAgIHdfbmVlZGVkID0gMiAqIG1hcmdpbl95ICsgKE5fYyAtIDEpICogRGVsdGFfeSArIHNlbGYud190cmFwCiAgICAgICAgbF9uZWVkZWQgPSAyICogbWFyZ2luX3ggKyAoTl9sIC0gMSkgKiBEZWx0YV94ICsgc2VsZi5sX3RyYXAKCiAgICAgICAgaWYgd19uZWVkZWQgPiBzZWxmLlc6CiAgICAgICAgICAgIHNlbGYud2FybmluZ3MuYXBwZW5kKAogICAgICAgICAgICAgICAgZiJBcnJheSB3aWR0aCB7d19uZWVkZWQ6LjFmfSDCtW0gPiBjYXZpdHkgVyA9IHtzZWxmLlc6LjFmfSDCtW0uICIKICAgICAgICAgICAgICAgIGYiUmVkdWNlIE5fYyBvciBnYXBfeS4iKQogICAgICAgICAgICBzZWxmLmZlYXNpYmxlID0gRmFsc2UKICAgICAgICBpZiBsX25lZWRlZCA+IHNlbGYuTDoKICAgICAgICAgICAgc2VsZi53YXJuaW5ncy5hcHBlbmQoCiAgICAgICAgICAgICAgICBmIkFycmF5IGxlbmd0aCB7bF9uZWVkZWQ6LjFmfSDCtW0gPiBjYXZpdHkgTCA9IHtzZWxmLkw6LjFmfSDCtW0uICIKICAgICAgICAgICAgICAgIGYiUmVkdWNlIE5fbCBvciBnYXBfeC4iKQogICAgICAgICAgICBzZWxmLmZlYXNpYmxlID0gRmFsc2UKCiAgICAgICAgc2VsZi5OX2wgICAgICA9IGludChOX2wpCiAgICAgICAgc2VsZi5OX2MgICAgICA9IGludChOX2MpCiAgICAgICAgc2VsZi5OX3RyYXBzICA9IHNlbGYuTl9sICogc2VsZi5OX2MKICAgICAgICBzZWxmLkRlbHRhX3ggID0gRGVsdGFfeAogICAgICAgIHNlbGYuRGVsdGFfeSAgPSBEZWx0YV95CiAgICAgICAgc2VsZi5tYXJnaW5feCA9IG1hcmdpbl94CiAgICAgICAgc2VsZi5tYXJnaW5feSA9IG1hcmdpbl95CiAgICAgICAgc2VsZi5sICAgICAgICA9IGxfbmVlZGVkCiAgICAgICAgc2VsZi53ICAgICAgICA9IHdfbmVlZGVkCiAgICAgICAgc2VsZi54MF9hcnJheSA9IChzZWxmLkwgLSBzZWxmLmwpIC8gMi4wCiAgICAgICAgc2VsZi55MF9hcnJheSA9IChzZWxmLlcgLSBzZWxmLncpIC8gMi4wCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGRlZiBfc29sdmVfbWF4KHNlbGYsIERlbHRhX3gsIERlbHRhX3ksIG1hcmdpbl94PU5vbmUsIG1hcmdpbl95PU5vbmUpOgogICAgICAgIG1hcmdpbl95ID0gRGVsdGFfeSAvIDIuMCBpZiBtYXJnaW5feSBpcyBOb25lIGVsc2UgZmxvYXQobWFyZ2luX3kpCiAgICAgICAgbWFyZ2luX3ggPSBtYXJnaW5feSAgICAgICBpZiBtYXJnaW5feCBpcyBOb25lIGVsc2UgZmxvYXQobWFyZ2luX3gpCgogICAgICAgIE5fYyA9IG1heCgwLCBtYXRoLmZsb29yKAogICAgICAgICAgICAoc2VsZi5XIC0gMiAqIG1hcmdpbl95IC0gc2VsZi53X3RyYXApIC8gRGVsdGFfeSkgKyAxKQogICAgICAgIE5fbCA9IG1heCgwLCBtYXRoLmZsb29yKAogICAgICAgICAgICAoc2VsZi5MIC0gMiAqIG1hcmdpbl94IC0gc2VsZi5sX3RyYXApIC8gRGVsdGFfeCkgKyAxKQoKICAgICAgICBpZiBOX2MgPCAxIG9yIE5fbCA8IDE6CiAgICAgICAgICAgIHNlbGYud2FybmluZ3MuYXBwZW5kKAogICAgICAgICAgICAgICAgZiJObyB0cmFwcyBmaXQgaW4gY2F2aXR5IHtzZWxmLkx9IMOXIHtzZWxmLld9IMK1bSAiCiAgICAgICAgICAgICAgICBmIndpdGggzpR4PXtEZWx0YV94fSwgzpR5PXtEZWx0YV95fSwgIgogICAgICAgICAgICAgICAgZiJtYXJnaW5feD17bWFyZ2luX3g6LjFmfSwgbWFyZ2luX3k9e21hcmdpbl95Oi4xZn0gwrVtLiIpCiAgICAgICAgICAgIHNlbGYuZmVhc2libGUgPSBGYWxzZQogICAgICAgICAgICBOX2MgPSBtYXgoMSwgTl9jKQogICAgICAgICAgICBOX2wgPSBtYXgoMSwgTl9sKQoKICAgICAgICBzZWxmLk5fbCAgICAgID0gaW50KE5fbCkKICAgICAgICBzZWxmLk5fYyAgICAgID0gaW50KE5fYykKICAgICAgICBzZWxmLk5fdHJhcHMgID0gc2VsZi5OX2wgKiBzZWxmLk5fYwogICAgICAgIHNlbGYuRGVsdGFfeCAgPSBmbG9hdChEZWx0YV94KQogICAgICAgIHNlbGYuRGVsdGFfeSAgPSBmbG9hdChEZWx0YV95KQogICAgICAgIHNlbGYubWFyZ2luX3ggPSBtYXJnaW5feAogICAgICAgIHNlbGYubWFyZ2luX3kgPSBtYXJnaW5feQogICAgICAgIHNlbGYubCAgICAgICAgPSAyICogbWFyZ2luX3ggKyAoTl9sIC0gMSkgKiBEZWx0YV94ICsgc2VsZi5sX3RyYXAKICAgICAgICBzZWxmLncgICAgICAgID0gMiAqIG1hcmdpbl95ICsgKE5fYyAtIDEpICogRGVsdGFfeSArIHNlbGYud190cmFwCiAgICAgICAgc2VsZi54MF9hcnJheSA9IChzZWxmLkwgLSBzZWxmLmwpIC8gMi4wCiAgICAgICAgc2VsZi55MF9hcnJheSA9IChzZWxmLlcgLSBzZWxmLncpIC8gMi4wCgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGRlZiB0cmFwX3Bvc2l0aW9ucyhzZWxmLCBEX2Y9MC4wLCBkaXNvcmRlcl90eXBlPSd1bmlmb3JtJywgc2VlZD1Ob25lKToKICAgICAgICAiIiIKICAgICAgICBSZXR1cm4gbGlzdCBvZiAoeDAsIHkwKSBib3R0b20tbGVmdCBjb3JuZXJzIGZvciBhbGwgdHJhcHMuCgogICAgICAgIEl0ZXJhdGlvbiBvcmRlcjogY29sdW1uLW1ham9yIChpYyBvdXRlciwgaWwgaW5uZXIpLCBtYXRjaGluZyB0aGUKICAgICAgICBzdGFnZ2VyIGNvbnZlbnRpb246IGNvbHVtbiBpYyAoMC1pbmRleGVkKSBpcyBzaGlmdGVkIGJ5ICvOlHgvMiBpbiB4CiAgICAgICAgd2hlbiBpYyBpcyBvZGQuCgogICAgICAgIERpc29yZGVyIChEX2YgPiAwKTogZWFjaCBwb3NpdGlvbiBwZXJ0dXJiZWQgYnkKICAgICAgICAgICAgKM+IX3ggwrcgRF9mIMK3IM6UeCwgIM+IX3kgwrcgRF9mIMK3IM6UeSkKICAgICAgICB3aGVyZSDPiCBpcyBzYW1wbGVkIGZyb20gdW5pZm9ybVviiJIxLCAxXSBvciBjbGlwcGVkIEdhdXNzaWFuKDAsIDAuMykuCgogICAgICAgIFBhcmFtZXRlcnMKICAgICAgICAtLS0tLS0tLS0tCiAgICAgICAgRF9mICAgICAgICAgIDogZmxvYXQgIFsw4oCTMV0KICAgICAgICBkaXNvcmRlcl90eXBlOiAndW5pZm9ybScgb3IgJ2dhdXNzaWFuJwogICAgICAgIHNlZWQgICAgICAgICA6IGludCB8IE5vbmUgIChmb3IgcmVwcm9kdWNpYmlsaXR5KQogICAgICAgICIiIgogICAgICAgIHJuZyA9IHJhbmRvbS5SYW5kb20oc2VlZCkKICAgICAgICBwb3NpdGlvbnMgPSBbXQogICAgICAgIGZvciBpYyBpbiByYW5nZShzZWxmLk5fYyk6CiAgICAgICAgICAgIHN0YWdnZXIgPSAoc2VsZi5EZWx0YV94IC8gMi4wKSBpZiAoaWMgJSAyID09IDEpIGVsc2UgMC4wCiAgICAgICAgICAgIGZvciBpbCBpbiByYW5nZShzZWxmLk5fbCk6CiAgICAgICAgICAgICAgICB4MCA9IChzZWxmLngwX2FycmF5ICsgc2VsZi5tYXJnaW5feAogICAgICAgICAgICAgICAgICAgICAgICsgaWwgKiBzZWxmLkRlbHRhX3ggKyBzdGFnZ2VyKQogICAgICAgICAgICAgICAgeTAgPSBzZWxmLnkwX2FycmF5ICsgc2VsZi5tYXJnaW5feSArIGljICogc2VsZi5EZWx0YV95CiAgICAgICAgICAgICAgICBpZiBEX2YgPiAwLjA6CiAgICAgICAgICAgICAgICAgICAgeDAgKz0gX3NhbXBsZV9wc2kocm5nLCBkaXNvcmRlcl90eXBlKSAqIERfZiAqIHNlbGYuRGVsdGFfeAogICAgICAgICAgICAgICAgICAgIHkwICs9IF9zYW1wbGVfcHNpKHJuZywgZGlzb3JkZXJfdHlwZSkgKiBEX2YgKiBzZWxmLkRlbHRhX3kKICAgICAgICAgICAgICAgIHBvc2l0aW9ucy5hcHBlbmQoKHgwLCB5MCkpCiAgICAgICAgcmV0dXJuIHBvc2l0aW9ucwoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgc3VtbWFyeShzZWxmKToKICAgICAgICAiIiJSZXR1cm4gYSBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUgcmVzb2x2ZWQgZ2VvbWV0cnkuIiIiCiAgICAgICAgbGluZXMgPSBbCiAgICAgICAgICAgIGYiTW9kZSAgICAgICAgOiB7c2VsZi5tb2RlfSIsCiAgICAgICAgICAgIGYiQ2F2aXR5ICAgICAgOiBMID0ge3NlbGYuTH0gwrVtLCAgVyA9IHtzZWxmLld9IMK1bSIsCiAgICAgICAgICAgIGYiR3JpZCAgICAgICAgOiB7c2VsZi5OX2x9IGxpbmVzIMOXIHtzZWxmLk5fY30gY29sdW1ucyIKICAgICAgICAgICAgZiIgID0gIHtzZWxmLk5fdHJhcHN9IHRyYXBzIiwKICAgICAgICAgICAgZiJQaXRjaCAgICAgICA6IM6UeCA9IHtzZWxmLkRlbHRhX3g6LjNmfSDCtW0sIgogICAgICAgICAgICBmIiAgzpR5ID0ge3NlbGYuRGVsdGFfeTouM2Z9IMK1bSIsCiAgICAgICAgICAgIGYiQXJyYXkgc3BhbiAgOiB7c2VsZi5sOi4zZn0gKHgpIMOXIHtzZWxmLnc6LjNmfSAoeSkgwrVtIiwKICAgICAgICAgICAgZiJNYXJnaW5zICAgICA6IHggwrEge3NlbGYubWFyZ2luX3g6LjNmfSDCtW0sIgogICAgICAgICAgICBmIiAgeSDCsSB7c2VsZi5tYXJnaW5feTouM2Z9IMK1bSIsCiAgICAgICAgICAgIGYiQXJyYXkgb3JpZ2luOiAoe3NlbGYueDBfYXJyYXk6LjNmfSwge3NlbGYueTBfYXJyYXk6LjNmfSkgwrVtIiwKICAgICAgICAgICAgZiJGZWFzaWJsZSAgICA6IHtzZWxmLmZlYXNpYmxlfSIsCiAgICAgICAgXQogICAgICAgIGZvciB3IGluIHNlbGYud2FybmluZ3M6CiAgICAgICAgICAgIGxpbmVzLmFwcGVuZChmIiAg4pqgICB7d30iKQogICAgICAgIHJldHVybiAiXG4iLmpvaW4obGluZXMpCgogICAgZGVmIF9fcmVwcl9fKHNlbGYpOgogICAgICAgIHJldHVybiAoZiJBcnJheUdyaWQoe3NlbGYubW9kZX0sICIKICAgICAgICAgICAgICAgIGYiTj17c2VsZi5OX2x9w5d7c2VsZi5OX2N9LCAiCiAgICAgICAgICAgICAgICBmIs6UeD17c2VsZi5EZWx0YV94Oi4yZn0sIM6UeT17c2VsZi5EZWx0YV95Oi4yZn0pIikKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEhlbHBlcnMKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmRlZiBfc2FtcGxlX3BzaShybmcsIGRpc29yZGVyX3R5cGUpOgogICAgIiIiU2FtcGxlIM+IIOKIiCBb4oiSMSwgMV0gZnJvbSB0aGUgY2hvc2VuIGRpc3RyaWJ1dGlvbi4iIiIKICAgIGlmIGRpc29yZGVyX3R5cGUgPT0gJ2dhdXNzaWFuJzoKICAgICAgICByZXR1cm4gbWF4KC0xLjAsIG1pbigxLjAsIHJuZy5nYXVzcygwLjAsIDAuMykpKQogICAgcmV0dXJuIHJuZy51bmlmb3JtKC0xLjAsIDEuMCkK').decode(),
'core/builder.py': __import__("base64").b64decode('IiIiCmNvcmUvYnVpbGRlci5weQotLS0tLS0tLS0tLS0tLS0KVHJhcHBpbmdBcnJheUJ1aWxkZXI6IGNvbWJpbmVzIGFuIEFycmF5R3JpZCB3aXRoIHRyYXAtc2hhcGUgYW5kIElPCnBhcmFtZXRlcnMgdG8gcHJvZHVjZSB0aGUgZnVsbCBjaGlwIGxheW91dCBpbiBhIHB5YSBjZWxsLgoiIiIKCmZyb20gLnByaW1pdGl2ZXMgaW1wb3J0IHRvX2RidSwgcmVjdCwgZHJhd190cmFwCmZyb20gLmlvX3NoYXBlcyBpbXBvcnQgKGRyYXdfZGlyZWN0X2NoYW5uZWxzLCBkcmF3X2RpdmVyZ2luZ19jaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgZGl2ZXJnaW5nX2hhbGZfYW5nbGUpCgppbXBvcnQgcHlhCgoKY2xhc3MgVHJhcHBpbmdBcnJheUJ1aWxkZXI6CiAgICAiIiIKICAgIFBhcmFtZXRlcnMKICAgIC0tLS0tLS0tLS0KICAgIGdyaWQgICAgICAgICAgOiBBcnJheUdyaWQKICAgIGxfdHJhcCAgICAgICAgOiBmbG9hdCAg4oCTIHRyYXAgc3RyZWFtd2lzZSBsZW5ndGggKMK1bSkKICAgIHdfdHJhcCAgICAgICAgOiBmbG9hdCAg4oCTIHRyYXAgbGF0ZXJhbCBvdXRlciB3aWR0aCAowrVtKQogICAgd2FsbF90ICAgICAgICA6IGZsb2F0ICDigJMgcGlsbGFyIHdhbGwgdGhpY2tuZXNzICjCtW0pCiAgICBiYXNlX3QgICAgICAgIDogZmxvYXQgIOKAkyBiYXNlIGJhciBkZXB0aCBvbiBkb3duc3RyZWFtIGZhY2UgKMK1bSkKICAgIHdfb19kb3duICAgICAgOiBmbG9hdCAg4oCTIGRvd25zdHJlYW0gc2xpdCB3aWR0aCAowrVtKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11c3Qgc2F0aXNmeSAwIDwgd19vX2Rvd24gPCB3X3RyYXAg4oiSIDLCt3dhbGxfdAogICAgaW9fbW9kZSAgICAgICA6IHN0ciAgICDigJMgJ2RpcmVjdCcgb3IgJ2RpdmVyZ2luZycKICAgIEMgICAgICAgICAgICAgOiBmbG9hdCAg4oCTIElPIGNlbnRyaW5nIFsw4oCTMV0sIGRpcmVjdCBtb2RlIG9ubHkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSA9IGNoYW5uZWxzIGFsaWduZWQsIDAgPSBtYXhpbXVtIG9mZnNldCkKICAgIHdfaW8gICAgICAgICAgOiBmbG9hdCAg4oCTIGlubGV0L291dGxldCBjaGFubmVsIHdpZHRoICjCtW0pCiAgICBjaGFubmVsX2xlbiAgIDogZmxvYXQgIOKAkyBzdHViIGxlbmd0aCBwcm90cnVkaW5nIG91dHNpZGUgY2hpcCAowrVtKQogICAgbF9kaXYgICAgICAgICA6IGZsb2F0ICDigJMgZGl2ZXJnaW5nIHNlY3Rpb24gbGVuZ3RoICjCtW0pLCBkaXZlcmdpbmcgbW9kZSBvbmx5CiAgICBEX2YgICAgICAgICAgIDogZmxvYXQgIOKAkyBkaXNvcmRlciBmYWN0b3IgWzDigJMxXSAgKDAgPSByZWd1bGFyKQogICAgZGlzb3JkZXJfdHlwZSA6IHN0ciAgICDigJMgJ3VuaWZvcm0nIG9yICdnYXVzc2lhbicKICAgIHNlZWQgICAgICAgICAgOiBpbnQgfCBOb25lICDigJMgcmFuZG9tIHNlZWQgZm9yIGRpc29yZGVyIChOb25lID0gcmFuZG9tKQoKICAgIFJlYWQtb25seSBwcm9wZXJ0aWVzCiAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd19vICAgICAgICAgICAgICAgOiB1cHN0cmVhbSBvcGVuaW5nIHdpZHRoICA9IHdfdHJhcCDiiJIgMsK3d2FsbF90CiAgICBEZWx0YV95X2lvICAgICAgICA6IGlubGV0IGxhdGVyYWwgb2Zmc2V0IChkaXJlY3QgbW9kZSkKICAgIGRpdl9oYWxmX2FuZ2xlX2RlZzogZGl2ZXJnaW5nIGhhbGYtYW5nbGUgaW4gZGVncmVlcyAoZGl2ZXJnaW5nIG1vZGUpCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgZ3JpZCwgbF90cmFwLCB3X3RyYXAsIHdhbGxfdCwgYmFzZV90LCB3X29fZG93biwKICAgICAgICAgICAgICAgICBpb19tb2RlPSdkaXJlY3QnLCBDPTEuMCwgd19pbz0xMDAuMCwgY2hhbm5lbF9sZW49MTAwLjAsCiAgICAgICAgICAgICAgICAgbF9kaXY9MjAwLjAsIERfZj0wLjAsIGRpc29yZGVyX3R5cGU9J3VuaWZvcm0nLCBzZWVkPU5vbmUpOgoKICAgICAgICB3X28gPSB3X3RyYXAgLSAyLjAgKiB3YWxsX3QKCiAgICAgICAgIyAtLS0gdmFsaWRhdGlvbiAtLS0KICAgICAgICBpZiB3X28gPD0gMC4wOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKAogICAgICAgICAgICAgICAgZiJ3X3RyYXAgKHt3X3RyYXB9KSDiiJIgMsK3d2FsbF90ICh7d2FsbF90fSkgPSB7d19vOi4zZn0g4omkIDAuICIKICAgICAgICAgICAgICAgICJJbmNyZWFzZSB3X3RyYXAgb3IgcmVkdWNlIHdhbGxfdC4iKQogICAgICAgIGlmIG5vdCAoMC4wIDwgd19vX2Rvd24gPCB3X28pOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKAogICAgICAgICAgICAgICAgZiJ3X29fZG93biAoe3dfb19kb3dufSkgbXVzdCBiZSBpbiAiCiAgICAgICAgICAgICAgICBmIigwLCB3X28gPSB7d19vOi4zZn0pLiIpCiAgICAgICAgaWYgYmFzZV90ID49IGxfdHJhcDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigKICAgICAgICAgICAgICAgIGYiYmFzZV90ICh7YmFzZV90fSkgbXVzdCBiZSA8IGxfdHJhcCAoe2xfdHJhcH0pLiIpCiAgICAgICAgaWYgaW9fbW9kZSBub3QgaW4gKCdkaXJlY3QnLCAnZGl2ZXJnaW5nJyk6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoCiAgICAgICAgICAgICAgICBmImlvX21vZGUgbXVzdCBiZSAnZGlyZWN0JyBvciAnZGl2ZXJnaW5nJywgZ290ICd7aW9fbW9kZX0nLiIpCiAgICAgICAgaWYgaW9fbW9kZSA9PSAnZGl2ZXJnaW5nJyBhbmQgd19pbyA+PSBncmlkLlc6CiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoCiAgICAgICAgICAgICAgICBmIndfaW8gKHt3X2lvfSkgbXVzdCBiZSA8IFcgKHtncmlkLld9KSBpbiBkaXZlcmdpbmcgbW9kZS4iKQogICAgICAgIGlmIHdfaW8gPD0gMC4wOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJ3X2lvIG11c3QgYmUgcG9zaXRpdmUuIikKICAgICAgICBpZiBjaGFubmVsX2xlbiA8IDAuMDoKICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiY2hhbm5lbF9sZW4gbXVzdCBiZSDiiaUgMC4iKQoKICAgICAgICBzZWxmLmdyaWQgICAgICAgICAgPSBncmlkCiAgICAgICAgc2VsZi5sX3RyYXAgICAgICAgID0gZmxvYXQobF90cmFwKQogICAgICAgIHNlbGYud190cmFwICAgICAgICA9IGZsb2F0KHdfdHJhcCkKICAgICAgICBzZWxmLndhbGxfdCAgICAgICAgPSBmbG9hdCh3YWxsX3QpCiAgICAgICAgc2VsZi5iYXNlX3QgICAgICAgID0gZmxvYXQoYmFzZV90KQogICAgICAgIHNlbGYud19vX2Rvd24gICAgICA9IGZsb2F0KHdfb19kb3duKQogICAgICAgIHNlbGYud19vICAgICAgICAgICA9IGZsb2F0KHdfbykKICAgICAgICBzZWxmLmlvX21vZGUgICAgICAgPSBpb19tb2RlCiAgICAgICAgc2VsZi5DICAgICAgICAgICAgID0gZmxvYXQoQykKICAgICAgICBzZWxmLndfaW8gICAgICAgICAgPSBmbG9hdCh3X2lvKQogICAgICAgIHNlbGYuY2hhbm5lbF9sZW4gICA9IGZsb2F0KGNoYW5uZWxfbGVuKQogICAgICAgIHNlbGYubF9kaXYgICAgICAgICA9IGZsb2F0KGxfZGl2KQogICAgICAgIHNlbGYuRF9mICAgICAgICAgICA9IGZsb2F0KERfZikKICAgICAgICBzZWxmLmRpc29yZGVyX3R5cGUgPSBkaXNvcmRlcl90eXBlCiAgICAgICAgc2VsZi5zZWVkICAgICAgICAgID0gc2VlZAoKICAgICAgICAjIGRlcml2ZWQgSU8gcXVhbnRpdGllcwogICAgICAgIHNlbGYuRGVsdGFfeV9pbyA9ICgxLjAgLSBDKSAqIChncmlkLlcgLSB3X2lvKSAvIDIuMAogICAgICAgIHNlbGYuZGl2X2hhbGZfYW5nbGVfZGVnID0gKAogICAgICAgICAgICBkaXZlcmdpbmdfaGFsZl9hbmdsZShncmlkLlcsIHdfaW8sIGxfZGl2KQogICAgICAgICAgICBpZiBpb19tb2RlID09ICdkaXZlcmdpbmcnIGVsc2UgMC4wCiAgICAgICAgKQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgYnVpbGQoc2VsZiwgbGF5b3V0LCBsYXllciwgY2VsbF9uYW1lPSJUcmFwQXJyYXkiKToKICAgICAgICAiIiIKICAgICAgICBDcmVhdGUgYSBuZXcgbmFtZWQgY2VsbCBpbiBgbGF5b3V0YCwgcG9wdWxhdGUgaXQsIGFuZCByZXR1cm4gaXQuCgogICAgICAgIFBhcmFtZXRlcnMKICAgICAgICAtLS0tLS0tLS0tCiAgICAgICAgbGF5b3V0ICAgIDogcHlhLkxheW91dAogICAgICAgIGxheWVyICAgICA6IGludCAg4oCTIGxheWVyIGluZGV4IChmcm9tIGxheW91dC5sYXllciguLi4pKQogICAgICAgIGNlbGxfbmFtZSA6IHN0cgogICAgICAgICIiIgogICAgICAgIGN2dCAgPSB0b19kYnUobGF5b3V0LmRidSkKICAgICAgICBjZWxsID0gbGF5b3V0LmNyZWF0ZV9jZWxsKGNlbGxfbmFtZSkKICAgICAgICBzZWxmLl9kcmF3X2FsbChjZWxsLCBsYXllciwgY3Z0KQogICAgICAgIHJldHVybiBjZWxsCgogICAgZGVmIGJ1aWxkX2ludG8oc2VsZiwgY2VsbCwgbGF5ZXIpOgogICAgICAgICIiIgogICAgICAgIEluc2VydCBhbGwgc2hhcGVzIGludG8gYW4gZXhpc3RpbmcgYGNlbGxgLgogICAgICAgIFVzZWZ1bCB3aGVuIGNvbXBvc2luZyBtdWx0aXBsZSBhcnJheXMgaW50byBvbmUgbGF5b3V0IChlLmcuIDQtaW4tcGFyYWxsZWwpLgogICAgICAgICIiIgogICAgICAgIGN2dCA9IHRvX2RidShjZWxsLmxheW91dCgpLmRidSkKICAgICAgICBzZWxmLl9kcmF3X2FsbChjZWxsLCBsYXllciwgY3Z0KQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgX2RyYXdfYWxsKHNlbGYsIGNlbGwsIGxheWVyLCBjdnQpOgogICAgICAgIHNlbGYuX2RyYXdfY2hhbWJlcihjZWxsLCBsYXllciwgY3Z0KQogICAgICAgIHNlbGYuX2RyYXdfaW8oY2VsbCwgbGF5ZXIsIGN2dCkKICAgICAgICBzZWxmLl9kcmF3X3RyYXBzKGNlbGwsIGxheWVyLCBjdnQpCgogICAgZGVmIF9kcmF3X2NoYW1iZXIoc2VsZiwgY2VsbCwgbGF5ZXIsIGN2dCk6CiAgICAgICAgcmVjdChjZWxsLCBsYXllciwgY3Z0LCAwLCAwLCBzZWxmLmdyaWQuTCwgc2VsZi5ncmlkLlcpCgogICAgZGVmIF9kcmF3X2lvKHNlbGYsIGNlbGwsIGxheWVyLCBjdnQpOgogICAgICAgIGlmIHNlbGYuaW9fbW9kZSA9PSAnZGlyZWN0JzoKICAgICAgICAgICAgZHJhd19kaXJlY3RfY2hhbm5lbHMoCiAgICAgICAgICAgICAgICBjZWxsLCBsYXllciwgY3Z0LAogICAgICAgICAgICAgICAgc2VsZi5ncmlkLCBzZWxmLndfaW8sIHNlbGYuY2hhbm5lbF9sZW4sIHNlbGYuRGVsdGFfeV9pbykKICAgICAgICBlbHNlOgogICAgICAgICAgICBkcmF3X2RpdmVyZ2luZ19jaGFubmVscygKICAgICAgICAgICAgICAgIGNlbGwsIGxheWVyLCBjdnQsCiAgICAgICAgICAgICAgICBzZWxmLmdyaWQsIHNlbGYud19pbywgc2VsZi5jaGFubmVsX2xlbiwgc2VsZi5sX2RpdikKCiAgICBkZWYgX2RyYXdfdHJhcHMoc2VsZiwgY2VsbCwgbGF5ZXIsIGN2dCk6CiAgICAgICAgdCAgPSBzZWxmLndhbGxfdAogICAgICAgIHBvc2l0aW9ucyA9IHNlbGYuZ3JpZC50cmFwX3Bvc2l0aW9ucygKICAgICAgICAgICAgRF9mPXNlbGYuRF9mLAogICAgICAgICAgICBkaXNvcmRlcl90eXBlPXNlbGYuZGlzb3JkZXJfdHlwZSwKICAgICAgICAgICAgc2VlZD1zZWxmLnNlZWQsCiAgICAgICAgKQogICAgICAgIGZvciAoeDAsIHkwKSBpbiBwb3NpdGlvbnM6CiAgICAgICAgICAgICMgY2xhbXAgZGlzb3JkZXJlZCB0cmFwcyB0byBzdGF5IGluc2lkZSBjaGFtYmVyIHdpdGggd2FsbF90IG1hcmdpbgogICAgICAgICAgICB4MCA9IG1heCh0LCBtaW4oc2VsZi5ncmlkLkwgLSBzZWxmLmxfdHJhcCAtIHQsIHgwKSkKICAgICAgICAgICAgeTAgPSBtYXgodCwgbWluKHNlbGYuZ3JpZC5XIC0gc2VsZi53X3RyYXAgLSB0LCB5MCkpCiAgICAgICAgICAgIGRyYXdfdHJhcChjZWxsLCBsYXllciwgY3Z0LAogICAgICAgICAgICAgICAgICAgICAgeDAsIHkwLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi5sX3RyYXAsIHNlbGYud190cmFwLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi53YWxsX3QsIHNlbGYuYmFzZV90LCBzZWxmLndfb19kb3duKQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBkZWYgc3VtbWFyeShzZWxmKToKICAgICAgICAiIiJSZXR1cm4gYSBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUgZnVsbCBjaGlwIGdlb21ldHJ5LiIiIgogICAgICAgIGxpbmVzID0gW3NlbGYuZ3JpZC5zdW1tYXJ5KCksICIiXQogICAgICAgIGxpbmVzLmFwcGVuZChmIklPIG1vZGUgICAgIDoge3NlbGYuaW9fbW9kZX0iKQogICAgICAgIGlmIHNlbGYuaW9fbW9kZSA9PSAnZGlyZWN0JzoKICAgICAgICAgICAgbGluZXMuYXBwZW5kKAogICAgICAgICAgICAgICAgZiIgIEMgPSB7c2VsZi5DfSAg4oaSICDOlHlfaW8gPSB7c2VsZi5EZWx0YV95X2lvOi4zZn0gwrVtIikKICAgICAgICBlbHNlOgogICAgICAgICAgICBsaW5lcy5hcHBlbmQoCiAgICAgICAgICAgICAgICBmIiAgbF9kaXYgPSB7c2VsZi5sX2Rpdn0gwrVtICAiCiAgICAgICAgICAgICAgICBmIuKGkiAgaGFsZi1hbmdsZSA9IHtzZWxmLmRpdl9oYWxmX2FuZ2xlX2RlZzouMmZ9wrAiKQogICAgICAgIGxpbmVzICs9IFsKICAgICAgICAgICAgZiJDaGFubmVsICAgICA6IHdfaW8gPSB7c2VsZi53X2lvfSDCtW0sIgogICAgICAgICAgICBmIiAgc3R1YiA9IHtzZWxmLmNoYW5uZWxfbGVufSDCtW0iLAogICAgICAgICAgICBmIlRyYXAgICAgICAgIDogbF90cmFwID0ge3NlbGYubF90cmFwfSDCtW0sIgogICAgICAgICAgICBmIiAgd190cmFwID0ge3NlbGYud190cmFwfSDCtW0sIiwKICAgICAgICAgICAgZiIgICAgICAgICAgICAgIHdhbGxfdCA9IHtzZWxmLndhbGxfdH0gwrVtLCIKICAgICAgICAgICAgZiIgIGJhc2VfdCA9IHtzZWxmLmJhc2VfdH0gwrVtIiwKICAgICAgICAgICAgZiIgIHdfbyAodXBzdHJlYW0gb3BlbmluZykgPSB7c2VsZi53X286LjNmfSDCtW0iLAogICAgICAgICAgICBmIiAgd19vX2Rvd24gKGRvd25zdHJlYW0gc2xpdCkgPSB7c2VsZi53X29fZG93bn0gwrVtIiwKICAgICAgICAgICAgZiJEaXNvcmRlciAgICA6IERfZiA9IHtzZWxmLkRfZn0gICh7c2VsZi5kaXNvcmRlcl90eXBlfSkiLAogICAgICAgIF0KICAgICAgICByZXR1cm4gIlxuIi5qb2luKGxpbmVzKQoKICAgIGRlZiBfX3JlcHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gKGYiVHJhcHBpbmdBcnJheUJ1aWxkZXIoIgogICAgICAgICAgICAgICAgZiJncmlkPXtzZWxmLmdyaWQhcn0sICIKICAgICAgICAgICAgICAgIGYiaW9fbW9kZT0ne3NlbGYuaW9fbW9kZX0nLCAiCiAgICAgICAgICAgICAgICBmIkRfZj17c2VsZi5EX2Z9KSIpCg==').decode(),
'core/primitives.py': __import__("base64").b64decode('IiIiCmNvcmUvcHJpbWl0aXZlcy5weQotLS0tLS0tLS0tLS0tLS0tLS0KTG93LWxldmVsIHB5YSBkcmF3aW5nIGhlbHBlcnMgYW5kIHRoZSBzaW5nbGUtdHJhcCBwb2x5Z29uIGdlbmVyYXRvci4KTm8gY2xhc3Mgc3RhdGU7IGFsbCBmdW5jdGlvbnMgYXJlIHB1cmUgZ2l2ZW4gdGhlaXIgYXJndW1lbnRzLgoKQ29vcmRpbmF0ZSBjb252ZW50aW9uIChzaGFyZWQgYWNyb3NzIHRoZSB3aG9sZSBsaWJyYXJ5KQogICAgeCA9IHN0cmVhbXdpc2UgIChpbmNyZWFzZXMgdG93YXJkIGlubGV0IC8gdXBzdHJlYW0pCiAgICB5ID0gbGF0ZXJhbAogICAgT3JpZ2luIGF0IGJvdHRvbS1sZWZ0IGNvcm5lciBvZiB0aGUgY2hhbWJlciByZWN0YW5nbGUuCgpUcmFwIHNoYXBlOiBpbnZlcnRlZC1VIHdpdGggZG93bnN0cmVhbSBzbGl0CiAgICBUd28gaG9yaXpvbnRhbCBwaWxsYXJzICh3YWxsX3QgdGhpY2spIHJ1bm5pbmcgdGhlIGZ1bGwgbF90cmFwIGluIHguCiAgICBBIGJhc2UgYmFyIChiYXNlX3QgZGVlcCBpbiB4KSBvbiB0aGUgZG93bnN0cmVhbSBmYWNlICh4ID0geDApLAogICAgc3BsaXQgYnkgYSBjZW50cmVkIHNsaXQgb2Ygd2lkdGggd19vX2Rvd24uCiAgICBUaGUgdXBzdHJlYW0gZmFjZSAoeCA9IHgwICsgbF90cmFwKSBpcyBmdWxseSBvcGVuIG92ZXIKICAgIHdfbyA9IHdfdHJhcCAtIDIqd2FsbF90LgoiIiIKCmltcG9ydCBweWEKCgpkZWYgdG9fZGJ1KGxheW91dF9vcl9kYnUpOgogICAgIiIiUmV0dXJuIGEgwrVt4oaSZGJ1IGNvbnZlcnRlciBmb3IgdGhlIGdpdmVuIGxheW91dCBvciBkYnUgZmxvYXQuIiIiCiAgICBkYnUgPSBsYXlvdXRfb3JfZGJ1IGlmIGlzaW5zdGFuY2UobGF5b3V0X29yX2RidSwgZmxvYXQpIGVsc2UgbGF5b3V0X29yX2RidS5kYnUKICAgIHJldHVybiBsYW1iZGEgdjogaW50KHJvdW5kKHYgLyBkYnUpKQoKCmRlZiByZWN0KGNlbGwsIGxheWVyLCBjdnQsIHgwLCB5MCwgeDEsIHkxKToKICAgICIiIkluc2VydCBhbiBheGlzLWFsaWduZWQgcmVjdGFuZ2xlICjCtW0gY29vcmRzLCBjb252ZXJ0ZWQgYnkgY3Z0KS4iIiIKICAgIHB0cyA9IFsKICAgICAgICBweWEuUG9pbnQoY3Z0KHgwKSwgY3Z0KHkwKSksCiAgICAgICAgcHlhLlBvaW50KGN2dCh4MSksIGN2dCh5MCkpLAogICAgICAgIHB5YS5Qb2ludChjdnQoeDEpLCBjdnQoeTEpKSwKICAgICAgICBweWEuUG9pbnQoY3Z0KHgwKSwgY3Z0KHkxKSksCiAgICBdCiAgICBjZWxsLnNoYXBlcyhsYXllcikuaW5zZXJ0KHB5YS5Qb2x5Z29uKHB0cykpCgoKZGVmIHBvbHlnb24oY2VsbCwgbGF5ZXIsIGN2dCwgcHRzX3VtKToKICAgICIiIkluc2VydCBhbiBhcmJpdHJhcnkgcG9seWdvbiBmcm9tIGEgbGlzdCBvZiAoeCwgeSkgwrVtIHR1cGxlcy4iIiIKICAgIHB0cyA9IFtweWEuUG9pbnQoY3Z0KHgpLCBjdnQoeSkpIGZvciB4LCB5IGluIHB0c191bV0KICAgIGNlbGwuc2hhcGVzKGxheWVyKS5pbnNlcnQocHlhLlBvbHlnb24ocHRzKSkKCgpkZWYgZHJhd190cmFwKGNlbGwsIGxheWVyLCBjdnQsIHgwLCB5MCwgbF90cmFwLCB3X3RyYXAsIHdhbGxfdCwgYmFzZV90LCB3X29fZG93bik6CiAgICAiIiIKICAgIERyYXcgYSBzaW5nbGUgdHJhcCBhdCBib3R0b20tbGVmdCBjb3JuZXIgKHgwLCB5MCkuCgogICAgUGFyYW1ldGVycwogICAgLS0tLS0tLS0tLQogICAgeDAsIHkwICAgOiDCtW0g4oCTIGJvdHRvbS1sZWZ0IG9mIHRyYXAgYm91bmRpbmcgYm94CiAgICBsX3RyYXAgICA6IMK1bSDigJMgdG90YWwgc3RyZWFtd2lzZSBsZW5ndGggKG9wZW4gZmFjZSBhdCB4MCtsX3RyYXApCiAgICB3X3RyYXAgICA6IMK1bSDigJMgdG90YWwgbGF0ZXJhbCBvdXRlciB3aWR0aAogICAgd2FsbF90ICAgOiDCtW0g4oCTIHBpbGxhciB3YWxsIHRoaWNrbmVzcyAodG9wIGFuZCBib3R0b20gaW4geSkKICAgIGJhc2VfdCAgIDogwrVtIOKAkyBiYXNlIGJhciBkZXB0aCAoZG93bnN0cmVhbSBmYWNlLCBpbiB4KQogICAgd19vX2Rvd24gOiDCtW0g4oCTIGRvd25zdHJlYW0gc2xpdCB3aWR0aCAoY2VudHJlZCB3aXRoaW4gaW50ZXJpb3IpCgogICAgV2FsbCBjb21wb25lbnRzCiAgICAtLS0tLS0tLS0tLS0tLS0KICAgIEJvdHRvbSBwaWxsYXIgOiB4IOKIiCBbeDAsICAgICAgICB4MCtsX3RyYXBdLCAgeSDiiIggW3kwLCAgICAgICAgICAgIHkwK3dhbGxfdF0KICAgIFRvcCAgICBwaWxsYXIgOiB4IOKIiCBbeDAsICAgICAgICB4MCtsX3RyYXBdLCAgeSDiiIggW3kwK3dfdHJhcC10LCAgIHkwK3dfdHJhcF0KICAgIEJhc2UgbGVmdCBzdHViOiB4IOKIiCBbeDAsICAgICAgICB4MCtiYXNlX3RdLCAgeSDiiIggW3kwK3dhbGxfdCwgICAgIHNsaXRfeTAgIF0KICAgIEJhc2UgcmdodCBzdHViOiB4IOKIiCBbeDAsICAgICAgICB4MCtiYXNlX3RdLCAgeSDiiIggW3NsaXRfeTEsICAgICAgIHkwK3dfdHJhcC10XQoKICAgIHdoZXJlCiAgICAgIHdfbyAgICAgPSB3X3RyYXAgLSAyKndhbGxfdCAgICAgICAgICAoaW50ZXJpb3IgLyB1cHN0cmVhbSBvcGVuaW5nIHdpZHRoKQogICAgICBzbGl0X3kwID0geTAgKyB3YWxsX3QgKyAod19vIC0gd19vX2Rvd24pIC8gMgogICAgICBzbGl0X3kxID0gc2xpdF95MCArIHdfb19kb3duCiAgICAiIiIKICAgIHQgICA9IHdhbGxfdAogICAgYnQgID0gYmFzZV90CiAgICB3X28gPSB3X3RyYXAgLSAyICogdAoKICAgIHNsaXRfeTAgPSB5MCArIHQgKyAod19vIC0gd19vX2Rvd24pIC8gMi4wCiAgICBzbGl0X3kxID0gc2xpdF95MCArIHdfb19kb3duCgogICAgIyBib3R0b20gcGlsbGFyICjiiJJ5IHNpZGUsIGZ1bGwgbGVuZ3RoKQogICAgcmVjdChjZWxsLCBsYXllciwgY3Z0LCB4MCwgeTAsIHgwICsgbF90cmFwLCB5MCArIHQpCgogICAgIyB0b3AgcGlsbGFyICgreSBzaWRlLCBmdWxsIGxlbmd0aCkKICAgIHJlY3QoY2VsbCwgbGF5ZXIsIGN2dCwgeDAsIHkwICsgd190cmFwIC0gdCwgeDAgKyBsX3RyYXAsIHkwICsgd190cmFwKQoKICAgICMgYmFzZSBiYXIgbGVmdCBzdHViIChiZWxvdyBzbGl0KQogICAgcmVjdChjZWxsLCBsYXllciwgY3Z0LCB4MCwgeTAgKyB0LCB4MCArIGJ0LCBzbGl0X3kwKQoKICAgICMgYmFzZSBiYXIgcmlnaHQgc3R1YiAoYWJvdmUgc2xpdCkKICAgIHJlY3QoY2VsbCwgbGF5ZXIsIGN2dCwgeDAsIHNsaXRfeTEsIHgwICsgYnQsIHkwICsgd190cmFwIC0gdCkK').decode(),
'core/io_shapes.py': __import__("base64").b64decode('IiIiCmNvcmUvaW9fc2hhcGVzLnB5Ci0tLS0tLS0tLS0tLS0tLS0tCklubGV0IGFuZCBvdXRsZXQgY2hhbm5lbCBkcmF3aW5nIGZvciBib3RoIElPIG1vZGVzLgoKJ2RpcmVjdCcgICAg4oCTIHJlY3Rhbmd1bGFyIHN0dWJzIGNvbm5lY3RpbmcgZGlyZWN0bHkgdG8gdGhlIGNoYW1iZXIgd2FsbHMuCiAgICAgICAgICAgICAgVGhlIGlubGV0IG1heSBiZSBsYXRlcmFsbHkgb2Zmc2V0IGJ5IM6UeV9pbyA9ICgx4oiSQynCtyhX4oiSd19pbykvMi4KICAgICAgICAgICAgICBUaGUgb3V0bGV0IGlzIGFsd2F5cyBjZW50cmVkIG9uIFcvMi4KCidkaXZlcmdpbmcnIOKAkyBzdHJhaWdodCB0cmFwZXpvaWRhbCB0cmFuc2l0aW9uIHNlY3Rpb25zIGZhbiB0aGUgY2hhbm5lbCBmcm9tCiAgICAgICAgICAgICAgd19pbyB0byB0aGUgZnVsbCBjaGFtYmVyIHdpZHRoIFcgb3ZlciBsZW5ndGggbF9kaXYsIHRoZW4gYQogICAgICAgICAgICAgIHJlY3Rhbmd1bGFyIHN0dWIgb2YgbGVuZ3RoIGNoYW5uZWxfbGVuIGJleW9uZCB0aGF0LgogICAgICAgICAgICAgIEJvdGggY2hhbm5lbHMgYXJlIGNlbnRyZWQgb24gVy8yOyBDIGlzIGlycmVsZXZhbnQuCiIiIgoKaW1wb3J0IG1hdGgKZnJvbSAucHJpbWl0aXZlcyBpbXBvcnQgcmVjdCwgcG9seWdvbgoKCmRlZiBkcmF3X2RpcmVjdF9jaGFubmVscyhjZWxsLCBsYXllciwgY3Z0LCBncmlkLCB3X2lvLCBjaGFubmVsX2xlbiwgRGVsdGFfeV9pbyk6CiAgICAiIiIKICAgIERyYXcgaW5sZXQgYW5kIG91dGxldCBhcyBwbGFpbiByZWN0YW5ndWxhciBzdHVicy4KCiAgICBJbmxldCAgKHJpZ2h0IHNpZGUsICt4KTogIGNlbnRyZWQgYXQgVy8yICsgRGVsdGFfeV9pbwogICAgT3V0bGV0IChsZWZ0ICBzaWRlLCDiiJJ4KTogIGNlbnRyZWQgYXQgVy8yCiAgICAiIiIKICAgIFcgID0gZ3JpZC5XCiAgICBMICA9IGdyaWQuTAogICAgY2wgPSBjaGFubmVsX2xlbgogICAgd2lvID0gd19pbwoKICAgICMgb3V0bGV0CiAgICB5Y19vdXQgPSBXIC8gMi4wCiAgICByZWN0KGNlbGwsIGxheWVyLCBjdnQsCiAgICAgICAgIC1jbCwgeWNfb3V0IC0gd2lvIC8gMi4wLAogICAgICAgICAwLjAsIHljX291dCArIHdpbyAvIDIuMCkKCiAgICAjIGlubGV0CiAgICB5Y19pbiA9IFcgLyAyLjAgKyBEZWx0YV95X2lvCiAgICByZWN0KGNlbGwsIGxheWVyLCBjdnQsCiAgICAgICAgIEwsICAgICAgeWNfaW4gLSB3aW8gLyAyLjAsCiAgICAgICAgIEwgKyBjbCwgeWNfaW4gKyB3aW8gLyAyLjApCgoKZGVmIGRyYXdfZGl2ZXJnaW5nX2NoYW5uZWxzKGNlbGwsIGxheWVyLCBjdnQsIGdyaWQsIHdfaW8sIGNoYW5uZWxfbGVuLCBsX2Rpdik6CiAgICAiIiIKICAgIERyYXcgaW5sZXQgYW5kIG91dGxldCBlYWNoIGFzIGEgc3RyYWlnaHQgdHJhcGV6b2lkICsgcmVjdGFuZ3VsYXIgc3R1YiwKICAgIGJvdGggY2VudHJlZCBvbiBXLzIuCgogICAgSW5sZXQgc2lkZSAoK3gpOgogICAgICAgIHN0dWIgICAgICA6IHgg4oiIIFtMK2xfZGl2LCBMK2xfZGl2K2NoYW5uZWxfbGVuXSwgIHdpZHRoIHdfaW8KICAgICAgICB0cmFwZXpvaWQgOiB3aWRlIGZhY2UgKFcpIGF0IHg9TCwgbmFycm93IGZhY2UgKHdfaW8pIGF0IHg9TCtsX2RpdgoKICAgIE91dGxldCBzaWRlICjiiJJ4KToKICAgICAgICBzdHViICAgICAgOiB4IOKIiCBb4oiSbF9kaXbiiJJjaGFubmVsX2xlbiwg4oiSbF9kaXZdLCAgd2lkdGggd19pbwogICAgICAgIHRyYXBlem9pZCA6IG5hcnJvdyBmYWNlICh3X2lvKSBhdCB4PeKIkmxfZGl2LCB3aWRlIGZhY2UgKFcpIGF0IHg9MAogICAgIiIiCiAgICBXICAgPSBncmlkLlcKICAgIEwgICA9IGdyaWQuTAogICAgY2wgID0gY2hhbm5lbF9sZW4KICAgIGxkICA9IGxfZGl2CiAgICB3aW8gPSB3X2lvCiAgICB5YyAgPSBXIC8gMi4wCgogICAgIyDilIDilIAgaW5sZXQg4pSA4pSACiAgICBwb2x5Z29uKGNlbGwsIGxheWVyLCBjdnQsIFsKICAgICAgICAoTCwgICAgICAwLjApLAogICAgICAgIChMLCAgICAgIFcpLAogICAgICAgIChMICsgbGQsIHljICsgd2lvIC8gMi4wKSwKICAgICAgICAoTCArIGxkLCB5YyAtIHdpbyAvIDIuMCksCiAgICBdKQogICAgcmVjdChjZWxsLCBsYXllciwgY3Z0LAogICAgICAgICBMICsgbGQsICAgICAgeWMgLSB3aW8gLyAyLjAsCiAgICAgICAgIEwgKyBsZCArIGNsLCB5YyArIHdpbyAvIDIuMCkKCiAgICAjIOKUgOKUgCBvdXRsZXQg4pSA4pSACiAgICBwb2x5Z29uKGNlbGwsIGxheWVyLCBjdnQsIFsKICAgICAgICAoLWxkLCB5YyAtIHdpbyAvIDIuMCksCiAgICAgICAgKC1sZCwgeWMgKyB3aW8gLyAyLjApLAogICAgICAgICgwLjAsIFcpLAogICAgICAgICgwLjAsIDAuMCksCiAgICBdKQogICAgcmVjdChjZWxsLCBsYXllciwgY3Z0LAogICAgICAgICAtbGQgLSBjbCwgeWMgLSB3aW8gLyAyLjAsCiAgICAgICAgIC1sZCwgICAgICB5YyArIHdpbyAvIDIuMCkKCgpkZWYgZGl2ZXJnaW5nX2hhbGZfYW5nbGUoVywgd19pbywgbF9kaXYpOgogICAgIiIiUmV0dXJuIHRoZSBoYWxmLWFuZ2xlIG9mIHRoZSBkaXZlcmdpbmcgc2VjdGlvbiBpbiBkZWdyZWVzLiIiIgogICAgaWYgbF9kaXYgPD0gMDoKICAgICAgICByZXR1cm4gOTAuMAogICAgcmV0dXJuIG1hdGguZGVncmVlcyhtYXRoLmF0YW4oKFcgLSB3X2lvKSAvICgyLjAgKiBsX2RpdikpKQo=').decode(),
'trapping_array_lib.py': __import__("base64").b64decode('IiIiCnRyYXBwaW5nX2FycmF5X2xpYi5weQo9PT09PT09PT09PT09PT09PT09PT0KS0xheW91dCBQQ2VsbCBsaWJyYXJ5IOKAlCByZWdpc3RlcnMgIlRyYXBwaW5nIEFycmF5IiBpbiB0aGUgTGlicmFyaWVzIHBhbmVsLgoKVHdvIFBDZWxsczoKICBUcmFwQXJyYXlfQSAg4oCUICBmaXhlZCBOX2wgw5cgTl9jIGdyaWQKICBUcmFwQXJyYXlfQiAg4oCUICBtYXhpbWlzZSB0cmFwIGNvdW50IGdpdmVuIHBpdGNoCgpFYWNoIFBDZWxsIGRlY2xhcmVzIGl0cyBwYXJhbWV0ZXJzIHNvIEtMYXlvdXQgcmVuZGVycyB0aGUgZWRpdCBmb3JtCmF1dG9tYXRpY2FsbHkgd2hlbiB0aGUgdXNlciBwbGFjZXMgb3IgZG91YmxlLWNsaWNrcyBhbiBpbnN0YW5jZS4KIiIiCgppbXBvcnQgcHlhLCBzeXMsIG9zCgojIE1ha2Ugc3VyZSB0aGUgZXh0cmFjdGVkIGNvcmUgcGFja2FnZSBpcyBpbXBvcnRhYmxlCl9wa2cgPSBvcy5wYXRoLmpvaW4ob3MucGF0aC5leHBhbmR1c2VyKCJ+IiksICIua2xheW91dCIsICJweW1hY3JvcyIsICJ0cmFwcGluZ19hcnJheSIpCmlmIF9wa2cgbm90IGluIHN5cy5wYXRoOgogICAgc3lzLnBhdGguaW5zZXJ0KDAsIF9wa2cpCgpmcm9tIGNvcmUgaW1wb3J0IG1ha2VfZml4ZWRfZ3JpZCwgbWFrZV9tYXhfdHJhcHMKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNoYXJlZCBoZWxwZXJzCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpkZWYgX2xheWVyX2luZGV4KGxheW91dCwgbGF5ZXJfcGFyYW0pOgogICAgIiIiUmV0dXJuIGEgdXNhYmxlIGxheWVyIGluZGV4IGZyb20gYSBMYXllckluZm8gcGFyYW1ldGVyIHZhbHVlLiIiIgogICAgdHJ5OgogICAgICAgIHJldHVybiBsYXlvdXQubGF5ZXIobGF5ZXJfcGFyYW0pCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiBsYXlvdXQubGF5ZXIoMSwgMCkKCgpkZWYgX2J1aWxkKGxheW91dCwgbGF5ZXIsIGdyaWQsIGJ1aWxkZXIpOgogICAgIiIiSW5zZXJ0IGFsbCBjaGlwIHNoYXBlcyBpbnRvIHRoZSBQQ2VsbCdzIG93biBjZWxsLiIiIgogICAgIyBQQ2VsbHMgZ2V0IGEgZnJlc2ggY2VsbCBmcm9tIEtMYXlvdXQ7IHdlIHBvcHVsYXRlIGl0IGluLXBsYWNlLgogICAgIyBidWlsZF9pbnRvKCkgZXhwZWN0cyBhIGNlbGwgd2hvc2UgbGF5b3V0KCkgaXMgYWNjZXNzaWJsZS4KICAgIGNlbGwgPSBsYXlvdXQuY3JlYXRlX2NlbGwoIl9fdG1wX18iKQogICAgYnVpbGRlci5idWlsZF9pbnRvKGNlbGwsIGxheWVyKQogICAgcmV0dXJuIGNlbGwKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIE1vZGUgQSBQQ2VsbAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgVHJhcEFycmF5QShweWEuUENlbGxEZWNsYXJhdGlvbkhlbHBlcik6CiAgICAiIiIKICAgIEZpeGVkIE5fbCDDlyBOX2MgaHlkcm9keW5hbWljIHRyYXBwaW5nIGFycmF5LgogICAgUGFyYW1ldGVycyBhcmUgZGVjbGFyZWQgb25jZTsgS0xheW91dCBidWlsZHMgdGhlIGVkaXQgZGlhbG9nIGF1dG9tYXRpY2FsbHkuCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygpCgogICAgICAgICMg4pSA4pSAIENhdml0eSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgICBzZWxmLnBhcmFtKCJMIiwgc2VsZi5UeXBlRG91YmxlLCAiQ2F2aXR5IHN0cmVhbXdpc2UgbGVuZ3RoICjCtW0pIiwKICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9MTUwMC4wKQogICAgICAgIHNlbGYucGFyYW0oIlciLCBzZWxmLlR5cGVEb3VibGUsICJDYXZpdHkgbGF0ZXJhbCB3aWR0aCAowrVtKSIsCiAgICAgICAgICAgICAgICAgICBkZWZhdWx0PTEyMDAuMCkKCiAgICAgICAgIyDilIDilIAgR3JpZCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgICBzZWxmLnBhcmFtKCJOX2wiLCBzZWxmLlR5cGVJbnQsICJMaW5lcyDigJQgc3RyZWFtd2lzZSAoTl9sKSIsCiAgICAgICAgICAgICAgICAgICBkZWZhdWx0PTcpCiAgICAgICAgc2VsZi5wYXJhbSgiTl9jIiwgc2VsZi5UeXBlSW50LCAiQ29sdW1ucyDigJQgbGF0ZXJhbCAoTl9jKSIsCiAgICAgICAgICAgICAgICAgICBkZWZhdWx0PTE0KQogICAgICAgIHNlbGYucGFyYW0oImdhcF94Iiwgc2VsZi5UeXBlRG91YmxlLCAiSW50ZXItdHJhcCBnYXAgeCAowrVtKSAg4oaSICDOlHggPSBsX3RyYXAgKyBnYXBfeCIsCiAgICAgICAgICAgICAgICAgICBkZWZhdWx0PTEwLjApCiAgICAgICAgc2VsZi5wYXJhbSgiZ2FwX3kiLCBzZWxmLlR5cGVEb3VibGUsICJJbnRlci10cmFwIGdhcCB5ICjCtW0pICDihpIgIM6UeSA9IHdfdHJhcCArIGdhcF95IiwKICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9MTAuMCkKICAgICAgICBzZWxmLnBhcmFtKCJnYXBfeF9tYXJnaW4iLCBzZWxmLlR5cGVEb3VibGUsCiAgICAgICAgICAgICAgICAgICAiU3RyZWFtd2lzZSB3YWxsIG1hcmdpbiAowrVtKSAgWzAgPSB1c2UgZ2FwX3hdIiwKICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9MC4wKQogICAgICAgIHNlbGYucGFyYW0oImdhcF95X21hcmdpbiIsIHNlbGYuVHlwZURvdWJsZSwKICAgICAgICAgICAgICAgICAgICJMYXRlcmFsIHdhbGwgbWFyZ2luICjCtW0pICBbMCA9IHVzZSDOlHkvMl0iLAogICAgICAgICAgICAgICAgICAgZGVmYXVsdD0wLjApCgogICAgICAgICMg4pSA4pSAIFRyYXAgc2hhcGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgICAgc2VsZi5wYXJhbSgibF90cmFwIiwgICBzZWxmLlR5cGVEb3VibGUsICJsX3RyYXAg4oCUIHN0cmVhbXdpc2UgbGVuZ3RoICjCtW0pIiwgIGRlZmF1bHQ9MzAuMCkKICAgICAgICBzZWxmLnBhcmFtKCJ3X3RyYXAiLCAgIHNlbGYuVHlwZURvdWJsZSwgIndfdHJhcCDigJQgbGF0ZXJhbCBvdXRlciB3aWR0aCAowrVtKSIsIGRlZmF1bHQ9MjUuMCkKICAgICAgICBzZWxmLnBhcmFtKCJ3YWxsX3QiLCAgIHNlbGYuVHlwZURvdWJsZSwgIndhbGxfdCDigJQgcGlsbGFyIHRoaWNrbmVzcyAowrVtKSIsICAgIGRlZmF1bHQ9My4wKQogICAgICAgIHNlbGYucGFyYW0oImJhc2VfdCIsICAgc2VsZi5UeXBlRG91YmxlLCAiYmFzZV90IOKAlCBiYXNlIGJhciBkZXB0aCAowrVtKSIsICAgICAgZGVmYXVsdD00LjApCiAgICAgICAgc2VsZi5wYXJhbSgid19vX2Rvd24iLCBzZWxmLlR5cGVEb3VibGUsICJ3X29fZG93biDigJQgZG93bnN0cmVhbSBzbGl0ICjCtW0pIiwgICBkZWZhdWx0PTguMCkKCiAgICAgICAgIyDilIDilIAgSU8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgICAgc2VsZi5wYXJhbSgiaW9fbW9kZSIsIHNlbGYuVHlwZVN0cmluZywKICAgICAgICAgICAgICAgICAgICJJTyBtb2RlOiAnZGlyZWN0JyBvciAnZGl2ZXJnaW5nJyIsIGRlZmF1bHQ9ImRpcmVjdCIpCiAgICAgICAgc2VsZi5wYXJhbSgiQyIsIHNlbGYuVHlwZURvdWJsZSwKICAgICAgICAgICAgICAgICAgICJDZW50cmluZyBDIFsw4oCTMV0gKGRpcmVjdCBtb2RlIG9ubHkpICAxPWFsaWduZWQiLCBkZWZhdWx0PTEuMCkKICAgICAgICBzZWxmLnBhcmFtKCJ3X2lvIiwgICAgICAgc2VsZi5UeXBlRG91YmxlLCAiQ2hhbm5lbCB3aWR0aCAowrVtKSIsICAgICAgICAgICAgICBkZWZhdWx0PTEwMC4wKQogICAgICAgIHNlbGYucGFyYW0oImNoYW5uZWxfbGVuIixzZWxmLlR5cGVEb3VibGUsICJTdHViIGxlbmd0aCBvdXRzaWRlIGNoaXAgKMK1bSkiLCAgIGRlZmF1bHQ9MTAwLjApCiAgICAgICAgc2VsZi5wYXJhbSgibF9kaXYiLCAgICAgIHNlbGYuVHlwZURvdWJsZSwgIkRpdmVyZ2luZyBzZWN0aW9uIGxlbmd0aCAowrVtKSIsICAgZGVmYXVsdD0yMDAuMCkKCiAgICAgICAgIyDilIDilIAgRGlzb3JkZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgICAgc2VsZi5wYXJhbSgiRF9mIiwgICAgICAgICAgIHNlbGYuVHlwZURvdWJsZSwgIkRpc29yZGVyIGZhY3RvciBEX2YgWzDigJMxXSIsICAgIGRlZmF1bHQ9MC4wKQogICAgICAgIHNlbGYucGFyYW0oImRpc29yZGVyX3R5cGUiLCBzZWxmLlR5cGVTdHJpbmcsCiAgICAgICAgICAgICAgICAgICAiRGlzb3JkZXIgdHlwZTogJ3VuaWZvcm0nIG9yICdnYXVzc2lhbiciLCBkZWZhdWx0PSJ1bmlmb3JtIikKICAgICAgICBzZWxmLnBhcmFtKCJzZWVkIiwgc2VsZi5UeXBlSW50LCAiUmFuZG9tIHNlZWQgKDAgPSByYW5kb20pIiwgZGVmYXVsdD00MikKCiAgICAgICAgIyDilIDilIAgTGF5ZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgICAgc2VsZi5wYXJhbSgibGF5ZXIiLCBzZWxmLlR5cGVMYXllciwgIkdEUyBsYXllciIsIGRlZmF1bHQ9cHlhLkxheWVySW5mbygxLCAwKSkKCiAgICBkZWYgZGlzcGxheV90ZXh0X2ltcGwoc2VsZik6CiAgICAgICAgcmV0dXJuIGYiVHJhcEFycmF5X0EgIHtzZWxmLk5fbH3Dl3tzZWxmLk5fY30gIHtzZWxmLmlvX21vZGV9IgoKICAgIGRlZiBjb2VyY2VfcGFyYW1ldGVyc19pbXBsKHNlbGYpOgogICAgICAgICMgS2VlcCBOX2wsIE5fYyBwb3NpdGl2ZQogICAgICAgIGlmIHNlbGYuTl9sIDwgMTogc2VsZi5OX2wgPSAxCiAgICAgICAgaWYgc2VsZi5OX2MgPCAxOiBzZWxmLk5fYyA9IDEKICAgICAgICAjIENsYW1wIEMKICAgICAgICBzZWxmLkMgPSBtYXgoMC4wLCBtaW4oMS4wLCBzZWxmLkMpKQogICAgICAgICMgQ2xhbXAgRF9mCiAgICAgICAgc2VsZi5EX2YgPSBtYXgoMC4wLCBtaW4oMS4wLCBzZWxmLkRfZikpCgogICAgZGVmIHByb2R1Y2VfaW1wbChzZWxmKToKICAgICAgICBsYXllciA9IF9sYXllcl9pbmRleChzZWxmLmxheW91dCwgc2VsZi5sYXllcikKICAgICAgICBneG0gICA9IHNlbGYuZ2FwX3hfbWFyZ2luIGlmIHNlbGYuZ2FwX3hfbWFyZ2luID4gMCBlbHNlIE5vbmUKICAgICAgICBneW0gICA9IHNlbGYuZ2FwX3lfbWFyZ2luIGlmIHNlbGYuZ2FwX3lfbWFyZ2luID4gMCBlbHNlIE5vbmUKICAgICAgICBzZWVkICA9IHNlbGYuc2VlZCBpZiBzZWxmLnNlZWQgPiAwIGVsc2UgTm9uZQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGdyaWQsIGJ1aWxkZXIgPSBtYWtlX2ZpeGVkX2dyaWQoCiAgICAgICAgICAgICAgICBMPXNlbGYuTCwgVz1zZWxmLlcsCiAgICAgICAgICAgICAgICBOX2w9c2VsZi5OX2wsIE5fYz1zZWxmLk5fYywKICAgICAgICAgICAgICAgIGdhcF94PXNlbGYuZ2FwX3gsIGdhcF95PXNlbGYuZ2FwX3ksCiAgICAgICAgICAgICAgICBnYXBfeF9tYXJnaW49Z3htLCBnYXBfeV9tYXJnaW49Z3ltLAogICAgICAgICAgICAgICAgbF90cmFwPXNlbGYubF90cmFwLCB3X3RyYXA9c2VsZi53X3RyYXAsCiAgICAgICAgICAgICAgICB3YWxsX3Q9c2VsZi53YWxsX3QsIGJhc2VfdD1zZWxmLmJhc2VfdCwKICAgICAgICAgICAgICAgIHdfb19kb3duPXNlbGYud19vX2Rvd24sCiAgICAgICAgICAgICAgICBpb19tb2RlPXNlbGYuaW9fbW9kZSwgQz1zZWxmLkMsCiAgICAgICAgICAgICAgICB3X2lvPXNlbGYud19pbywgY2hhbm5lbF9sZW49c2VsZi5jaGFubmVsX2xlbiwKICAgICAgICAgICAgICAgIGxfZGl2PXNlbGYubF9kaXYsCiAgICAgICAgICAgICAgICBEX2Y9c2VsZi5EX2YsIGRpc29yZGVyX3R5cGU9c2VsZi5kaXNvcmRlcl90eXBlLAogICAgICAgICAgICAgICAgc2VlZD1zZWVkLAogICAgICAgICAgICApCiAgICAgICAgZXhjZXB0IChWYWx1ZUVycm9yLCBUeXBlRXJyb3IpIGFzIGV4YzoKICAgICAgICAgICAgIyBEcmF3IGEgd2FybmluZyBtYXJrZXIgc28gdGhlIGNlbGwgaXNuJ3Qgc2lsZW50bHkgZW1wdHkKICAgICAgICAgICAgX2RyYXdfZXJyb3JfbWFya2VyKHNlbGYuY2VsbCwgbGF5ZXIsIHNlbGYubGF5b3V0LmRidSwgc3RyKGV4YykpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBidWlsZGVyLmJ1aWxkX2ludG8oc2VsZi5jZWxsLCBsYXllcikKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIE1vZGUgQiBQQ2VsbAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgVHJhcEFycmF5QihweWEuUENlbGxEZWNsYXJhdGlvbkhlbHBlcik6CiAgICAiIiIKICAgIE1heGltaXNlIHRyYXAgY291bnQgZ2l2ZW4gY2F2aXR5IGFuZCBwaXRjaC4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzdXBlcigpLl9faW5pdF9fKCkKCiAgICAgICAgIyDilIDilIAgQ2F2aXR5IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgICAgIHNlbGYucGFyYW0oIkwiLCBzZWxmLlR5cGVEb3VibGUsICJDYXZpdHkgc3RyZWFtd2lzZSBsZW5ndGggKMK1bSkiLAogICAgICAgICAgICAgICAgICAgZGVmYXVsdD0xNTAwLjApCiAgICAgICAgc2VsZi5wYXJhbSgiVyIsIHNlbGYuVHlwZURvdWJsZSwgIkNhdml0eSBsYXRlcmFsIHdpZHRoICjCtW0pIiwKICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ9MTIwMC4wKQoKICAgICAgICAjIOKUgOKUgCBQaXRjaCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgICBzZWxmLnBhcmFtKCJEZWx0YV94Iiwgc2VsZi5UeXBlRG91YmxlLAogICAgICAgICAgICAgICAgICAgIs6UeCDigJQgc3RyZWFtd2lzZSBwaXRjaCAowrVtKSAgPSAgbF90cmFwICsgZ2FwX3giLCBkZWZhdWx0PTQwLjApCiAgICAgICAgc2VsZi5wYXJhbSgiRGVsdGFfeSIsIHNlbGYuVHlwZURvdWJsZSwKICAgICAgICAgICAgICAgICAgICLOlHkg4oCUIGxhdGVyYWwgcGl0Y2ggKMK1bSkgID0gIHdfdHJhcCArIGdhcF95IiwgZGVmYXVsdD0zNS4wKQogICAgICAgIHNlbGYucGFyYW0oIm1hcmdpbl94Iiwgc2VsZi5UeXBlRG91YmxlLAogICAgICAgICAgICAgICAgICAgIlN0cmVhbXdpc2Ugd2FsbCBtYXJnaW4gKMK1bSkgIFswID0gzpR5LzJdIiwgZGVmYXVsdD0wLjApCiAgICAgICAgc2VsZi5wYXJhbSgibWFyZ2luX3kiLCBzZWxmLlR5cGVEb3VibGUsCiAgICAgICAgICAgICAgICAgICAiTGF0ZXJhbCB3YWxsIG1hcmdpbiAowrVtKSAgWzAgPSDOlHkvMl0iLCBkZWZhdWx0PTAuMCkKCiAgICAgICAgIyDilIDilIAgVHJhcCBzaGFwZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgICBzZWxmLnBhcmFtKCJsX3RyYXAiLCAgIHNlbGYuVHlwZURvdWJsZSwgImxfdHJhcCDigJQgc3RyZWFtd2lzZSBsZW5ndGggKMK1bSkiLCAgZGVmYXVsdD0zMC4wKQogICAgICAgIHNlbGYucGFyYW0oIndfdHJhcCIsICAgc2VsZi5UeXBlRG91YmxlLCAid190cmFwIOKAlCBsYXRlcmFsIG91dGVyIHdpZHRoICjCtW0pIiwgZGVmYXVsdD0yNS4wKQogICAgICAgIHNlbGYucGFyYW0oIndhbGxfdCIsICAgc2VsZi5UeXBlRG91YmxlLCAid2FsbF90IOKAlCBwaWxsYXIgdGhpY2tuZXNzICjCtW0pIiwgICAgZGVmYXVsdD0zLjApCiAgICAgICAgc2VsZi5wYXJhbSgiYmFzZV90IiwgICBzZWxmLlR5cGVEb3VibGUsICJiYXNlX3Qg4oCUIGJhc2UgYmFyIGRlcHRoICjCtW0pIiwgICAgICBkZWZhdWx0PTQuMCkKICAgICAgICBzZWxmLnBhcmFtKCJ3X29fZG93biIsIHNlbGYuVHlwZURvdWJsZSwgIndfb19kb3duIOKAlCBkb3duc3RyZWFtIHNsaXQgKMK1bSkiLCAgIGRlZmF1bHQ9OC4wKQoKICAgICAgICAjIOKUgOKUgCBJTyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgICBzZWxmLnBhcmFtKCJpb19tb2RlIiwgc2VsZi5UeXBlU3RyaW5nLAogICAgICAgICAgICAgICAgICAgIklPIG1vZGU6ICdkaXJlY3QnIG9yICdkaXZlcmdpbmcnIiwgZGVmYXVsdD0iZGlyZWN0IikKICAgICAgICBzZWxmLnBhcmFtKCJDIiwgc2VsZi5UeXBlRG91YmxlLAogICAgICAgICAgICAgICAgICAgIkNlbnRyaW5nIEMgWzDigJMxXSAoZGlyZWN0IG1vZGUgb25seSkgIDE9YWxpZ25lZCIsIGRlZmF1bHQ9MS4wKQogICAgICAgIHNlbGYucGFyYW0oIndfaW8iLCAgICAgICAgc2VsZi5UeXBlRG91YmxlLCAiQ2hhbm5lbCB3aWR0aCAowrVtKSIsICAgICAgICAgICAgIGRlZmF1bHQ9MTAwLjApCiAgICAgICAgc2VsZi5wYXJhbSgiY2hhbm5lbF9sZW4iLCBzZWxmLlR5cGVEb3VibGUsICJTdHViIGxlbmd0aCBvdXRzaWRlIGNoaXAgKMK1bSkiLCAgZGVmYXVsdD0xMDAuMCkKICAgICAgICBzZWxmLnBhcmFtKCJsX2RpdiIsICAgICAgIHNlbGYuVHlwZURvdWJsZSwgIkRpdmVyZ2luZyBzZWN0aW9uIGxlbmd0aCAowrVtKSIsICBkZWZhdWx0PTIwMC4wKQoKICAgICAgICAjIOKUgOKUgCBEaXNvcmRlciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgICBzZWxmLnBhcmFtKCJEX2YiLCAgICAgICAgICAgc2VsZi5UeXBlRG91YmxlLCAiRGlzb3JkZXIgZmFjdG9yIERfZiBbMOKAkzFdIiwgICAgZGVmYXVsdD0wLjApCiAgICAgICAgc2VsZi5wYXJhbSgiZGlzb3JkZXJfdHlwZSIsIHNlbGYuVHlwZVN0cmluZywKICAgICAgICAgICAgICAgICAgICJEaXNvcmRlciB0eXBlOiAndW5pZm9ybScgb3IgJ2dhdXNzaWFuJyIsIGRlZmF1bHQ9InVuaWZvcm0iKQogICAgICAgIHNlbGYucGFyYW0oInNlZWQiLCBzZWxmLlR5cGVJbnQsICJSYW5kb20gc2VlZCAoMCA9IHJhbmRvbSkiLCBkZWZhdWx0PTQyKQoKICAgICAgICAjIOKUgOKUgCBMYXllciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgICBzZWxmLnBhcmFtKCJsYXllciIsIHNlbGYuVHlwZUxheWVyLCAiR0RTIGxheWVyIiwgZGVmYXVsdD1weWEuTGF5ZXJJbmZvKDEsIDApKQoKICAgIGRlZiBkaXNwbGF5X3RleHRfaW1wbChzZWxmKToKICAgICAgICByZXR1cm4gKGYiVHJhcEFycmF5X0IgIM6UeD17c2VsZi5EZWx0YV94fSDOlHk9e3NlbGYuRGVsdGFfeX0iCiAgICAgICAgICAgICAgICBmIiAge3NlbGYuaW9fbW9kZX0iKQoKICAgIGRlZiBjb2VyY2VfcGFyYW1ldGVyc19pbXBsKHNlbGYpOgogICAgICAgIGlmIHNlbGYuRGVsdGFfeCA8PSAwOiBzZWxmLkRlbHRhX3ggPSAxLjAKICAgICAgICBpZiBzZWxmLkRlbHRhX3kgPD0gMDogc2VsZi5EZWx0YV95ID0gMS4wCiAgICAgICAgc2VsZi5DICAgPSBtYXgoMC4wLCBtaW4oMS4wLCBzZWxmLkMpKQogICAgICAgIHNlbGYuRF9mID0gbWF4KDAuMCwgbWluKDEuMCwgc2VsZi5EX2YpKQoKICAgIGRlZiBwcm9kdWNlX2ltcGwoc2VsZik6CiAgICAgICAgbGF5ZXIgPSBfbGF5ZXJfaW5kZXgoc2VsZi5sYXlvdXQsIHNlbGYubGF5ZXIpCiAgICAgICAgbXhiICAgPSBzZWxmLm1hcmdpbl94IGlmIHNlbGYubWFyZ2luX3ggPiAwIGVsc2UgTm9uZQogICAgICAgIG15YiAgID0gc2VsZi5tYXJnaW5feSBpZiBzZWxmLm1hcmdpbl95ID4gMCBlbHNlIE5vbmUKICAgICAgICBzZWVkICA9IHNlbGYuc2VlZCBpZiBzZWxmLnNlZWQgPiAwIGVsc2UgTm9uZQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGdyaWQsIGJ1aWxkZXIgPSBtYWtlX21heF90cmFwcygKICAgICAgICAgICAgICAgIEw9c2VsZi5MLCBXPXNlbGYuVywKICAgICAgICAgICAgICAgIERlbHRhX3g9c2VsZi5EZWx0YV94LCBEZWx0YV95PXNlbGYuRGVsdGFfeSwKICAgICAgICAgICAgICAgIG1hcmdpbl94PW14YiwgbWFyZ2luX3k9bXliLAogICAgICAgICAgICAgICAgbF90cmFwPXNlbGYubF90cmFwLCB3X3RyYXA9c2VsZi53X3RyYXAsCiAgICAgICAgICAgICAgICB3YWxsX3Q9c2VsZi53YWxsX3QsIGJhc2VfdD1zZWxmLmJhc2VfdCwKICAgICAgICAgICAgICAgIHdfb19kb3duPXNlbGYud19vX2Rvd24sCiAgICAgICAgICAgICAgICBpb19tb2RlPXNlbGYuaW9fbW9kZSwgQz1zZWxmLkMsCiAgICAgICAgICAgICAgICB3X2lvPXNlbGYud19pbywgY2hhbm5lbF9sZW49c2VsZi5jaGFubmVsX2xlbiwKICAgICAgICAgICAgICAgIGxfZGl2PXNlbGYubF9kaXYsCiAgICAgICAgICAgICAgICBEX2Y9c2VsZi5EX2YsIGRpc29yZGVyX3R5cGU9c2VsZi5kaXNvcmRlcl90eXBlLAogICAgICAgICAgICAgICAgc2VlZD1zZWVkLAogICAgICAgICAgICApCiAgICAgICAgZXhjZXB0IChWYWx1ZUVycm9yLCBUeXBlRXJyb3IpIGFzIGV4YzoKICAgICAgICAgICAgX2RyYXdfZXJyb3JfbWFya2VyKHNlbGYuY2VsbCwgbGF5ZXIsIHNlbGYubGF5b3V0LmRidSwgc3RyKGV4YykpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBidWlsZGVyLmJ1aWxkX2ludG8oc2VsZi5jZWxsLCBsYXllcikKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEVycm9yIG1hcmtlciAoZHJhd24gd2hlbiBwYXJhbWV0ZXJzIGFyZSBpbnZhbGlkKQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKZGVmIF9kcmF3X2Vycm9yX21hcmtlcihjZWxsLCBsYXllciwgZGJ1LCBtZXNzYWdlKToKICAgICIiIkRyYXcgYSAxMDDDlzEwMCDCtW0gY3Jvc3Mgc28gdGhlIHVzZXIgc2VlcyBzb21ldGhpbmcgd2VudCB3cm9uZy4iIiIKICAgIGN2dCA9IGxhbWJkYSB2OiBpbnQocm91bmQodiAvIGRidSkpCiAgICBzaXplID0gMTAwCiAgICB0ICAgID0gNQogICAgcHRzX2ggPSBbCiAgICAgICAgcHlhLlBvaW50KGN2dCgtc2l6ZS8vMiksIGN2dCgtdC8vMikpLAogICAgICAgIHB5YS5Qb2ludChjdnQoIHNpemUvLzIpLCBjdnQoLXQvLzIpKSwKICAgICAgICBweWEuUG9pbnQoY3Z0KCBzaXplLy8yKSwgY3Z0KCB0Ly8yKSksCiAgICAgICAgcHlhLlBvaW50KGN2dCgtc2l6ZS8vMiksIGN2dCggdC8vMikpLAogICAgXQogICAgcHRzX3YgPSBbCiAgICAgICAgcHlhLlBvaW50KGN2dCgtdC8vMiksIGN2dCgtc2l6ZS8vMikpLAogICAgICAgIHB5YS5Qb2ludChjdnQoIHQvLzIpLCBjdnQoLXNpemUvLzIpKSwKICAgICAgICBweWEuUG9pbnQoY3Z0KCB0Ly8yKSwgY3Z0KCBzaXplLy8yKSksCiAgICAgICAgcHlhLlBvaW50KGN2dCgtdC8vMiksIGN2dCggc2l6ZS8vMikpLAogICAgXQogICAgY2VsbC5zaGFwZXMobGF5ZXIpLmluc2VydChweWEuUG9seWdvbihwdHNfaCkpCiAgICBjZWxsLnNoYXBlcyhsYXllcikuaW5zZXJ0KHB5YS5Qb2x5Z29uKHB0c192KSkKICAgIHByaW50KGYiW1RyYXBBcnJheV0gUGFyYW1ldGVyIGVycm9yOiB7bWVzc2FnZX0iKQoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgTGlicmFyeSByZWdpc3RyYXRpb24KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmNsYXNzIFRyYXBwaW5nQXJyYXlMaWJyYXJ5KHB5YS5MaWJyYXJ5KToKCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygpCiAgICAgICAgc2VsZi5kZXNjcmlwdGlvbiA9ICJNaWNyb2ZsdWlkaWMgdHJhcHBpbmcgYXJyYXlzIChSdXlzc2VuIGV0IGFsLiAyMDI1KSIKICAgICAgICBzZWxmLmxheW91dCgpLnJlZ2lzdGVyX3BjZWxsKCJUcmFwQXJyYXlfQSDigJQgRml4ZWQgZ3JpZCIsICAgVHJhcEFycmF5QSgpKQogICAgICAgIHNlbGYubGF5b3V0KCkucmVnaXN0ZXJfcGNlbGwoIlRyYXBBcnJheV9CIOKAlCBNYXggdHJhcHMiLCAgICBUcmFwQXJyYXlCKCkpCiAgICAgICAgc2VsZi5yZWdpc3RlcigiVHJhcHBpbmcgQXJyYXkiKQoKCiMgSW5zdGFudGlhdGUg4oCUIHRoaXMgcmVnaXN0ZXJzIHRoZSBsaWJyYXJ5IHdpdGggS0xheW91dApfbGliX2luc3RhbmNlID0gVHJhcHBpbmdBcnJheUxpYnJhcnkoKQo=').decode(),
}
_D = {
'core/__init__.py': os.path.join(_core, '__init__.py'),
'core/grid.py': os.path.join(_core, 'grid.py'),
'core/builder.py': os.path.join(_core, 'builder.py'),
'core/primitives.py': os.path.join(_core, 'primitives.py'),
'core/io_shapes.py': os.path.join(_core, 'io_shapes.py'),
'trapping_array_lib.py': os.path.join(_pkg, 'trapping_array_lib.py'),
}
for _k, _v in _D.items():
with open(_v, "w", encoding="utf-8") as _f:
_f.write(_M[_k])
if _pkg not in sys.path:
sys.path.insert(0, _pkg)
import trapping_array_lib as _tlib
importlib.reload(_tlib)
</text>
</klayout-macro>