diff options
author | Kali Kaneko <kali@leap.se> | 2018-02-27 01:52:59 +0100 |
---|---|---|
committer | Kali Kaneko <kali@leap.se> | 2018-03-02 03:54:14 +0100 |
commit | 031a2044a77153b6c2a3e111de17827c8395ea1e (patch) | |
tree | 3c013eb9d03366630aa04fe98cee78ae90ba79b0 | |
parent | c9fbec21b700c25d35a03b12df1adbb65f67ff12 (diff) |
[pkg] install helpers from snap
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | pkg/riseupvpn/Makefile | 5 | ||||
-rw-r--r-- | pkg/riseupvpn/TODO | 5 | ||||
-rwxr-xr-x | pkg/riseupvpn/pack_installers | 35 | ||||
-rw-r--r-- | pkg/riseupvpn/snap/gui/riseup-vpn.desktop | 14 | ||||
-rw-r--r-- | pkg/riseupvpn/snap/gui/riseupvpn.svg | 80 | ||||
-rwxr-xr-x | pkg/riseupvpn/snap/hooks/install | 648 | ||||
-rwxr-xr-x | pkg/riseupvpn/snap/hooks/remove | 7 | ||||
-rw-r--r-- | pkg/riseupvpn/snap/snapcraft.yaml | 16 |
9 files changed, 803 insertions, 9 deletions
@@ -73,7 +73,7 @@ test_functional_graphical_wip: install_helpers: # if there's no sudo, assumming this is running as root by the CI test -f $(SUDO) && sudo cp $(BITMASK_ROOT) /usr/local/sbin/ || cp $(BITMASK_ROOT) /usr/local/sbin/ - test -f $(SUDO) && sudo cp $(POLKIT_POLICY) /usr/share/polkit-1/actions/se.bitmask.bundle.policy || cp $(POLKIT_POLICY) /usr/share/polkit-1/actions/se.bitmask.bundle.policy + test -f $(SUDO) && sudo cp $(POLKIT_POLICY) /usr/share/polkit-1/actions/se.leap.bitmask.bundle.policy || cp $(POLKIT_POLICY) /usr/share/polkit-1/actions/se.leap.bitmask.bundle.policy install_pixelated: pip install leap.pixelated leap.pixelated-www diff --git a/pkg/riseupvpn/Makefile b/pkg/riseupvpn/Makefile index 47985e28..ab2b7793 100644 --- a/pkg/riseupvpn/Makefile +++ b/pkg/riseupvpn/Makefile @@ -1,4 +1,5 @@ -build: +build: installers + # for speeding up build, see https://tribaal.io/making-lxd-fly-on-ubuntu-as-well.html sudo snapcraft cleanbuild install: sudo snap install riseup-vpn_*.snap --dangerous --classic @@ -6,3 +7,5 @@ uninstall: sudo snap remove riseup-vpn init-lxd: sudo lxd init +installers: + ./pack_installers diff --git a/pkg/riseupvpn/TODO b/pkg/riseupvpn/TODO index 2288e7e4..ac310d66 100644 --- a/pkg/riseupvpn/TODO +++ b/pkg/riseupvpn/TODO @@ -1,4 +1,5 @@ -[ ] copy libzmq.so.5 library to the binary path (HACK, ask in forums). [ ] install polkit helpers [ ] install bitmask root in its place (can classic confinement install something in the global path? does this produce conflicts with proper debs?) -[ ] add a desktop file entry +[x] add icon +[x] add a desktop file entry +[x] copy libzmq.so.5 library to the binary path (HACK, ask in forums). diff --git a/pkg/riseupvpn/pack_installers b/pkg/riseupvpn/pack_installers new file mode 100755 index 00000000..693a9543 --- /dev/null +++ b/pkg/riseupvpn/pack_installers @@ -0,0 +1,35 @@ +#!/usr/bin/env python +import os +import subprocess +from base64 import encodestring as encode +HELPDIR = '../../src/leap/bitmask/vpn/helpers/linux/' +INSTALL = './snap/hooks/install' + +with open(os.path.join(HELPDIR, 'bitmask-root')) as bmroot: + b64_bmroot = encode(bmroot.read()) + +with open(os.path.join(HELPDIR, 'se.leap.bitmask.bundle.policy')) as polkit: + b64_polkit = encode(polkit.read()) + +with open(INSTALL, 'w') as install: + install.write('#!/usr/bin/env python\n') + install.write('# This helper installs bitmask-root and polkit policy file\n') + install.write('import subprocess\n') + install.write('from base64 import decodestring as decode\n') + install.write(""" +BMROOT = \"\"\"{bmroot}\"\"\" +POLKIT = \"\"\"{polkit}\"\"\" +BMROOT_DEST = "/usr/local/sbin/bitmask-root" +with open(BMROOT_DEST, "w") as bmroot: + lines = str(decode(BMROOT)).split("\\n") + for line in lines: + bmroot.write(line + "\\n") +with open('/usr/share/polkit-1/actions/se.leap.bitmask.bundle.policy', 'w') as polkit: + lines = str(decode(POLKIT)).split("\\n") + for line in lines: + polkit.write(line + "\\n") +""".format(bmroot=b64_bmroot, polkit=b64_polkit)) + install.write('subprocess.Popen(["chmod", "+x", BMROOT_DEST])\n') + +subprocess.Popen(["chmod", "+x", INSTALL]) +print("done packing installers") diff --git a/pkg/riseupvpn/snap/gui/riseup-vpn.desktop b/pkg/riseupvpn/snap/gui/riseup-vpn.desktop new file mode 100644 index 00000000..1d586e74 --- /dev/null +++ b/pkg/riseupvpn/snap/gui/riseup-vpn.desktop @@ -0,0 +1,14 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=RiseupVPN +Comment=Anonymous VPN +Comment[es]=VPN Anonima +Comment[de]=Secure Communication +Exec=/snap/bin/riseup-vpn.launcher +Terminal=false +Icon=riseup-vpn +Categories=Network;Application; +StartupNotify=true +Keywords=VPN;riseup;leap + diff --git a/pkg/riseupvpn/snap/gui/riseupvpn.svg b/pkg/riseupvpn/snap/gui/riseupvpn.svg new file mode 100644 index 00000000..a19c6c61 --- /dev/null +++ b/pkg/riseupvpn/snap/gui/riseupvpn.svg @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="128" + height="128" + viewBox="0 0 33.866666 33.866668" + version="1.1" + id="svg896" + inkscape:version="0.92.2 (5c3e80d, 2017-08-06)" + sodipodi:docname="riseupvpn-launcher.svg"> + <defs + id="defs890" /> + <sodipodi:namedview + id="base" + pagecolor="#d7d7d7" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:zoom="5.12" + inkscape:cx="26.899914" + inkscape:cy="56.22909" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + units="px" + inkscape:window-width="1869" + inkscape:window-height="1025" + inkscape:window-x="51" + inkscape:window-y="27" + inkscape:window-maximized="1"> + <inkscape:grid + type="xygrid" + id="grid1471" + empspacing="4" /> + </sodipodi:namedview> + <metadata + id="metadata893"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-263.13332)"> + <path + style="fill:#006cb2;fill-opacity:1;stroke-width:0.26458335" + d="M 15.617988,295.66418 C 9.9401302,292.50672 5.6959906,287.52131 4.7342129,282.87951 4.4622971,281.56718 4.4516145,281.24899 4.4519256,274.47112 l 2.394e-4,-6.47461 0.5616386,-0.36177 c 2.3734615,-1.52883 4.8841786,-2.55103 7.4419094,-3.06699 5.221864,-1.05337 10.639669,0.003 15.485448,3.16684 l 0.398232,0.25998 v 6.50684 c 0,6.8044 -0.01093,7.13134 -0.280843,8.43104 -0.956329,4.6043 -4.632206,9.09553 -10.057782,12.28874 -1.576255,0.9277 -1.527525,0.91863 -2.382844,0.44299 z" + id="path5137" + inkscape:connector-curvature="0" + sodipodi:nodetypes="csccssscssscc" /> + <path + inkscape:connector-curvature="0" + style="fill:#007cc3;fill-opacity:1;stroke-width:0.26458335" + d="m 16.396917,264.17336 c -1.317958,-4.7e-4 -2.635612,0.13103 -3.941076,0.39437 -2.5577318,0.51596 -5.068528,1.53812 -7.4419895,3.06696 l -0.5615828,0.36177 -4.707e-4,6.47466 c -2.394e-4,6.77787 0.010371,7.096 0.2822554,8.40832 0.9617776,4.64181 5.2059168,9.62724 10.8837756,12.7847 h 1.19e-4 c 0.368953,0.20517 0.569745,0.32326 0.805249,0.31706 v -31.80747 c -0.0088,-2e-5 -0.01755,-4.8e-4 -0.02641,-4.8e-4 z" + id="path887" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458338" + d="m 16.989143,272.54844 c 0,0 -0.315707,-0.61165 -0.336761,-0.69601 -0.02106,-0.0844 -0.189431,-0.94909 -0.189431,-0.94909 l 0.210485,-0.37963 0.463046,-0.696 0.673531,-0.52727 0.168377,-0.0633 1.620684,-0.61164 0.147331,-0.14764 -0.168385,-0.25308 -0.231523,-0.12655 -0.424879,-0.10907 -1.064407,-0.10907 -0.825967,0.007 -0.568293,0.12654 -0.505146,-0.18981 -0.63143,-0.0844 -0.9261,-0.0211 -0.463054,-0.0211 -0.778761,0.29527 -1.178677,1.37091 -0.147339,0.52727 -0.08418,0.464 -0.399908,0.86473 -0.252577,0.82254 -0.126285,0.88582 v 0.18982 l -0.610384,0.92799 -0.336761,0.69601 v 0.99126 l 0.10523,2.04581 0.189431,0.73821 0.378861,0.6749 0.4841,0.44292 0.210477,0.8647 0.799815,1.77155 0.947154,1.13886 0.06311,0.0633 0.336761,1.70835 -1.157623,2.10911 -0.363408,0.28169 -0.272426,0.22054 -0.467179,-0.0129 -0.260603,0.13452 -0.316122,0.0134 -0.190994,0.19047 -0.408963,-0.0616 -0.4044091,-0.0196 -0.311982,0.24606 -0.044916,0.36556 0.207365,-0.23472 0.3488649,-0.10158 0.03654,0.33552 0.5512672,-0.18726 0.316122,-0.0134 0.557721,0.0667 c 0,0 0.483518,-0.0316 0.567216,-0.0407 0.0837,-0.009 0.597276,0.0411 0.597276,0.0411 l 0.376644,-0.041 0.199723,0.0844 0.267456,-0.0716 0.290265,0.13818 0.418488,-0.0455 0.05401,-0.28169 -0.01596,-0.14678 0.28571,0.0962 0.232049,0.18692 0.150642,0.21701 -0.0088,-0.27495 -0.182953,-0.31946 c 0,0 -0.125159,-0.17737 -0.208857,-0.16824 -0.0837,0.009 -0.408971,-0.0616 -0.408971,-0.0616 l -0.223321,0.088 -0.243857,-0.10085 -0.239677,0.13226 -0.220665,-0.0822 -0.106491,-0.20049 -0.153322,-0.0471 0.164763,-0.42962 0.378861,-0.52859 0.505146,-0.84364 0.442,-0.5273 0.168385,-0.21088 c 0,0 0.210477,-0.31633 0.210477,-0.40071 0,-0.0844 0.04212,-0.97016 0.04212,-0.97016 l -0.273623,-0.56947 -0.126285,-0.46402 2.441546,0.59059 h 0.147331 l 2.083731,1.49744 0.294669,0.37959 0.10523,1.49729 -0.04212,0.33746 -0.147338,0.27419 -0.105358,0.16875 -0.09101,0.23675 -0.06215,0.1583 -0.386712,0.11988 -0.393086,-0.0709 -0.238209,-0.0294 -0.437428,0.0633 -0.184118,0.19713 -0.07084,0.24475 0.05712,0.24744 0.09172,-0.24769 0.124641,-0.16724 0.121984,-0.0388 0.0094,0.21174 0.163957,0.10406 0.338995,-0.15563 0.166646,-0.0242 0.05409,0.22658 0.508999,-0.01 0.345035,-0.11394 0.282886,0.0443 0.410893,0.047 0.142823,-0.0417 0.112881,-0.10156 0.182442,0.37841 0.0024,-0.42654 -0.176722,-0.48581 -0.256358,-0.15463 0.04324,-0.12712 -0.189423,-0.35849 0.02106,-1.37079 1.052392,1.2444 1.389154,1.09674 c 0,0 0.947146,0.33749 1.03133,0.33749 0.08419,0 0.736677,-0.0844 0.736677,-0.0844 l 0.420954,-0.69598 -0.315715,-0.94908 0.126284,-0.31642 -0.673531,-0.88574 -1.426794,-1.45279 -0.341213,-1.14141 0.02106,-0.78037 -0.315707,-0.82257 -0.357816,-0.65376 0.210477,-0.65377 -0.168377,-0.94904 -0.717785,-1.61568 0.265151,-0.0448 -0.444984,-0.77034 0.289101,-0.0918 -0.508218,-0.82847 0.213764,-0.11524 -0.380944,-0.62543 0.124202,-0.0696 -0.460971,-0.37337 0.168384,-0.0875 -1.199723,-0.84051 z" + id="path5892" + inkscape:connector-curvature="0" + sodipodi:nodetypes="csccccccccccccccccccccccccccccccccccccccccccccccccccccccscccccccccccccsccccccccccccscccccccccccccccccccccccccccccccccccccccccccscccccccccccccccccccccccc" /> + </g> +</svg> diff --git a/pkg/riseupvpn/snap/hooks/install b/pkg/riseupvpn/snap/hooks/install new file mode 100755 index 00000000..6d8a9d03 --- /dev/null +++ b/pkg/riseupvpn/snap/hooks/install @@ -0,0 +1,648 @@ +#!/usr/bin/env python +# This helper installs bitmask-root and polkit policy file +import subprocess +from base64 import decodestring as decode + +BMROOT = """IyEvdXNyL2Jpbi9weXRob24yLjcKIyAtKi0gY29kaW5nOiB1dGYtOCAtKi0KIwojIENvcHlyaWdo +dCAoQykgMjAxNCBMRUFQCiMKIyBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNh +biByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQojIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0 +aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiMgdGhlIEZyZWUg +U29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IK +IyAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgojCiMgVGhpcyBwcm9ncmFtIGlz +IGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiMgYnV0IFdJ +VEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YK +IyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBT +ZWUgdGhlCiMgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KIwoj +IFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1Ymxp +YyBMaWNlbnNlCiMgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uICBJZiBub3QsIHNlZSA8aHR0cDov +L3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uCiMKIiIiClRoaXMgaXMgYSBwcml2aWxlZ2VkIGhlbHBl +ciBzY3JpcHQgZm9yIHNhZmVseSBydW5uaW5nIGNlcnRhaW4gY29tbWFuZHMgYXMgcm9vdC4KSXQg +c2hvdWxkIG9ubHkgYmUgY2FsbGVkIGJ5IHRoZSBCaXRtYXNrIGFwcGxpY2F0aW9uLgoKRXhwZWN0 +ZWQgcGF0aHM6CgogIFdoZW4gaW5zdGFsbGVkIGJ5IGRpc3RybyBwYXRoOgogICAgL3Vzci9zYmlu +L2JpdG1hc2stcm9vdAoKICBXaGVuIGluc3RhbGxlZCBieSBidW5kbGUgb3IgZnJvbSBnaXQ6CiAg +ICAvdXNyL2xvY2FsL3NiaW4vYml0bWFzay1yb290CgpVU0FHRToKICBiaXRtYXNrLXJvb3QgZmly +ZXdhbGwgc3RvcAogIGJpdG1hc2stcm9vdCBmaXJld2FsbCBzdGFydCBbcmVzdGFydF0gR0FURVdB +WTEgR0FURVdBWTIgLi4uCiAgYml0bWFzay1yb290IG9wZW52cG4gc3RvcAogIGJpdG1hc2stcm9v +dCBvcGVudnBuIHN0YXJ0IENPTkZJRzEgQ09ORklHMSAuLi4KICBiaXRtYXNrLXJvb3QgZnctZW1h +aWwgc3RvcAogIGJpdG1hc2stcm9vdCBmdy1lbWFpbCBzdGFydCB1aWQKCkFsbCBhY3Rpb25zIHJl +dHVybiBleGl0IGNvZGUgMCBmb3Igc3VjY2Vzcywgbm9uLXplcm8gb3RoZXJ3aXNlLgoKVGhlIGBv +cGVudnBuIHN0YXJ0YCBhY3Rpb24gaXMgc3BlY2lhbDogaXQgY2FsbHMgZXhlYyBvbiBvcGVudnBu +IGFuZCByZXBsYWNlcwp0aGUgY3VycmVudCBwcm9jZXNzLiBJZiB0aGUgYHJlc3RhcnRgIHBhcmFt +ZXRlciBpcyBwYXNzZWQsIHRoZSBmaXJld2FsbCB3aWxsCm5vdCBiZSB0ZWFyZWQgZG93biBpbiB0 +aGUgY2FzZSBvZiBhbiBlcnJvciBkdXJpbmcgbGF1bmNoLgoiIiIKIyBUT0RPIHNob3VsZCBiZSB0 +ZXN0ZWQgd2l0aCBweXRob24zLCB3aGljaCBjYW4gYmUgdGhlIGRlZmF1bHQgb24gc29tZSBkaXN0 +cm8uCmZyb20gX19mdXR1cmVfXyBpbXBvcnQgcHJpbnRfZnVuY3Rpb24KaW1wb3J0IG9zCmltcG9y +dCByZQppbXBvcnQgc2lnbmFsCmltcG9ydCBzb2NrZXQKaW1wb3J0IHN5c2xvZwppbXBvcnQgc3Vi +cHJvY2VzcwppbXBvcnQgc3lzCmltcG9ydCBzdGF0CmltcG9ydCB0cmFjZWJhY2sKCmNtZGNoZWNr +ID0gc3VicHJvY2Vzcy5jaGVja19vdXRwdXQKCiMKIyBDT05TVEFOVFMKIwoKCmRlZiBnZXRfbm9f +Z3JvdXBfbmFtZSgpOgogICAgIiIiCiAgICBSZXR1cm4gdGhlIHJpZ2h0IGdyb3VwIG5hbWUgdG8g +dXNlIGZvciB0aGUgY3VycmVudCBPUy4KICAgIEV4YW1wbGVzOgogICAgICAgIC0gVWJ1bnR1OiBu +b2dyb3VwCiAgICAgICAgLSBBcmNoOiBub2JvZHkKCiAgICA6cnR5cGU6IHN0ciBvciBOb25lCiAg +ICAiIiIKICAgIGltcG9ydCBncnAKICAgIHRyeToKICAgICAgICBncnAuZ2V0Z3JuYW0oJ25vYm9k +eScpCiAgICAgICAgcmV0dXJuICdub2JvZHknCiAgICBleGNlcHQgS2V5RXJyb3I6CiAgICAgICAg +dHJ5OgogICAgICAgICAgICBncnAuZ2V0Z3JuYW0oJ25vZ3JvdXAnKQogICAgICAgICAgICByZXR1 +cm4gJ25vZ3JvdXAnCiAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICByZXR1cm4g +Tm9uZQoKClZFUlNJT04gPSAiOCIKU0NSSVBUID0gImJpdG1hc2stcm9vdCIKTkFNRVNFUlZFUl9U +Q1AgPSAiMTAuNDEuMC4xIgpOQU1FU0VSVkVSX1VEUCA9ICIxMC40Mi4wLjEiCiMgZm9yIHRoZSB0 +aW1lIGJlaW5nLCB3ZSdyZSBoYXJkY29kaW5nIHRjcCBvbiBjb25uZWN0aW9uIHBhcmFtcy4KTkFN +RVNFUlZFUiA9IE5BTUVTRVJWRVJfVENQCkJJVE1BU0tfQ0hBSU4gPSAiYml0bWFzayIKQklUTUFT +S19DSEFJTl9OQVRfT1VUID0gImJpdG1hc2siCkJJVE1BU0tfQ0hBSU5fTkFUX1BPU1QgPSAiYml0 +bWFza19wb3N0cm91dGluZyIKQklUTUFTS19DSEFJTl9FTUFJTCA9ICJiaXRtYXNrX2VtYWlsIgpC +SVRNQVNLX0NIQUlOX0VNQUlMX09VVCA9ICJiaXRtYXNrX2VtYWlsX291dHB1dCIKTE9DQUxfSU5U +RVJGQUNFID0gImxvIgpJTUFQX1BPUlQgPSAiMTk4NCIKU01UUF9QT1JUID0gIjIwMTMiCgpJUCA9 +ICIvc2Jpbi9pcCIKSVBUQUJMRVMgPSAiL3NiaW4vaXB0YWJsZXMiCklQNlRBQkxFUyA9ICIvc2Jp +bi9pcDZ0YWJsZXMiCgpPUEVOVlBOX1VTRVIgPSAibm9ib2R5IgpPUEVOVlBOX0dST1VQID0gZ2V0 +X25vX2dyb3VwX25hbWUoKQpMRUFQT1BFTlZQTiA9ICJMRUFQT1BFTlZQTiIKT1BFTlZQTl9TWVNU +RU1fQklOID0gIi91c3Ivc2Jpbi9vcGVudnBuIiAgIyBEZWJpYW4gbG9jYXRpb24KT1BFTlZQTl9M +RUFQX0JJTiA9ICIvdXNyL2xvY2FsL3NiaW4vbGVhcC1vcGVudnBuIiAgIyBpbnN0YWxsZWQgYnkg +YnVuZGxlCgpGSVhFRF9GTEFHUyA9IFsKICAgICItLXNldGVudiIsICJMRUFQT1BFTlZQTiIsICIx +IiwKICAgICItLW5vYmluZCIsCiAgICAiLS1jbGllbnQiLAogICAgIi0tZGV2IiwgInR1biIsCiAg +ICAiLS10bHMtY2xpZW50IiwKICAgICItLXJlbW90ZS1jZXJ0LXRscyIsICJzZXJ2ZXIiLAogICAg +Ii0tbWFuYWdlbWVudC1zaWduYWwiLAogICAgIi0tc2NyaXB0LXNlY3VyaXR5IiwgIjEiLAogICAg +Ii0tdXNlciIsICJub2JvZHkiLAogICAgIi0tcGVyc2lzdC1rZXkiLAogICAgIi0tcGVyc2lzdC1s +b2NhbC1pcCIsCl0KCmlmIE9QRU5WUE5fR1JPVVAgaXMgbm90IE5vbmU6CiAgICBGSVhFRF9GTEFH +Uy5leHRlbmQoWyItLWdyb3VwIiwgT1BFTlZQTl9HUk9VUF0pCgpBTExPV0VEX0ZMQUdTID0gewog +ICAgIi0tcmVtb3RlIjogWyJJUCIsICJOVU1CRVIiLCAiUFJPVE8iXSwKICAgICItLXRscy1jaXBo +ZXIiOiBbIkNJUEhFUiJdLAogICAgIi0tY2lwaGVyIjogWyJDSVBIRVIiXSwKICAgICItLWF1dGgi +OiBbIkNJUEhFUiJdLAogICAgIi0tbWFuYWdlbWVudCI6IFsiRElSIiwgIlVOSVhTT0NLRVQiXSwK +ICAgICItLW1hbmFnZW1lbnQtY2xpZW50LXVzZXIiOiBbIlVTRVIiXSwKICAgICItLWNlcnQiOiBb +IkZJTEUiXSwKICAgICItLWtleSI6IFsiRklMRSJdLAogICAgIi0tY2EiOiBbIkZJTEUiXSwKICAg +ICItLWZyYWdtZW50IjogWyJOVU1CRVIiXSwKICAgICItLWtlZXBhbGl2ZSI6IFsiTlVNQkVSIiwg +Ik5VTUJFUiJdLAogICAgIi0tdmVyYiI6IFsiTlVNQkVSIl0sCn0KClBBUkFNX0ZPUk1BVFMgPSB7 +CiAgICAiTlVNQkVSIjogbGFtYmRhIHM6IHJlLm1hdGNoKCJeXGQrJCIsIHMpLAogICAgIlBST1RP +IjogbGFtYmRhIHM6IHJlLm1hdGNoKCJeKHRjcHx1ZHB8dGNwNHx1ZHA0KSQiLCBzKSwKICAgICJJ +UCI6IGxhbWJkYSBzOiBpc192YWxpZF9hZGRyZXNzKHMpLAogICAgIkNJUEhFUiI6IGxhbWJkYSBz +OiByZS5tYXRjaCgiXltBLVowLTktXSskIiwgcyksCiAgICAiVVNFUiI6IGxhbWJkYSBzOiByZS5t +YXRjaCgKICAgICAgICAiXlthLXpBLVowLTlfXC5cQF1bYS16QS1aMC05X1wtXC5cQF0qXCQ/JCIs +IHMpLCAgIyBJRUVFIFN0ZCAxMDAzLjEtMjAwMQogICAgIkZJTEUiOiBsYW1iZGEgczogb3MucGF0 +aC5pc2ZpbGUocyksCiAgICAiRElSIjogbGFtYmRhIHM6IG9zLnBhdGguaXNkaXIob3MucGF0aC5z +cGxpdChzKVswXSksCiAgICAiVU5JWFNPQ0tFVCI6IGxhbWJkYSBzOiBzID09ICJ1bml4IiwKICAg +ICJVSUQiOiBsYW1iZGEgczogcmUubWF0Y2goIl5bYS16QS1aMC05XSskIiwgcykKfQoKIyBEZXRl +cm1pbmUgUXViZXMgT1MgdmVyc2lvbiwgaWYgYW55ClFVQkVTX1BST1hZID0gb3MucGF0aC5leGlz +dHMoIi92YXIvcnVuL3F1YmVzL3RoaXMtaXMtcHJveHl2bSIpCmlmIG9zLnBhdGguaXNkaXIoIi9l +dGMvcXViZXMiKToKICAgIFFVQkVTX0NGRyA9ICIvcncvY29uZmlnLyIKICAgIFFVQkVTX0lQSE9P +SyA9IFFVQkVTX0NGRyArICJxdWJlcy1pcC1jaGFuZ2UtaG9vayIKICAgIFFVQkVTX0ZXX1NDUklQ +VCA9IFFVQkVTX0NGRyArICJxdWJlcy1maXJld2FsbC11c2VyLXNjcmlwdCIKICAgIGlmIHN1YnBy +b2Nlc3MuY2FsbChbSVBUQUJMRVMsICItLWxpc3QiLCAiUUJTLUZPUldBUkQiXSkgPT0gMDoKICAg +ICAgICBRVUJFU19WRVIgPSA0CiAgICBlbHNlOgogICAgICAgIFFVQkVTX1ZFUiA9IDMKZWxzZToK +ICAgICMgbm90IGEgUXViZXMgc3lzdGVtCiAgICBRVUJFU19WRVIgPSAwCgoKREVCVUcgPSBvcy5n +ZXRlbnYoIkRFQlVHIikKVEVTVCA9IG9zLmdldGVudigiVEVTVCIpCgppZiBERUJVRzoKICAgIGlt +cG9ydCBsb2dnaW5nCiAgICBmb3JtYXR0ZXIgPSBsb2dnaW5nLkZvcm1hdHRlcigKICAgICAgICAi +JShhc2N0aW1lKXMgLSAlKG5hbWUpcyAtICUobGV2ZWxuYW1lKXMgLSAlKG1lc3NhZ2UpcyIpCiAg +ICBjaCA9IGxvZ2dpbmcuU3RyZWFtSGFuZGxlcigpCiAgICBjaC5zZXRMZXZlbChsb2dnaW5nLkRF +QlVHKQogICAgY2guc2V0Rm9ybWF0dGVyKGZvcm1hdHRlcikKICAgIGxvZ2dlciA9IGxvZ2dpbmcu +Z2V0TG9nZ2VyKF9fbmFtZV9fKQogICAgbG9nZ2VyLnNldExldmVsKGxvZ2dpbmcuREVCVUcpCiAg +ICBsb2dnZXIuYWRkSGFuZGxlcihjaCkKCnN5c2xvZy5vcGVubG9nKFNDUklQVCkKCiMKIyBVVElM +SVRZCiMKCgpkZWYgaXNfdmFsaWRfYWRkcmVzcyh2YWx1ZSk6CiAgICAiIiIKICAgIFZhbGlkYXRl +IHRoYXQgdGhlIHBhc3NlZCBpcCBpcyBhIHZhbGlkIElQIGFkZHJlc3MuCgogICAgOnBhcmFtIHZh +bHVlOiB0aGUgdmFsdWUgdG8gYmUgdmFsaWRhdGVkCiAgICA6dHlwZSB2YWx1ZTogc3RyCiAgICA6 +cnR5cGU6IGJvb2wKICAgICIiIgogICAgdHJ5OgogICAgICAgIHNvY2tldC5pbmV0X2F0b24odmFs +dWUpCiAgICAgICAgcmV0dXJuIFRydWUKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgbG9n +KCIlczogRVJST1I6IE1BTEZPUk1FRCBJUDogJXMhIiAlIChTQ1JJUFQsIHZhbHVlKSkKICAgICAg +ICByZXR1cm4gRmFsc2UKCgpkZWYgc3BsaXRfbGlzdChfbGlzdCwgcmVnZXgpOgogICAgIiIiCiAg +ICBTcGxpdCBhIGxpc3QgYmFzZWQgb24gYSByZWdleDoKICAgIGUuZy4gc3BsaXRfbGlzdChbInh4 +IiwgInl5IiwgIngxIiwgInp6Il0sICJeeCIpID0+IFtbInh4IiwgInl5Il0sIFsieDEiLAogICAg +Inp6Il1dCgogICAgOnBhcmFtIF9saXN0OiB0aGUgbGlzdCB0byBiZSBzcGxpdC4KICAgIDp0eXBl +IF9saXN0OiBsaXN0CiAgICA6cGFyYW0gcmVnZXg6IHRoZSByZWdleCBleHByZXNzaW9uIHRvIGZp +bHRlciB3aXRoLgogICAgOnR5cGUgcmVnZXg6IHN0cgoKICAgIDpydHlwZTogbGlzdAogICAgIiIi +CiAgICBpZiBub3QgaGFzYXR0cihyZWdleCwgIm1hdGNoIik6CiAgICAgICAgcmVnZXggPSByZS5j +b21waWxlKHJlZ2V4KQogICAgcmVzdWx0ID0gW10KICAgIGkgPSAwCiAgICBpZiBub3QgX2xpc3Q6 +CiAgICAgICAgcmV0dXJuIHJlc3VsdAogICAgd2hpbGUgVHJ1ZToKICAgICAgICBpZiByZWdleC5t +YXRjaChfbGlzdFtpXSk6CiAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoW10pCiAgICAgICAgICAg +IHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICByZXN1bHRbLTFdLmFwcGVuZChfbGlzdFtpXSkK +ICAgICAgICAgICAgICAgIGkgKz0gMQogICAgICAgICAgICAgICAgaWYgaSA+PSBsZW4oX2xpc3Qp +IG9yIHJlZ2V4Lm1hdGNoKF9saXN0W2ldKToKICAgICAgICAgICAgICAgICAgICBicmVhawogICAg +ICAgIGVsc2U6CiAgICAgICAgICAgIGkgKz0gMQogICAgICAgIGlmIGkgPj0gbGVuKF9saXN0KToK +ICAgICAgICAgICAgYnJlYWsKICAgIHJldHVybiByZXN1bHQKCgpkZWYgZ2V0X3Byb2Nlc3NfbGlz +dCgpOgogICAgIiIiCiAgICBHZXQgYSBwcm9jZXNzIGxpc3QgYnkgcmVhZGluZyBgL3Byb2NgIGZp +bGVzeXN0ZW0uCgogICAgOnJldHVybjogYSBsaXN0IG9mIHR1cGxlcywgZWFjaCBjb250YWluaW5n +IHBpZCBhbmQgY29tbWFuZCBzdHJpbmcuCiAgICA6cnR5cGU6IHR1cGxlIGlmIGxpc3RzCiAgICAi +IiIKICAgIHJlcyA9IFtdCiAgICBwaWRzID0gW3BpZCBmb3IgcGlkIGluIG9zLmxpc3RkaXIoJy9w +cm9jJykgaWYgcGlkLmlzZGlnaXQoKV0KCiAgICBmb3IgcGlkIGluIHBpZHM6CiAgICAgICAgdHJ5 +OgogICAgICAgICAgICByZXMuYXBwZW5kKChwaWQsIG9wZW4oCiAgICAgICAgICAgICAgICBvcy5w +YXRoLmpvaW4oCiAgICAgICAgICAgICAgICAgICAgJy9wcm9jJywgcGlkLCAnY21kbGluZScpLCAn +cmInKS5yZWFkKCkpKQogICAgICAgIGV4Y2VwdCBJT0Vycm9yOiAgIyBwcm9jIGhhcyBhbHJlYWR5 +IHRlcm1pbmF0ZWQKICAgICAgICAgICAgY29udGludWUKICAgIHJldHVybiBmaWx0ZXIoTm9uZSwg +cmVzKQoKCmRlZiBydW4oY29tbWFuZCwgKmFyZ3MsICoqb3B0aW9ucyk6CiAgICAiIiIKICAgIFJ1 +biBhbiBleHRlcm5hbCBjb21tYW5kLgoKICAgIE9wdGlvbnM6CgogICAgICBgY2hlY2tgOiBJZiBU +cnVlLCBjaGVjayB0aGUgY29tbWFuZCdzIG91dHB1dC4gYmFpbCBpZiBub24temVyby4gKHRoZQog +ICAgICAgICAgICAgICBkZWZhdWx0IGlzIHRydWUgdW5sZXNzIGRldGFjaCBvciBpbnB1dCBpcyB0 +cnVlKQogICAgICBgZXhpdGNvZGVgOiBsaWtlIGBjaGVja2AsIGJ1dCByZXR1cm4gZXhpdGNvZGUg +aW5zdGVhZCBvZiBiYWlsaW5nLgogICAgICBgZGV0YWNoYDogSWYgVHJ1ZSwgcnVuIGluIGRldGFj +aGVkIHByb2Nlc3MuCiAgICAgIGBpbnB1dGA6IElmIFRydWUsIG9wZW4gY29tbWFuZCBmb3Igd3Jp +dGluZyBzdHJlYW0gdG8sIHJldHVybmluZyB0aGUgUG9wZW4KICAgICAgICAgICAgICAgb2JqZWN0 +LgogICAgICBgdGhyb3dgOiBJZiBUcnVlLCByYWlzZSBhbiBleGNlcHRpb24gaWYgdGhlcmUgaXMg +YW4gZXJyb3IgaW5zdGVhZAogICAgICAgICAgICAgICBvZiBiYWlsaW5nLgogICAgIiIiCiAgICBw +YXJ0cyA9IFtjb21tYW5kXQogICAgcGFydHMuZXh0ZW5kKGFyZ3MpCiAgICBkZWJ1ZygiJXMgcnVu +OiAlcyAiICUgKFNDUklQVCwgIiAiLmpvaW4ocGFydHMpKSkKCiAgICBfY2hlY2sgPSBvcHRpb25z +LmdldCgiY2hlY2siLCBUcnVlKQogICAgX2RldGFjaCA9IG9wdGlvbnMuZ2V0KCJkZXRhY2giLCBG +YWxzZSkKICAgIF9pbnB1dCA9IG9wdGlvbnMuZ2V0KCJpbnB1dCIsIEZhbHNlKQogICAgX2V4aXRj +b2RlID0gb3B0aW9ucy5nZXQoImV4aXRjb2RlIiwgRmFsc2UpCiAgICBfdGhyb3cgPSBvcHRpb25z +LmdldCgidGhyb3ciLCBGYWxzZSkKCiAgICBpZiBub3QgKF9jaGVjayBvciBfdGhyb3cpIG9yIF9k +ZXRhY2ggb3IgX2lucHV0OgogICAgICAgIGlmIF9pbnB1dDoKICAgICAgICAgICAgcmV0dXJuIHN1 +YnByb2Nlc3MuUG9wZW4ocGFydHMsIHN0ZGluPXN1YnByb2Nlc3MuUElQRSkKICAgICAgICBlbHNl +OgogICAgICAgICAgICBzdWJwcm9jZXNzLlBvcGVuKHBhcnRzKQogICAgICAgICAgICByZXR1cm4g +Tm9uZQogICAgZWxzZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGRldm51bGwgPSBvcGVuKCcv +ZGV2L251bGwnLCAndycpCiAgICAgICAgICAgIHN1YnByb2Nlc3MuY2hlY2tfY2FsbChwYXJ0cywg +c3Rkb3V0PWRldm51bGwsIHN0ZGVycj1kZXZudWxsKQogICAgICAgICAgICByZXR1cm4gMAogICAg +ICAgIGV4Y2VwdCBzdWJwcm9jZXNzLkNhbGxlZFByb2Nlc3NFcnJvciBhcyBleGM6CiAgICAgICAg +ICAgIGlmIF9leGl0Y29kZToKICAgICAgICAgICAgICAgIGlmIGV4Yy5yZXR1cm5jb2RlICE9IDE6 +CiAgICAgICAgICAgICAgICAgICAgIyAwIG9yIDEgaXMgdG8gYmUgZXhwZWN0ZWQsIGJ1dCBhbnl0 +aGluZyBlbHNlCiAgICAgICAgICAgICAgICAgICAgIyBzaG91bGQgYmUgbG9nZ2VkLgogICAgICAg +ICAgICAgICAgICAgIGRlYnVnKCJFUlJPUjogQ291bGQgbm90IHJ1biAlczogJXMiICUKICAgICAg +ICAgICAgICAgICAgICAgICAgICAoZXhjLmNtZCwgZXhjLm91dHB1dCksIGV4Y2VwdGlvbj1leGMp +CiAgICAgICAgICAgICAgICByZXR1cm4gZXhjLnJldHVybmNvZGUKICAgICAgICAgICAgZWxpZiBf +dGhyb3c6CiAgICAgICAgICAgICAgICByYWlzZSBleGMKICAgICAgICAgICAgZWxzZToKICAgICAg +ICAgICAgICAgIGJhaWwoIkVSUk9SOiBDb3VsZCBub3QgcnVuICVzOiAlcyIgJSAoZXhjLmNtZCwg +ZXhjLm91dHB1dCksCiAgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbj1leGMpCgoKZGVmIGxv +Zyhtc2c9Tm9uZSwgZXhjZXB0aW9uPU5vbmUsIHByaW9yaXR5PXN5c2xvZy5MT0dfSU5GTyk6CiAg +ICAiIiIKICAgIHByaW50IGFuZCBsb2cgd2FybmluZyBtZXNzYWdlIG9yIGV4Y2VwdGlvbi4KCiAg +ICA6cGFyYW0gbXNnOiBvcHRpb25hbCBlcnJvciBtZXNzYWdlLgogICAgOnR5cGUgbXNnOiBzdHIK +ICAgIDpwYXJhbSBtc2c6IG9wdGlvbmFsIGV4Y2VwdGlvbi4KICAgIDp0eXBlIG1zZzogRXhjZXB0 +aW9uCiAgICA6cGFyYW0gbXNnOiBzeXNsb2cgbGV2ZWwKICAgIDp0eXBlIG1zZzogb25lIG9mIExP +R19FTUVSRywgTE9HX0FMRVJULCBMT0dfQ1JJVCwgTE9HX0VSUiwKICAgICAgICAgICAgICAgTE9H +X1dBUk5JTkcsIExPR19OT1RJQ0UsIExPR19JTkZPLCBMT0dfREVCVUcKICAgICIiIgogICAgaWYg +bXNnIGlzIG5vdCBOb25lOgogICAgICAgIHByaW50KCIlczogJXMiICUgKFNDUklQVCwgbXNnKSkK +ICAgICAgICBzeXNsb2cuc3lzbG9nKHByaW9yaXR5LCBtc2cpCiAgICBpZiBleGNlcHRpb24gaXMg +bm90IE5vbmU6CiAgICAgICAgaWYgVEVTVCBvciBERUJVRzoKICAgICAgICAgICAgdHJhY2ViYWNr +LnByaW50X2V4YygpCiAgICAgICAgc3lzbG9nLnN5c2xvZyhwcmlvcml0eSwgdHJhY2ViYWNrLmZv +cm1hdF9leGMoKSkKCgpkZWYgZGVidWcobXNnPU5vbmUsIGV4Y2VwdGlvbj1Ob25lKToKICAgICIi +IgogICAgSnVzdCBsaWtlIGxvZywgYnV0IGlzIHNraXBwZWQgdW5sZXNzIERFQlVHLiBVc2Ugc3lz +bG9nLkxPR19JTkZPCiAgICBldmVuIGZvciBkZWJ1ZyBtZXNzYWdlcyAod2UgZG9uJ3Qgd2FudCB0 +byBtaXNzIHRoZW0pLgogICAgIiIiCiAgICBpZiBURVNUIG9yIERFQlVHOgogICAgICAgIGxvZyht +c2csIGV4Y2VwdGlvbikKCgpkZWYgYmFpbChtc2c9Tm9uZSwgZXhjZXB0aW9uPU5vbmUpOgogICAg +IiIiCiAgICBhYm5vcm1hbCBleGl0LiBsaWtlIGxvZygpLCBidXQgZXhpdHMgd2l0aCBlcnJvciBz +dGF0dXMgY29kZS4KICAgICIiIgogICAgbG9nKG1zZywgZXhjZXB0aW9uKQogICAgZXhpdCgxKQoK +IwojIE9QRU5WUE4KIwoKCmRlZiBnZXRfb3BlbnZwbl9iaW4oKToKICAgICIiIgogICAgUmV0dXJu +IHRoZSBwYXRoIGZvciBlaXRoZXIgdGhlIHN5c3RlbSBvcGVudnBuIG9yIHRoZSBvbmUgdGhlCiAg +ICBidW5kbGUgaGFzIHB1dCB0aGVyZS4KICAgICIiIgogICAgaWYgb3MucGF0aC5pc2ZpbGUoT1BF +TlZQTl9TWVNURU1fQklOKToKICAgICAgICByZXR1cm4gT1BFTlZQTl9TWVNURU1fQklOCgogICAg +IyB0aGUgYnVuZGxlIG9wdGlvbiBzaG91bGQgYmUgcmVtb3ZlZCBmcm9tIHRoZSBkZWJpYW4gcGFj +a2FnZS4KICAgIGlmIG9zLnBhdGguaXNmaWxlKE9QRU5WUE5fTEVBUF9CSU4pOgogICAgICAgIHJl +dHVybiBPUEVOVlBOX0xFQVBfQklOCgoKZGVmIHBhcnNlX29wZW52cG5fZmxhZ3MoYXJncyk6CiAg +ICAiIiIKICAgIFRha2UgYXJndW1lbnQgbGlzdCBmcm9tIHRoZSBjb21tYW5kIGxpbmUgYW5kIHBh +cnNlIGl0LCBvbmx5IGFsbG93aW5nIHNvbWUKICAgIGNvbmZpZ3VyYXRpb24gZmxhZ3MuCgogICAg +OnR5cGUgYXJnczogbGlzdAogICAgIiIiCiAgICByZXN1bHQgPSBbXQogICAgdHJ5OgogICAgICAg +IGZvciBmbGFnIGluIHNwbGl0X2xpc3QoYXJncywgIl4tLSIpOgogICAgICAgICAgICBmbGFnX25h +bWUgPSBmbGFnWzBdCiAgICAgICAgICAgIGlmIGZsYWdfbmFtZSBpbiBBTExPV0VEX0ZMQUdTOgog +ICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChmbGFnX25hbWUpCiAgICAgICAgICAgICAgICBy +ZXF1aXJlZF9wYXJhbXMgPSBBTExPV0VEX0ZMQUdTW2ZsYWdfbmFtZV0KICAgICAgICAgICAgICAg +IGlmIHJlcXVpcmVkX3BhcmFtczoKICAgICAgICAgICAgICAgICAgICAjIGZsYXR0ZW4gaWYgc2Vw +YXJhdGVkIGJ5IHNwYWNlcwogICAgICAgICAgICAgICAgICAgIGZsYWdfcGFyYW1zID0gW2kgZm9y +IHN1Ymxpc3QgaW4gbWFwKAogICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEgczogcy5zcGxp +dCgpLCBmbGFnWzE6XSkgZm9yIGkgaW4gc3VibGlzdF0KICAgICAgICAgICAgICAgICAgICBpZiBs +ZW4oZmxhZ19wYXJhbXMpICE9IGxlbihyZXF1aXJlZF9wYXJhbXMpOgogICAgICAgICAgICAgICAg +ICAgICAgICBsb2coIiVzOiBFUlJPUjogbm90IGVub3VnaCBwYXJhbXMgZm9yICVzIiAlCiAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAoU0NSSVBULCBmbGFnX25hbWUpKQogICAgICAgICAgICAg +ICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgICAgICAgICAgICAgIGZvciBwYXJhbSwgcGFy +YW1fdHlwZSBpbiB6aXAoZmxhZ19wYXJhbXMsIHJlcXVpcmVkX3BhcmFtcyk6CiAgICAgICAgICAg +ICAgICAgICAgICAgIGlmIFBBUkFNX0ZPUk1BVFNbcGFyYW1fdHlwZV0ocGFyYW0pOgogICAgICAg +ICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChwYXJhbSkKICAgICAgICAgICAgICAg +ICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZygiJXM6IEVSUk9S +OiBCYWQgYXJndW1lbnQgJXMiICUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU0NS +SVBULCBwYXJhbSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTm9uZQogICAg +ICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgbG9nKCJXQVJOSU5HOiB1bnJlY29nbml6ZWQg +b3BlbnZwbiBmbGFnICVzIiAlIGZsYWdfbmFtZSkKICAgICAgICByZXR1cm4gcmVzdWx0CiAgICBl +eGNlcHQgRXhjZXB0aW9uIGFzIGV4YzoKICAgICAgICBsb2coIiVzOiBFUlJPUiBQQVJTSU5HIEZM +QUdTOiAlcyIgJSAoU0NSSVBULCBleGMpKQogICAgICAgIGlmIERFQlVHOgogICAgICAgICAgICBs +b2dnZXIuZXhjZXB0aW9uKGV4YykKICAgICAgICByZXR1cm4gTm9uZQoKCmRlZiBvcGVudnBuX3N0 +YXJ0KGFyZ3MpOgogICAgIiIiCiAgICBMYXVuY2ggb3BlbnZwbiwgc2FuaXRpemluZyBpbnB1dCwg +YW5kIHJlcGxhY2luZyB0aGUgY3VycmVudCBwcm9jZXNzIHdpdGgKICAgIHRoZSBvcGVudnBuIHBy +b2Nlc3MuCgogICAgOnBhcmFtIGFyZ3M6IGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gb3BlbnZw +bgogICAgOnR5cGUgYXJnczogbGlzdAogICAgIiIiCiAgICBvcGVudnBuX2ZsYWdzID0gcGFyc2Vf +b3BlbnZwbl9mbGFncyhhcmdzKQogICAgaWYgb3BlbnZwbl9mbGFnczoKICAgICAgICBPUEVOVlBO +ID0gZ2V0X29wZW52cG5fYmluKCkKICAgICAgICBmbGFncyA9IFtPUEVOVlBOXSArIEZJWEVEX0ZM +QUdTICsgb3BlbnZwbl9mbGFncwogICAgICAgIGlmIERFQlVHOgogICAgICAgICAgICBsb2coIiVz +OiBydW5uaW5nIG9wZW52cG4gd2l0aCBmbGFnczoiICUgKFNDUklQVCwpKQogICAgICAgICAgICBs +b2coZmxhZ3MpCiAgICAgICAgIyBub3RlOiBmaXJzdCBhcmd1bWVudCB0byBjb21tYW5kIGlzIGln +bm9yZWQsIGJ1dCBjdXN0b21hcmlseSBzZXQgdG8KICAgICAgICAjIHRoZSBjb21tYW5kLgogICAg +ICAgIG9zLmV4ZWN2KE9QRU5WUE4sIGZsYWdzKQogICAgZWxzZToKICAgICAgICBiYWlsKCdFUlJP +UjogY291bGQgbm90IHBhcnNlIG9wZW52cG4gb3B0aW9ucycpCgoKZGVmIG9wZW52cG5fc3RvcChh +cmdzKToKICAgICIiIgogICAgU3RvcCB0aGUgb3BlbnZwbiB0aGF0IGhhcyBsaWtlbHkgYmVlbiBs +YXVuY2hlZCBieSBiaXRtYXNrLgoKICAgIDpwYXJhbSBhcmdzOiBhcmd1bWVudHMgdG8gb3BlbnZw +bgogICAgOnR5cGUgYXJnczogbGlzdAogICAgIiIiCiAgICBwbGlzdCA9IGdldF9wcm9jZXNzX2xp +c3QoKQogICAgT1BFTlZQTl9CSU4gPSBnZXRfb3BlbnZwbl9iaW4oKQogICAgZm91bmRfbGVhcF9v +cGVudnBuID0gZmlsdGVyKAogICAgICAgIGxhbWJkYSAocCwgcyk6IHMuc3RhcnRzd2l0aChPUEVO +VlBOX0JJTikgYW5kIExFQVBPUEVOVlBOIGluIHMsCiAgICAgICAgcGxpc3QpCgogICAgaWYgZm91 +bmRfbGVhcF9vcGVudnBuOgogICAgICAgIHBpZCA9IGZvdW5kX2xlYXBfb3BlbnZwblswXVswXQog +ICAgICAgIG9zLmtpbGwoaW50KHBpZCksIHNpZ25hbC5TSUdURVJNKQoKIwojIEZJUkVXQUxMCiMK +CgpkZWYgZ2V0X2dhdGV3YXlzKGdhdGV3YXlzKToKICAgICIiIgogICAgRmlsdGVyIGEgcGFzc2Vk +IHNlcXVlbmNlIG9mIGdhdGV3YXlzLCByZXR1cm5pbmcgb25seSB0aGUgdmFsaWQgb25lcy4KCiAg +ICA6cGFyYW0gZ2F0ZXdheXM6IGEgc2VxdWVuY2Ugb2YgZ2F0ZXdheXMgdG8gZmlsdGVyLgogICAg +OnR5cGUgZ2F0ZXdheXM6IGl0ZXJhYmxlCiAgICA6cnR5cGU6IGl0ZXJhYmxlCiAgICAiIiIKICAg +IHJlc3VsdCA9IGZpbHRlcihpc192YWxpZF9hZGRyZXNzLCBnYXRld2F5cykKICAgIGlmIG5vdCBy +ZXN1bHQ6CiAgICAgICAgYmFpbCgiRVJST1I6IE5vIHZhbGlkIGdhdGV3YXlzIHNwZWNpZmllZCIp +CiAgICBlbHNlOgogICAgICAgIHJldHVybiByZXN1bHQKCgpkZWYgZ2V0X2RlZmF1bHRfZGV2aWNl +KCk6CiAgICAiIiIKICAgIFJldHJpZXZlIHRoZSBjdXJyZW50IGRlZmF1bHQgbmV0d29yayBkZXZp +Y2UuCgogICAgOnJ0eXBlOiBzdHIKICAgICIiIgogICAgcm91dGVzID0gc3VicHJvY2Vzcy5jaGVj +a19vdXRwdXQoW0lQLCAicm91dGUiLCAic2hvdyJdKQogICAgbWF0Y2ggPSByZS5zZWFyY2goIl5k +ZWZhdWx0IC4qZGV2IChbXlxzXSopIC4qJCIsIHJvdXRlcywgZmxhZ3M9cmUuTSkKICAgIGlmIG1h +dGNoIGFuZCBtYXRjaC5ncm91cHMoKToKICAgICAgICByZXR1cm4gbWF0Y2guZ3JvdXAoMSkKICAg +IGVsc2U6CiAgICAgICAgYmFpbCgiQ291bGQgbm90IGZpbmQgZGVmYXVsdCBkZXZpY2UiKQoKCmRl +ZiBnZXRfbG9jYWxfbmV0d29ya19pcHY0KGRldmljZSk6CiAgICAiIiIKICAgIEdldCB0aGUgbG9j +YWwgaXB2NCBhZGRyZXMgZm9yIGEgZ2l2ZW4gZGV2aWNlLgoKICAgIDpwYXJhbSBkZXZpY2U6CiAg +ICA6dHlwZSBkZXZpY2U6IHN0cgogICAgIiIiCiAgICBhZGRyZXNzZXMgPSBjbWRjaGVjayhbSVAs +ICItbyIsICJhZGRyZXNzIiwgInNob3ciLCAiZGV2IiwgZGV2aWNlXSkKICAgIG1hdGNoID0gcmUu +c2VhcmNoKCJeLippbmV0IChbXiBdKikgLiokIiwgYWRkcmVzc2VzLCBmbGFncz1yZS5NKQogICAg +aWYgbWF0Y2ggYW5kIG1hdGNoLmdyb3VwcygpOgogICAgICAgIHJldHVybiBtYXRjaC5ncm91cCgx +KQogICAgZWxzZToKICAgICAgICByZXR1cm4gTm9uZQoKCmRlZiBnZXRfbG9jYWxfbmV0d29ya19p +cHY2KGRldmljZSk6CiAgICAiIiIKICAgIEdldCB0aGUgbG9jYWwgaXB2NiBhZGRyZXMgZm9yIGEg +Z2l2ZW4gZGV2aWNlLgoKICAgIDpwYXJhbSBkZXZpY2U6CiAgICA6dHlwZSBkZXZpY2U6IHN0cgog +ICAgIiIiCiAgICBhZGRyZXNzZXMgPSBjbWRjaGVjayhbSVAsICItbyIsICJhZGRyZXNzIiwgInNo +b3ciLCAiZGV2IiwgZGV2aWNlXSkKICAgIG1hdGNoID0gcmUuc2VhcmNoKCJeLippbmV0NiAoW14g +XSopIC4qJCIsIGFkZHJlc3NlcywgZmxhZ3M9cmUuTSkKICAgIGlmIG1hdGNoIGFuZCBtYXRjaC5n +cm91cHMoKToKICAgICAgICByZXR1cm4gbWF0Y2guZ3JvdXAoMSkKICAgIGVsc2U6CiAgICAgICAg +cmV0dXJuIE5vbmUKCgpkZWYgcnVuX2lwdGFibGVfd2l0aF9jaGVjayhjbWQsICphcmdzLCAqKm9w +dGlvbnMpOgogICAgIiIiCiAgICBSdW4gYW4gaXB0YWJsZXMgY29tbWFuZCBjaGVja2luZyB0byBz +ZWUgaWYgaXQgc2hvdWxkOgogICAgICBmb3IgLS1hcHBlbmQ6IHJ1biBvbmx5IGlmIHJ1bGUgZG9l +cyBub3QgYWxyZWFkeSBleGlzdC4KICAgICAgZm9yIC0taW5zZXJ0OiBydW4gb25seSBpZiBydWxl +IGRvZXMgbm90IGFscmVhZHkgZXhpc3QuCiAgICAgIGZvciAtLWRlbGV0ZTogcnVuIG9ubHkgaWYg +cnVsZSBkb2VzIGV4aXN0LgogICAgb3RoZXIgY29tbWFuZHMgYXJlIHJ1biBub3JtYWxseS4KICAg +ICIiIgogICAgaWYgIi0taW5zZXJ0IiBpbiBhcmdzOgogICAgICAgIGNoZWNrX2FyZ3MgPSBbYXJn +LnJlcGxhY2UoIi0taW5zZXJ0IiwgIi0tY2hlY2siKSBmb3IgYXJnIGluIGFyZ3NdCiAgICAgICAg +Y2hlY2tfY29kZSA9IHJ1bihjbWQsICpjaGVja19hcmdzLCBleGl0Y29kZT1UcnVlKQogICAgICAg +IGlmIGNoZWNrX2NvZGUgIT0gMDoKICAgICAgICAgICAgcnVuKGNtZCwgKmFyZ3MsICoqb3B0aW9u +cykKICAgIGVsaWYgIi0tYXBwZW5kIiBpbiBhcmdzOgogICAgICAgIGNoZWNrX2FyZ3MgPSBbYXJn +LnJlcGxhY2UoIi0tYXBwZW5kIiwgIi0tY2hlY2siKSBmb3IgYXJnIGluIGFyZ3NdCiAgICAgICAg +Y2hlY2tfY29kZSA9IHJ1bihjbWQsICpjaGVja19hcmdzLCBleGl0Y29kZT1UcnVlKQogICAgICAg +IGlmIGNoZWNrX2NvZGUgIT0gMDoKICAgICAgICAgICAgcnVuKGNtZCwgKmFyZ3MsICoqb3B0aW9u +cykKICAgIGVsaWYgIi0tZGVsZXRlIiBpbiBhcmdzOgogICAgICAgIGNoZWNrX2FyZ3MgPSBbYXJn +LnJlcGxhY2UoIi0tZGVsZXRlIiwgIi0tY2hlY2siKSBmb3IgYXJnIGluIGFyZ3NdCiAgICAgICAg +Y2hlY2tfY29kZSA9IHJ1bihjbWQsICpjaGVja19hcmdzLCBleGl0Y29kZT1UcnVlKQogICAgICAg +IGlmIGNoZWNrX2NvZGUgPT0gMDoKICAgICAgICAgICAgcnVuKGNtZCwgKmFyZ3MsICoqb3B0aW9u +cykKICAgIGVsc2U6CiAgICAgICAgcnVuKGNtZCwgKmFyZ3MsICoqb3B0aW9ucykKCgpkZWYgaXB0 +YWJsZXMoKmFyZ3MsICoqb3B0aW9ucyk6CiAgICAiIiIKICAgIFJ1biBpcHRhYmxlczQgYW5kIGlw +dGFibGVzNi4KICAgICIiIgogICAgaXA0dGFibGVzKCphcmdzLCAqKm9wdGlvbnMpCiAgICBpcDZ0 +YWJsZXMoKmFyZ3MsICoqb3B0aW9ucykKCgpkZWYgaXA0dGFibGVzKCphcmdzLCAqKm9wdGlvbnMp +OgogICAgIiIiCiAgICBSdW4gaXB0YWJsZXM0IHdpdGggY2hlY2tzLgogICAgIiIiCiAgICBydW5f +aXB0YWJsZV93aXRoX2NoZWNrKElQVEFCTEVTLCAqYXJncywgKipvcHRpb25zKQoKCmRlZiBpcDZ0 +YWJsZXMoKmFyZ3MsICoqb3B0aW9ucyk6CiAgICAiIiIKICAgIFJ1biBpcHRhYmxlczYgd2l0aCBj +aGVja3MuCiAgICAiIiIKICAgIHJ1bl9pcHRhYmxlX3dpdGhfY2hlY2soSVA2VEFCTEVTLCAqYXJn +cywgKipvcHRpb25zKQoKIwojIE5PVEU6IHRoZXNlIHRlc3RzIHRvIHNlZSBpZiBhIGNoYWluIGV4 +aXN0cyBtaWdodCBpbmNvcnJlY3RseSByZXR1cm4gZmFsc2UuCiMgVGhpcyBoYXBwZW5zIHdoZW4g +dGhlcmUgaXMgYW4gZXJyb3IgaW4gY2FsbGluZyBgaXB0YWJsZXMgLS1saXN0IGJpdG1hc2tgLgoj +CiMgRm9yIHRoaXMgcmVhc29uLCB3aGVuIHN0b3BwaW5nIHRoZSBmaXJld2FsbCwgd2UgZG8gbm90 +IHRydXN0IHRoZQojIG91dHB1dCBvZiBpcHZ4X2NoYWluX2V4aXN0cygpIGJ1dCBpbnN0ZWFkIGFs +d2F5cyBhdHRlbXB0IHRvIGRlbGV0ZQojIHRoZSBjaGFpbi4KIwoKCmRlZiBpcHY0X2NoYWluX2V4 +aXN0cyhjaGFpbiwgdGFibGU9Tm9uZSk6CiAgICAiIiIKICAgIENoZWNrIGlmIGEgZ2l2ZW4gY2hh +aW4gZXhpc3RzLiBPbmx5IHJldHVybnMgdHJ1ZSBpZiBpdCBhY3R1YWxseSBleGlzdHMsCiAgICBi +dXQgbWlnaHQgcmV0dXJuIGZhbHNlIGlmIGl0IGV4aXN0cyBhbmQgaXB0YWJsZXMgZmFpbGVkIHRv +IHJ1bi4KCiAgICA6cGFyYW0gY2hhaW46IHRoZSBjaGFpbiB0byBjaGVjayBhZ2FpbnN0CiAgICA6 +dHlwZSBjaGFpbjogc3RyCiAgICA6cnR5cGU6IGJvb2wKICAgICIiIgogICAgaWYgdGFibGUgaXMg +bm90IE5vbmU6CiAgICAgICAgY29kZSA9IHJ1bihJUFRBQkxFUywgIi10IiwgdGFibGUsCiAgICAg +ICAgICAgICAgICAgICAiLS1saXN0IiwgY2hhaW4sICItLW51bWVyaWMiLCBleGl0Y29kZT1UcnVl +KQogICAgZWxzZToKICAgICAgICBjb2RlID0gcnVuKElQVEFCTEVTLCAiLS1saXN0IiwgY2hhaW4s +ICItLW51bWVyaWMiLCBleGl0Y29kZT1UcnVlKQogICAgaWYgY29kZSA9PSAwOgogICAgICAgIHJl +dHVybiBUcnVlCiAgICBlbGlmIGNvZGUgPT0gMToKICAgICAgICByZXR1cm4gRmFsc2UKICAgIGVs +c2U6CiAgICAgICAgbG9nKCJFUlJPUjogQ291bGQgbm90IGRldGVybWluZSBzdGF0ZSBvZiBpcHRh +YmxlIGNoYWluIikKICAgICAgICByZXR1cm4gRmFsc2UKCgpkZWYgaXB2Nl9jaGFpbl9leGlzdHMo +Y2hhaW4pOgogICAgIiIiCiAgICBzZWUgaXB2NF9jaGFpbl9leGlzdHMoKQoKICAgIDpwYXJhbSBj +aGFpbjogdGhlIGNoYWluIHRvIGNoZWNrIGFnYWluc3QKICAgIDp0eXBlIGNoYWluOiBzdHIKICAg +IDpydHlwZTogYm9vbAogICAgIiIiCiAgICBjb2RlID0gcnVuKElQNlRBQkxFUywgIi0tbGlzdCIs +IGNoYWluLCAiLS1udW1lcmljIiwgZXhpdGNvZGU9VHJ1ZSkKICAgIGlmIGNvZGUgPT0gMDoKICAg +ICAgICByZXR1cm4gVHJ1ZQogICAgZWxpZiBjb2RlID09IDE6CiAgICAgICAgcmV0dXJuIEZhbHNl +CiAgICBlbHNlOgogICAgICAgIGxvZygiRVJST1I6IENvdWxkIG5vdCBkZXRlcm1pbmUgc3RhdGUg +b2YgaXB0YWJsZSBjaGFpbiIpCiAgICAgICAgcmV0dXJuIEZhbHNlCgoKZGVmIGVuYWJsZV9pcF9m +b3J3YXJkaW5nKCk6CiAgICAiIiIKICAgIGlwX2Zvd2FyZGluZyBtdXN0IGJlIGVuYWJsZWQgZm9y +IHRoZSBmaXJld2FsbCB0byB3b3JrLgogICAgIiIiCiAgICB3aXRoIG9wZW4oJy9wcm9jL3N5cy9u +ZXQvaXB2NC9pcF9mb3J3YXJkJywgJ3cnKSBhcyBmOgogICAgICAgIGYud3JpdGUoJzFcbicpCgoK +ZGVmIGZpcmV3YWxsX3N0YXJ0KGFyZ3MpOgogICAgIiIiCiAgICBCcmluZyB1cCB0aGUgZmlyZXdh +bGwuCgogICAgOnBhcmFtIGFyZ3M6IGxpc3Qgb2YgZ2F0ZXdheXMsIHRvIGJlIHNhbml0aXplZC4K +ICAgIDp0eXBlIGFyZ3M6IGxpc3QKICAgICIiIgogICAgZGVmYXVsdF9kZXZpY2UgPSBnZXRfZGVm +YXVsdF9kZXZpY2UoKQogICAgbG9jYWxfbmV0d29ya19pcHY0ID0gZ2V0X2xvY2FsX25ldHdvcmtf +aXB2NChkZWZhdWx0X2RldmljZSkKICAgIGxvY2FsX25ldHdvcmtfaXB2NiA9IGdldF9sb2NhbF9u +ZXR3b3JrX2lwdjYoZGVmYXVsdF9kZXZpY2UpCiAgICBnYXRld2F5cyA9IGdldF9nYXRld2F5cyhh +cmdzKQoKICAgICMgYWRkIGN1c3RvbSBjaGFpbiAiYml0bWFzayIgdG8gZnJvbnQgb2YgT1VUUFVU +IGNoYWluIGZvciBib3RoCiAgICAjIHRoZSAnZmlsdGVyJyBhbmQgdGhlICduYXQnIHRhYmxlcy4K +ICAgIGlmIG5vdCBpcHY0X2NoYWluX2V4aXN0cyhCSVRNQVNLX0NIQUlOKToKICAgICAgICBpcDR0 +YWJsZXMoIi0tbmV3LWNoYWluIiwgQklUTUFTS19DSEFJTikKICAgIGlmIG5vdCBpcHY0X2NoYWlu +X2V4aXN0cyhCSVRNQVNLX0NIQUlOX05BVF9PVVQsICduYXQnKToKICAgICAgICBpcDR0YWJsZXMo +Ii0tdGFibGUiLCAibmF0IiwgIi0tbmV3LWNoYWluIiwgQklUTUFTS19DSEFJTl9OQVRfT1VUKQog +ICAgaWYgbm90IGlwdjRfY2hhaW5fZXhpc3RzKEJJVE1BU0tfQ0hBSU5fTkFUX1BPU1QsICduYXQn +KToKICAgICAgICBpcDR0YWJsZXMoIi0tdGFibGUiLCAibmF0IiwgIi0tbmV3LWNoYWluIiwgQklU +TUFTS19DSEFJTl9OQVRfUE9TVCkKICAgIGlmIG5vdCBpcHY2X2NoYWluX2V4aXN0cyhCSVRNQVNL +X0NIQUlOKToKICAgICAgICBpcDZ0YWJsZXMoIi0tbmV3LWNoYWluIiwgQklUTUFTS19DSEFJTikK +ICAgIGlwNHRhYmxlcygiLS10YWJsZSIsICJuYXQiLCAiLS1pbnNlcnQiLCAiT1VUUFVUIiwKICAg +ICAgICAgICAgICAiLS1qdW1wIiwgQklUTUFTS19DSEFJTl9OQVRfT1VUKQogICAgaXA0dGFibGVz +KCItLXRhYmxlIiwgIm5hdCIsICItLWluc2VydCIsICJQT1NUUk9VVElORyIsCiAgICAgICAgICAg +ICAgIi0tanVtcCIsIEJJVE1BU0tfQ0hBSU5fTkFUX1BPU1QpCiAgICBpcHRhYmxlcygiLS1pbnNl +cnQiLCAiT1VUUFVUIiwgIi0tanVtcCIsIEJJVE1BU0tfQ0hBSU4pCgogICAgIyByb3V0ZSBhbGwg +aXB2NCBETlMgb3ZlciBWUE4KICAgICMgKG5vdGU6IE5BVCBkb2VzIG5vdCB3b3JrIHdpdGggaXB2 +NiB1bnRpbCBrZXJuZWwgMy43KQogICAgZW5hYmxlX2lwX2ZvcndhcmRpbmcoKQogICAgaWYgUVVC +RVNfUFJPWFkgYW5kIFFVQkVTX1ZFUiA+PSAzOgogICAgICAgICMgcmV3cml0ZSBETlMgcGFja2V0 +cyBmb3IgVlBOIEROUzsgUXViZXMgcHJlY29uZmlndXJlcyBtYXNxdWVyYWRlCiAgICAgICAgaXA0 +dGFibGVzKCItdCIsICJuYXQiLCAiLS1mbHVzaCIsICJQUi1RQlMiKQogICAgICAgIGlwNHRhYmxl +cygiLXQiLCAibmF0IiwgIi0tYXBwZW5kIiwgIlBSLVFCUyIsICItcCIsICJ1ZHAiLAogICAgICAg +ICAgICAgICAgICAiLS1kcG9ydCIsICI1MyIsICItLWp1bXAiLCAiRE5BVCIsICItLXRvIiwgTkFN +RVNFUlZFUisiOjUzIikKICAgICAgICBpcDR0YWJsZXMoIi10IiwgIm5hdCIsICItLWFwcGVuZCIs +ICJQUi1RQlMiLCAiLXAiLCAidGNwIiwKICAgICAgICAgICAgICAgICAgIi0tZHBvcnQiLCAiNTMi +LCAiLS1qdW1wIiwgIkROQVQiLCAiLS10byIsIE5BTUVTRVJWRVIrIjo1MyIpCiAgICBlbHNlOgog +ICAgICAgICMgYWxsb3cgZG5zIHRvIGxvY2FsaG9zdAogICAgICAgIGlwNHRhYmxlcygiLXQiLCAi +bmF0IiwgIi0tYXBwZW5kIiwgQklUTUFTS19DSEFJTiwgIi0tcHJvdG9jb2wiLCAidWRwIiwKICAg +ICAgICAgICAgICAgICAgIi0tZGVzdCIsICIxMjcuMC4xLjEsMTI3LjAuMC4xLDEyNy4wLjAuNTMi +LCAiLS1kcG9ydCIsICI1MyIsCiAgICAgICAgICAgICAgICAgICItLWp1bXAiLCAiQUNDRVBUIikK +ICAgICAgICAjIHJld3JpdGUgYWxsIG91dGdvaW5nIHBhY2tldHMgdG8gdXNlIFZQTiBETlMgc2Vy +dmVyCiAgICAgICAgIyAoRE5TIGRvZXMgc29tZXRpbWVzIHVzZSBUQ1AhKQogICAgICAgIGlwNHRh +YmxlcygiLXQiLCAibmF0IiwgIi0tYXBwZW5kIiwgQklUTUFTS19DSEFJTl9OQVRfT1VULCAiLXAi +LCAidWRwIiwKICAgICAgICAgICAgICAgICAgIi0tZHBvcnQiLCAiNTMiLCAiLS1qdW1wIiwgIkRO +QVQiLCAiLS10byIsIE5BTUVTRVJWRVIrIjo1MyIpCiAgICAgICAgaXA0dGFibGVzKCItdCIsICJu +YXQiLCAiLS1hcHBlbmQiLCBCSVRNQVNLX0NIQUlOX05BVF9PVVQsICItcCIsICJ0Y3AiLAogICAg +ICAgICAgICAgICAgICAiLS1kcG9ydCIsICI1MyIsICItLWp1bXAiLCAiRE5BVCIsICItLXRvIiwg +TkFNRVNFUlZFUisiOjUzIikKICAgICAgICAjIGVuYWJsZSBtYXNxdWVyYWRpbmcsIHNvIHRoYXQg +RE5TIHBhY2tldHMgcmV3cml0dGVuIGJ5IEROQVQgd2lsbAogICAgICAgICMgaGF2ZSB0aGUgY29y +cmVjdCBzb3VyY2UgSVBzLiBBcHBseSBtYXNxdWVyYWRlIG9ubHkgdG8gdGhlIE5BTUVTRVJWRVIs +CiAgICAgICAgIyB3ZSBkb24ndCB3YW50IHRvIGFwcGx5IGl0IHRvIHRoZSBsb2NhbGhvc3QgZG5z +IHJlc29sdmVyLgogICAgICAgIGlwNHRhYmxlcygiLXQiLCAibmF0IiwgIi0tYXBwZW5kIiwgQklU +TUFTS19DSEFJTl9OQVRfUE9TVCwKICAgICAgICAgICAgICAgICAgIi0tZGVzdCIsIE5BTUVTRVJW +RVIsCiAgICAgICAgICAgICAgICAgICItLXByb3RvY29sIiwgInVkcCIsICItLWRwb3J0IiwgIjUz +IiwgIi0tanVtcCIsICJNQVNRVUVSQURFIikKICAgICAgICBpcDR0YWJsZXMoIi10IiwgIm5hdCIs +ICItLWFwcGVuZCIsIEJJVE1BU0tfQ0hBSU5fTkFUX1BPU1QsCiAgICAgICAgICAgICAgICAgICIt +LWRlc3QiLCBOQU1FU0VSVkVSLAogICAgICAgICAgICAgICAgICAiLS1wcm90b2NvbCIsICJ0Y3Ai +LCAiLS1kcG9ydCIsICI1MyIsICItLWp1bXAiLCAiTUFTUVVFUkFERSIpCgogICAgIyBhbGxvdyBs +b2NhbCBuZXR3b3JrIHRyYWZmaWMKICAgIGlmIGxvY2FsX25ldHdvcmtfaXB2NDoKICAgICAgICAj +IGFsbG93IGxvY2FsIG5ldHdvcmsgZGVzdGluYXRpb25zCiAgICAgICAgaXA0dGFibGVzKCItLWFw +cGVuZCIsIEJJVE1BU0tfQ0hBSU4sCiAgICAgICAgICAgICAgICAgICItLWRlc3RpbmF0aW9uIiwg +bG9jYWxfbmV0d29ya19pcHY0LCAiLW8iLCBkZWZhdWx0X2RldmljZSwKICAgICAgICAgICAgICAg +ICAgIi0tanVtcCIsICJBQ0NFUFQiKQogICAgICAgICMgYWxsb3cgbG9jYWwgbmV0d29yayBzb3Vy +Y2VzIGZvciBETlMKICAgICAgICAjIChyZXF1aXJlZCB0byBhbGxvdyBsb2NhbCBuZXR3b3JrIERO +UyB0aGF0IGdldHMgcmV3cml0dGVuIGJ5IE5BVAogICAgICAgICMgIHRvIGdldCBwYXNzZWQgdGhy +b3VnaCBzbyB0aGF0IE1BU1FVRVJBREUgY2FuIHNldCBjb3JyZWN0IHNvdXJjZSBJUCkKICAgICAg +ICBpcDR0YWJsZXMoIi0tYXBwZW5kIiwgQklUTUFTS19DSEFJTiwKICAgICAgICAgICAgICAgICAg +Ii0tc291cmNlIiwgbG9jYWxfbmV0d29ya19pcHY0LCAiLW8iLCBkZWZhdWx0X2RldmljZSwKICAg +ICAgICAgICAgICAgICAgIi1wIiwgInVkcCIsICItLWRwb3J0IiwgIjUzIiwgIi0tanVtcCIsICJB +Q0NFUFQiKQogICAgICAgIGlwNHRhYmxlcygiLS1hcHBlbmQiLCBCSVRNQVNLX0NIQUlOLAogICAg +ICAgICAgICAgICAgICAiLS1zb3VyY2UiLCBsb2NhbF9uZXR3b3JrX2lwdjQsICItbyIsIGRlZmF1 +bHRfZGV2aWNlLAogICAgICAgICAgICAgICAgICAiLXAiLCAidGNwIiwgIi0tZHBvcnQiLCAiNTMi +LCAiLS1qdW1wIiwgIkFDQ0VQVCIpCiAgICAgICAgIyBhbGxvdyBtdWx0aWNhc3QgU2ltcGxlIFNl +cnZpY2UgRGlzY292ZXJ5IFByb3RvY29sCiAgICAgICAgaXA0dGFibGVzKCItLWFwcGVuZCIsIEJJ +VE1BU0tfQ0hBSU4sCiAgICAgICAgICAgICAgICAgICItLXByb3RvY29sIiwgInVkcCIsCiAgICAg +ICAgICAgICAgICAgICItLWRlc3RpbmF0aW9uIiwgIjIzOS4yNTUuMjU1LjI1MCIsICItLWRwb3J0 +IiwgIjE5MDAiLAogICAgICAgICAgICAgICAgICAiLW8iLCBkZWZhdWx0X2RldmljZSwgIi0tanVt +cCIsICJSRVRVUk4iKQogICAgICAgICMgYWxsb3cgbXVsdGljYXN0IEJvbmpvdXIvbUROUwogICAg +ICAgIGlwNHRhYmxlcygiLS1hcHBlbmQiLCBCSVRNQVNLX0NIQUlOLAogICAgICAgICAgICAgICAg +ICAiLS1wcm90b2NvbCIsICJ1ZHAiLAogICAgICAgICAgICAgICAgICAiLS1kZXN0aW5hdGlvbiIs +ICIyMjQuMC4wLjI1MSIsICItLWRwb3J0IiwgIjUzNTMiLAogICAgICAgICAgICAgICAgICAiLW8i +LCBkZWZhdWx0X2RldmljZSwgIi0tanVtcCIsICJSRVRVUk4iKQogICAgaWYgbG9jYWxfbmV0d29y +a19pcHY2OgogICAgICAgIGlwNnRhYmxlcygiLS1hcHBlbmQiLCBCSVRNQVNLX0NIQUlOLAogICAg +ICAgICAgICAgICAgICAiLS1kZXN0aW5hdGlvbiIsIGxvY2FsX25ldHdvcmtfaXB2NiwgIi1vIiwg +ZGVmYXVsdF9kZXZpY2UsCiAgICAgICAgICAgICAgICAgICItLWp1bXAiLCAiQUNDRVBUIikKICAg +ICAgICAjIGFsbG93IG11bHRpY2FzdCBTaW1wbGUgU2VydmljZSBEaXNjb3ZlcnkgUHJvdG9jb2wK +ICAgICAgICBpcDZ0YWJsZXMoIi0tYXBwZW5kIiwgQklUTUFTS19DSEFJTiwKICAgICAgICAgICAg +ICAgICAgIi0tcHJvdG9jb2wiLCAidWRwIiwKICAgICAgICAgICAgICAgICAgIi0tZGVzdGluYXRp +b24iLCAiRkYwNTo6QyIsICItLWRwb3J0IiwgIjE5MDAiLAogICAgICAgICAgICAgICAgICAiLW8i +LCBkZWZhdWx0X2RldmljZSwgIi0tanVtcCIsICJSRVRVUk4iKQogICAgICAgICMgYWxsb3cgbXVs +dGljYXN0IEJvbmpvdXIvbUROUwogICAgICAgIGlwNnRhYmxlcygiLS1hcHBlbmQiLCBCSVRNQVNL +X0NIQUlOLAogICAgICAgICAgICAgICAgICAiLS1wcm90b2NvbCIsICJ1ZHAiLAogICAgICAgICAg +ICAgICAgICAiLS1kZXN0aW5hdGlvbiIsICJGRjAyOjpGQiIsICItLWRwb3J0IiwgIjUzNTMiLAog +ICAgICAgICAgICAgICAgICAiLW8iLCBkZWZhdWx0X2RldmljZSwgIi0tanVtcCIsICJSRVRVUk4i +KQoKICAgICMgYWxsb3cgaXB2NCB0cmFmZmljIHRvIGdhdGV3YXlzCiAgICBmb3IgZ2F0ZXdheSBp +biBnYXRld2F5czoKICAgICAgICBpcDR0YWJsZXMoIi0tYXBwZW5kIiwgQklUTUFTS19DSEFJTiwg +Ii0tZGVzdGluYXRpb24iLCBnYXRld2F5LAogICAgICAgICAgICAgICAgICAiLW8iLCBkZWZhdWx0 +X2RldmljZSwgIi0tanVtcCIsICJBQ0NFUFQiKQoKICAgICMgbG9nIHJlamVjdGVkIHBhY2tldHMg +dG8gc3lzbG9nCiAgICBpZiBERUJVRzoKICAgICAgICBpcHRhYmxlcygiLS1hcHBlbmQiLCBCSVRN +QVNLX0NIQUlOLCAiLW8iLCBkZWZhdWx0X2RldmljZSwKICAgICAgICAgICAgICAgICAiLS1qdW1w +IiwgIkxPRyIsICItLWxvZy1wcmVmaXgiLCAiaXB0YWJsZXMgZGVuaWVkOiAiLAogICAgICAgICAg +ICAgICAgICItLWxvZy1sZXZlbCIsICI3IikKCiAgICAjIGZvciBub3csIGVuc3VyZSBhbGwgb3Ro +ZXIgaXB2NiBwYWNrZXRzIGdldCByZWplY3RlZCAocmVnYXJkbGVzcyBvZgogICAgIyBkZXZpY2Up +LiBub3Qgc3VyZSB3aHksIGJ1dCAiLXAgYW55IiBkb2Vzbid0IHdvcmsuCiAgICBpcDZ0YWJsZXMo +Ii0tYXBwZW5kIiwgQklUTUFTS19DSEFJTiwgIi1wIiwgInRjcCIsICItLWp1bXAiLCAiUkVKRUNU +IikKICAgIGlwNnRhYmxlcygiLS1hcHBlbmQiLCBCSVRNQVNLX0NIQUlOLCAiLXAiLCAidWRwIiwg +Ii0tanVtcCIsICJSRUpFQ1QiKQoKICAgICMgcmVqZWN0IGFsbCBvdGhlciBpcHY0IHNlbnQgb3Zl +ciB0aGUgZGVmYXVsdCBkZXZpY2UKICAgIGlwNHRhYmxlcygiLS1hcHBlbmQiLCBCSVRNQVNLX0NI +QUlOLCAiLW8iLAogICAgICAgICAgICAgIGRlZmF1bHRfZGV2aWNlLCAiLS1qdW1wIiwgIlJFSkVD +VCIpCgogICAgIyBPbiBRdWJlcyBPUywgYWRkIGFudGktbGVhayBydWxlcyBmb3IgcHJveHlWTSBx +dWJlcy1maXJld2FsbC5zZXJ2aWNlCiAgICAjIE11c3Qgc3RheSBvbiAndG9wJyBvZiBjaGFpbiEK +ICAgIGlmIFFVQkVTX1BST1hZIGFuZCBRVUJFU19WRVIgPj0gMyBhbmQgcnVuKCJncmVwIiwgXAog +ICAgICAgICJpbnN0YWxsZWRcIGJ5XCAiICsgU0NSSVBULCBRVUJFU19GV19TQ1JJUFQsIGV4aXRj +b2RlPVRydWUpICE9IDA6CiAgICAgICAgd2l0aCBvcGVuKFFVQkVTX0ZXX1NDUklQVCwgbW9kZT0i +dyIpIGFzIHFmaWxlOgogICAgICAgICAgICBxZmlsZS53cml0ZSgiIyEvYmluL3NoXG4iKQogICAg +ICAgICAgICBxZmlsZS53cml0ZSgiIyBBbnRpLWxlYWsgcnVsZXMgaW5zdGFsbGVkIGJ5ICIgKyBT +Q1JJUFQgKyAiICIgXAogICAgICAgICAgICArIFZFUlNJT04gKyAiXG4iKQogICAgICAgICAgICBx +ZmlsZS53cml0ZSgiaXB0YWJsZXMgLS1pbnNlcnQgRk9SV0FSRCAtaSBldGgwIC1qIERST1BcbiIp +CiAgICAgICAgICAgIHFmaWxlLndyaXRlKCJpcHRhYmxlcyAtLWluc2VydCBGT1JXQVJEIC1vIGV0 +aDAgLWogRFJPUFxuIikKICAgICAgICAgICAgcWZpbGUud3JpdGUoImlwNnRhYmxlcyAtLWluc2Vy +dCBGT1JXQVJEIC1pIGV0aDAgLWogRFJPUFxuIikKICAgICAgICAgICAgcWZpbGUud3JpdGUoImlw +NnRhYmxlcyAtLWluc2VydCBGT1JXQVJEIC1vIGV0aDAgLWogRFJPUFxuIikKICAgICAgICAgICAg +cWZpbGUud3JpdGUoImlwdGFibGVzIC0taW5zZXJ0IElOUFVUIC1pIHR1bisgLWogRFJPUFxuIikK +ICAgICAgICAgICAgcWZpbGUud3JpdGUoImlwNnRhYmxlcyAtLWluc2VydCBJTlBVVCAtaSB0dW4r +IC1qIERST1BcbiIpCiAgICAgICAgb3MuY2htb2QoUVVCRVNfRldfU0NSSVBULCBzdGF0LlNfSVJX +WFUpCiAgICAgICAgaWYgbm90IG9zLnBhdGguZXhpc3RzKFFVQkVTX0lQSE9PSyk6CiAgICAgICAg +ICAgIG9zLnN5bWxpbmsoUVVCRVNfRldfU0NSSVBULCBRVUJFU19JUEhPT0spCiAgICAgICAgaWYg +UVVCRVNfVkVSID09IDQ6CiAgICAgICAgICAgIHJ1bihRVUJFU19GV19TQ1JJUFQpCiAgICAgICAg +ZWxpZiBRVUJFU19WRVIgPT0gMzoKICAgICAgICAgICAgcnVuKCJzeXN0ZW1jdGwiLCAicmVzdGFy +dCIsICJxdWJlcy1maXJld2FsbC5zZXJ2aWNlIikKCgpkZWYgZmlyZXdhbGxfc3RvcCgpOgogICAg +IiIiCiAgICBTdG9wIHRoZSBmaXJld2FsbC4gQmVjYXVzZSB3ZSByZWFsbHkgcmVhbGx5IGFsd2F5 +cyB3YW50IHRoZSBmaXJld2FsbCB0bwogICAgYmUgc3RvcHBlZCBpZiBhdCBhbGwgcG9zc2libGUs +IHRoaXMgZnVuY3Rpb24gaXMgY2F1dGlvdXMgYW5kIGNvbnRhaW5zIGEKICAgIGxvdCBvZiB0cnlz +IGFuZCBleGNlcHRzLgoKICAgIElmIHRoZXJlIHdlcmUgYW55IHByb2JsZW1zLCB3ZSByYWlzZSBh +biBleGNlcHRpb24gYXQgdGhlIGVuZC4gVGhpcyBhbGxvd3MKICAgIHRoZSBjYWxsaW5nIGNvZGUg +dG8gcmV0cnkgc3RvcHBpbmcgdGhlIGZpcmV3YWxsLiBTdG9wcGluZyB0aGUgZmlyZXdhbGwKICAg +IGNhbiBmYWlsIGlmIGlwdGFibGVzIGlzIGJlaW5nIHJ1biBieSBhbm90aGVyIHByb2Nlc3MgKG9u +bHkgb25lIGlwdGFibGVzCiAgICBjb21tYW5kIGNhbiBiZSBydW4gYXQgYSB0aW1lKS4KICAgICIi +IgogICAgb2sgPSBUcnVlCgogICAgIyAtdCBmaWx0ZXIgLUQgT1VUUFVUIC1qIGJpdG1hc2sKICAg +IHRyeToKICAgICAgICBpcHRhYmxlcygiLS1kZWxldGUiLCAiT1VUUFVUIiwgIi0tanVtcCIsIEJJ +VE1BU0tfQ0hBSU4sIHRocm93PVRydWUpCiAgICBleGNlcHQgc3VicHJvY2Vzcy5DYWxsZWRQcm9j +ZXNzRXJyb3IgYXMgZXhjOgogICAgICAgIGRlYnVnKCJJTkZPOiBub3QgYWJsZSB0byByZW1vdmUg +Yml0bWFzayBmaXJld2FsbCBmcm9tIE9VVFBVVCBjaGFpbiAiCiAgICAgICAgICAgICAgIihtYXli +ZSBpdCBpcyBhbHJlYWR5IHJlbW92ZWQ/KSIsIGV4YykKICAgICAgICBvayA9IEZhbHNlCgogICAg +IyAtdCBuYXQgLUQgT1VUUFVUIC1qIGJpdG1hc2sKICAgIHRyeToKICAgICAgICBpcDR0YWJsZXMo +Ii10IiwgIm5hdCIsICItLWRlbGV0ZSIsICJPVVRQVVQiLAogICAgICAgICAgICAgICAgICAiLS1q +dW1wIiwgQklUTUFTS19DSEFJTl9OQVRfT1VULCB0aHJvdz1UcnVlKQogICAgZXhjZXB0IHN1YnBy +b2Nlc3MuQ2FsbGVkUHJvY2Vzc0Vycm9yIGFzIGV4YzoKICAgICAgICBkZWJ1ZygiSU5GTzogbm90 +IGFibGUgdG8gcmVtb3ZlIGJpdG1hc2sgZmlyZXdhbGwgZnJvbSBPVVRQVVQgY2hhaW4gIgogICAg +ICAgICAgICAgICJpbiAnbmF0JyB0YWJsZSAobWF5YmUgaXQgaXMgYWxyZWFkeSByZW1vdmVkPyki +LCBleGMpCiAgICAgICAgb2sgPSBGYWxzZQoKICAgICMgLXQgbmF0IC1EIFBPU1RST1VUSU5HIC1q +IGJpdG1hc2tfcG9zdHJvdXRpbmcKICAgIHRyeToKICAgICAgICBpcDR0YWJsZXMoIi10IiwgIm5h +dCIsICItLWRlbGV0ZSIsICJQT1NUUk9VVElORyIsCiAgICAgICAgICAgICAgICAgICItLWp1bXAi +LCBCSVRNQVNLX0NIQUlOX05BVF9QT1NULCB0aHJvdz1UcnVlKQogICAgZXhjZXB0IHN1YnByb2Nl +c3MuQ2FsbGVkUHJvY2Vzc0Vycm9yIGFzIGV4YzoKICAgICAgICBkZWJ1ZygiSU5GTzogbm90IGFi +bGUgdG8gcmVtb3ZlIGJpdG1hc2sgZmlyZXdhbGwgZnJvbSBQT1NUUk9VVElORyAiCiAgICAgICAg +ICAgICAgImNoYWluIGluICduYXQnIHRhYmxlIChtYXliZSBpdCBpcyBhbHJlYWR5IHJlbW92ZWQ/ +KSIsIGV4YykKICAgICAgICBvayA9IEZhbHNlCgogICAgIyAtdCBmaWx0ZXIgLS1kZWxldGUtY2hh +aW4gYml0bWFzawogICAgdHJ5OgogICAgICAgIGlwNHRhYmxlcygiLS1mbHVzaCIsIEJJVE1BU0tf +Q0hBSU4sIHRocm93PVRydWUpCiAgICAgICAgaXA0dGFibGVzKCItLWRlbGV0ZS1jaGFpbiIsIEJJ +VE1BU0tfQ0hBSU4sIHRocm93PVRydWUpCiAgICBleGNlcHQgc3VicHJvY2Vzcy5DYWxsZWRQcm9j +ZXNzRXJyb3IgYXMgZXhjOgogICAgICAgIGRlYnVnKCJJTkZPOiBub3QgYWJsZSB0byBmbHVzaCBh +bmQgZGVsZXRlIGJpdG1hc2sgaXB2NCBmaXJld2FsbCAiCiAgICAgICAgICAgICAgImNoYWluICht +YXliZSBpdCBpcyBhbHJlYWR5IGRlc3Ryb3llZD8pIiwgZXhjKQogICAgICAgIG9rID0gRmFsc2UK +CiAgICAjIC10IG5hdCAtLWRlbGV0ZS1jaGFpbiBiaXRtYXNrCiAgICB0cnk6CiAgICAgICAgaXA0 +dGFibGVzKCItdCIsICJuYXQiLCAiLS1mbHVzaCIsIEJJVE1BU0tfQ0hBSU5fTkFUX09VVCwgdGhy +b3c9VHJ1ZSkKICAgICAgICBpcDR0YWJsZXMoIi10IiwgIm5hdCIsICItLWRlbGV0ZS1jaGFpbiIs +CiAgICAgICAgICAgICAgICAgIEJJVE1BU0tfQ0hBSU5fTkFUX09VVCwgdGhyb3c9VHJ1ZSkKICAg +IGV4Y2VwdCBzdWJwcm9jZXNzLkNhbGxlZFByb2Nlc3NFcnJvciBhcyBleGM6CiAgICAgICAgZGVi +dWcoIklORk86IG5vdCBhYmxlIHRvIGZsdXNoIGFuZCBkZWxldGUgYml0bWFzayBpcHY0IGZpcmV3 +YWxsICIKICAgICAgICAgICAgICAiY2hhaW4gaW4gJ25hdCcgdGFibGUgKG1heWJlIGl0IGlzIGFs +cmVhZHkgZGVzdHJveWVkPykiLCBleGMpCiAgICAgICAgb2sgPSBGYWxzZQoKICAgICMgLXQgbmF0 +IC0tZGVsZXRlLWNoYWluIGJpdG1hc2tfcG9zdHJvdXRpbmcKICAgIHRyeToKICAgICAgICBpcDR0 +YWJsZXMoIi10IiwgIm5hdCIsICItLWZsdXNoIiwgQklUTUFTS19DSEFJTl9OQVRfUE9TVCwgdGhy +b3c9VHJ1ZSkKICAgICAgICBpcDR0YWJsZXMoIi10IiwgIm5hdCIsICItLWRlbGV0ZS1jaGFpbiIs +CiAgICAgICAgICAgICAgICAgIEJJVE1BU0tfQ0hBSU5fTkFUX1BPU1QsIHRocm93PVRydWUpCiAg +ICBleGNlcHQgc3VicHJvY2Vzcy5DYWxsZWRQcm9jZXNzRXJyb3IgYXMgZXhjOgogICAgICAgIGRl +YnVnKCJJTkZPOiBub3QgYWJsZSB0byBmbHVzaCBhbmQgZGVsZXRlIGJpdG1hc2sgaXB2NCBmaXJl +d2FsbCAiCiAgICAgICAgICAgICAgImNoYWluIGluICduYXQnIHRhYmxlIChtYXliZSBpdCBpcyBh +bHJlYWR5IGRlc3Ryb3llZD8pIiwgZXhjKQogICAgICAgIG9rID0gRmFsc2UKCiAgICAjIC10IGZp +bHRlciAtLWRlbGV0ZS1jaGFpbiBiaXRtYXNrIChpcHY2KQogICAgdHJ5OgogICAgICAgIGlwNnRh +YmxlcygiLS1mbHVzaCIsIEJJVE1BU0tfQ0hBSU4sIHRocm93PVRydWUpCiAgICAgICAgaXA2dGFi +bGVzKCItLWRlbGV0ZS1jaGFpbiIsIEJJVE1BU0tfQ0hBSU4sIHRocm93PVRydWUpCiAgICBleGNl +cHQgc3VicHJvY2Vzcy5DYWxsZWRQcm9jZXNzRXJyb3IgYXMgZXhjOgogICAgICAgIGRlYnVnKCJJ +TkZPOiBub3QgYWJsZSB0byBmbHVzaCBhbmQgZGVsZXRlIGJpdG1hc2sgaXB2NiBmaXJld2FsbCAi +CiAgICAgICAgICAgICAgImNoYWluIChtYXliZSBpdCBpcyBhbHJlYWR5IGRlc3Ryb3llZD8pIiwg +ZXhjKQogICAgICAgIG9rID0gRmFsc2UKCiAgICBpZiBub3QgKG9rIG9yIGlwdjRfY2hhaW5fZXhp +c3RzIG9yIGlwdjZfY2hhaW5fZXhpc3RzKToKICAgICAgICByYWlzZSBFeGNlcHRpb24oImZpcmV3 +YWxsIG1pZ2h0IHN0aWxsIGJlIGxlZnQgdXAuICIKICAgICAgICAgICAgICAgICAgICAgICAgIlBs +ZWFzZSB0cnkgYGZpcmV3YWxsIHN0b3BgIGFnYWluLiIpCgoKZGVmIGZ3X2VtYWlsX3N0YXJ0KGFy +Z3MpOgogICAgIiIiCiAgICBCcmluZyB1cCB0aGUgZW1haWwgZmlyZXdhbGwuCgogICAgOnBhcmFt +IGFyZ3M6IHRoZSB1c2VyIHVpZCBvZiB0aGUgYml0bWFzayBwcm9jZXNzCiAgICA6dHlwZSBhcmdz +OiBsaXN0CiAgICAiIiIKICAgICMgYWRkIGN1c3RvbSBjaGFpbiAiYml0bWFza19lbWFpbCIgdG8g +ZnJvbnQgb2YgSU5QVVQgY2hhaW4KICAgIGlmIG5vdCBpcHY0X2NoYWluX2V4aXN0cyhCSVRNQVNL +X0NIQUlOX0VNQUlMKToKICAgICAgICBpcDR0YWJsZXMoIi0tbmV3LWNoYWluIiwgQklUTUFTS19D +SEFJTl9FTUFJTCkKICAgIGlmIG5vdCBpcHY2X2NoYWluX2V4aXN0cyhCSVRNQVNLX0NIQUlOX0VN +QUlMKToKICAgICAgICBpcDZ0YWJsZXMoIi0tbmV3LWNoYWluIiwgQklUTUFTS19DSEFJTl9FTUFJ +TCkKICAgIGlwdGFibGVzKCItLWluc2VydCIsICJJTlBVVCIsICItLWp1bXAiLCBCSVRNQVNLX0NI +QUlOX0VNQUlMKQoKICAgICMgYWRkIGN1c3RvbSBjaGFpbiAiYml0bWFza19lbWFpbF9vdXRwdXQi +IHRvIGZyb250IG9mIE9VVFBVVCBjaGFpbgogICAgaWYgbm90IGlwdjRfY2hhaW5fZXhpc3RzKEJJ +VE1BU0tfQ0hBSU5fRU1BSUxfT1VUKToKICAgICAgICBpcDR0YWJsZXMoIi0tbmV3LWNoYWluIiwg +QklUTUFTS19DSEFJTl9FTUFJTF9PVVQpCiAgICBpZiBub3QgaXB2Nl9jaGFpbl9leGlzdHMoQklU +TUFTS19DSEFJTl9FTUFJTF9PVVQpOgogICAgICAgIGlwNnRhYmxlcygiLS1uZXctY2hhaW4iLCBC +SVRNQVNLX0NIQUlOX0VNQUlMX09VVCkKICAgIGlwdGFibGVzKCItLWluc2VydCIsICJPVVRQVVQi +LCAiLS1qdW1wIiwgQklUTUFTS19DSEFJTl9FTUFJTF9PVVQpCgogICAgIyBEaXNhYmxlIHRoZSBh +Y2Nlc3MgdG8gaW1hcCBhbmQgc210cCBmcm9tIG91dHNpZGUKICAgIGlwdGFibGVzKCItLWFwcGVu +ZCIsIEJJVE1BU0tfQ0hBSU5fRU1BSUwsCiAgICAgICAgICAgICAiLS1pbi1pbnRlcmZhY2UiLCBM +T0NBTF9JTlRFUkZBQ0UsICItLXByb3RvY29sIiwgInRjcCIsCiAgICAgICAgICAgICAiLS1kcG9y +dCIsIElNQVBfUE9SVCwgIi0tanVtcCIsICJBQ0NFUFQiKQogICAgaXB0YWJsZXMoIi0tYXBwZW5k +IiwgQklUTUFTS19DSEFJTl9FTUFJTCwKICAgICAgICAgICAgICItLWluLWludGVyZmFjZSIsIExP +Q0FMX0lOVEVSRkFDRSwgIi0tcHJvdG9jb2wiLCAidGNwIiwKICAgICAgICAgICAgICItLWRwb3J0 +IiwgU01UUF9QT1JULCAiLS1qdW1wIiwgIkFDQ0VQVCIpCiAgICBpcHRhYmxlcygiLS1hcHBlbmQi +LCBCSVRNQVNLX0NIQUlOX0VNQUlMLAogICAgICAgICAgICAgIi0tcHJvdG9jb2wiLCAidGNwIiwg +Ii0tZHBvcnQiLCBJTUFQX1BPUlQsICItLWp1bXAiLCAiUkVKRUNUIikKICAgIGlwdGFibGVzKCIt +LWFwcGVuZCIsIEJJVE1BU0tfQ0hBSU5fRU1BSUwsCiAgICAgICAgICAgICAiLS1wcm90b2NvbCIs +ICJ0Y3AiLCAiLS1kcG9ydCIsIFNNVFBfUE9SVCwgIi0tanVtcCIsICJSRUpFQ1QiKQoKICAgIGlm +IG5vdCBhcmdzIG9yIG5vdCBQQVJBTV9GT1JNQVRTWyJVSUQiXShhcmdzWzBdKToKICAgICAgICBy +YWlzZSBFeGNlcHRpb24oIk5vIHVpZCBnaXZlbiIpCiAgICB1aWQgPSBhcmdzWzBdCgogICAgIyBP +bmx5IHRoZSB1bml4ICd1aWQnIGhhdmUgYWNjZXNzIHRvIHRoZSBlbWFpbCBpbWFwIGFuZCBzbXRw +IHBvcnRzCiAgICBpcHRhYmxlcygiLS1hcHBlbmQiLCBCSVRNQVNLX0NIQUlOX0VNQUlMX09VVCwK +ICAgICAgICAgICAgICItLW91dC1pbnRlcmZhY2UiLCBMT0NBTF9JTlRFUkZBQ0UsCiAgICAgICAg +ICAgICAiLS1tYXRjaCIsICJvd25lciIsICItLXVpZC1vd25lciIsIHVpZCwgIi0tcHJvdG9jb2wi +LCAidGNwIiwKICAgICAgICAgICAgICItLWRwb3J0IiwgSU1BUF9QT1JULCAiLS1qdW1wIiwgIkFD +Q0VQVCIpCiAgICBpcHRhYmxlcygiLS1hcHBlbmQiLCBCSVRNQVNLX0NIQUlOX0VNQUlMX09VVCwK +ICAgICAgICAgICAgICItLW91dC1pbnRlcmZhY2UiLCBMT0NBTF9JTlRFUkZBQ0UsCiAgICAgICAg +ICAgICAiLS1tYXRjaCIsICJvd25lciIsICItLXVpZC1vd25lciIsIHVpZCwgIi0tcHJvdG9jb2wi +LCAidGNwIiwKICAgICAgICAgICAgICItLWRwb3J0IiwgU01UUF9QT1JULCAiLS1qdW1wIiwgIkFD +Q0VQVCIpCiAgICBpcHRhYmxlcygiLS1hcHBlbmQiLCBCSVRNQVNLX0NIQUlOX0VNQUlMX09VVCwK +ICAgICAgICAgICAgICItLW91dC1pbnRlcmZhY2UiLCBMT0NBTF9JTlRFUkZBQ0UsCiAgICAgICAg +ICAgICAiLS1wcm90b2NvbCIsICJ0Y3AiLCAiLS1kcG9ydCIsIElNQVBfUE9SVCwgIi0tanVtcCIs +ICJSRUpFQ1QiKQogICAgaXB0YWJsZXMoIi0tYXBwZW5kIiwgQklUTUFTS19DSEFJTl9FTUFJTF9P +VVQsCiAgICAgICAgICAgICAiLS1vdXQtaW50ZXJmYWNlIiwgTE9DQUxfSU5URVJGQUNFLAogICAg +ICAgICAgICAgIi0tcHJvdG9jb2wiLCAidGNwIiwgIi0tZHBvcnQiLCBTTVRQX1BPUlQsICItLWp1 +bXAiLCAiUkVKRUNUIikKCgpkZWYgZndfZW1haWxfc3RvcCgpOgogICAgIiIiCiAgICBTdG9wIHRo +ZSBlbWFpbCBmaXJld2FsbC4KICAgICIiIgogICAgb2sgPSBUcnVlCgogICAgdHJ5OgogICAgICAg +IGlwdGFibGVzKCItLWRlbGV0ZSIsICJJTlBVVCIsICItLWp1bXAiLCBCSVRNQVNLX0NIQUlOX0VN +QUlMLAogICAgICAgICAgICAgICAgIHRocm93PVRydWUpCiAgICBleGNlcHQgc3VicHJvY2Vzcy5D +YWxsZWRQcm9jZXNzRXJyb3IgYXMgZXhjOgogICAgICAgIGRlYnVnKCJJTkZPOiBub3QgYWJsZSB0 +byByZW1vdmUgYml0bWFzayBlbWFpbCBmaXJld2FsbCBmcm9tIElOUFVUICIKICAgICAgICAgICAg +ICAiY2hhaW4gKG1heWJlIGl0IGlzIGFscmVhZHkgcmVtb3ZlZD8pIiwgZXhjKQogICAgICAgIG9r +ID0gRmFsc2UKCiAgICB0cnk6CiAgICAgICAgaXB0YWJsZXMoIi0tZGVsZXRlIiwgIk9VVFBVVCIs +ICItLWp1bXAiLCBCSVRNQVNLX0NIQUlOX0VNQUlMX09VVCwKICAgICAgICAgICAgICAgICB0aHJv +dz1UcnVlKQogICAgZXhjZXB0IHN1YnByb2Nlc3MuQ2FsbGVkUHJvY2Vzc0Vycm9yIGFzIGV4YzoK +ICAgICAgICBkZWJ1ZygiSU5GTzogbm90IGFibGUgdG8gcmVtb3ZlIGJpdG1hc2sgZW1haWwgZmly +ZXdhbGwgZnJvbSBPVVRQVVQgIgogICAgICAgICAgICAgICJjaGFpbiAobWF5YmUgaXQgaXMgYWxy +ZWFkeSByZW1vdmVkPykiLCBleGMpCiAgICAgICAgb2sgPSBGYWxzZQoKICAgIHRyeToKICAgICAg +ICBpcDR0YWJsZXMoIi0tZmx1c2giLCBCSVRNQVNLX0NIQUlOX0VNQUlMLCB0aHJvdz1UcnVlKQog +ICAgICAgIGlwNHRhYmxlcygiLS1kZWxldGUtY2hhaW4iLCBCSVRNQVNLX0NIQUlOX0VNQUlMLCB0 +aHJvdz1UcnVlKQogICAgZXhjZXB0IHN1YnByb2Nlc3MuQ2FsbGVkUHJvY2Vzc0Vycm9yIGFzIGV4 +YzoKICAgICAgICBkZWJ1ZygiSU5GTzogbm90IGFibGUgdG8gZmx1c2ggYW5kIGRlbGV0ZSBiaXRt +YXNrIGlwdjQgZW1haWwgZmlyZXdhbGwgIgogICAgICAgICAgICAgICJjaGFpbiAobWF5YmUgaXQg +aXMgYWxyZWFkeSBkZXN0cm95ZWQ/KSIsIGV4YykKICAgICAgICBvayA9IEZhbHNlCgogICAgdHJ5 +OgogICAgICAgIGlwNnRhYmxlcygiLS1mbHVzaCIsIEJJVE1BU0tfQ0hBSU5fRU1BSUwsIHRocm93 +PVRydWUpCiAgICAgICAgaXA2dGFibGVzKCItLWRlbGV0ZS1jaGFpbiIsIEJJVE1BU0tfQ0hBSU5f +RU1BSUwsIHRocm93PVRydWUpCiAgICBleGNlcHQgc3VicHJvY2Vzcy5DYWxsZWRQcm9jZXNzRXJy +b3IgYXMgZXhjOgogICAgICAgIGRlYnVnKCJJTkZPOiBub3QgYWJsZSB0byBmbHVzaCBhbmQgZGVs +ZXRlIGJpdG1hc2sgaXB2NiBlbWFpbCBmaXJld2FsbCAiCiAgICAgICAgICAgICAgImNoYWluICht +YXliZSBpdCBpcyBhbHJlYWR5IGRlc3Ryb3llZD8pIiwgZXhjKQogICAgICAgIG9rID0gRmFsc2UK +CiAgICB0cnk6CiAgICAgICAgaXA0dGFibGVzKCItLWZsdXNoIiwgQklUTUFTS19DSEFJTl9FTUFJ +TF9PVVQsIHRocm93PVRydWUpCiAgICAgICAgaXA0dGFibGVzKCItLWRlbGV0ZS1jaGFpbiIsIEJJ +VE1BU0tfQ0hBSU5fRU1BSUxfT1VULCB0aHJvdz1UcnVlKQogICAgZXhjZXB0IHN1YnByb2Nlc3Mu +Q2FsbGVkUHJvY2Vzc0Vycm9yIGFzIGV4YzoKICAgICAgICBkZWJ1ZygiSU5GTzogbm90IGFibGUg +dG8gZmx1c2ggYW5kIGRlbGV0ZSBiaXRtYXNrIGlwdjQgZW1haWwgZmlyZXdhbGwgIgogICAgICAg +ICAgICAgICJjaGFpbiAobWF5YmUgaXQgaXMgYWxyZWFkeSBkZXN0cm95ZWQ/KSIsIGV4YykKICAg +ICAgICBvayA9IEZhbHNlCgogICAgdHJ5OgogICAgICAgIGlwNnRhYmxlcygiLS1mbHVzaCIsIEJJ +VE1BU0tfQ0hBSU5fRU1BSUxfT1VULCB0aHJvdz1UcnVlKQogICAgICAgIGlwNnRhYmxlcygiLS1k +ZWxldGUtY2hhaW4iLCBCSVRNQVNLX0NIQUlOX0VNQUlMX09VVCwgdGhyb3c9VHJ1ZSkKICAgIGV4 +Y2VwdCBzdWJwcm9jZXNzLkNhbGxlZFByb2Nlc3NFcnJvciBhcyBleGM6CiAgICAgICAgZGVidWco +IklORk86IG5vdCBhYmxlIHRvIGZsdXNoIGFuZCBkZWxldGUgYml0bWFzayBpcHY2IGVtYWlsIGZp +cmV3YWxsICIKICAgICAgICAgICAgICAiY2hhaW4gKG1heWJlIGl0IGlzIGFscmVhZHkgZGVzdHJv +eWVkPykiLCBleGMpCiAgICAgICAgb2sgPSBGYWxzZQoKICAgIGlmIG5vdCAob2sgb3IgaXB2NF9j +aGFpbl9leGlzdHMgb3IgaXB2Nl9jaGFpbl9leGlzdHMpOgogICAgICAgIHJhaXNlIEV4Y2VwdGlv +bigiZW1haWwgZmlyZXdhbGwgbWlnaHQgc3RpbGwgYmUgbGVmdCB1cC4gIgogICAgICAgICAgICAg +ICAgICAgICAgICAiUGxlYXNlIHRyeSBgZnctZW1haWwgc3RvcGAgYWdhaW4uIikKCgojCiMgTUFJ +TgojCgoKZGVmIG1haW4oKToKICAgICIiIgogICAgRW50cnkgcG9pbnQgZm9yIGNtZGxpbmUgZXhl +Y3V0aW9uLgogICAgIiIiCiAgICAjIFRPRE8gdXNlIGFyZ3BhcnNlIGluc3RlYWQuCgogICAgaWYg +bGVuKHN5cy5hcmd2KSA+PSAyOgogICAgICAgIGNvbW1hbmQgPSAiXyIuam9pbihzeXMuYXJndlsx +OjNdKQogICAgICAgIGFyZ3MgPSBzeXMuYXJndlszOl0KCiAgICAgICAgaXNfcmVzdGFydCA9IEZh +bHNlCiAgICAgICAgaWYgYXJncyBhbmQgYXJnc1swXSA9PSAicmVzdGFydCI6CiAgICAgICAgICAg +IGlzX3Jlc3RhcnQgPSBUcnVlCiAgICAgICAgICAgIGFyZ3MucmVtb3ZlKCdyZXN0YXJ0JykKCiAg +ICAgICAgaWYgY29tbWFuZCA9PSAidmVyc2lvbiI6CiAgICAgICAgICAgIHByaW50KFZFUlNJT04p +CiAgICAgICAgICAgIGV4aXQoMCkKCiAgICAgICAgaWYgb3MuZ2V0dWlkKCkgIT0gMDoKICAgICAg +ICAgICAgYmFpbCgiRVJST1I6IG11c3QgYmUgcnVuIGFzIHJvb3QiKQoKICAgICAgICBpZiBjb21t +YW5kID09ICJvcGVudnBuX3N0YXJ0IjoKICAgICAgICAgICAgb3BlbnZwbl9zdGFydChhcmdzKQoK +ICAgICAgICBlbGlmIGNvbW1hbmQgPT0gIm9wZW52cG5fc3RvcCI6CiAgICAgICAgICAgIG9wZW52 +cG5fc3RvcChhcmdzKQoKICAgICAgICBlbGlmIGNvbW1hbmQgPT0gImZpcmV3YWxsX3N0YXJ0IjoK +ICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgZmlyZXdhbGxfc3RhcnQoYXJncykKICAg +ICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBleDoKICAgICAgICAgICAgICAgIGlmIG5vdCBp +c19yZXN0YXJ0OgogICAgICAgICAgICAgICAgICAgIGZpcmV3YWxsX3N0b3AoKQogICAgICAgICAg +ICAgICAgYmFpbCgiRVJST1I6IGNvdWxkIG5vdCBzdGFydCBmaXJld2FsbCIsIGV4KQoKICAgICAg +ICBlbGlmIGNvbW1hbmQgPT0gImZpcmV3YWxsX3N0b3AiOgogICAgICAgICAgICB0cnk6CiAgICAg +ICAgICAgICAgICBmaXJld2FsbF9zdG9wKCkKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBh +cyBleDoKICAgICAgICAgICAgICAgIGJhaWwoIkVSUk9SOiBjb3VsZCBub3Qgc3RvcCBmaXJld2Fs +bCIsIGV4KQoKICAgICAgICBlbGlmIGNvbW1hbmQgPT0gImZpcmV3YWxsX2lzdXAiOgogICAgICAg +ICAgICBpZiBpcHY0X2NoYWluX2V4aXN0cyhCSVRNQVNLX0NIQUlOKToKICAgICAgICAgICAgICAg +ICMgdG9vIHZlcmJvc2Ugc2luY2UgYml0bWFzayBwb2xscyB0aGlzCiAgICAgICAgICAgICAgICBw +YXNzCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBiYWlsKCJJTkZPOiBiaXRtYXNr +IGZpcmV3YWxsIGlzIGRvd24iKQoKICAgICAgICBlbGlmIGNvbW1hbmQgPT0gImZ3LWVtYWlsX3N0 +YXJ0IjoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgZndfZW1haWxfc3RhcnQoYXJn +cykKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBleDoKICAgICAgICAgICAgICAgIGlm +IG5vdCBpc19yZXN0YXJ0OgogICAgICAgICAgICAgICAgICAgIGZ3X2VtYWlsX3N0b3AoKQogICAg +ICAgICAgICAgICAgYmFpbCgiRVJST1I6IGNvdWxkIG5vdCBzdGFydCBlbWFpbCBmaXJld2FsbCIs +IGV4KQoKICAgICAgICBlbGlmIGNvbW1hbmQgPT0gImZ3LWVtYWlsX3N0b3AiOgogICAgICAgICAg +ICB0cnk6CiAgICAgICAgICAgICAgICBmd19lbWFpbF9zdG9wKCkKICAgICAgICAgICAgZXhjZXB0 +IEV4Y2VwdGlvbiBhcyBleDoKICAgICAgICAgICAgICAgIGJhaWwoIkVSUk9SOiBjb3VsZCBub3Qg +c3RvcCBlbWFpbCBmaXJld2FsbCIsIGV4KQoKICAgICAgICBlbGlmIGNvbW1hbmQgPT0gImZ3LWVt +YWlsX2lzdXAiOgogICAgICAgICAgICBpZiBpcHY0X2NoYWluX2V4aXN0cyhCSVRNQVNLX0NIQUlO +X0VNQUlMKToKICAgICAgICAgICAgICAgIGxvZygiJXM6IElORk86IGJpdG1hc2sgZW1haWwgZmly +ZXdhbGwgaXMgdXAiICUgKFNDUklQVCwpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAg +ICAgYmFpbCgiSU5GTzogYml0bWFzayBlbWFpbCBmaXJld2FsbCBpcyBkb3duIikKCiAgICAgICAg +ZWxzZToKICAgICAgICAgICAgYmFpbCgiRVJST1I6IE5vIHN1Y2ggY29tbWFuZCIpCiAgICBlbHNl +OgogICAgICAgIGJhaWwoIkVSUk9SOiBObyBzdWNoIGNvbW1hbmQiKQoKCmlmIF9fbmFtZV9fID09 +ICJfX21haW5fXyI6CiAgICBkZWJ1ZygiICIuam9pbihzeXMuYXJndikpCiAgICBtYWluKCkKICAg +IGV4aXQoMCkK +""" +POLKIT = """PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHBvbGljeWNv +bmZpZyBQVUJMSUMKICItLy9mcmVlZGVza3RvcC8vRFREIFBvbGljeUtpdCBQb2xpY3kgQ29uZmln +dXJhdGlvbiAxLjAvL0VOIgogImh0dHA6Ly93d3cuZnJlZWRlc2t0b3Aub3JnL3N0YW5kYXJkcy9Q +b2xpY3lLaXQvMS9wb2xpY3ljb25maWcuZHRkIj4KPHBvbGljeWNvbmZpZz4KCiAgPHZlbmRvcj5M +RUFQIFByb2plY3Q8L3ZlbmRvcj4KICA8dmVuZG9yX3VybD5odHRwOi8vbGVhcC5zZS88L3ZlbmRv +cl91cmw+CgogIDxhY3Rpb24gaWQ9InNlLmxlYXAuYml0bWFzay5idW5kbGUucG9saWN5Ij4KICAg +IDxkZXNjcmlwdGlvbj5SdW5zIGJpdG1hc2sgaGVscGVyIHRvIGxhdW5jaCBmaXJld2FsbCBhbmQg +b3BlbnZwbiAoYnVuZGxlIHZlcnNpb24pPC9kZXNjcmlwdGlvbj4KICAgIDxkZXNjcmlwdGlvbiB4 +bWw6bGFuZz0iZXMiPkVqZWN1dGEgZWwgYXNpc3RlbnRlIGRlIGJpdG1hc2sgcGFyYSBsYW56YXIg +ZWwgZmlyZXdhbGwgeSBvcGVudnBuICh2ZXJzaW9uIGJ1bmRsZSk8L2Rlc2NyaXB0aW9uPgogICAg +PG1lc3NhZ2U+Qml0bWFzayBuZWVkcyB0aGF0IHlvdSBhdXRoZW50aWNhdGUgdG8gc3RhcnQ8L21l +c3NhZ2U+CiAgICA8bWVzc2FnZSB4bWw6bGFuZz0iZXMiPkJpdG1hc2sgbmVjZXNpdGEgYXV0b3Jp +emFjaW9uIHBhcmEgY29tZW56YXI8L21lc3NhZ2U+CiAgICA8aWNvbl9uYW1lPnBhY2thZ2UteC1n +ZW5lcmljPC9pY29uX25hbWU+IAogICAgPGRlZmF1bHRzPgogICAgICA8YWxsb3dfYW55Pnllczwv +YWxsb3dfYW55PgogICAgICA8YWxsb3dfaW5hY3RpdmU+eWVzPC9hbGxvd19pbmFjdGl2ZT4KICAg +ICAgPGFsbG93X2FjdGl2ZT55ZXM8L2FsbG93X2FjdGl2ZT4KICAgIDwvZGVmYXVsdHM+CiAgICA8 +YW5ub3RhdGUga2V5PSJvcmcuZnJlZWRlc2t0b3AucG9saWN5a2l0LmV4ZWMucGF0aCI+L3Vzci9s +b2NhbC9zYmluL2JpdG1hc2stcm9vdDwvYW5ub3RhdGU+CiAgPC9hY3Rpb24+CjwvcG9saWN5Y29u +ZmlnPgo= +""" +BMROOT_DEST = "/usr/local/sbin/bitmask-root" +with open(BMROOT_DEST, "w") as bmroot: + lines = str(decode(BMROOT)).split("\n") + for line in lines: + bmroot.write(line + "\n") +with open('/usr/share/polkit-1/actions/se.leap.bitmask.bundle.policy', 'w') as polkit: + lines = str(decode(POLKIT)).split("\n") + for line in lines: + polkit.write(line + "\n") +subprocess.Popen(["chmod", "+x", BMROOT_DEST]) diff --git a/pkg/riseupvpn/snap/hooks/remove b/pkg/riseupvpn/snap/hooks/remove new file mode 100755 index 00000000..c7442a26 --- /dev/null +++ b/pkg/riseupvpn/snap/hooks/remove @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +echo "Executing remove hook for RiseupVPN" +rm "/usr/local/sbin/bitmask-root" +rm "/usr/share/polkit-1/actions/se.leap.bitmask.bundle.policy" +echo "done" diff --git a/pkg/riseupvpn/snap/snapcraft.yaml b/pkg/riseupvpn/snap/snapcraft.yaml index 024bdf3b..f358615b 100644 --- a/pkg/riseupvpn/snap/snapcraft.yaml +++ b/pkg/riseupvpn/snap/snapcraft.yaml @@ -8,8 +8,8 @@ description: | Just click on it. And don't forget to donate. grade: devel # must be 'stable' to release into candidate/stable channels -#confinement: devmode #classic # use 'strict' once you have the right plugs and slots confinement: classic +icon: snap/gui/riseupvpn.svg parts: @@ -17,7 +17,7 @@ parts: plugin: python python-version: python2 source-branch: snap - # XXX change to leap/master + # XXX change to leap/master when merged source: https://0xacab.org/kali/bitmask-dev.git requirements: pkg/requirements-vpn.pip stage-packages: @@ -31,11 +31,13 @@ parts: plugin: nil stage-packages: - openvpn + # TODO copy openvpn to /usr/local/sbin bitmask-systray: plugin: go source: https://0xacab.org/leap/bitmask-systray.git build-packages: - pkg-config + - patchelf - libzmq5 - libzmq3-dev - libsodium-dev @@ -45,16 +47,20 @@ parts: - libzmq5 - libsodium18 - libappindicator3-1 + install: | + TRIPLET_PATH="$SNAPCRAFT_PART_INSTALL/usr/lib/$(gcc -print-multiarch)" + LIBZMQ=$(readlink -n $TRIPLET_PATH/libzmq.so.5) + LIBSOD=$(readlink -n $TRIPLET_PATH/libsodium.so.18) + ln -s "../usr/lib/$(gcc -print-multiarch)/$LIBZMQ" $SNAPCRAFT_PART_INSTALL/bin/libzmq.so.5 + ln -s "../usr/lib/$(gcc -print-multiarch)/$LIBSOD" $SNAPCRAFT_PART_INSTALL/bin/libsodium.so.18 + patchelf --set-rpath /snap/riseup-vpn/current/bin/ $SNAPCRAFT_PART_INSTALL/bin/bitmask-systray.git desktop-gtk3: prime: ['*'] apps: bitmask-systray: command: ./bin/bitmask-systray.git - plugs: [x11, network] launcher: command: ./bin/bitmask_anonvpn - plugs: [x11, network] bitmaskd: command: ./bin/bitmaskd - plugs: [network] |