{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.11"},"kaggle":{"accelerator":"nvidiaTeslaT4","isGpuEnabled":true,"isInternetEnabled":false,"language":"python","sourceType":"notebook"}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"4941a3bf-880d-4739-90e5-d907a27b7d92","cell_type":"markdown","source":"# RSNA v5 probe: 正式训练探路 run (main 路径, fold0, GPU)\n目的:验证 notebook 提交链路 + 拿首条 LB 分数(探路,非全量)。\n变更(2026-09-06, 本地干跑验证后):\n1. 报告抽取器标签(rsna_report_labels.py, 弃 barun 0.5 死值)✅ 五环已过;\n2. 提交列名 LABELS_EN→LABELS(带空格/Baker's, 与 sample_submission 一致,修 400);\n3. plane_oof_auc 只用官方 gold 0/1 表评估 + 单类保护;\n4. --only-fold 0 探路:GroupKFold(5) 切分不变,只训第 0 折(4/5 数据与正式同分布),\n   test 推理用该折模型(代码现状:test 用最后一折模型);OOF AUC 单折不完整故跳过;\n5. 环境:numpy 2.0.2 + torch 2.2.0+cu118 共存,代码禁 .cpu().numpy() 用 tolist。\n命令:python rsna_v3.py --planes sagittal --epochs 3 --folds 5 --only-fold 0","metadata":{}},{"id":"cf839cde-cc39-4d7f-8215-b0034fc2c580","cell_type":"code","source":"# 提交模式:禁网(enable_internet:false),torch 2.2.0+cu118 + nvidia-cu11 依赖全部离线安装\n# 坑1:Kaggle 挂载把文件名中 '+' 去掉(2.2.0cu118=非法 PEP440)→ 复制为合法名\n# 坑2:torch 2.2.0+cu118 的 CUDA 库在 nvidia-*-cu11 依赖包中(不在 torch wheel 内),\n#     只装 torch 会缺 libcudart(v8/v9 实证)→ 必须显式安装全部 13 个 wheel\n# 坑3:/kaggle/working 会被收集为 kernel 输出 → 装完立即删除\nimport subprocess, sys, os, glob, shutil\nwh = sorted(glob.glob('/kaggle/input/**/*.whl', recursive=True))\nprint('挂载 wheel 共', len(wh), '个')\nfor w in wh: print('  ', os.path.basename(w))\nassert len(wh) >= 13, 'FAIL: 离线 wheel 不足(应 13: torch+torchvision+11 nvidia-cu11)'\nfixed = []\nfor w in wh:\n    base = os.path.basename(w)\n    dst = os.path.join('/kaggle/working', base.replace('cu118', '+cu118', 1) if 'cu118' in base else base)\n    shutil.copy(w, dst)\n    fixed.append(dst)\nprint('安装 wheel:', [os.path.basename(f) for f in fixed])\nsubprocess.check_call([sys.executable,\"-m\",\"pip\",\"uninstall\",\"-y\",\"-q\",\"torch\",\"torchvision\",\"torchaudio\"])\n# 显式安装全部 wheel(--no-deps --no-index: 无版本解析/无联网)\nsubprocess.check_call([sys.executable,\"-m\",\"pip\",\"install\",\"-q\",\"--no-deps\",\"--no-index\"] + fixed)\nfor f in fixed: os.remove(f)\nimport numpy, torch, torchvision, sklearn, pandas\nprint(\"torch\", torch.__version__, \"cuda\", torch.version.cuda, \"| numpy\", numpy.__version__)\nassert torch.cuda.is_available()\nprint(\"GPU:\", torch.cuda.get_device_name(0))\n","metadata":{},"outputs":[],"execution_count":null},{"id":"7d52b285-e40d-4642-9f76-3a19e849a4c2","cell_type":"code","source":"# preflight:test DICOM 布局抽样(防训完才暴露 test 读不到,浪费额度)\n# 扫描兼容 1/2/3 层挂载:/kaggle/input/<slug>/、/<slug>/<slug>、/competitions/<slug>;\n# 跳过 train_series/test_series 大目录(内部不可能有 test.csv)\nimport os\nbase='/kaggle/input'\ndef _find(b, depth=0, max_depth=3):\n    if not os.path.isdir(b): return None\n    try: entries = sorted(os.listdir(b))\n    except OSError: return None\n    for e in entries:\n        p = os.path.join(b, e)\n        if not os.path.isdir(p): continue\n        if e in ('train_series', 'test_series'): continue\n        if os.path.isfile(os.path.join(p, 'test.csv')) and os.path.isdir(os.path.join(p, 'test_series')):\n            return p\n        if depth < max_depth - 1:\n            r = _find(p, depth + 1)\n            if r: return r\n    return None\nroot = _find(base)\nif root is None:\n    raise SystemExit('FAIL: 未找到含 test_series+test.csv 的比赛挂载(已扫 /kaggle/input 3 层)')\nprint('root =', root)\nts=os.path.join(root,'test_series'); n_dcm=0\nfor st in sorted(os.listdir(ts))[:3]:\n    sp=os.path.join(ts,st)\n    if not os.path.isdir(sp): continue\n    for se in sorted(os.listdir(sp))[:3]:\n        sdir=os.path.join(sp,se)\n        if not os.path.isdir(sdir): continue\n        k=len([f for f in os.listdir(sdir) if f.lower().endswith('.dcm')])\n        print(' study', st[:14], 'series', se[:14], 'dcm:', k); n_dcm+=k\nprint('preflight:', 'OK' if n_dcm>0 else 'FAIL: test DICOM 为空')\nassert n_dcm>0\n","metadata":{},"outputs":[],"execution_count":null},{"id":"30b5ae90-a60e-4a06-972e-7557aec708cd","cell_type":"code","source":"import base64, os\nparts = []\nparts.append('IyAtKi0gY29kaW5nOiB1dGYtOCAtKi0KIiIiClJTTkEgS25lZSBBYm5vcm1hbGl0eSBEZXRlY3Rpb24g4oCUIHYyKOaMiSBBbmF0b21pY2FsX1BsYW5lIOWIhuW5s+mdoueLrOeri+W7uuaooSArIOiejeWQiCkKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0K55u45a+5IGJhc2VsaW5lKHJzbmFfYmFzZWxpbmUucHkp55qE5qC45b+D5pS55YqoOgotIGJhc2VsaW5lIOaKiiBzdHVkeSDlhoXmiYDmnInlubPpnaLnmoQgc2VyaWVzIOeyl+aatOaLvOaIkOmAmumBkzt2MiDmjIkgQW5hdG9taWNhbF9QbGFuZQogIChBeGlhbCAvIFNhZ2l0dGFsIC8gQ29yb25hbCnlkITorq3kuIDkuKrni6znq4sgUmVzTmV0MzQs5bmz6Z2i5YaF6YOo5YaN5YGaIDIuNUQgY2xpcDsKLSB0ZXN0IOaOqOeQhuaXtuavj+S4quW5s+mdouaooeWei+eLrOeri+mihOa1iyzmnIDnu4jmjIkg5ZCE5bmz6Z2iIE9PRiDlro/lubPlnYcgQVVDIOWKoOadg+iejeWQiAogICjmnYPph43lj68gLS1mdXNlIHdlaWdodCDnlKggQVVDIOWKoOadgyzmiJYgLS1mdXNlIG1lYW4g566A5Y2V5bmz5Z2HKTsKLSDmn5Agc3R1ZHkg57y65p+Q5bmz6Z2i5pe2LOiejeWQiOWPquWvueivpSBzdHVkeSDlrp7pmYXlj6/nlKjnmoTlubPpnaLlvZLkuIDljJbmnYPph43jgIIKCuWFtuS9memAu+i+kSjova/moIfnrb7loavlhYXjgIFHcm91cEtGb2xk44CBdmFsaWQg5o6p56CB5o2f5aSx44CBRElDT00g6aKE5aSE55CGKeS4jiBiYXNlbGluZSDkuIDoh7TjgIIKCui/kOihjOeOr+WigzpLYWdnbGUgTm90ZWJvb2soR1BVLOaMgui9veavlOi1m+aVsOaNriArIOekvuWMuui9r+agh+etvuaVsOaNrumbhinjgIIK55So5rOVOgogICAgIXB5dGhvbiByc25hX3YyLnB5IC0tZXBvY2hzIDMgLS1iYXRjaCAxNiAtLW4tY2xpcHMgMiAtLXBsYW5lcyBzYWdpdHRhbCxjb3JvbmFsCiAgICAhcHl0aG9uIHJzbmFfdjIucHkgLS1lcG9jaHMgMyAtLWJhdGNoIDE2IC0tZnVzZSB3ZWlnaHQgLS1wc2V1ZG8tY29uZiAwLjMK6L6T5Ye6OiBzdWJtaXNzaW9uLmNzdihTdHVkeUluc3RhbmNlVUlEICsgMTIg5YiX572u5L+h5YiG5pWwKQoiIiIKaW1wb3J0IGFyZ3BhcnNlCmltcG9ydCBvcwppbXBvcnQgc3lzCmltcG9ydCB0aW1lCmltcG9ydCB3YXJuaW5ncwoKaW1wb3J0IG51bXB5IGFzIG5wCmltcG9ydCBwYW5kYXMgYXMgcGQKCnRyeToKICAgIGltcG9ydCB0b3JjaAogICAgaW1wb3J0IHRvcmNoLm5uIGFzIG5uCiAgICBmcm9tIHRvcmNoLnV0aWxzLmRhdGEgaW1wb3J0IERhdGFzZXQsIERhdGFMb2FkZXIKICAgIGZyb20gdG9yY2gub3B0aW0gaW1wb3J0IEFkYW1XCiAgICBmcm9tIHRvcmNoLm9wdGltLmxyX3NjaGVkdWxlciBpbXBvcnQgQ29zaW5lQW5uZWFsaW5nTFIKICAgIEhBU19UT1JDSCA9IFRydWUKZXhjZXB0IEltcG9ydEVycm9yOgogICAgSEFTX1RPUkNIID0gRmFsc2UKCnRyeToKICAgIGltcG9ydCB0b3JjaHZpc2lvbi5tb2RlbHMgYXMgdHZtCiAgICBIQVNfVFYgPSBUcnVlCmV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgIEhBU19UViA9IEZhbHNlCgp0cnk6CiAgICBpbXBvcnQgcHlkaWNvbQogICAgSEFTX1BZRElDT00gPSBUcnVlCmV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgIEhBU19QWURJQ09NID0gRmFsc2UKCnRyeToKICAgIGltcG9ydCByc25hX3JlcG9ydF9sYWJlbHMgYXMgUkwgICAjIOaKpeWRiuKGkjEyIOeXheeBtuW8seagh+etvijkuI4gcnNuYV92My5weSDlkIznm67lvZUpCiAgICBIQVNfUkwgPSBUcnVlCmV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgIEhBU19STCA9IEZhbHNlCgpmcm9tIHNrbGVhcm4ubW9kZWxfc2VsZWN0aW9uIGltcG9ydCBHcm91cEtGb2xkCmZyb20gc2tsZWFybi5tZXRyaWNzIGltcG9ydCByb2NfYXVjX3Njb3JlCgp3YXJuaW5ncy5maWx0ZXJ3YXJuaW5ncygiaWdub3JlIikKCkxBQkVMUyA9IFsiQUNMIiwgIk1DTCIsICJNZWRpYWwgTWVuaXNjdXMiLCAiTGF0ZXJhbCBNZW5pc2N1cyIsCiAgICAgICAgICAiTWVkaWFsIE9BIiwgIkxhdGVyYWwgT0EiLCAiUEYgT0EiLCAiRWZmdXNpb24iLCAiU3lub3ZpdGlzIiwKICAgICAgICAgICJCYWtlcidzIiwgIkNvbnR1c2lvbiIsICJGcmFjdHVyZSJdCkxBQkVMU19FTiA9IFsiQUNMIiwgIk1DTCIsICJNZWRpYWxNZW5pc2N1cyIsICJMYXRlcmFsTWVuaXNjdXMiLAogICAgICAgICAgICAgIk1lZGlhbE9BIiwgIkxhdGVyYWxPQSIsICJQRk9BIiwgIkVmZnVzaW9uIiwgIlN5bm92aXRpcyIsCiAgICAgICAgICAgICAiQmFrZXJzIiwgIkNvbnR1c2lvbiIsICJGcmFjdHVyZSJdICAjIOWIl+WQjeWuieWFqOWMlijlhpnmj5DkuqTnlKgpClBMQU5FUyA9IFsiQXhpYWwiLCAiU2FnaXR0YWwiLCAiQ29yb25hbCJdCgpJTUdfU0laRSA9IDIyNApDTElQID0gMyAgICAgICAgICAjIOavjyBjbGlwIOWIh+eJh+aVsChwcmV2L2NlbnRlci9uZXh0KQpNQVhfU0VSSUVTID0gNCAgICAjIOavjyBzdHVkeSDmr4/kuKrlubPpnaLmnIDlpJrlj5bnmoQgc2VyaWVzIOaVsCh2MiDmjInlubPpnaLlj5Ys5Y2V5bmz6Z2iIHNlcmllcyDmm7TlsJEsNCDotrPlpJ8pCkZPTERTID0gNQpTRUVEID0gNDIKCgpkZWYgcmVzb2x2ZV9wYXRocygpOgogICAgIiIi5pWw5o2u5a6a5L2N6aG65bqPOjEpIC9rYWdnbGUvaW5wdXQg5oyC6L29OzIpIGthZ2dsZWh1YiDoh6rliqjkuIvovb07Mykg5pys5ZywIHJzbmFfa25lZS8g55uu5b2V44CCIiIiCiAgICAjIDEpIEthZ2dsZSDmjILovb0o5YW85a655aSa5bGC5oyC6L29Oi9rYWdnbGUvaW5wdXQvPOaVsOaNruWQjT4vIOaIliAva2FnZ2xlL2lucHV0LzzliIbnsbs+LzzmlbDmja7lkI0+LykKICAgIGlmIG9zLnBhdGguaXNkaXIoIi9rYWdnbGUvaW5wdXQiKToKICAgICAgICBmb3Igc3ViIGluIHNvcnRlZChvcy5saXN0ZGlyKCIva2FnZ2xlL2lucHV0IikpOgogICAgICAgICAgICBkID0gb3MucGF0aC5qb2luKCIva2FnZ2xlL2lucHV0Iiwgc3ViKQogICAgICAgICAgICBmb3IgY2FuZCBpbiAoZCwgb3MucGF0aC5qb2luKGQsIHN1YikpOiAgIyDlpITnkIYgS2FnZ2xlIOWPjOWxguaMgui9vQogICAgICAgICAgICAgICAgaWYgb3MucGF0aC5leGlzdHMob3MucGF0aC5qb2luKGNhbmQsICJ0cmFpbi5jc3YiKSk6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbmQsICIva2FnZ2xlL3dvcmtpbmciCiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNkaXIoZCk6ICAjIOWGjeW+gOS4i+S4gOWxguaJvijlpoIgL2thZ2dsZS9pbnB1dC9jb21wZXRpdGlvbnMvPG5hbWU+LykKICAgICAgICAgICAgICAgIGZvciBzdWIyIGluIHNvcnRlZChvcy5saXN0ZGlyKGQpKToKICAgICAgICAgICAgICAgICAgICBjYW5kID0gb3MucGF0aC5qb2luKGQsIHN1YjIpCiAgICAgICAgICAgICAgICAgICAgaWYgb3MucGF0aC5leGlzdHMob3MucGF0aC5qb2luKGNhbmQsICJ0cmFpbi5jc3YiKSk6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjYW5kLCAiL2thZ2dsZS93b3JraW5nIgogICAgICAgIHByaW50KCJb6K+K5patXSAva2FnZ2xlL2lucHV0IOWtmOWcqCzkvYbmsqHmib7liLDlkKsgdHJhaW4uY3N2IOeahOebruW9leOAguWunumZheaMgui9veWGheWuueWmguS4izoiLCBmbHVzaD1UcnVlKQogICAgICAgIGZvciBzdWIgaW4gc29ydGVkKG9zLmxpc3RkaXIoIi9rYWdnbGUvaW5wdXQiKSk6CiAgICAgICAgICAgIHAgPSBvcy5wYXRoLmpvaW4oIi9rYWdnbGUvaW5wdXQiLCBzdWIpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGlubmVyID0gb3MubGlzdGRpcihwKQogICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgIGlubmVyID0gWyIo5peg5rOV6K+75Y+WKSJdCiAgICAgICAgICAgIHByaW50KGYiICAva2FnZ2xlL2lucHV0L3tzdWJ9LyAgLT4gIHtpbm5lcls6OF19IiwgZmx1c2g9VHJ1ZSkKICAgICAgICBwcmludCgiW+iviuaWrV0g5aaC5p6c5L2g5oyC55qE5pivICfkvZzogIXmlbDmja7ljIUv5Yir5Lq655qEIGtlcm5lbCDovpPlh7onLCDph4zpnaLmsqHmnIkgdHJhaW4uY3N2IOWSjCB0cmFpbl9zZXJpZXMvLCIsCiAgICAgICAgICAgICAgIuW/hemhu+aMguavlOi1m+aVsOaNruacrOS9kyByc25hLWtuZWUtYWJub3JtYWxpdHktZGV0ZWN0aW9uIChBZGQgSW5wdXQgLT4gQ29tcGV0aXRpb25zIOagh+etvumhtSkiLCBmbHVzaD1UcnVlKQogICAgIyAyKSBrYWdnbGVodWIg5YWc5bqVOuacquaMgui9veaXtuiHquWKqOS4i+i9veavlOi1m+aVsOaNrihLYWdnbGUgTm90ZWJvb2sg5YaF572u5Yet5o2uKQogICAgdHJ5OgogICAgICAgIGltcG9ydCBrYWdnbGVodWIKICAgICAgICBkID0ga2FnZ2xlaHViLmNvbXBldGl0aW9uX2Rvd25sb2FkKCJyc25hLWtuZWUtYWJub3JtYWxpdHktZGV0ZWN0aW9uIikKICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhvcy5wYXRoLmpvaW4oZCwgInRyYWluLmNzdiIpKToKICAgICAgICAgICAgcHJpbnQoZiJb6Lev5b6EXSDmnKrmjILovb0s5bey55SoIGthZ2dsZWh1YiDojrflj5bmlbDmja46IHtkfSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIHJldHVybiBkLCAiL2thZ2dsZS93b3JraW5nIgogICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgIHBhc3MgICMg5pys5Zyw5pyq6KOFIGthZ2dsZWh1YgogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGYiW+aPkOekul0ga2FnZ2xlaHViIOS4i+i9veaVsOaNruWksei0pToge2V9IiwgZmx1c2g9VHJ1ZSkKICAgICMgMykg5pys5Zyw5Zue6YCAKOiEmuacrOebruW9lSAvIGN3ZCAvIGN3ZCDkuIvnmoQgcnNuYV9rbmVlIOWtkOebruW9lemDveaJvikKICAgIGNhbmRzID0gW10KICAgIHRyeToKICAgICAgICBjYW5kcy5hcHBlbmQob3MucGF0aC5kaXJuYW1lKG9zLnBhdGguYWJzcGF0aChfX2ZpbGVfXykpKQogICAgZXhjZXB0IE5hbWVFcnJvcjoKICAgICAgICBwYXNzCiAgICBjYW5kcy5hcHBlbmQob3MuZ2V0Y3dkKCkpCiAgICBmb3IgYmFzZSBpbiBsaXN0KGNhbmRzKToKICAgICAgICBjYW5kcy5hcHBlbmQob3MucGF0aC5qb2luKGJhc2UsICJyc25hX2tuZWUiKSkKICAgIHNlZW4gPSBzZXQoKQogICAgZm9yIGJhc2UgaW4gY2FuZHM6CiAgICAgICAgaWYgYmFzZSBpbiBzZWVuOgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIHNlZW4uYWRkKGJhc2UpCiAgICAgICAgaWYgb3MucGF0aC5leGlzdHMob3MucGF0aC5qb2luKGJhc2UsICJ0cmFpbi5jc3YiKSk6CiAgICAgICAgICAgIHJldHVybiBiYXNlLCBiYXNlCiAgICBzeXMuZXhpdCgi5om+5LiN5Yiw5pWw5o2uOuivt+WFiOWcqOavlOi1m+mhteWKoOWFpeavlOi1m+W5tuWQjOaEj+aVsOaNruinhOWImSzlho0gQWRkIElucHV0IOaMgui9vSAiCiAgICAgICAgICAgICAicnNuYS1rbmVlLWFibm9ybWFsaXR5LWRldGVjdGlvbjvmnKzlnLDor7flnKggcnNuYV9rbmVlLyDkuIvov5DooYzjgIIiKQoKCl9QU0VVRE9fRklMRVMgPSAoInRyYWluX2ZvbGRzX3dpdGhfcHNldWRvLmNzdiIsICJ0cmFpbl93aXRoX3BzZXVkby5jc3YiLAogICAgICAgICAgICAgICAgICJ0cmFpbl93aXRoX3NvZnRfbGFiZWxzLmNzdiIsICJ0cmFpbl9wc2V1ZG8uY3N2IikKX1NLSVBfRElSUyA9IHsidHJhaW5fc2VyaWVzIiwgInRlc3Rfc2VyaWVzIn0gICMgRElDT00g5aSn55uu5b2VLOe7neS4jeWOu+mBjeWOhgpfV0VJR0hUX0VYVCA9ICgiLnB0aCIsICIucHQiLCAiLmNrcHQiLCAiLnB0aC50YXIiKSAgIyDnprvnur/pooTorq3nu4PmnYPph43mlofku7bmianlsZXlkI0KCiMgMTIg5qCH562+5aSa6K+t6KiA5YWz6ZSu6K+N6K+N5YW4KOiLsS/opb8v6I23L+W+ty/ms5Up4oCU4oCU6Zu25oyC6L296L2v5qCH562+5YWc5bqVCiMg5ZG95LitIOKGkiDpq5jnva7kv6Es5pyq5ZG95LitIOKGkiDkvY7nva7kv6Eo6L2v5qCH562+LOS4jee7meehrCAwLzEs6YG/5YWN6ZSZ6K+N6K+v5a+8KQpfUkVQT1JUX0tFWVdPUkRTID0gewogICAgIkFDTCI6IFsiYWNsIiwgImFudGVyaW9yIGNydWNpYXRlIiwgImNydWNpYWRvIGFudGVyaW9yIiwgInZvb3JzdGUga3J1aXNiYW5kIiwKICAgICAgICAgICAgInZvcmRlcmVuIGtyZXV6YmFuZCIsICJsY2EiLCAibGlnYW1lbnQgY3JvaXPDqSBhbnTDqXJpZXVyIl0sCiAgICAiTUNMIjogWyJtY2wiLCAibWVkaWFsIGNvbGxhdGVyYWwiLCAiY29sYXRlcmFsIG1lZGlhbCIsICJtZWRpYWxlIGNvbGxhdGVyYWxlIiwKICAgICAgICAgICAgImlubmVyZXMgc2VpdGVuYmFuZCIsICJsaWdhbWVudCBjb2xsYXTDqXJhbCBtw6lkaWFsIl0sCiAgICAiTWVkaWFsIE1lbmlzY3VzIjogWyJtZWRpYWwgbWVuaXNjdXMiLCAibWVuaXNjbyBpbnRlcm5vIiwgIm1lbmlzY3VzIG1lZGlhbGlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgIm1lbmlza3VzIG1lZGlhbCIsICJtZW5pc3F1ZSBtw6lkaWFsIiwgImlubmVyIG1lbmlzY3VzIiwgIm1lbmlzY28gbWVkaWFsIl0sCiAgICAiTGF0ZXJhbCBNZW5pc2N1cyI6IFsibGF0ZXJhbCBtZW5pc2N1cyIsICJtZW5pc2NvIGV4dGVybm8iLCAibWVuaXNjdXMgbGF0ZXJhbGlzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICJtZW5pc2t1cyBsYXRlcmFsIiwgIm1lbmlzcXVlIGxhdMOpcmFsIiwgIm91dGVyIG1lbmlzY3VzIl0sCiAgICAiTWVkaWFsIE9BIjogWyJtZWRpYWwgb3N0ZW9hcnRocml0aXMiLCAiYXJ0cm9zaXMgZmVtb3JvdGliaWFsIG1lZGlhbCIsCiAgICAgICAgICAgICAgICAgICJtZWRpYWxlIGdvbmFydHJvc2UiLCAibWVkaWFsZSBhcnRocm9zZSIsICJvc3Rlb2FydHJpdGlzIG1lZGlhbCIsCiAgICAgICAgICAgICAgICAgICJtZWRpYWwgY29tcGFydG1lbnQgbmFycm93aW5nIiwgIm1lZGlhbCBqb2ludCBzcGFjZSBuYXJyb3dpbmciXSwKICAgICJMYXRlcmFsIE9BIjogWyJsYXRlcmFsIG9zdGVvYXJ0aHJpdGlzIiwgImFydHJvc2lzIGZlbW9yb3RpYmlhbCBsYXRlcmFsIiwKICAgICAgICAgICAgICAgICAgICJsYXRlcmFsZSBnb25hcnRyb3NlIiwgImxhdGVyYWxlIGFydGhyb3NlIiwgImxhdGVyYWwgam9pbnQgc3BhY2UgbmFycm93aW5nIl0sCiAgICAiUEYgT0EiOiBbInBhdGVsbG9mZW1vcmFsIG9zdGVvYXJ0aHJpdGlzIiwgImFydHJvc2lzIHBhdGVsb2ZlbW9yYWwiLAogICAgICAgICAgICAgICJwYXRlbGxvZmVtb3JhbGUgYXJ0cm9zZSIsICJwYXRlbGxvZmVtb3JhbCBhcnRocm9zZSIsICJwZiBvYSIsCiAgICAgICAgICAgICAgInBhdGVsbG9mZW1vcmFsIG5hcnJvd2luZyIsICJwYXRlbGxvZmVtb3JhbCBqb2ludCBzcGFjZSJdLAogICAgIkVmZnVzaW9uIjogWyJlZmZ1c2lvbiIsICJkZXJyYW1lIiwgInZvY2h0IiwgImVyZ3VzcyIsICLDqXBhbmNoZW1lbnQiLCAiam9pbnQgZWZmdXNpb24iXSwKICAgICJTeW5vdml0aXMiOiBbInN5bm92aXRpcyIsICJzaW5vdml0aXMiLCAic3lub3ZpYWxlIiwgInN5bm92aWFsIHRoaWNrZW5pbmciLCAic3lub3ZpdGlzIl0sCiAgICAiQmFrZXIncyI6IFsiYmFrZXIiLCAicG9wbGl0ZWFsIGN5c3QiLCAicXVpc3RlIGRlIGJha2VyIiwgImJha2VyIGN5c3QiXSwKICAgICJDb250dXNpb24iOiBbImNvbnR1c2lvbiIsICJib25lIGJydWlzZSIsICJjb250dXNpw7NuIiwgImtuZXV6aW5nIiwgImtvbnR1c2lvbiIsCiAgICAgICAgICAgICAgICAgICJtYXJyb3cgZWRlbWEiLCAiw7NzZW8iLCAiYm9uZSBicnVpc2luZyJdLAogICAgIkZyYWN0dXJlIjogWyJmcmFjdHVyZSIsICJmcmFjdHVyYSIsICJmcmFjdHV1ciIsICJmcmFrdHVyIiwgImZyYWN0dXJlIGxpbmUiLAogICAgICAgICAgICAgICAgICJmcmFjdHVyZSBsaW5lIiwgInN1YmNob25kcmFsIGZyYWN0dXJlIl0sCn0KCgpkZWYgX3BzZXVkb19mcm9tX3JlcG9ydHModHJhaW5fY3N2LCBjb25mX2hpdD0wLjksIGNvbmZfbWlzcz0wLjEpOgogICAgIiIi5LuO5pS+5bCE5oql5ZGK5paH5pys55So5aSa6K+t6KiA5YWz6ZSu6K+N55Sf5oiQIDEyIOagh+etvui9r+agh+etvijpm7bmjILovb3lhZzlupUp44CCCgogICAg6L+U5ZueIERhdGFGcmFtZShTdHVkeUluc3RhbmNlVUlEICsgcHNldWRvXyog5YiXKeOAguWFs+mUruivjeWRveS4reKGkmNvbmZfaGl0LAogICAg5pyq5ZG95Lit4oaSY29uZl9taXNzKOS4jee7meehrCAwLzEs6ZmN5L2O6ZSZ6K+N6K+v5a+8KeOAguWumOaWueW3suacieagh+azqOeahCBzdHVkeQogICAg5LuN5Lul5a6Y5pa55Li65YeGKGxvYWRfbGFiZWxzIOeahOWhq+WFhemAu+i+keS/neivgeWumOaWueS8mOWFiCnjgIIKICAgICIiIgogICAgaWYgIlJlcG9ydCIgbm90IGluIHRyYWluX2Nzdi5jb2x1bW5zOgogICAgICAgIHJldHVybiBOb25lCiAgICByZXAgPSB0cmFpbl9jc3ZbIlJlcG9ydCJdLmZpbGxuYSgiIikKICAgIHJvd3MgPSB7fQogICAgZm9yIGxhYiwga3dzIGluIF9SRVBPUlRfS0VZV09SRFMuaXRlbXMoKToKICAgICAgICBsb3cgPSBbay5sb3dlcigpIGZvciBrIGluIGt3c10KICAgICAgICByb3dzW2YicHNldWRvX3tsYWJ9Il0gPSByZXAuYXBwbHkoCiAgICAgICAgICAgIGxhbWJkYSB0OiBjb25mX2hpdCBpZiBhbnkoayBpbiBzdHIodCkubG93ZXIoKSBmb3IgayBpbiBsb3cpIGVsc2UgY29uZl9taXNzKQogICAgZGYgPSBwZC5EYXRhRnJhbWUoeyJTdHVkeUluc3RhbmNlVUlEIjogdHJhaW5fY3N2WyJTdHVkeUluc3RhbmNlVUlEIl0sICoqcm93c30pCiAgICByZXR1cm4gZGYKCgpkZWYgX3ByaW50X21vdW50X3RyZWUoYmFzZT0iL2thZ2dsZS9pbnB1dCIsIHRhZz0i5pWw5o2uIiwgbWF4X2ZpbGVzPTYpOgogICAgIiIi5omT5Y2w5oyC6L2955uu5b2V5qCRKOacgOWkmuS4pOWxgizmr4/nm67lvZXliY3lh6DkuKrmlofku7YpLOW4rueUqOaIt+ehruiupOaMgui9veWGheWuueOAgiIiIgogICAgaWYgbm90IG9zLnBhdGguaXNkaXIoYmFzZSk6CiAgICAgICAgcHJpbnQoZiJb6K+K5patLXt0YWd9XSDnm67lvZXkuI3lrZjlnKg6IHtiYXNlfSIsIGZsdXNoPVRydWUpCiAgICAgICAgcmV0dXJuCiAgICBwcmludChmIlvor4rmlq0te3RhZ31dIC9rYWdnbGUvaW5wdXQg5a6e6ZmF5oyC6L295YaF5a65OiIsIGZsdXNoPVRydWUpCiAgICBmb3Igc3ViIGluIHNvcnRlZChvcy5saXN0ZGlyKGJhc2UpKToKICAgICAgICBwID0gb3MucGF0aC5qb2luKGJhc2UsIHN1YikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNkaXIocCk6CiAgICAgICAgICAgICAgICBpbm5lciA9IHNvcnRlZChvcy5saXN0ZGlyKHApKVs6bWF4X2ZpbGVzXQogICAgICAgICAgICAgICAgcHJpbnQoZiIgIHtzdWJ9LyAtPiB7aW5uZXJ9IiwgZmx1c2g9VHJ1ZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHByaW50KGYiICB7c3VifSAo5paH5Lu2KSIsIGZsdXNoPVRydWUpCiAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgIHByaW50KGYiICB7c3VifSAo5peg5rOV6K+75Y+WKSIsIGZsdXNoPVRydWUpCgoKZGVmIF9wcmludF9kY21fdHJlZShyb290LCB0YWc9IkRJQ09NIiwgbWF4X3Nob3c9NSk6CiAgICAiIiLmiZPljbAgdHJhaW5fc2VyaWVzIOebruW9leWJjeWHoOWxguecn+Wunue7k+aehCArIOaKveagtyAuZGNtIOiuoeaVsCznoa7orqQgRElDT00g5biD5bGA44CCCgogICAgUlNOQSDluLjop4HluIPlsYA6dHJhaW5fc2VyaWVzLzxTdHVkeUluc3RhbmNlVUlEPi88U2VyaWVzSW5zdGFuY2VVSUQ+LyouZGNtKOS4pOWxgik7CiAgICDkuZ/lhbzlrrnkuIDlsYIoPFNlcmllc0luc3RhbmNlVUlEPi8qLmRjbSnmiJbmm7Tmt7HlsYIs6L+Z6YeM5omT5Y2w5a6e6ZmF55yL5Yiw55qE44CCCiAgICAiIiIKICAgIGRjbSA9IG9zLnBhdGguam9pbihyb290LCAidHJhaW5fc2VyaWVzIikKICAgIGlmIG5vdCBvcy5wYXRoLmlzZGlyKGRjbSk6CiAgICAgICAgcHJpbnQoZiJb6K+K5patLXt0YWd9XSB7ZGNtfSDkuI3lrZjlnKghIiwgZmx1c2g9VHJ1ZSkKICAgICAgICByZXR1cm4KICAgIHRyeToKICAgICAgICBzdWJzX2FsbCA9IHNvcnRlZChvcy5saXN0ZGlyKGRjbSkpCiAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICBzdWJzX2FsbCA9IFtdCiAgICBzdWJzID0gc3Vic19hbGxbOm1heF9zaG93XQogICAgcHJpbnQoZiJb6K+K5patLXt0YWd9XSB7ZGNtfSIsIGZsdXNoPVRydWUpCiAgICBwcmludChmIlvor4rmlq0te3RhZ31dIOWtkOebruW9lS/mlofku7bmlbA6IHtsZW4oc3Vic19hbGwpfSzmoLfmnKw6IiwgZmx1c2g9VHJ1ZSkKICAgIGZvciBzIGluIHN1YnM6CiAgICAgICAgc3AgPSBvcy5wYXRoLmpvaW4oZGNtLCBzKQogICAgICAgIGlmIG9zLnBhdGguaXNkaXIoc3ApOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbm5lciA9IHNvcnRlZChvcy5saXN0ZGlyKHNwKSlbOm1heF9zaG93XQogICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgIGlubmVyID0gW10KICAgICAgICAgICAgcHJpbnQoZiIgIHtzfS8gLT4ge2lubmVyfSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIGZvciBpdCBpbiBpbm5lcls6Ml06CiAgICAgICAgICAgICAgICBpdHAgPSBvcy5wYXRoLmpvaW4oc3AsIGl0KQogICAgICAgICAgICAgICAgaWYgb3MucGF0aC5pc2RpcihpdHApOgogICAgICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXMgPSBzb3J0ZWQob3MubGlzdGRpcihpdHApKVs6M10KICAgICAgICAgICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXMgPSBbXQogICAgICAgICAgICAgICAgICAgIHByaW50KGYiICAgICAge2l0fS8gLT4ge2ZpbGVzfSIsIGZsdXNoPVRydWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQoZiIgIHtzfSAo5paH5Lu2KSIsIGZsdXNoPVRydWUpCiAgICAjIOaKveagtyAuZGNtIOiuoeaVsDrliY0gMyBzdHVkeSDDlyDliY0gMyBzZXJpZXMKICAgIG5fZGNtID0gMAogICAgdHJ5OgogICAgICAgIGZvciBzIGluIHN1YnNfYWxsWzozXToKICAgICAgICAgICAgc3AgPSBvcy5wYXRoLmpvaW4oZGNtLCBzKQogICAgICAgICAgICBpZiBub3Qgb3MucGF0aC5pc2RpcihzcCk6CiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBmb3IgaXQgaW4gc29ydGVkKG9zLmxpc3RkaXIoc3ApKVs6M106CiAgICAgICAgICAgICAgICBpdHAgPSBvcy5wYXRoLmpvaW4oc3AsIGl0KQogICAgICAgICAgICAgICAgaWYgb3MucGF0aC5pc2RpcihpdHApOgogICAgICAgICAgICAgICAgICAgIG5fZGNtICs9IHN1bSgxIGZvciBmIGluIG9zLmxpc3RkaXIoaXRwKSBpZiBmLmxvd2VyKCkuZW5kc3dpdGgoIi5kY20iKSkKICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgIHBhc3MKICAgIHByaW50KGYiW+iviuaWrS17dGFnfV0g5oq95qC3IC5kY20g5paH5Lu25pWwOiB7bl9kY219KOWJjSAzIHN0dWR5IMOXIOWJjSAzIHNlcmllcykiLCBmbHVzaD1UcnVlKQoKCmRlZiBfc2Nhbl9vZmZsaW5lX3dlaWdodHMoYmFzZT0iL2thZ2dsZS9pbnB1dCIsIGRlcHRoPTAsIG1heF9kZXB0aD00KToKICAgICIiIumAkuW9kuaJq+aPj+aMgui9veebruW9leS4i+eahOmihOiuree7g+adg+mHjeaWh+S7tigucHRoLy5wdCDnrYkpLOi3s+i/hyBESUNPTSDlpKfnm67lvZXjgIIKCiAgICDov5Tlm54gWyjnu53lr7not6/lvoQsIOebuOWvuSAva2FnZ2xlL2lucHV0IOeahOaPj+i/sCldO+aJvuS4jeWIsOi/lOWbnuepuuWIl+ihqOOAggogICAg56S+5Yy65omT5YyF55qE56a757q/5p2D6YeN5pWw5o2u6ZuGKOWmgiBtYXR0ZW9uYWNjYXJhdG8vcmVzbmV0MzQtaW1hZ2VuZXQtcHRo44CBCiAgICBtYXJjc2hhZGUvcmVzbmV0LXByZXRyYWluZWQtd2VpZ2h0cy1pbWFnZW5ldOOAgXB5dG9yY2gvcmVzbmV0MzQp5oyC6L295ZCO5Y2z5Y+v6KKr5omr5YiwLAogICAg5peg6ZyA6IGU572R44CCCiAgICAiIiIKICAgIGhpdHMgPSBbXQogICAgaWYgZGVwdGggPiBtYXhfZGVwdGggb3Igbm90IG9zLnBhdGguaXNkaXIoYmFzZSk6CiAgICAgICAgcmV0dXJuIGhpdHMKICAgIHRyeToKICAgICAgICBlbnRyaWVzID0gc29ydGVkKG9zLmxpc3RkaXIoYmFzZSkpCiAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICByZXR1cm4gaGl0cwogICAgZm9yIGZuIGluIGVudHJpZXM6CiAgICAgICAgcCA9IG9zLnBhdGguam9pbihiYXNlLCBmbikKICAgICAgICBpZiBvcy5wYXRoLmlzZmlsZShwKSBhbmQgZm4ubG93ZXIoKS5lbmRzd2l0aChfV0VJR0hUX0VYVCk6CiAgICAgICAgICAgIGhpdHMuYXBwZW5kKChwLCBvcy5wYXRoLnJlbHBhdGgocCwgIi9rYWdnbGUvaW5wdXQiKSkpCiAgICAgICAgZWxpZiBvcy5wYXRoLmlzZGlyKHApIGFuZCBmbiBub3QgaW4gX1NLSVBfRElSUzoKICAgICAgICAgICAgaGl0cy5leHRlbmQoX3NjYW5fb2ZmbGluZV93ZWlnaHRzKHAsIGRlcHRoICsgMSwgbWF4X2RlcHRoKSkKICAgIHJldHVybiBoaXRzCgoKZGVmIF9sb2FkX3N0YXRlX2RpY3RfZnJvbV9maWxlKHBhdGgpOgogICAgIiIi5LuO5p2D6YeN5paH5Lu26K+7IHN0YXRlX2RpY3Qo5YW85a65OuebtOaOpSBzdGF0ZV9kaWN0IC8g5YyF5ZyoIGNoZWNrcG9pbnQg6YeMIC8g5ZCE56eN5YmN57yAKeOAggoKICAgIOivu+WPluWksei0peaIluagvOW8j+S4jeWvuei/lOWbniBOb25l44CCCiAgICAiIiIKICAgIHRyeToKICAgICAgICBvYmogPSB0b3JjaC5sb2FkKHBhdGgsIG1hcF9sb2NhdGlvbj0iY3B1Iiwgd2VpZ2h0c19vbmx5PVRydWUpCiAgICBleGNlcHQgVHlwZUVycm9yOiAgIyDml6fniYggdG9yY2gg5pegIHdlaWdodHNfb25seSDlj4LmlbAKICAgICAgICBvYmogPSB0b3JjaC5sb2FkKHBhdGgsIG1hcF9sb2NhdGlvbj0iY3B1IikKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICBwcmludChmIlvmnYPph41dIHtwYXRofSDor7vlj5blpLHotKU6IHtlfSIsIGZsdXNoPVRydWUpCiAgICAgICAgcmV0dXJuIE5vbmUKICAgIGlmIGlzaW5zdGFuY2Uob2JqLCBkaWN0KSBhbmQgInN0YXRlX2RpY3QiIGluIG9iajoKICAgICAgICBvYmogPSBvYmpbInN0YXRlX2RpY3QiXQogICAgZWxpZiBpc2luc3RhbmNlKG9iaiwgZGljdCkgYW5kICJtb2RlbF9zdGF0ZV9kaWN0IiBpbiBvYmo6CiAgICAgICAgb2JqID0gb2JqWyJtb2RlbF9zdGF0ZV9kaWN0Il0KICAgIGVsaWYgaXNpbnN0YW5jZShvYmosIGRpY3QpIGFuZCAibW9kZWwiIGluIG9iaiBhbmQgaXNpbnN0YW5jZShvYmpbIm1vZGVsIl0sIGRpY3QpOgogICAgICAgIG9iaiA9IG9ialsibW9kZWwiXQogICAgaWYgbm90IGlzaW5zdGFuY2Uob2JqLCBkaWN0KToKICAgICAgICByZXR1cm4gTm9uZQogICAgIyDliaXluLjop4HliY3nvIA6bW9kdWxlLiAvIG1vZGVsLiAvIGJhY2tib25lLijoi6XmlbTkvZPluKbliY3nvIAs57uf5LiA6L+Y5Y6fKQogICAgb3V0ID0ge30KICAgIGZvciBrLCB2IGluIG9iai5pdGVtcygpOgogICAgICAgIGZvciBwcmUgaW4gKCJtb2R1bGUuIiwgIm1vZGVsLiIsICJiYWNrYm9uZS4iKToKICAgICAgICAgICAgaWYgay5zdGFydHN3aXRoKHByZSk6CiAgICAgICAgICAgICAgICBrID0ga1tsZW4ocHJlKTpdCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgIG91dFtrXSA9IHYKICAgIHJldHVybiBvdXQKCgpkZWYgX3RyeV9sb2FkX29mZmxpbmUobmV0LCBwYXRocyk6CiAgICAiIiLmjInluo/lsJ3or5XmiorlgJnpgInnprvnur/mnYPph43liqDovb3ov5sgbmV0KHN0YXRlX2RpY3Qg57uT5p6E6aG75LiOIFJlc05ldDM0IOWMuemFjSnjgIIKCiAgICDpgILphY3op4TliJko6Z2i5ZCR56S+5Yy6IFJTTkEg5p2D6YeNLOWmgiBiYXJ1bjIxMDQg55qEIGJlc3RfcmVzbmV0MzRfZm9sZDAucHRoKToKICAgIC0gY29udjEud2VpZ2h0IOmAmumBk+aVsOS4jeWQjOaXtjpyZXNoYXBlK21lYW4g6YCC6YWN5YiwIG5ldCDnmoQgY29udjEg6YCa6YGT5pWwKOWmgiAyNOKGkjMsCiAgICAgIGJhcnVuMjEwNCDmmK8gOCBjbGlwIMOXIDMg6YCa6YGT55qEIDIuNUQg5qih5Z6LKTsKICAgIC0gZmMuKiAvIGhlYWQuKiAvIGNsYXNzaWZpZXIuKiDkuIDlvovliaXnprso5oiR5Lus55qE5qih5Z6L5Lya5pu/5o2i5oiQIDEyIOWktCk7CiAgICDov5Tlm54gKOaYr+WQpuaIkOWKnywg5ZG95Lit5o+P6L+wKeOAggogICAgIiIiCiAgICBmb3IgcCwgZGVzYyBpbiBwYXRoczoKICAgICAgICBzZCA9IF9sb2FkX3N0YXRlX2RpY3RfZnJvbV9maWxlKHApCiAgICAgICAgaWYgc2QgaXMgTm9uZToKICAgICAgICAgICAgY29udGludWUKICAgICAgICAjIDEpIOmAgumFjSBjb252MTrpgJrpgZPmlbDkuI3lkIzliJkgcmVzaGFwZSttZWFuKOWmgiAyNCDpgJrpgZMg4oaSIDMg6YCa6YGTKQogICAgICAgIGlmICJjb252MS53ZWlnaHQiIGluIHNkOgogICAgICAgICAgICB3ID0gc2RbImNvbnYxLndlaWdodCJdCiAgICAgICAgICAgIHRhcmdldCA9IG5ldC5jb252MS53ZWlnaHQuc2hhcGVbMV0KICAgICAgICAgICAgaWYgdy5zaGFwZVsxXSAhPSB0YXJnZXQgYW5kIHcuc2hhcGVbMV0gJSB0YXJnZXQgPT0gMDoKICAgICAgICAgICAgICAgIEIsIEMsIEgsIFcgPSB3LnNoYXBlCiAgICAgICAgICAgICAgICB3MiA9IHcucmVzaGFwZShCLCB0YXJnZXQsIEMgLy8gdGFyZ2V0LCBILCBXKS5tZWFuKGRpbT0yKQogICAgICAgICAgICAgICAgc2RbImNvbnYxLndlaWdodCJdID0gdzIKICAgICAgICAgICAgICAgIHByaW50KGYiW+adg+mHjV0ge2Rlc2N9IGNvbnYxIOmAmumBkyB7Q33ihpJ7dGFyZ2V0fSDlubPlnYfpgILphY0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICBlbGlmIHcuc2hhcGVbMV0gIT0gdGFyZ2V0OgogICAgICAgICAgICAgICAgc2QucG9wKCJjb252MS53ZWlnaHQiKSAgIyDml6Dms5XpgILphY0s5Lii5byDKOeUqOmaj+acuuWIneWni+WMlikKICAgICAgICAjIDIpIOWJpeemuyBmYy9oZWFkL2NsYXNzaWZpZXIo5qih5Z6L5Lya5pu/5o2i5oiQIDEyIOWktCkKICAgICAgICBmb3IgayBpbiBsaXN0KHNkLmtleXMoKSk6CiAgICAgICAgICAgIGlmIGsuc3RhcnRzd2l0aCgoImZjLiIsICJoZWFkLiIsICJjbGFzc2lmaWVyLiIpKToKICAgICAgICAgICAgICAgIHNkLnBvcChrKQogICAgICAgIHRyeToKICAgICAgICAgICAgbWlzc2luZywgdW5leHBlY3RlZCA9IG5ldC5sb2FkX3N0YXRlX2RpY3Qoc2QsIHN0cmljdD1GYWxzZSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgIHByaW50KGYiW+adg+mHjV0ge2Rlc2N9IOS4jiBSZXNOZXQzNCDnu5PmnoTkuI3ljLnphY06IHtlfSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgZXhlbXB0ID0ge2sgZm9yIGsgaW4gbWlzc2luZyBpZiBrLnN0YXJ0c3dpdGgoKCJjb252MS4iLCAiZmMuIikpfQogICAgICAgIGlmIG5vdCB1bmV4cGVjdGVkIGFuZCBsZW4obWlzc2luZykgPT0gbGVuKGV4ZW1wdCk6CiAgICAgICAgICAgIHByaW50KGYiW+adg+mHjV0g56a757q/6aKE6K6t57uD5Yqg6L295oiQ5YqfOiB7ZGVzY30gKOimhuebliB7bGVuKHNkKX0g5Liq5Y+C5pWw5byg6YePKSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIHJldHVybiBUcnVlLCBkZXNjCiAgICAgICAgcHJpbnQoZiJb5p2D6YeNXSB7ZGVzY30g57uT5p6E5LiN5Yy56YWNKG1pc3Npbmcge2xlbihtaXNzaW5nKSAtIGxlbihleGVtcHQpfSDkuKrpnZ7osYHlhY0ga2V5LCAiCiAgICAgICAgICAgICAgZiJ1bmV4cGVjdGVkIHtsZW4odW5leHBlY3RlZCl9KSzlsJ3or5XkuIvkuIDkuKoiLCBmbHVzaD1UcnVlKQogICAgcmV0dXJuIEZhbHNlLCAiIgoKCmRlZiBfc2Nhbl9wc2V1ZG8oYmFzZSwgZGVwdGg9MCwgbWF4X2RlcHRoPTMpOgogICAgIiIi6YCS5b2S5Zyo5oyC6L2955uu5b2V5LiL5om+6L2v5qCH562+IENTVijpmZDliLbmt7HluqYs6Lez6L+HIERJQ09NIOebruW9lSnjgIIKCiAgICDov5Tlm54gKERhdGFGcmFtZSDmiJYgTm9uZSwg5p2l5rqQ5o+P6L+wKeOAguivhuWIq+inhOWImTrlkKsgU3R1ZHlJbnN0YW5jZVVJRCDkuJToh7PlsJHmnInkuIDkuKoKICAgIHBzZXVkb18g5YmN57yA5YiXKOWmgiBwc2V1ZG9fQUNMKeOAguaJvuS4jeWIsOi/lOWbniAoTm9uZSwgIiIp44CCCgogICAg6K+G5Yir5pa55byP5Y+M6YCa6YGTOgogICAgMS4g5paH5Lu25ZCN55m95ZCN5Y2VKF9QU0VVRE9fRklMRVMp5b+r6YCf5ZG95LitOwogICAgMi4gKirmjInlhoXlrrnor4bliKsqKjrku7vmhI8gKi5jc3Yg5Y+q6KaB6KGo5aS05ZCrIFN0dWR5SW5zdGFuY2VVSUQgKyBwc2V1ZG9fKiDliJfljbPlkb3kuK0KICAgICAgICjkuI3kvp3otZbmlofku7blkI0s56S+5Yy65pWw5o2u6ZuG5pS55ZCNL+aNoue7k+aehOS5n+iDveaJq+WIsCnjgIIKICAgICIiIgogICAgaWYgZGVwdGggPiBtYXhfZGVwdGggb3Igbm90IG9zLnBhdGguaXNkaXIoYmFzZSk6CiAgICAgICAgcmV0dXJuIE5vbmUsICIiCiAgICB0cnk6CiAgICAgICAgZW50cmllcyA9IHNvcnRlZChvcy5saXN0ZGlyKGJhc2UpKQogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgcmV0dXJuIE5vbmUsICIiCiAgICAjIOmAmumBkyAxOuaWh+S7tuWQjeeZveWQjeWNlSjlkJHlkI7lhbzlrrks6K+75YWo6YePKQogICAgZm9yIGZuIGluIF9QU0VVRE9fRklMRVM6CiAgICAgICAgcCA9IG9zLnBhdGguam9pbihiYXNlLCBmbikKICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhwKSBhbmQgb3MucGF0aC5pc2ZpbGUocCk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGNhbmQgPSBwZC5yZWFkX2NzdihwKQogICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgaWYgIlN0dWR5SW5zdGFuY2VVSUQiIGluIGNhbmQuY29sdW1ucyBhbmQgYW55KAogICAgICAgICAgICAgICAgICAgIGMuc3RhcnRzd2l0aCgicHNldWRvXyIpIGZvciBjIGluIGNhbmQuY29sdW1ucyk6CiAgICAgICAgICAgICAgICByZXR1cm4gY2FuZCwgb3MucGF0aC5yZWxwYXRoKHAsICIva2FnZ2xlL2lucHV0IikKICAgICMg6YCa6YGTIDI65oyJ5YaF5a656K+G5YirKOWPquivu+ihqOWktCBucm93cz0zIOWIpOaWrSzlkb3kuK3lho3lhajor7spCiAgICBmb3IgZm4gaW4gZW50cmllczoKICAgICAgICBpZiBub3QgZm4ubG93ZXIoKS5lbmRzd2l0aCgiLmNzdiIpOgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIHAgPSBvcy5wYXRoLmpvaW4oYmFzZSwgZm4pCiAgICAgICAgaWYgbm90IG9zLnBhdGguaXNmaWxlKHApOgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIHRyeToKICAgICAgICAgICAgaGVhZCA9IHBkLnJlYWRfY3N2KHAsIG5yb3dzPTMpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgY29udGludWUKICAgICAgICBpZiAiU3R1ZHlJbnN0YW5jZVVJRCIgaW4gaGVhZC5jb2x1bW5zIGFuZCBhbnkoCiAgICAgICAgICAgICAgICBjLnN0YXJ0c3dpdGgoInBzZXVkb18iKSBmb3IgYyBpbiBoZWFkLmNvbHVtbnMpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBjYW5kID0gcGQucmVhZF9jc3YocCkKICAgICAgICAgICAgICAgIHJldHVybiBjYW5kLCBvcy5wYXRoLnJlbHBhdGgocCwgIi9rYWdnbGUvaW5wdXQiKQogICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgY29udGludWUKICAgIGZvciBzdWIgaW4gZW50cmllczoKICAgICAgICBpZiBzdWIgaW4gX1NLSVBfRElSUzoKICAgICAgICAgICAgY29udGludWUKICAgICAgICBjYW5kLCBzcmMgPSBfc2Nhbl9wc2V1ZG8ob3MucGF0aC5qb2luKGJhc2UsIHN1YiksIGRlcHRoICsgMSwgbWF4X2RlcHRoKQogICAgICAgIGlmIGNhbmQgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHJldHVybiBjYW5kLCBzcmMKICAgIHJldHVybiBOb25lLCAiIgoKCmRlZiBmaW5kX3BzZXVkb19kYXRhc2V0KCk6CiAgICAiIiLlnKggL2thZ2dsZS9pbnB1dCDkuIvpgJLlvZLmiavmj4/npL7ljLrova/moIfnrb7mlbDmja7pm4YoTExNIOS7juaKpeWRiuaPkOWPlueahOS8quagh+etvinjgIIKCiAgICDlhbzlrrnljZXlsYIoL2thZ2dsZS9pbnB1dC88c2x1Zz4vKeS4juWkmuWxgigva2FnZ2xlL2lucHV0L2RhdGFzZXRzLzxzbHVnPi8p5oyC6L2944CCCiAgICDov5Tlm54gKERhdGFGcmFtZSDmiJYgTm9uZSwg5p2l5rqQ5o+P6L+wKTvmib7kuI3liLDov5Tlm54gKE5vbmUsICIiKeOAggogICAgIiIiCiAgICBpZiBub3Qgb3MucGF0aC5pc2RpcigiL2thZ2dsZS9pbnB1dCIpOgogICAgICAgIHJldHVybiBOb25lLCAiIgogICAgcmV0dXJuIF9zY2FuX3BzZXVkbygiL2thZ2dsZS9pbnB1dCIpCgoKZGVmIGxvYWRfbGFiZWxzKHJvb3QsIHBzZXVkb19jb25mPTAuMCwgdXNlX3JlcG9ydF9sYWJlbHM9VHJ1ZSk6CiAgICAiIiLov5Tlm54gdHJhaW4gc3R1ZHkg57qn5qCH562+IERhdGFGcmFtZSjooYw9U3R1ZHlJbnN0YW5jZVVJRCwg5YiXPUxBQkVMUywg5YiG5pWwL05hTinjgIIKCiAgICDmoIfnrb7mnaXmupDkvJjlhYjnuqcoMjAyNi0wOS0wNiDotbc75pen55qEIuekvuWMuui9r+agh+etvuaVsOaNrumbhiLmlrnmoYjlt7Lor4HkvKrlvIPnlKjigJTigJQKICAgIGJhcnVuMjEwNCDnmoQgcHNldWRvXyogOTguNyUg5piv5a2X6Z2iIDAuNSDmrbvlgLzjgIHpm7blop7ph4/kv6Hmga8s5pivIGxvc3Mg5oGSIDAuNjkzCiAgICDnmoTnnJ/moLnlm6ApOgogICAgMS4g5a6Y5pa5IHRyYWluLmNzdiDmoIfms6goMC8xLOS7hSA1OC80NDA3IOS+iyk7CiAgICAyLiDlhoXnva7miqXlkYrop4TliJnmir3lj5blmaggcnNuYV9yZXBvcnRfbGFiZWxzKOenu+akjeiHqiByc25hLWtuZWUtYmFzZWxpbmUtdjEsCiAgICAgICDlpJror63oqIAv5oyJ5Y+l5ZCm5a6a5p6B5oCnL+S4pemHjeW6puWIhue6pyk65a+55q+P5Lu95pS+5bCE5oql5ZGK5Lqn5Ye6IDEyIOeXheeBtiBzb2Z0IOWIhuaVsAogICAgICAgKOmYs+aApyAwLjcyfjAuOTUgLyDpmLTmgKcgMC4wNH4wLjIwIC8g5peg6K+B5o2uPU5hTik7CiAgICAgICDlrpjmlrnnvLrlpLHmoLznlKjmir3lj5bliIbmlbDloavlhYUs5peg6K+B5o2u5qC85L+d5oyBIE5hTijkuI3ov5vmjZ/lpLEs55SxIHZhbGlkIOaOqeeggeaOkumZpCnjgIIKICAgICIiIgogICAgdHJhaW4gPSBwZC5yZWFkX2Nzdihvcy5wYXRoLmpvaW4ocm9vdCwgInRyYWluLmNzdiIpKQogICAgZGYgPSB0cmFpbltbIlN0dWR5SW5zdGFuY2VVSUQiXSArIExBQkVMU10uY29weSgpCiAgICBvZmZpY2lhbF9jbnQgPSB7YzogaW50KGRmW2NdLm5vdG5hKCkuc3VtKCkpIGZvciBjIGluIExBQkVMU30KCiAgICBpZiBub3QgdXNlX3JlcG9ydF9sYWJlbHM6CiAgICAgICAgcHJpbnQoIlvmoIfnrb5dIC0tbm8tcmVwb3J0LWxhYmVsczrku4XlrpjmlrnmoIfms6jlj6/nlKgiKQogICAgICAgIHJldHVybiBkZgogICAgaWYgbm90IEhBU19STDoKICAgICAgICBwcmludCgiW+agh+etvl0g5pyq5om+5YiwIHJzbmFfcmVwb3J0X2xhYmVscy5weSjpnIDkuI4gcnNuYV92My5weSDlkIznm67lvZUpLCIKICAgICAgICAgICAgICAi5LuF5a6Y5pa55qCH5rOo5Y+v55SoIikKICAgICAgICByZXR1cm4gZGYKICAgIGlmICJSZXBvcnQiIG5vdCBpbiB0cmFpbi5jb2x1bW5zOgogICAgICAgIHByaW50KCJb5qCH562+XSB0cmFpbi5jc3Yg5pegIFJlcG9ydCDliJcs5LuF5a6Y5pa55qCH5rOo5Y+v55SoIikKICAgICAgICByZXR1cm4gZGYKCiAgICBwc2V1ZG8gPSBSTC5idWlsZF9wc2V1ZG9fdGFibGUodHJhaW4sIHZlcmJvc2U9VHJ1ZSkKICAgIHBzZXVkbyA9IHBzZXVkby5zZXRfaW5kZXgoIlN0dWR5SW5zdGFuY2VVSUQiKQogICAgcHJpbnQoZiJb5qCH562+XSDloavlhYXnu5/orqEoe2xlbihkZil9IOS4qiBzdHVkeSk6IikKICAgIGZvciBjIGluIExBQkVMUzoKICAgICAgICBtYXNrID0gZGZbY10uaXNuYSgpLnZhbHVlcwogICAgICAgIGlmIG5vdCBtYXNrLmFueSgpOgogICAgICAgICAgICBwcmludChmIiAge2M6MThzfSDlrpjmlrnlhajph48s5peg6ZyA5aGr5YWFIikKICAgICAgICAgICAgY29udGludWUKICAgICAgICB1aWRzID0gZGYubG9jW21hc2ssICJTdHVkeUluc3RhbmNlVUlEIl0KICAgICAgICB2YWxzID0gcHNldWRvWyJwc2V1ZG9fIiArIGNdLnJlaW5kZXgodWlkcykudmFsdWVzCiAgICAgICAgbl9maWxsID0gaW50KHBkLm5vdG5hKHZhbHMpLnN1bSgpKQogICAgICAgIGRmLmxvY1ttYXNrLCBjXSA9IHZhbHMKICAgICAgICBwcmludChmIiAge2M6MThzfSDlrpjmlrkge29mZmljaWFsX2NudFtjXTo0ZH0gKyDmiqXlkYrmir3lj5bloavlhYUge25fZmlsbDo0ZH0iCiAgICAgICAgICAgICAgZiIgPSDmnInmlYgge2ludChkZltjXS5ub3RuYSgpLnN1bSgpKTo1ZH0iKQogICAgcmV0dXJuIGRmCgoKX0RDTV9NSVNTX1BSSU5URUQgPSBbRmFsc2VdICAjIOWPquaJk+WNsOS4gOasoSBESUNPTSDmnKrlkb3kuK3or4rmlq0s6YG/5YWNIDIg5LiHIHNlcmllcyDliLflsY8KCgpkZWYgcmVhZF9kaWNvbV9zbGljZXMoZGNtX2Rpciwgc2VyaWVzX3VpZCwgc3R1ZHlfdWlkPU5vbmUpOgogICAgIiIi6K+75Y+W5LiA5LiqIHNlcmllcyDnmoTmiYDmnInliIfniYcs5oyJ54mp55CG5L2N572u5o6S5bqPLOi/lOWbniBbKHBhdGgsIHopXeOAggoKICAgIOi3r+W+hOWFvOWuueWkmuenjSBLYWdnbGUg5biD5bGAKOWunua1iyBSU05BIDIwMjYg5Li65Lik5bGCKToKICAgICAgMSkgPGRjbV9kaXI+LzxzZXJpZXNfdWlkPi8gICAgICAgICAgICAgICAgKOaXp+WBh+iuvjpzZXJpZXMg55uu5b2V55u05o6l5oyCKQogICAgICAyKSA8ZGNtX2Rpcj4vPHN0dWR5X3VpZD4vPHNlcmllc191aWQ+LyAgICAoUlNOQSDmoIflh4Y6c3R1ZHkg55uu5b2V5LiL5YaN5oyCIHNlcmllcykKICAgIOaJvuS4jeWIsOaIluivu+S4jeWIsOi/lOWbniBbXeOAggogICAgIiIiCiAgICBjYW5kcyA9IFtvcy5wYXRoLmpvaW4oZGNtX2Rpciwgc2VyaWVzX3VpZCldCiAgICBpZiBzdHVkeV91aWQ6CiAgICAgICAgY2FuZHMuYXBwZW5kKG9zLnBhdGguam9pbihkY21fZGlyLCBzdHVkeV91aWQsIHNlcmllc191aWQpKQogICAgc2RpciA9IG5leHQoKGMgZm9yIGMgaW4gY2FuZHMgaWYgb3MucGF0aC5pc2RpcihjKSksIE5vbmUpCiAgICBpZiBzZGlyIGlzIE5vbmU6CiAgICAgICAgaWYgbm90IF9EQ01fTUlTU19QUklOVEVEWzBdOgogICAgICAgICAgICBfRENNX01JU1NfUFJJTlRFRFswXSA9IFRydWUKICAgICAgICAgICAgcHJpbnQoZiJb6K+K5patLURJQ09NXSDmib7kuI3liLAgc2VyaWVzIOebruW9lSzlsJ3or5Xov4c6IHtjYW5kc30iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICBwcmludChmIlvor4rmlq0tRElDT01dIHtkY21fZGlyfSDmmK/lkKblrZjlnKg6IHtvcy5wYXRoLmlzZGlyKGRjbV9kaXIpfSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIGlubmVyID0gc29ydGVkKG9zLmxpc3RkaXIoZGNtX2RpcikpWzo4XSBpZiBvcy5wYXRoLmlzZGlyKGRjbV9kaXIpIGVsc2UgW10KICAgICAgICAgICAgICAgIHByaW50KGYiW+iviuaWrS1ESUNPTV0ge2RjbV9kaXJ9IOWunumZheWGheWuueagt+acrDoge2lubmVyfSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICAgICAgcGFzcwogICAgICAgIHJldHVybiBbXQogICAgZmlsZXMgPSBbb3MucGF0aC5qb2luKHNkaXIsIGYpIGZvciBmIGluIG9zLmxpc3RkaXIoc2RpcikgaWYgZi5sb3dlcigpLmVuZHN3aXRoKCIuZGNtIildCiAgICBpZiBub3QgZmlsZXM6CiAgICAgICAgaWYgbm90IF9EQ01fTUlTU19QUklOVEVEWzBdOgogICAgICAgICAgICBfRENNX01JU1NfUFJJTlRFRFswXSA9IFRydWUKICAgICAgICAgICAgcHJpbnQoZiJb6K+K5patLURJQ09NXSDnm67lvZXlrZjlnKjkvYbml6AgLmRjbSDmlofku7Y6IHtzZGlyfSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIHByaW50KGYiW+iviuaWrS1ESUNPTV0g55uu5b2V5YaF5a655qC35pysOiB7c29ydGVkKG9zLmxpc3RkaXIoc2RpcikpWzo4XX0iLCBmbHVzaD1UcnVlKQogICAgICAgIHJldHVybiBbXQogICAgcm93cyA9IFtdCiAgICBmb3IgZiBpbiBmaWxlczoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGQgPSBweWRpY29tLmRjbXJlYWQoZiwgc3RvcF9iZWZvcmVfcGl4ZWxzPUZhbHNlKQogICAgICAgICAgICBwb3MgPSBkLmdldCgiSW1hZ2VQb3NpdGlvblBhdGllbnQiKQogICAgICAgICAgICB6ID0gZmxvYXQocG9zWzJdKSBpZiBwb3MgaXMgbm90IE5vbmUgYW5kIGxlbihwb3MpID49IDMgZWxzZSBOb25lCiAgICAgICAgICAgIHJvd3MuYXBwZW5kKChmLCB6KSkKICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICBjb250aW51ZQogICAgcm93cy5zb3J0KGtleT1sYW1iZGEgcjogKHJbMV0gaXMgTm9uZSwgclsxXSBpZiByWzFdIGlzIG5vdCBOb25lIGVsc2UgMC4wKSkKICAgIHJldHVybiByb3dzCgoKIyAtLS0tLS0tLS0tLS0tLS0tIERJQ09NIC0+IDIuNUQgY2xpcCDpooTlpITnkIYgLS0tLS0tLS0tLS0tLS0tLQoKZGVmIHdpbmRvd19hbmRfcmVzaXplKGRjbSwgaW1nX3NpemU9SU1HX1NJWkUpOgogICAgIiIi5Y2V5byg5YiH54mHOlJlc2NhbGUg5ZCO55m+5YiG5L2N56qX5Y+j5YyWIC0+IFswLDFdIC0+IHJlc2l6ZSAyMjTjgIIiIiIKICAgIGFyciA9IGRjbS5waXhlbF9hcnJheS5hc3R5cGUobnAuZmxvYXQzMikKICAgIHNsb3BlID0gZmxvYXQoZGNtLmdldCgiUmVzY2FsZVNsb3BlIiwgMSkpCiAgICBpbnRlciA9IGZsb2F0KGRjbS5nZXQoIlJlc2NhbGVJbnRlcmNlcHQiLCAwKSkKICAgIGFyciA9IGFyciAqIHNsb3BlICsgaW50ZXIKICAgIGlmIGRjbS5nZXQoIlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb24iKSA9PSAiTU9OT0NIUk9NRTEiOgogICAgICAgIGFyciA9IGFyci5tYXgoKSAtIGFycgogICAgbG8sIGhpID0gbnAucGVyY2VudGlsZShhcnIsIFsxLCA5OV0pCiAgICBhcnIgPSBucC5jbGlwKChhcnIgLSBsbykgLyBtYXgoaGkgLSBsbywgMWUtNiksIDAsIDEpCiAgICBmcm9tIFBJTCBpbXBvcnQgSW1hZ2UKICAgIGltZyA9IEltYWdlLmZyb21hcnJheSgoYXJyICogMjU1KS5hc3R5cGUobnAudWludDgpKS5yZXNpemUoKGltZ19zaXplLCBpbWdfc2l6ZSksIEltYWdlLkJJTElORUFSKQogICAgcmV0dXJuIG5wLmFzYXJyYXkoaW1nLCBkdHlwZT1ucC5mbG9hdDMyKSAvIDI1NS4wCgoKZGVmIG1ha2VfY2xpcHMoc2VyaWVzX3Jvd3MsIG5fY2xpcHM9MiwgaW1nX3NpemU9SU1HX1NJWkUpOgogICAgIiIi5LuO5o6S5bqP5aW955qE5YiH54mH5YiX6KGo55Sf5oiQ6Iul5bmyIDMg6YCa6YGTIGNsaXAo55u46YK75LiJ5bygKeOAgiIiIgogICAgY2xpcHMgPSBbXQogICAgcGF0aHMgPSBbclswXSBmb3IgciBpbiBzZXJpZXNfcm93c10KICAgIGlmIGxlbihwYXRocykgPCBDTElQOgogICAgICAgIHJldHVybiBjbGlwcwogICAgc3RlcCA9IG1heCgxLCAobGVuKHBhdGhzKSAtIDIpIC8vIG5fY2xpcHMpCiAgICBmb3IgYyBpbiByYW5nZSgxLCBsZW4ocGF0aHMpIC0gMSwgc3RlcCk6CiAgICAgICAgaWYgbGVuKGNsaXBzKSA+PSBuX2NsaXBzOgogICAgICAgICAgICBicmVhawogICAgICAgIGNoYW4gPSBbXQogICAgICAgIG9rID0gVHJ1ZQogICAgICAgIGZvciBrIGluIChjIC0gMSwgYywgYyArIDEpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBkY20gPSBweWRpY29tLmRjbXJlYWQocGF0aHNba10pCiAgICAgICAgICAgICAgICBjaGFuLmFwcGVuZCh3aW5kb3dfYW5kX3Jlc2l6ZShkY20sIGltZ19zaXplKSkKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgICAgIG9rID0gRmFsc2UKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgaWYgb2s6CiAgICAgICAgICAgIGNsaXBzLmFwcGVuZChucC5zdGFjayhjaGFuLCBheGlzPTApKSAgIyAoMywgSCwgVykKICAgIHJldHVybiBjbGlwcwoKCiMgLS0tLS0tLS0tLS0tLS0tLSDmlbDmja7pm4YodjI65oyJ5bmz6Z2i6L+H5rukIHNlcmllcykgLS0tLS0tLS0tLS0tLS0tLQoKY2xhc3MgS25lZURhdGFzZXQoRGF0YXNldCk6CiAgICAiIiJzdHVkeSDnuqfmlbDmja7pm4Ys5Y+q5Y+W5oyH5a6aIEFuYXRvbWljYWxfUGxhbmUg55qEIHNlcmllcyzmi7zmiJAgKEMqMywgSCwgVynjgIIiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgc3R1ZGllcywgbGFiZWxzX2RmLCBkY21fcm9vdCwgc2VyaWVzX2RmLCBwbGFuZSwKICAgICAgICAgICAgICAgICBoYXNfdGFyZ2V0cz1UcnVlLCBuX2NsaXBzPTIpOgogICAgICAgIHNlbGYuc3R1ZGllcyA9IHN0dWRpZXMKICAgICAgICBzZWxmLmxhYmVsc19kZiA9IGxhYmVsc19kZgogICAgICAgIHNlbGYuZGNtX3Jvb3QgPSBkY21fcm9vdAogICAgICAgIHNlbGYuc2VyaWVzX2RmID0gc2VyaWVzX2RmCiAgICAgICAgc2VsZi5wbGFuZSA9IHBsYW5lCiAgICAgICAgc2VsZi5oYXNfdGFyZ2V0cyA9IGhhc190YXJnZXRzCiAgICAgICAgc2VsZi5uX2NsaXBzID0gbl9jbGlwcwogICAgICAgIHNlbGYuY2FjaGUgPSB7fSAgIyDmr4/mipjni6znq4vnvJPlrZg6Zm9sZCDnu5PmnZ/pmo8gZGF0YXNldCDph4rmlL4s6YG/5YWNIDUg5oqY57Sv56evIE9PTQogICAgICAgICMg6K+K5pat6K6h5pWwOuivu+WIsCBjbGlwIOeahCBzdHVkeSAvIOepuiBzdHVkeSAvIOe0r+iuoSBjbGlwIOaVsAogICAgICAgIHNlbGYubl9oaXQgPSAwCiAgICAgICAgc2VsZi5uX2VtcHR5ID0gMAogICAgICAgIHNlbGYubl9jbGlwc190b3RhbCA9IDAKCiAgICBkZWYgc3RhdHMoc2VsZik6CiAgICAgICAgIiIi6L+U5ZueICjor7vliLAgY2xpcCDnmoQgc3R1ZHkg5pWwLCDnqbogc3R1ZHkg5pWwLCDlubPlnYcgY2xpcCDmlbApLOmYsuatoumdmem7mOeZveiuree7g+OAgiIiIgogICAgICAgIHRvdGFsID0gc2VsZi5uX2hpdCArIHNlbGYubl9lbXB0eQogICAgICAgIGF2ZyA9IChzZWxmLm5fY2xpcHNfdG90YWwgLyBzZWxmLm5faGl0KSBpZiBzZWxmLm5faGl0IGVsc2UgMC4wCiAgICAgICAgcmV0dXJuIHNlbGYubl9oaXQsIHNlbGYubl9lbXB0eSwgYXZnCgogICAgZGVmIF9sb2FkX3N0dWR5KHNlbGYsIHVpZCk6CiAgICAgICAga2V5ID0gKHVpZCwgc2VsZi5wbGFuZSkKICAgICAgICBpZiBrZXkgaW4gc2VsZi5jYWNoZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuY2FjaGVba2V5XQogICAgICAgIHNyb3dzID0gc2VsZi5zZXJpZXNfZGZbc2VsZi5zZXJpZXNfZGZbIlN0dWR5SW5zdGFuY2VVSUQiXSA9PSB1aWRdCiAgICAgICAgaWYgIkFuYXRvbWljYWxfUGxhbmUiIGluIHNyb3dzLmNvbHVtbnM6CiAgICAgICAgICAgIHNyb3dzID0gc3Jvd3Nbc3Jvd3NbIkFuYXRvbWljYWxfUGxhbmUiXSA9PSBzZWxmLnBsYW5lXQogICAgICAgICAgICBzcm93cyA9IHNyb3dzLnNvcnRfdmFsdWVzKCJGbHVpZF9TZW5zaXRpdmUiLCBraW5kPSJzdGFibGUiKS5kcm9wX2R1cGxpY2F0ZXMoCiAgICAgICAgICAgICAgICBzdWJzZXQ9WyJGbHVpZF9TZW5zaXRpdmUiXSkuaGVhZChNQVhfU0VSSUVTKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNyb3dzID0gc3Jvd3MuaGVhZChNQVhfU0VSSUVTKQogICAgICAgIGNsaXBzID0gW10KICAgICAgICBmb3IgXywgc3IgaW4gc3Jvd3MuaXRlcnJvd3MoKToKICAgICAgICAgICAgc2lkID0gc3JbIlNlcmllc0luc3RhbmNlVUlEIl0KICAgICAgICAgICAgcm93cyA9IHJlYWRfZGljb21fc2xpY2VzKHNlbGYuZGNtX3Jvb3QsIHNpZCwgc3R1ZHlfdWlkPXVpZCkKICAgICAgICAgICAgY2xpcHMuZXh0ZW5kKG1ha2VfY2xpcHMocm93cywgbl9jbGlwcz1zZWxmLm5fY2xpcHMpKQogICAgICAgIHNlbGYuY2FjaGVbdWlkXSA9IGNsaXBzCiAgICAgICAgIyDku4XpppbmrKHliqDovb3orqHmlbAo57yT5a2Y5ZG95Lit5LiN5YaN57Sv5YqgLOmBv+WFjeWkmiBlcG9jaCDph43lpI0pCiAgICAgICAgaWYgY2xpcHM6CiAgICAgICAgICAgIHNlbGYubl9oaXQgKz0gMQogICAgICAgICAgICBzZWxmLm5fY2xpcHNfdG90YWwgKz0gbGVuKGNsaXBzKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYubl9lbXB0eSArPSAxCiAgICAgICAgcmV0dXJuIGNsaXBzCgogICAgZGVmIF9fbGVuX18oc2VsZik6CiAgICAgICAgcmV0dXJuIGxlbihzZWxmLnN0dWRpZXMpCgogICAgZGVmIF9fZ2V0aXRlbV9fKHNlbGYsIGkpOgogICAgICAgIHVpZCA9IHNlbGYuc3R1ZGllc1tpXQogICAgICAgIGNsaXBzID0gc2VsZi5fbG9hZF9zdHVkeSh1aWQpICAjIOWRveS4rS/nqbrorqHmlbDlnKggX2xvYWRfc3R1ZHkg6aaW5qyh5Yqg6L295pe25a6M5oiQCiAgICAgICAgaW5fY2ggPSBzZWxmLm5fY2xpcHMgKiBDTElQICAjIOi+k+WFpemAmumBk+aVsDpjbGlwIOaVsCDDlyDmr48gY2xpcCAzIOWIh+eJhwogICAgICAgIGlmIG5vdCBjbGlwczoKICAgICAgICAgICAgeCA9IG5wLnplcm9zKChpbl9jaCwgSU1HX1NJWkUsIElNR19TSVpFKSwgZHR5cGU9bnAuZmxvYXQzMikKICAgICAgICBlbHNlOgogICAgICAgICAgICB4ID0gbnAuY29uY2F0ZW5hdGUoY2xpcHNbOiBzZWxmLm5fY2xpcHNdLCBheGlzPTApICAjIChrKjMsIEgsIFcpCiAgICAgICAgICAgIHBhZCA9IGluX2NoIC0geC5zaGFwZVswXQogICAgICAgICAgICBpZiBwYWQgPiAwOgogICAgICAgICAgICAgICAgeCA9IG5wLmNvbmNhdGVuYXRlKFt4LCBucC56ZXJvcygocGFkLCBJTUdfU0laRSwgSU1HX1NJWkUpLCBkdHlwZT1ucC5mbG9hdDMyKV0pCiAgICAgICAgICAgIGVsaWYgcGFkIDwgMDoKICAgICAgICAgICAgICAgIHggPSB4WzogaW5fY2hdCiAgICAgICAgeCA9IHRvcmNoLnRlbnNvcih4LCBkdHlwZT10b3JjaC5mbG9hdDMyKQogICAgICAgIHkgPSB0b3JjaC56ZXJvcyhsZW4oTEFCRUxTKSwgZHR5cGU9dG9yY2guZmxvYXQzMikKICAgICAgICB2YWxpZCA9IHRvcmNoLnplcm9zKGxlbihMQUJFTFMpLCBkdHlwZT10b3JjaC5mbG9hdDMyKQogICAgICAgIGlmIHNlbGYuaGFzX3RhcmdldHM6CiAgICAgICAgICAgIHJvdyA9IHNlbGYubGFiZWxzX2RmW3NlbGYubGFiZWxzX2RmWyJTdHVkeUluc3RhbmNlVUlEIl0gPT0gdWlkXQogICAgICAgICAgICBpZiBsZW4ocm93KToKICAgICAgICAgICAgICAgIGZvciBqLCBjIGluIGVudW1lcmF0ZShMQUJFTFMpOgogICAgICAgICAgICAgICAgICAgIHYgPSByb3cuaWxvY1swXVtjXQogICAgICAgICAgICAgICAgICAgIGlmIHBkLm5vdG5hKHYpOgogICAgICAgICAgICAgICAgICAgICAgICB5W2pdID0gZmxvYXQodikKICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRbal0gPSAxLjAKICAgICAgICByZXR1cm4geCwgeSwgdmFsaWQKCgojIC0tLS0tLS0tLS0tLS0tLS0g5qih5Z6LIC0tLS0tLS0tLS0tLS0tLS0KCl9QUkVUUkFJTkVEX1RSSUVEID0gW0ZhbHNlXSAgIyDmqKHlnZfnuqfmoIflv5c65LiL6L295aSx6LSl6L+H5LiA5qyh5bCx5LiN5YaN5Y+N5aSN6YeN6K+VCgoKZGVmIF9idWlsZF9yZXNuZXQzNCh1c2VfcHJldHJhaW5lZD1GYWxzZSwgb2ZmbGluZV9wYXRocz1Ob25lKToKICAgICIiIuaehOmAoCBSZXNOZXQzNCDlubbliqDovb0gSW1hZ2VOZXQg6aKE6K6t57uD5p2D6YeN44CCCgogICAg5p2D6YeN5p2l5rqQ5LyY5YWI57qnOgogICAgMS4gb2ZmbGluZV9wYXRoczrmjILovb3nmoTnprvnur/mnYPph43mlofku7Yo5omr5o+PIC9rYWdnbGUvaW5wdXQg5b6X5YiwLOaXoOmcgOiBlOe9kSk7CiAgICAyLiB1c2VfcHJldHJhaW5lZD1UcnVlOuiBlOe9keS4i+i9vSB0b3JjaHZpc2lvbiDmnYPph40o5bim6YeN6K+VLOWksei0peWbnumAgOmaj+acuik7CiAgICAzLiDlkKbliJnpmo/mnLrliJ3lp4vljJbjgIIKICAgIOaIkOWKn+WKoOi9veWQjuadg+mHjeeUsSB0b3JjaCDnvJPlrZgs5ZCO57utIGZvbGQg56eS5Yqg6L2944CCCiAgICAiIiIKICAgIG5ldCA9IHR2bS5yZXNuZXQzNCh3ZWlnaHRzPU5vbmUpCiAgICBpZiBvZmZsaW5lX3BhdGhzOgogICAgICAgIG9rLCBkZXNjID0gX3RyeV9sb2FkX29mZmxpbmUobmV0LCBvZmZsaW5lX3BhdGhzKQogICAgICAgIGlmIG9rOgogICAgICAgICAgICByZXR1cm4gbmV0CiAgICAgICAgcHJpbnQoZiJb5p2D6YeNXSDnprvnur/lgJnpgInlnYfkuI3ljLnphY0oe2Rlc2N9KSzlm57pgIDliLDpmo/mnLov6IGU572R6Lev5b6EIiwgZmx1c2g9VHJ1ZSkKICAgIGlmIG5vdCB1c2VfcHJldHJhaW5lZDoKICAgICAgICBwcmludCgiW+adg+mHjV0g5pyq5byA5ZCvIC0tcHJldHJhaW5lZCDkuJTml6Dnprvnur/mnYPph40s5L2/55So6ZqP5py65Yid5aeL5YyWIgogICAgICAgICAgICAgICIo5LiN6IGU572RO+WmgumcgOmihOiuree7g+ivt+WKoCAtLXByZXRyYWluZWQg5bm25byA5ZCvIEludGVybmV0LCIKICAgICAgICAgICAgICAi5oiW5oyC6L2956a757q/5p2D6YeN5pWw5o2u6ZuGKSIsIGZsdXNoPVRydWUpCiAgICAgICAgcmV0dXJuIG5ldAogICAgaWYgX1BSRVRSQUlORURfVFJJRURbMF06CiAgICAgICAgcmV0dXJuIG5ldCAgIyDkuYvliY3lt7Lnoa7orqTkuIvovb3kuI3kuoYs55u05o6l6ZqP5py6CiAgICBmb3IgYXR0ZW1wdCBpbiByYW5nZSgxLCA0KToKICAgICAgICB0cnk6CiAgICAgICAgICAgIG5ldCA9IHR2bS5yZXNuZXQzNCh3ZWlnaHRzPXR2bS5SZXNOZXQzNF9XZWlnaHRzLklNQUdFTkVUMUtfVjEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGhhc2F0dHIodHZtLCAiUmVzTmV0MzRfV2VpZ2h0cyIpIGVsc2UgTm9uZSkKICAgICAgICAgICAgcmV0dXJuIG5ldAogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgcHJpbnQoZiJb5p2D6YeNXSBSZXNOZXQzNCDpooTorq3nu4PkuIvovb3lpLHotKUo56ysIHthdHRlbXB0fS8zIOasoSk6IHtlfSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIHRpbWUuc2xlZXAoNSkKICAgIF9QUkVUUkFJTkVEX1RSSUVEWzBdID0gVHJ1ZQogICAgcHJpbnQoIlvmnYPph41dIDMg5qyh5Z2H5aSx6LSlLOaUueeUqOmaj+acuuWIneWni+WMlijnsr7luqbkvJrmmI7mmL7kuIvpmY075bu66K6u6YeN6K+V5oiW5oyC6L296aKE6K6t57uD5p2D6YeN5pWw5o2u6ZuGKSIsIGZsdXNoPVRydWUpCiAgICByZXR1cm4gdHZtLnJlc25ldDM0KHdlaWdodHM9Tm9uZSkKCgpjbGFzcyBLbmVlTW9kZWwobm4uTW9kdWxlKToKICAgICIiIlJlc05ldDM0IOWFseS6qyBiYWNrYm9uZSArIOWFqOWxgOaxoOWMliArIDEyIHNpZ21vaWQg5aS0KOavj+S4quW5s+mdouS4gOS4quWunuS+iynjgIIiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbnVtX2xhYmVscz1sZW4oTEFCRUxTKSwgY2hhbm5lbHM9Q0xJUCwgcHJldHJhaW5lZD1GYWxzZSwgb2ZmbGluZV9wYXRocz1Ob25lKToKICAgICAgICBzdXBlcigpLl9faW5pdF9fKCkKICAgICAgICBpZiBIQVNfVFY6CiAgICAgICAgICAgIHNlbGYuYmFja2JvbmUgPSBfYnVpbGRfcmVzbmV0MzQodXNlX3ByZXRyYWluZWQ9cHJldHJhaW5lZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZsaW5lX3BhdGhzPW9mZmxpbmVfcGF0aHMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgUnVudGltZUVycm9yKCLpnIDopoEgdG9yY2h2aXNpb24o6K+35ZyoIEthZ2dsZSBOb3RlYm9vayBHUFUg546v5aKD6L+Q6KGMKSIpCiAgICAgICAgY29udjFfdyA9IHNlbGYuYmFja2JvbmUuY29udjEud2VpZ2h0ICAjIOS/neeVmemihOiuree7gyBjb252MSDmnYPph40KICAgICAgICBzZWxmLmJhY2tib25lLmNvbnYxID0gbm4uQ29udjJkKGNoYW5uZWxzLCA2NCwga2VybmVsX3NpemU9Nywgc3RyaWRlPTIsIHBhZGRpbmc9MywgYmlhcz1GYWxzZSkKICAgICAgICBpZiBjb252MV93LnNoYXBlID09IHNlbGYuYmFja2JvbmUuY29udjEud2VpZ2h0LnNoYXBlOiAgIyBjaGFubmVscz09MyDml7bnm7TmjqXmsr/nlKgKICAgICAgICAgICAgc2VsZi5iYWNrYm9uZS5jb252MS53ZWlnaHQuZGF0YS5jb3B5Xyhjb252MV93LmRhdGEpCiAgICAgICAgZWxpZiBjaGFubmVscyAlIDMgPT0gMCBhbmQgY29udjFfdy5zaGFwZVsxXSA9PSAzOgogICAgICAgICAgICAjIDIuNUQg6YCa6YGT5omp5bGVOuaKiiAzIOmAmumBk+mihOiuree7g+adg+mHjeWkjeWItiBuX2NsaXBzIOS7vSjluLjop4HlgZrms5UpCiAgICAgICAgICAgIHJlcCA9IGNoYW5uZWxzIC8vIDMKICAgICAgICAgICAgc2VsZi5iYWNrYm9uZS5jb252MS53ZWlnaHQuZGF0YS5jb3B5Xyhjb252MV93LnJlcGVhdCgxLCByZXAsIDEsIDEpKQogICAgICAgICAgICBwcmludChmIlvmnYPph41dIGNvbnYxIOmihOiuree7g+adg+mHjeWkjeWItiB7cmVwfSDku73mianlsZXliLAge2NoYW5uZWxzfSDpgJrpgZMiLCBmbHVzaD1UcnVlKQogICAgICAgIHNlbGYuYmFja2JvbmUuZmMgPSBubi5JZGVudGl0eSgpCiAgICAgICAgc2VsZi5oZWFkID0gbm4uTGluZWFyKDUxMiwgbnVtX2xhYmVscykKCiAgICBkZWYgZm9yd2FyZChzZWxmLCB4KToKICAgICAgICBmZWF0ID0gc2VsZi5iYWNrYm9uZSh4KSAgIyAoQiwgNTEyKQogICAgICAgIHJldHVybiBzZWxmLmhlYWQoZmVhdCkgICAjIGxvZ2l0cyAoQiwgMTIpCgoKIyAtLS0tLS0tLS0tLS0tLS0tIOiuree7gyAvIOmqjOivgSAtLS0tLS0tLS0tLS0tLS0tCgpkZWYgdHJhaW5fZXBvY2gobW9kZWwsIGxvYWRlciwgb3B0LCBjcml0LCBkZXZpY2UpOgogICAgbW9kZWwudHJhaW4oKQogICAgdG90LCBjbnQgPSAwLjAsIDAKICAgIGZvciB4LCB5LCB2YWxpZCBpbiBsb2FkZXI6CiAgICAgICAgeCwgeSwgdmFsaWQgPSB4LnRvKGRldmljZSksIHkudG8oZGV2aWNlKSwgdmFsaWQudG8oZGV2aWNlKQogICAgICAgIG9wdC56ZXJvX2dyYWQoKQogICAgICAgIG91dCA9IG1vZGVsKHgpCiAgICAgICAgaWYgdmFsaWQuc3VtKCkgPT0gMDoKICAgICAgICAgICAgY29udGludWUKICAgICAgICBsb3NzID0gKGNyaXQob3V0LCB5KSAqIHZhbGlkKS5zdW0oKSAvIHZhbGlkLnN1bSgpCiAgICAgICAgbG9zcy5iYWNrd2FyZCgpCiAgICAgICAgb3B0LnN0ZXAoKQogICAgICAgIHRvdCArPSBsb3NzLml0ZW0oKSAqIGxlbih4KQogICAgICAgIGNudCArPSBsZW4oeCkKICAgIHJldHVybiB0b3QgLyBtYXgoY250LCAxKQoKCkB0b3JjaC5ub19ncmFkKCkKZGVmIHByZWRpY3QobW9kZWwsIGxvYWRlciwgZGV2aWNlKToKICAgIG1vZGVsLmV2YWwoKQogICAgcm93cyA9IFtdCiAgICBmb3IgeCwgXywgXyBpbiBsb2FkZXI6CiAgICAgICAgeCA9IHgudG8oZGV2aWNlKQogICAgICAgIG91dCA9IHRvcmNoLnNpZ21vaWQobW9kZWwoeCkpCiAgICAgICAgIyAuY3B1KCkudG9saXN0KCkg6ICM6Z2eIC5jcHUoKS5udW1weSgpOnRvcmNoIDIuMi4wK2N1MTE4IOe8luS6jiBudW1weTEueCwKICAgICAgICAjIOWcqCBLYWdnbGUgbnVtcHkyLjAuMiDkuIsgdG9yY2jihpJudW1weSBpbnRlcm9wIOW0qTt0b2xpc3Qg57qvIEMrKyDot6/lvoTlronlhajjgIIKICAgICAgICByb3dzLmV4dGVuZChvdXQuY3B1KCkudG9saXN0KCkpCiAgICByZXR1cm4gbnAuYXNhcnJheShyb3dzLCBkdHlwZT1ucC5mbG9hdDMyKSBpZiByb3dzIGVsc2UgbnAuemVyb3MoKDAsIGxlbihMQUJFTFMpKSwgZHR5cGU9bnAuZmxvYXQzMikKCgpkZWYgcnVuX2ZvbGQobW9kZWwsIHRyYWluX2RzLCB2YWxfZHMsIGRldmljZSwgYXJncyk6CiAgICB0cmFpbl9sb2FkZXIgPSBEYXRhTG9hZGVyKHRyYWluX2RzLCBiYXRjaF9zaXplPWFyZ3MuYmF0Y2gsIHNodWZmbGU9VHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtX3dvcmtlcnM9YXJncy53b3JrZXJzLCBkcm9wX2xhc3Q9RmFsc2UpCiAgICB2YWxfbG9hZGVyID0gRGF0YUxvYWRlcih2YWxfZHMsIGJhdGNoX3NpemU9YXJncy5iYXRjaCwgc2h1ZmZsZT1GYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bV93b3JrZXJzPWFyZ3Mud29ya2VycywgZHJvcF9sYXN0PUZhbHNlKQogICAgb3B0ID0gQWRhbVcobW9kZWwucGFyYW1ldGVycygpLCBscj1hcmdzLmxyLCB3ZWlnaHRfZGVjYXk9MWUtNCkKICAgIHNjaGVkID0gQ29zaW5lQW5uZWFsaW5nTFIob3B0LCBUX21heD1hcmdzLmVwb2NocykKICAgIGNyaXQgPSBubi5CQ0VXaXRoTG9naXRzTG9zcyhyZWR1Y3Rpb249Im5vbmUiKQogICAgZm9yIGVwIGluIHJhbmdlKGFyZ3MuZXBvY2hzKToKICAgICAgICB0MCA9IHRpbWUudGltZSgpCiAgICAgICAgbG9zcyA9IHRyYWluX2Vwb2NoKG1vZGVsLCB0cmFpbl9sb2FkZXIsIG9wdCwgY3JpdCwgZGV2aWNlKQogICAgICAgIHNjaGVkLnN0ZXAoKQogICAgICAgIGlmIGFyZ3MudmVyYm9zZToKICAgICAgICAgICAgcHJpbnQoZiIgIGVwb2NoIHtlcCArIDF9L3thcmdzLmVwb2Noc30gbG9zcyB7bG9zczouNGZ9ICh7dGltZS50aW1lKCkgLSB0MDouMGZ9cykiLCBmbHVzaD1UcnVlKQogICAgdmFsX3ByZWQgPSBwcmVkaWN0KG1vZGVsLCB2YWxfbG9hZGVyLCBkZXZpY2UpCiAgICAjIERJQ09NIOWRveS4reiviuaWrTrorq3nu4Mr6aqM6K+B5bey6L+t5Luj5a6M5q+VLOatpOaXtuiuoeaVsOaJjeWHhuehrgogICAgdGgsIGVoLCBhdCA9IHRyYWluX2RzLnN0YXRzKCkKICAgIHZoLCBldiwgYXYgPSB2YWxfZHMuc3RhdHMoKQogICAgcHJpbnQoZiJb5pWw5o2uXSB0cmFpbiDlkb3kuK0ge3RofS97bGVuKHRyYWluX2RzKX0gc3R1ZHko56m6IHtlaH0sIOW5s+WdhyB7YXQ6LjFmfSBjbGlwKSB8ICIKICAgICAgICAgIGYidmFsIOWRveS4rSB7dmh9L3tsZW4odmFsX2RzKX0gc3R1ZHko56m6IHtldn0pIiwgZmx1c2g9VHJ1ZSkKICAgIGlmIHRoID09IDAgb3IgdmggPT0gMDoKICAgICAgICBwcmludCgiW+itpuWRil0g5pyJ5oqYIERJQ09NIOWFqOmDqOayoeivu+WIsCjlkb3kuK0gMCnigJTigJTovpPlhaXlsIbmmK/lhajpm7Ys5YiG5pWw5b+F54S2IH4wLjUhIiwgZmx1c2g9VHJ1ZSkKICAgIHZhbF91aWQgPSBucC5hcnJheSh2YWxfZHMuc3R1ZGllcykgICMgc2h1ZmZsZT1GYWxzZSzpobrluo/kuI7mlbDmja7pm4bkuIDoh7QKICAgIHJldHVybiB2YWxfcHJlZCwgdmFsX3VpZAoKCiMgLS0tLS0tLS0tLS0tLS0tLSDmjqjnkIYgLyDono3lkIggLyDmj5DkuqQgLS0tLS0tLS0tLS0tLS0tLQoKZGVmIHByZWRpY3RfdGVzdChtb2RlbCwgdGVzdF9kZiwgc2VyaWVzX2RmLCByb290LCBkZXZpY2UsIHBsYW5lLCBuX2NsaXBzPTIpOgogICAgIiIi5a+5IHRlc3Qg5q+P5LiqIHN0dWR5IOaMieaMh+WumuW5s+mdouaUtumbhiBjbGlwcyzpooTmtYsgMTIg5Liq5qaC546H44CCIiIiCiAgICBkcyA9IEtuZWVEYXRhc2V0KHRlc3RfZGZbIlN0dWR5SW5zdGFuY2VVSUQiXS50b2xpc3QoKSwgTm9uZSwgcm9vdCwgc2VyaWVzX2RmLAogICAgICAgICAgICAgICAgICAgICBwbGFuZSwgaGFzX3RhcmdldHM9RmFsc2UsIG5fY2xpcHM9bl9jbGlwcykKICAgIGxvYWRlciA9IERhdGFMb2FkZXIoZHMsIGJhdGNoX3NpemU9MTYsIHNodWZmbGU9RmFsc2UsIG51bV93b3JrZXJzPTApCiAgICByZXR1cm4gcHJlZGljdChtb2RlbCwgbG9hZGVyLCBkZXZpY2UpCgoKZGVmIHBsYW5lX29vZl9hdWMob29mLCBsYWJlbHNfZGYsIHVpZF9saXN0KToKICAgICIiIuiuoeeul+S4gOS4quW5s+mdouaooeWei+WcqOaMh+WumiBzdHVkeSDlrZDpm4bkuIrnmoTlro/lubPlnYcgT09GIEFVQyjlj6rnrpfmnInmoIfms6jnmoTliJcp44CCCgogICAgbGFiZWxzX2RmIOW/hemhu+aYr+OAkOWumOaWuSBnb2xkIOWOn+Wni+ihqOOAkSgwLzEvTmFOLOWmgiB0cmFpbl9jc3Yg5Y6f5YiXKSzkuI3og73kvKAKICAgIGxvYWRfbGFiZWxzIOWhq+WFheWQjueahCBzb2Z0IOihqOKAlOKAlHNvZnQg5Lyq5qCH562+5pei6Z2eIGdyb3VuZCB0cnV0aCzkuZ/kvJrorqkKICAgIHJvY19hdWNfc2NvcmUg5bSpKGNvbnRpbnVvdXMp44CCNTgg5L6L5bCP5qC35pys5LiL5p+Q5YiX5Y+v6IO95Y+q5pyJ5Y2V5LiA57G75YirLOi3s+i/h+ivpeWIl+OAggogICAgIiIiCiAgICBhdWNzID0gW10KICAgIGZvciBqLCBjIGluIGVudW1lcmF0ZShMQUJFTFMpOgogICAgICAgIHlfdHJ1ZSA9IGxhYmVsc19kZi5zZXRfaW5kZXgoIlN0dWR5SW5zdGFuY2VVSUQiKVtjXS5yZWluZGV4KHVpZF9saXN0KS52YWx1ZXMuYXN0eXBlKGZsb2F0KQogICAgICAgIHZhbGlkID0gfm5wLmlzbmFuKHlfdHJ1ZSkKICAgICAgICBpZiB2YWxpZC5zdW0oKSA+PSAyMDoKICAgICAgICAgICAgeXYgPSB5X3RydWVbdmFsaWRdCiAgICAgICAgICAgIGlmIGxlbihucC51bmlxdWUoeXYpKSA8IDI6CiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBhdWNzLmFwcGVuZChyb2NfYXVjX3Njb3JlKHl2LCBvb2ZbdmFsaWQsIGpdKSkKICAgIHJldHVybiBmbG9hdChucC5tZWFuKGF1Y3MpKSBpZiBhdWNzIGVsc2UgMC4wCgoKZGVmIG1haW4oKToKICAgIGFwID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoKQogICAgYXAuYWRkX2FyZ3VtZW50KCItLWVwb2NocyIsIHR5cGU9aW50LCBkZWZhdWx0PTIpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tYmF0Y2giLCB0eXBlPWludCwgZGVmYXVsdD04KQogICAgYXAuYWRkX2FyZ3VtZW50KCItLWxyIiwgdHlwZT1mbG9hdCwgZGVmYXVsdD0zZS00KQogICAgYXAuYWRkX2FyZ3VtZW50KCItLXdvcmtlcnMiLCB0eXBlPWludCwgZGVmYXVsdD0wKQogICAgYXAuYWRkX2FyZ3VtZW50KCItLW4tY2xpcHMiLCB0eXBlPWludCwgZGVmYXVsdD0yKQogICAgYXAuYWRkX2FyZ3VtZW50KCItLXNlZWQiLCB0eXBlPWludCwgZGVmYXVsdD1TRUVEKQogICAgYXAuYWRkX2FyZ3VtZW50KCItLWZvbGRzIiwgdHlwZT1pbnQsIGRlZmF1bHQ9Rk9MRFMpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tb25seS1mb2xkIiwgdHlwZT1pbnQsIGRlZmF1bHQ9LTEsCiAgICAgICAgICAgICAgICAgICAgaGVscD0i5Y+q6LeR5oyH5a6a5oqYKOWFtuS9mei3s+i/hzvpu5jorqQgLTE95YWo6YOoKeOAguaOoui3r+eUqDotLWZvbGRzIDUgLS1vbmx5LWZvbGQgMCDorq3nrKwgMCDmipgiCiAgICAgICAgICAgICAgICAgICAgICAgICAiKHRyYWluIDQvNSDkuI7mraPlvI/lkIzliIbluIMpLHRlc3Qg5o6o55CG55So6K+l5oqY5qih5Z6L5Ye65o+Q5LqkIikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1wbGFuZXMiLCB0eXBlPXN0ciwgZGVmYXVsdD0iLCIuam9pbihQTEFORVMpLAogICAgICAgICAgICAgICAgICAgIGhlbHA9IumAl+WPt+WIhumalOeahOW5s+mdouWtkOmbhizlpoIgYXhpYWwsc2FnaXR0YWwo5bCP5YaZLOS4jeWMuuWIhuWkp+Wwj+WGmSkiKQogICAgYXAuYWRkX2FyZ3VtZW50KCItLWZ1c2UiLCB0eXBlPXN0ciwgZGVmYXVsdD0id2VpZ2h0IiwKICAgICAgICAgICAgICAgICAgICBjaG9pY2VzPVsid2VpZ2h0IiwgIm1lYW4iXSwKICAgICAgICAgICAgICAgICAgICBoZWxwPSLlubPpnaLono3lkIjmlrnlvI86d2VpZ2h0PeaMiSBPT0YgQVVDIOWKoOadgzttZWFuPeeugOWNleW5s+WdhyIpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tcHNldWRvLWNvbmYiLCB0eXBlPWZsb2F0LCBkZWZhdWx0PTAuMCwKICAgICAgICAgICAgICAgICAgICBoZWxwPSLkvKrmoIfnrb7nva7kv6Hluqbov4fmu6TpmIjlgLwoMD3kuI3ov4fmu6Q7MC41PeS4ouW8g+e9ruS/oeW6pjwwLjXnmoTkvKrmoIfnrb4pIikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1uby1yZXBvcnQtbGFiZWxzIiwgYWN0aW9uPSJzdG9yZV90cnVlIiwKICAgICAgICAgICAgICAgICAgICBoZWxwPSLnpoHnlKjlhoXnva7miqXlkYrlhbPplK7or43ova/moIfnrb7lhZzlupUo6buY6K6k5byA5ZCvOuacquaMguekvuWMuuaVsOaNrumbhuaXtiIKICAgICAgICAgICAgICAgICAgICAgICAgICLoh6rliqjku44gNDQwNyDku73mlL7lsITmiqXlkYrnlJ/miJDova/moIfnrb4s6Zu25oyC6L29KSIpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tdmVyYm9zZSIsIGFjdGlvbj0ic3RvcmVfdHJ1ZSIpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tcHJldHJhaW5lZCIsIGFjdGlvbj0ic3RvcmVfdHJ1ZSIsCiAgICAgICAgICAgICAgICAgICAgaGVscD0i5bCd6K+V5LiL6L29IEltYWdlTmV0IOmihOiuree7g+adg+mHjSjpnIDlvIDlkK8gSW50ZXJuZXQpO+m7mOiupOmaj+acuuWIneWni+WMluS4jeiBlOe9kSIpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tb2ZmbGluZS13ZWlnaHRzIiwgdHlwZT1zdHIsIGRlZmF1bHQ9IiIsCiAgICAgICAgICAgICAgICAgICAgaGVscD0i6YCX5Y+35YiG6ZqU55qE56a757q/5p2D6YeNIC5wdGgg6Lev5b6EKOS8mOWFiOe6p+acgOmrmCk755WZ56m65YiZ6Ieq5Yqo5omr5o+P5oyC6L2955uu5b2VIikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1uby1vZmZsaW5lLXNjYW4iLCBhY3Rpb249InN0b3JlX3RydWUiLAogICAgICAgICAgICAgICAgICAgIGhlbHA9IuemgeeUqOiHquWKqOaJq+aPjyAva2FnZ2xlL2lucHV0IOS4i+eahOemu+e6v+adg+mHjeaWh+S7tiIpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tZGF0YSIsIHR5cGU9c3RyLCBkZWZhdWx0PSIiLAogICAgICAgICAgICAgICAgICAgIGhlbHA9IuaYvuW8j+aMh+WumuaVsOaNruagueebruW9lSjlpoIga2FnZ2xlaHViLmNvbXBldGl0aW9uX2Rvd25sb2FkIOi/lOWbnueahCBwYXRoKSwiCiAgICAgICAgICAgICAgICAgICAgICAgICAi5oyH5a6a5ZCO6Lez6L+H6Ieq5Yqo5p+l5om+IikKICAgIGFyZ3MsIF8gPSBhcC5wYXJzZV9rbm93bl9hcmdzKCkKCiAgICBpZiBub3QgSEFTX1RPUkNIIG9yIG5vdCBIQVNfVFYgb3Igbm90IEhBU19QWURJQ09NOgogICAgICAgIHN5cy5leGl0KCLkvp3otZbnvLrlpLE66K+35ZyoIEthZ2dsZSBOb3RlYm9vayhHUFUp546v5aKD6L+Q6KGMKHRvcmNoL3RvcmNodmlzaW9uL3B5ZGljb20pO+acrOWcsOS7heWPr+WBmuaVsOaNruWxgumqjOivgeOAgiIpCgogICAgbnAucmFuZG9tLnNlZWQoYXJncy5zZWVkKQogICAgdG9yY2gubWFudWFsX3NlZWQoYXJncy5zZWVkKQoKICAgIGlmIGFyZ3MuZGF0YToKICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyhvcy5wYXRoLmpvaW4oYXJncy5kYXRhLCAidHJhaW4uY3N2IikpOgogICAgICAgICAgICByb290LCBvdXQgPSBhcmdzLmRhdGEsIGFyZ3MuZGF0YQogICAgICAgICAgICBwcmludChmIlvmlbDmja5dIOS9v+eUqCAtLWRhdGEg5oyH5a6a55uu5b2VOiB7cm9vdH0iKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHN5cy5leGl0KGYiLS1kYXRhIOaMh+WumuebruW9lSB7YXJncy5kYXRhfSDkuIvmsqHmnIkgdHJhaW4uY3N2LOivt+ajgOafpei3r+W+hCIpCiAgICBlbHNlOgogICAgICAgIHJvb3QsIG91dCA9IHJlc29sdmVfcGF0aHMoKQogICAgcHJpbnQoZiJb5pWw5o2uXSByb290PXtyb290fSAgb3V0PXtvdXR9IikKCiAgICB0cmFpbl9jc3YgPSBwZC5yZWFkX2Nzdihvcy5wYXRoLmpvaW4ocm9vdCwgInRyYWluLmNzdiIpKQogICAgbGFiZWxzX2RmID0gbG9hZF9sYWJlbHMocm9vdCwgcHNldWRvX2NvbmY9YXJncy5wc2V1ZG9fY29uZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZV9yZXBvcnRfbGFiZWxzPW5vdCBhcmdzLm5vX3JlcG9ydF9sYWJlbHMpCiAgICBzZXJpZXNfZGYgPSBwZC5yZWFkX2Nzdihvcy5wYXRoLmpvaW4ocm9vdCwgInRyYWluX3Nlcmllcy5jc3YiKSkKICAgIHRlc3RfZGYgPSBwZC5yZWFkX2Nzdihvcy5wYXRoLmpvaW4ocm9vdCwgInRlc3QuY3N2IikpCiAgICB0ZXN0X3NlcmllcyA9IHBkLnJlYWRfY3N2KG9zLnBhdGguam9pbihyb290LCAidGVzdF9zZXJpZXMuY3N2IikpCiAgICBkY21fdHJhaW4gPSBvcy5wYXRoLmpvaW4ocm9vdCwgInRyYWluX3NlcmllcyIpCiAgICBkY21fdGVzdCA9IG9zLnBhdGguam9pbihyb290LCAidGVzdF9zZXJpZXMiKQogICAgcHJpbnQoZiJb5pWw5o2uXSB0cmFpbiB7bGVuKHRyYWluX2Nzdil9IHN0dWR5IC8gdGVzdCB7bGVuKHRlc3RfZGYpfSBzdHVkeSAvIHNlcmllcyB7bGVuKHNlcmllc19kZil9IikKICAgIF9wcmludF9kY21fdHJlZShyb290LCAiRElDT00iKSAgIyDmiZPljbAgdHJhaW5fc2VyaWVzIOecn+WunuebruW9lee7k+aehCznoa7orqTluIPlsYAKCiAgICBwbGFuZXMgPSBbcC5zdHJpcCgpLnRpdGxlKCkgZm9yIHAgaW4gYXJncy5wbGFuZXMuc3BsaXQoIiwiKSBpZiBwLnN0cmlwKCldCiAgICBwbGFuZXMgPSBbcCBmb3IgcCBpbiBwbGFuZXMgaWYgcCBpbiBQTEFORVNdCiAgICBpZiBub3QgcGxhbmVzOgogICAgICAgIHN5cy5leGl0KGYiLS1wbGFuZXMg5peg5pWILOWPr+mAiToge1BMQU5FU30iKQogICAgcHJpbnQoZiJb5bmz6Z2iXSDkvb/nlKgge3BsYW5lc30iKQoKICAgIGRldmljZSA9IHRvcmNoLmRldmljZSgiY3VkYSIgaWYgdG9yY2guY3VkYS5pc19hdmFpbGFibGUoKSBlbHNlICJjcHUiKQogICAgcHJpbnQoZiJb6K6+5aSHXSB7ZGV2aWNlfSIpCgogICAgIyDnprvnur/pooTorq3nu4PmnYPph4065pi+5byP5oyH5a6a5LyY5YWILOWQpuWImeiHquWKqOaJq+aPjyAva2FnZ2xlL2lucHV0CiAgICBvZmZsaW5lX3BhdGhzID0gW10KICAgIGlmIGFyZ3Mub2ZmbGluZV93ZWlnaHRzLnN0cmlwKCk6CiAgICAgICAgZm9yIHAgaW4gW3guc3RyaXAoKSBmb3IgeCBpbiBhcmdzLm9mZmxpbmVfd2VpZ2h0cy5zcGxpdCgiLCIpIGlmIHguc3RyaXAoKV06CiAgICAgICAgICAgIGlmIG9zLnBhdGguaXNmaWxlKHApOgogICAgICAgICAgICAgICAgb2ZmbGluZV9wYXRocy5hcHBlbmQoKHAsIHApKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcHJpbnQoZiJb5p2D6YeNXSAtLW9mZmxpbmUtd2VpZ2h0cyDmjIflrprnmoTmlofku7bkuI3lrZjlnKgs6Lez6L+HOiB7cH0iLCBmbHVzaD1UcnVlKQogICAgZWxpZiBub3QgYXJncy5ub19vZmZsaW5lX3NjYW46CiAgICAgICAgb2ZmbGluZV9wYXRocyA9IF9zY2FuX29mZmxpbmVfd2VpZ2h0cygpCiAgICAgICAgaWYgb2ZmbGluZV9wYXRoczoKICAgICAgICAgICAgcHJpbnQoZiJb5p2D6YeNXSDoh6rliqjmiavmj4/liLAge2xlbihvZmZsaW5lX3BhdGhzKX0g5Liq56a757q/5p2D6YeN5YCZ6YCJOiIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIGZvciBwLCBkZXNjIGluIG9mZmxpbmVfcGF0aHNbOjZdOgogICAgICAgICAgICAgICAgcHJpbnQoZiIgIHtkZXNjfSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIGlmIGxlbihvZmZsaW5lX3BhdGhzKSA+IDY6CiAgICAgICAgICAgICAgICBwcmludChmIiAgLi4uIOWFsSB7bGVuKG9mZmxpbmVfcGF0aHMpfSDkuKoiLCBmbHVzaD1UcnVlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50KCJb5p2D6YeNXSDmnKrlnKjmjILovb3nm67lvZXlj5HnjrDnprvnur/mnYPph40o5Y+v5oyC6L2956S+5Yy65omT5YyF55qEIHJlc25ldDM0IOadg+mHjeaVsOaNrumbhikiLCBmbHVzaD1UcnVlKQogICAgICAgICAgICBfcHJpbnRfbW91bnRfdHJlZSgiL2thZ2dsZS9pbnB1dCIsICLmnYPph40iKQoKICAgIGdrZiA9IEdyb3VwS0ZvbGQobl9zcGxpdHM9YXJncy5mb2xkcykKICAgIGdyb3VwcyA9IHRyYWluX2NzdlsiU3R1ZHlJbnN0YW5jZVVJRCJdLnZhbHVlcwoKICAgICMg5q+P5Liq5bmz6Z2i54us56uL6LeR5oqYLOiusOW9lSBPT0Yg5LiOIHRlc3Qg6aKE5rWLCiAgICBwbGFuZV9vb2YsIHBsYW5lX3Rlc3QsIHBsYW5lX2F1YywgcGxhbmVfdWlkcyA9IHt9LCB7fSwge30sIHt9CiAgICBmb3IgcGxhbmUgaW4gcGxhbmVzOgogICAgICAgIHByaW50KGYiXG4jIyMjIyMjIyMjIOW5s+mdojoge3BsYW5lfSAjIyMjIyMjIyMjIikKICAgICAgICBvb2YgPSBucC56ZXJvcygobGVuKHRyYWluX2NzdiksIGxlbihMQUJFTFMpKSkKICAgICAgICBmb3IgaywgKHRyX2lkeCwgdmFfaWR4KSBpbiBlbnVtZXJhdGUoZ2tmLnNwbGl0KHRyYWluX2NzdiwgZ3JvdXBzPWdyb3VwcykpOgogICAgICAgICAgICBpZiBhcmdzLm9ubHlfZm9sZCA+PSAwIGFuZCBrICE9IGFyZ3Mub25seV9mb2xkOgogICAgICAgICAgICAgICAgY29udGludWUgICMg5o6i6LevOuWPquiureaMh+WumuaKmCzlhbbkvZnmipjot7Pov4cKICAgICAgICAgICAgdHJfc3R1ZGllcyA9IHRyYWluX2Nzdi5pbG9jW3RyX2lkeF1bIlN0dWR5SW5zdGFuY2VVSUQiXS50b2xpc3QoKQogICAgICAgICAgICB2YV9zdHVkaWVzID0gdHJhaW5fY3N2Lmlsb2NbdmFfaWR4XVsiU3R1ZHlJbnN0YW5jZVVJRCJdLnRvbGlzdCgpCiAgICAgICAgICAgIHRyX2RzID0gS25lZURhdGFzZXQodHJfc3R1ZGllcywgbGFiZWxzX2RmLCBkY21fdHJhaW4sIHNlcmllc19kZiwgcGxhbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9jbGlwcz1hcmdzLm5fY2xpcHMpCiAgICAgICAgICAgIHZhX2RzID0gS25lZURhdGFzZXQodmFfc3R1ZGllcywgbGFiZWxzX2RmLCBkY21fdHJhaW4sIHNlcmllc19kZiwgcGxhbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9jbGlwcz1hcmdzLm5fY2xpcHMpCiAgICAgICAgICAgIG1vZGVsID0gS25lZU1vZGVsKHByZXRyYWluZWQ9YXJncy5wcmV0cmFpbmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZsaW5lX3BhdGhzPW9mZmxpbmVfcGF0aHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzPWFyZ3Mubl9jbGlwcyAqIENMSVApLnRvKGRldmljZSkKICAgICAgICAgICAgcHJpbnQoZiJb5oqYIHtrICsgMX0ve2FyZ3MuZm9sZHN9XSB7cGxhbmV9IHRyYWluIHtsZW4odHJfZHMpfSAvIHZhbCB7bGVuKHZhX2RzKX0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICB2YWxfcHJlZCwgdmFsX3VpZCA9IHJ1bl9mb2xkKG1vZGVsLCB0cl9kcywgdmFfZHMsIGRldmljZSwgYXJncykKICAgICAgICAgICAgZm9yIGosIHVpZCBpbiBlbnVtZXJhdGUodmFsX3VpZCk6CiAgICAgICAgICAgICAgICByb3cgPSBucC53aGVyZSh0cmFpbl9jc3ZbIlN0dWR5SW5zdGFuY2VVSUQiXS52YWx1ZXMgPT0gdWlkKVswXQogICAgICAgICAgICAgICAgaWYgbGVuKHJvdyk6CiAgICAgICAgICAgICAgICAgICAgb29mW3Jvd1swXV0gPSB2YWxfcHJlZFtqXQogICAgICAgICMg6K+l5bmz6Z2iIE9PRiBBVUMo5a6P5bmz5Z2HKQogICAgICAgIHVpZF9saXN0ID0gdHJhaW5fY3N2WyJTdHVkeUluc3RhbmNlVUlEIl0udG9saXN0KCkKICAgICAgICAjIOaOoui3rygtLW9ubHktZm9sZCnlj6rorq3ljZXmipg6T09GIOS7heivpeaKmCB2YWwg5pyJ5YC8LDU4IGdvbGQg5YiG5pWj5ZCE5oqY5qC35pys5LiN6LazLAogICAgICAgICMgQVVDIOaXoOaEj+S5iSDihpIg6Lez6L+H6K+E5Lyw44CB5p2D6YeN6K6wIDAo6J6N5ZCI6YCA5YyW5Li65Z2H562JLOWNleW5s+mdouWNs+ivpeaooeWei+acrOi6qykKICAgICAgICBpZiBhcmdzLm9ubHlfZm9sZCA+PSAwOgogICAgICAgICAgICBwcmludChmIlt7cGxhbmV9XSDmjqLot6/mqKHlvI8oLS1vbmx5LWZvbGQge2FyZ3Mub25seV9mb2xkfSk6T09GIOWNleaKmOS4jeWujOaVtCwiCiAgICAgICAgICAgICAgICAgIGYi6Lez6L+HIE9PRiBBVUMo5p2D6YeN6K6wIDA95Z2H562JKTt0ZXN0IOaOqOeQhueUqOivpeaKmOaooeWeiyIpCiAgICAgICAgICAgIGF1YyA9IDAuMAogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgT09GIEFVQyDnlKjlrpjmlrkgZ29sZCDljp/lp4vooagoMC8xL05hTinor4TkvLA7bGFiZWxzX2RmIOaYryBzb2Z0IOWhq+WFheeJiCzkuI3og73lvZMgeV90cnVlCiAgICAgICAgICAgIGF1YyA9IHBsYW5lX29vZl9hdWMob29mLCB0cmFpbl9jc3ZbWyJTdHVkeUluc3RhbmNlVUlEIl0gKyBMQUJFTFNdLCB1aWRfbGlzdCkKICAgICAgICAgICAgcHJpbnQoZiJbe3BsYW5lfV0gT09GIOWuj+W5s+WdhyBBVUMge2F1YzouNGZ9IikKICAgICAgICAjIOivpeW5s+mdoiB0ZXN0IOmihOa1iyjkuI4gdHJhaW4g6KGM5a+56b2QOuacgOWQjuS4gOaKmOaooeWeiykKICAgICAgICBwbGFuZV9vb2ZbcGxhbmVdLCBwbGFuZV90ZXN0W3BsYW5lXSA9IG9vZiwgcHJlZGljdF90ZXN0KAogICAgICAgICAgICBtb2RlbCwgdGVzdF9kZiwgdGVzdF9zZXJpZXMsIGRjbV90ZXN0LCBkZXZpY2UsIHBsYW5lLCBuX2NsaXBzPWFyZ3Mubl9jbGlwcykKICAgICAgICBwbGFuZV9hdWNbcGxhbmVdLCBwbGFuZV91aWRzW3BsYW5lXSA9IGF1YywgdWlkX2xpc3QKCiAgICAjIOiejeWQiAogICAgaWYgYXJncy5mdXNlID09ICJ3ZWlnaHQiOgogICAgICAgIHdzdW0gPSBzdW0obWF4KGEsIDFlLTYpIGZvciBhIGluIHBsYW5lX2F1Yy52YWx1ZXMoKSkKICAgICAgICB3ZWlnaHRzID0ge3A6IG1heChhLCAxZS02KSAvIHdzdW0gZm9yIHAsIGEgaW4gcGxhbmVfYXVjLml0ZW1zKCl9CiAgICAgICAgcHJpbnQoZiJb6J6N5ZCIXSBPT0YgQVVDIOWKoOadgzogeyB7cDogcm91bmQodywgNCkgZm9yIHAsIHcgaW4gd2VpZ2h0cy5pdGVtcygpfSB9IikKICAgIGVsc2U6CiAgICAgICAgd2VpZ2h0cyA9IHtwOiAxLjAgLyBsZW4ocGxhbmVzKSBmb3IgcCBpbiBwbGFuZXN9CiAgICAgICAgcHJpbnQoIlvono3lkIhdIOeugOWNleW5s+WdhyIpCiAgICBmdXNlZCA9IG5wLnplcm9zX2xpa2UocGxhbmVfdGVzdFtwbGFuZXNbMF1dKQogICAgZm9yIHAsIHcgaW4gd2VpZ2h0cy5pdGVtcygpOgogICAgICAgIGZ1c2VkICs9IHcgKiBwbGFuZV90ZXN0W3BdCiAgICBzdWIgPSBwZC5EYXRhRnJhbWUoeyJTdHVkeUluc3RhbmNlVUlEIjogdGVzdF9kZlsiU3R1ZHlJbnN0YW5jZVVJRCJdLCAqKnsKICAgICAgICBMQUJFTFNbal06IGZ1c2VkWzosIGpdIGZvciBqIGluIHJhbmdlKGxlbihMQUJFTFMpKX19KQogICAgc3ViX3BhdGggPSBvcy5wYXRoLmpvaW4ob3V0LCAic3VibWlzc2lvbi5jc3YiKQogICAgc3ViLnRvX2NzdihzdWJfcGF0aCwgaW5kZXg9RmFsc2UpCiAgICBwcmludChmIlxu5o+Q5Lqk5paH5Lu25bey55Sf5oiQOiB7c3ViX3BhdGh9ICBzaGFwZT17c3ViLnNoYXBlfSIpCgoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIG1haW4oKQo=')\nopen(\"/kaggle/working/rsna_v3.py\",\"wb\").write(base64.b64decode(\"\".join(parts)))\nprint(\"rsna_v3.py ->\", os.path.getsize(\"/kaggle/working/rsna_v3.py\")//1024, \"KB\")","metadata":{},"outputs":[],"execution_count":null},{"id":"e302b59e-5f4e-48ce-8791-aa2dd482e7bd","cell_type":"code","source":"import base64, os\nparts = []\nparts.append('IyAtKi0gY29kaW5nOiB1dGYtOCAtKi0KIiIicnNuYV9yZXBvcnRfbGFiZWxzIC0g5LuO5pS+5bCE5oql5ZGK5paH5pys5oq95Y+WIDEyIOeXheeBtuW8seagh+etvijlpJror63oqIDop4TliJnmir3lj5blmagpCgrmnKzmlofku7bnlLEgdG9wX2tlcm5lbHMvcnNuYS1rbmVlLWJhc2VsaW5lLXYxLmlweW5iIOeahOaKveWPluWZqChjZWxscyA2LTExKeWOn+agt+enu+akjSwK6LSf6LSj5oqKIDQ0MDcg5Lu95aSa6K+t6KiAIE1SSSDmlL7lsITmiqXlkYrovazmiJAgMTIg55eF54G255qE6K+B5o2u5YiG5pWwICsg572u5L+h5bqm44CCCgrkuLrku4DkuYjlrZjlnKg65a6Y5pa5IGdvbGQg5Y+q5pyJIDU4IHN0dWR5LOekvuWMuiLova/moIfnrb4i5pWw5o2u6ZuGIDk4LjclIOaYr+Wtl+mdoiAwLjUg5q275YC8Cijpm7blop7ph4/kv6Hmga8pLOWvvOiHtCBCQ0Ug5qKv5bqm57qmIDDjgIFsb3NzIOaBkiAwLjY5M+OAgeaooeWei+WtpuS4jeWKqCgyMDI2LTA5LTA2IOWunuivgSnjgIIK5oql5ZGK5paH5pys6YeM5omN5pyJ55yf5q2j55qE5L+h5Y+34oCU4oCU5pys5oq95Y+W5Zmo5Y2z5L+h5Y+35rqQ44CCCgrnlKjms5Uo5LiOIHJzbmFfdjMubG9hZF9sYWJlbHMg6ZuG5oiQLOmbtuaMgui9vSznuq8gQ1BVKToKICAgIGltcG9ydCByc25hX3JlcG9ydF9sYWJlbHMgYXMgUgogICAgdGFibGUgPSBSLmJ1aWxkX3BzZXVkb190YWJsZSh0cmFpbl9kZikgICAjIFN0dWR5SW5zdGFuY2VVSUQgKyBwc2V1ZG9fPDEyPijliIbmlbDmiJYgTmFOKQoK6L6T5Ye66K+t5LmJKOavj+S4qiAoc3R1ZHksIGZpbmRpbmcpIOagvCk6CiAgICAxKSBuX3Bvcz4wICAgICAgICAgICAgICAgLT4gc29mdCDnm67moIcgPSDor4Hmja7liIbmlbAoMC43Mn4wLjk1LOaMieS4pemHjeW6pi/ph43lpI3liIbnuqcpCiAgICAyKSBuX3Bvcz09MCBhbmQgbl9uZWc+MCAgLT4gc29mdCDnm67moIcgPSDor4Hmja7liIbmlbAoMC4wNH4wLjIwLOWQpuWumuasoeaVsOi2iuWkmui2iuS9jikKICAgIDMpIOayiem7mCAvIOS4jeehruWumiAgICAgICAgIC0+IE5hTijkuI3ov5vmjZ/lpLEs55SxIEtuZWVEYXRhc2V0IHZhbGlkIOaOqeeggeaOkumZpCkKICAgIDQpIOWumOaWuSBnb2xkIOeUsSBsb2FkX2xhYmVscyDkvJjlhYjopobnm5Ys5pys6KGo5Y+q5aGr56m657y65qC844CCCiIiIgppbXBvcnQgcGFuZGFzIGFzIHBkCgojIC0tLSDku6XkuIvkuLrnpL7ljLrmir3lj5blmajljp/moLfnp7vmpI0o5Yu/5pS56K+N5YW4KSAtLS0KIyBzb3VyY2U6IHRvcF9rZXJuZWxzL3JzbmEta25lZS1iYXNlbGluZS12MS5pcHluYiBjZWxscyA2LTExIChydWxlIGV4dHJhY3RvciBzZWN0aW9uKQojIG5vcm1hbGlzZSAtPiBzZWdtZW50IC0+IHNjb3BlOyBuaW5lIGxhbmd1YWdlcyBwb29sZWQ7IHN0ZW0rc2lkZSBwcm94aW1pdHkgZmFsbGJhY2s7CiMgYXNzZXJ0aW9uL25lZ2F0aW9uL2hlZGdlIHBvbGFyaXR5IHBlciBjbGF1c2U7IGdyYWRlZCBzZXZlcml0eSBzY29yaW5nLgoKCmltcG9ydCByZQppbXBvcnQgdW5pY29kZWRhdGEKClRBUkdFVFMgPSBbCiAgICAiQUNMIiwgIk1DTCIsICJNZWRpYWwgTWVuaXNjdXMiLCAiTGF0ZXJhbCBNZW5pc2N1cyIsCiAgICAiTWVkaWFsIE9BIiwgIkxhdGVyYWwgT0EiLCAiUEYgT0EiLCAiRWZmdXNpb24iLAogICAgIlN5bm92aXRpcyIsICJCYWtlcidzIiwgIkNvbnR1c2lvbiIsICJGcmFjdHVyZSIsCl0KCgojIFR1cmtpc2ggZG90dGVkL2RvdGxlc3MgaSBtdXN0IGJlIGZvbGRlZCBiZWZvcmUgY2FzZWZvbGRpbmcsIG90aGVyd2lzZSAixLBaTEVOTUVaIgojIGFuZCAiaXpsZW5tZXoiIGRpdmVyZ2UuIMOfIGFuZCB0aGUgQ3JvYXRpYW4vU2VyYmlhbiBkLXdpdGgtc3Ryb2tlIGxpa2V3aXNlLgpfUFJFID0gc3RyLm1ha2V0cmFucyh7CiAgICAixLEiOiAiaSIsICLEsCI6ICJpIiwgIkkiOiAiaSIsICLDnyI6ICJzcyIsICLEkSI6ICJkIiwgIsSQIjogImQiLAogICAgIsO4IjogIm8iLCAiw5giOiAibyIsICLDpiI6ICJhZSIsICLDhiI6ICJhZSIsCn0pCgoKZGVmIG5vcm1hbGl6ZSh0ZXh0OiBzdHIpIC0+IHN0cjoKICAgICIiIkZvbGQgY2FzZSwgZGlhY3JpdGljcyBhbmQgc2VwYXJhdG9yczsga2VlcCBHcmVlayBhbmQgQ3lyaWxsaWMgbGV0dGVycy4KCiAgICBORktEIGRlY29tcG9zaXRpb24gc3RyaXBzIExhdGluIGFjY2VudHMgYW5kIEdyZWVrIHRvbm9zIGFsaWtlICjOrCAtPiDOsSksIHdoaWNoIGlzIHdoYXQKICAgIHdlIHdhbnQ6IHJlcG9ydHMgYXJlIGluY29uc2lzdGVudCBhYm91dCBhY2NlbnRzLiBJdCBhbHNvIG1hcHMgdGhlIE1JQ1JPIFNJR04gVSswMEI1CiAgICB0byBhIHJlYWwgbXUsIHdoaWNoIG1hdHRlcnMgYmVjYXVzZSBtb3N0IEdyZWVrIHJlcG9ydHMgaGVyZSB1c2UgdGhlIHdyb25nIGNvZGVwb2ludC4KICAgICIiIgogICAgaWYgbm90IGlzaW5zdGFuY2UodGV4dCwgc3RyKToKICAgICAgICByZXR1cm4gIiIKICAgIHRleHQgPSB0ZXh0LnRyYW5zbGF0ZShfUFJFKS5sb3dlcigpCiAgICB0ZXh0ID0gdW5pY29kZWRhdGEubm9ybWFsaXplKCJORktEIiwgdGV4dCkKICAgIHRleHQgPSAiIi5qb2luKGNoIGZvciBjaCBpbiB0ZXh0IGlmIG5vdCB1bmljb2RlZGF0YS5jb21iaW5pbmcoY2gpKQogICAgdGV4dCA9IHRleHQucmVwbGFjZSgiwq0iLCAiIikgICAgICAgICAgICAgICAgICAgICMgc29mdCBoeXBoZW4KICAgIHRleHQgPSByZS5zdWIociJbX1wtL1xcXSsiLCAiICIsIHRleHQpCiAgICB0ZXh0ID0gcmUuc3ViKHIiWyBcdF0rIiwgIiAiLCB0ZXh0KQogICAgcmV0dXJuIHRleHQKCgpfU0VOVF9TUExJVCA9IHJlLmNvbXBpbGUociIoPzw9Wy47IT9dKVxzK3xcbisiKQoKCmRlZiBjbGF1c2VzKHRleHQ6IHN0cik6CiAgICAiIiJTcGxpdCBpbnRvIGNsYXVzZXMsIHRoZW4gYXR0YWNoIGBoZWFkZXI6YCBsaW5lcyB0byB0aGUgdmFsdWUgdGhhdCBmb2xsb3dzLgoKICAgIEEgcmVwb3J0IGxpbmUgcmVhZGluZyBgRnJhY3R1cmVzIDpgIGZvbGxvd2VkIGJ5IGBBdWN1bmUuYCBpcyBvbmUgc3RhdGVtZW50LiBTcGxpdHRpbmcKICAgIG9uIHB1bmN0dWF0aW9uIGFsb25lIHNlcGFyYXRlcyB0aGUgYW5hdG9teSBmcm9tIGl0cyBuZWdhdGlvbiBhbmQgZmxpcHMgdGhlIGxhYmVsLgogICAgIiIiCiAgICBub3JtID0gbm9ybWFsaXplKHRleHQpCiAgICByYXcgPSBbYy5zdHJpcCgpIGZvciBjIGluIF9TRU5UX1NQTElULnNwbGl0KG5vcm0pIGlmIGMgYW5kIGMuc3RyaXAoKV0KCiAgICBtZXJnZWQgPSBbXQogICAgZm9yIGksIGMgaW4gZW51bWVyYXRlKHJhdyk6CiAgICAgICAgIyBBIGZyYWdtZW50IGVuZGluZyBpbiBhIGNvbG9uIGlzIGEgaGVhZGluZyBmb3IgdGhlIG5leHQgZnJhZ21lbnQuIFN0cnVjdHVyZWQKICAgICAgICAjIEVuZ2xpc2ggcmVwb3J0cyB3cml0ZSBsb25nIG9uZXMgLSAibGF0ZXJhbCBjb21wYXJ0bWVudCAobWVuaXNjdXMsIGNvbGxhdGVyYWwKICAgICAgICAjIGxpZ2FtZW50IGNvbXBsZXgsIGNhcnRpbGFnZSk6IiBpcyBlaWdodCB3b3JkcyAtIHNvIHRoZSBjYXAgaXMgZ2VuZXJvdXMuCiAgICAgICAgIwogICAgICAgICMgQSBtZXJnZWQgaGVhZGluZyBtdXN0IE5PVCBhbHNvIHN0YW5kIGFsb25lLiBPbiBpdHMgb3duIGl0IGNhcnJpZXMgdGhlIGFuYXRvbXkKICAgICAgICAjIHdvcmQgd2l0aCBubyBuZWdhdGlvbiBpbiBzY29wZSwgc28gYEZyYWN0dXJlcyA6YCAvIGBBdWN1bmUuYCBhc3NlcnRlZCBhIGZyYWN0dXJlCiAgICAgICAgIyBvZmYgdGhlIGhlYWRpbmcgd2hpbGUgdGhlIGpvaW5lZCBjbGF1c2UgY29ycmVjdGx5IHJlYWQgdGhlIGRlbmlhbC4gVGhlIGpvaW5lZAogICAgICAgICMgY2xhdXNlIGlzIGEgc3VwZXJzZXQgb2YgdGhlIGhlYWRpbmcsIHNvIG5vdGhpbmcgaXMgbG9zdCBieSBkcm9wcGluZyBpdDsgYQogICAgICAgICMgaGVhZGluZyB3aXRoIG5vIHZhbHVlIGJlbmVhdGggaXQgaXMgbm90IG1lcmdlZCBhbmQgc3RpbGwgc3RhbmRzLgogICAgICAgIGlmIGMuZW5kc3dpdGgoIjoiKSBhbmQgbGVuKGMuc3BsaXQoKSkgPD0gMTQgYW5kIGkgKyAxIDwgbGVuKHJhdyk6CiAgICAgICAgICAgIG1lcmdlZC5hcHBlbmQoYyArICIgIiArIHJhd1tpICsgMV0pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgbWVyZ2VkLmFwcGVuZChjKQogICAgIyBDb21tYS1zZXBhcmF0ZWQgZW51bWVyYXRpb25zIGluc2lkZSBhIGxvbmcgY2xhdXNlIGhpZGUgc2VwYXJhdGUgYXNzZXJ0aW9ucy4KICAgIG91dCA9IFtdCiAgICBmb3IgYyBpbiBtZXJnZWQ6CiAgICAgICAgb3V0LmFwcGVuZChjKQogICAgICAgIGlmIGxlbihjLnNwbGl0KCkpID4gMjU6CiAgICAgICAgICAgIG91dC5leHRlbmQocC5zdHJpcCgpIGZvciBwIGluIGMuc3BsaXQoIiwiKSBpZiBsZW4ocC5zcGxpdCgpKSA+IDIpCiAgICByZXR1cm4gb3V0CgoKZGVmIF9yeCgqYWx0czogc3RyKSAtPiByZS5QYXR0ZXJuOgogICAgcmV0dXJuIHJlLmNvbXBpbGUoInwiLmpvaW4oYWx0cykpCgoKTkVHQVRJT04gPSBfcngoCiAgICAjIGVuCiAgICByIlxibm9cYiIsIHIiXGJub3RcYiIsIHIiXGJ3aXRob3V0XGIiLCByIlxibmVnYXRpdmUgZm9yXGIiLCByIlxiYWJzZW5jZVxiIiwKICAgIHIiXGJubyBldmlkZW5jZVxiIiwgciJcYnVucmVtYXJrYWJsZVxiIiwgciJcYmZyZWUgb2ZcYiIsIHIiXGJub25lXGIiLCByIlxibmlsXGIiLAogICAgIyBlcwogICAgciJcYnNpblxiIiwgciJcYm5vIGhheVxiIiwgciJcYmF1c2VuY2lhXGIiLCByIlxiYXVzZW50ZXM/XGIiLAogICAgIyBmcgogICAgciJcYnBhcyBkZVxiIiwgciJcYnNhbnNcYiIsIHIiXGJhdWN1bmU/XGIiLCByIlxiYWJzZW5jZVxiIiwKICAgICMgbmwKICAgIHIiXGJnZWVuXGIiLCByIlxiem9uZGVyXGIiLCByIlxibmlldFxiIiwKICAgICMgZGUKICAgIHIiXGJrZWluZT9cYiIsIHIiXGJvaG5lXGIiLCByIlxibmljaHRcYiIsCiAgICAjIHRyCiAgICByIlxieW9rXGIiLCByIlxieW9rdHVyXGIiLCByIml6bGVubWVtZWt0ZSIsIHIic2FwdGFubWFkaSIsIHIiXGJkZWdpbFxiIiwKICAgIHIiZ296bGVubWVtZWt0ZSIsIHIibWV2Y3V0IGRlZ2lsIiwgciJlc2xpayBldG1peW9yIiwgciJcYml6bGVubWVkaVxiIiwKICAgICMgaHIgLyBzciAvIGJzCiAgICByIlxibmVtYVxiIiwgciJcYmJlelxiIiwgciJcYm5pc3VcYiIsIHIiXGJuaWplXGIiLAogICAgIyBlbCAoYWNjZW50cyBhbHJlYWR5IHN0cmlwcGVkKQogICAgciJcYs60zrXOvVxiIiwgciJcYs+Hz4nPgc65z4JcYiIsIHIizr/Phc60zrXOvSIsCiAgICAjIGJnIC8gcnUKICAgIHIiXGLQsdC10LdcYiIsIHIiXGLQvdC1XGIiLCByItC70LjQv9GB0LLQsCIsIHIiXGLQvdGP0LzQsFxiIiwKKQoKTk9STUFMSVRZID0gX3J4KAogICAgciJcYm5vcm1hbCIsIHIiXGJpbnRhY3RcYiIsIHIiXGJwcmVzZXJ2ZWRcYiIsIHIiXGJ3aXRoaW4gbm9ybWFsIGxpbWl0c1xiIiwKICAgIHIibGltaXRlcyBub3JtYWxlcyIsIHIiXGJjb25zZXJ2YWQiLCByIlxiaW50ZWdyIiwgciJcYm5vcm1hbGVzXGIiLAogICAgciJcYmRvZ2EobHxsbClcYiIsIHIia29ydW5tdXMiLCByIlxibm9ybWFsZGlyXGIiLCByIm9sYWdhbiIsCiAgICByIlxidXJlZG4iLCByIlxib2N1dmFuIiwgciJcYm9kcnphbiIsIHIiXGJpbnRha3QiLAogICAgciLPhs+Fz4POuc6/zrvOv86zzrnOuiIsIHIizrHOus61z4HOsc65IiwKICAgIHIidW5hdWZmYWxsaWciLCByInJlZ2VscmVjaHQiLCByIlxiaW50YWt0XGIiLAogICAgciLQvdC+0YDQvNCw0LsiLCByItC30LDQv9Cw0LfQtdC9IiwgciLRgdGK0YXRgNCw0L3QtdC9IiwgciJcYtCx0LXQtyDQvtGB0L7QsdC10L3QvtGB0YLQuFxiIiwKICAgIHIiXGJnYWFmXGIiLCByIlxibm9ybWFhbFxiIiwKKQoKVU5DRVJUQUlOID0gX3J4KAogICAgciJcYnBvc3NpYmxlXGIiLCByIlxicHJvYmFibGVcYiIsIHIiXGJzdXNwaWNpb3VzXGIiLCByIlxic3VzcGVjdGVkXGIiLAogICAgciJjYW5ub3QgKGJlICk/ZXhjbHVkZSIsIHIiXGJtYXlcYiIsIHIiXGJxdWVzdGlvbmFibGVcYiIsIHIiXGJlcXVpdm9jYWxcYiIsCiAgICByIlxicG9zaWJsZVxiIiwgciJzaW4gY3JpdGVyaW9zIGNhdGVnb3JpY29zIiwgciJcYmR1ZG9zIiwKICAgIHIiXGJtdWh0ZW1lbFxiIiwgciJcYm9sYXNpXGIiLCByIlxic3VwaGVsaVxiIiwgciJcYml6bGVuaW0iLAogICAgciJcYm1vZ3VjZVxiIiwgciJcYnZqZXJvamF0bm9cYiIsIHIiXGJzdW1uamFcYiIsCiAgICByIs+AzrnOuM6xzr0iLCByIs+Fz4DOv8+Az4QiLAogICAgciJcYm1vZ2xpY2giLCByIlxidmVyZGFjaHRpZyIsIHIiXGJmcmFnbGljaCIsIHIiXGJWXC5hXC5cYiIsCiAgICByIlxi0LLRitC30LzQvtC20L3QvlxiIiwgciJcYtCy0LXRgNC+0Y/RgtC90L5cYiIsIHIi0YHRg9GB0L/QtdC60YIiLAogICAgciJcYm1vZ2VsaWprXGIiLCByIlxidmVyZGFjaHRcYiIsCikKCiMgUGF0aG9sb2d5IHZvY2FidWxhcnkgc2hhcmVkIGJ5IHRoZSBwYWlyZWQgcnVsZXMuClRFQVIgPSBfcngoCiAgICByIlxidGVhciIsIHIiXGJ0b3JuXGIiLCByIlxicnVwdHVyZSIsIHIiXGJkaXNydXB0aW9uXGIiLCByImRpc2NvbnRpbnVpdCIsCiAgICByIlxiYXZ1bHMiLAogICAgciJcYnJvdHVyYVxiIiwgciJcYnJvdHVyYXNcYiIsIHIiXGJydXB0dXJhIiwgciJcYmRlc2dhcnJvIiwgciJcYnJvdG9cYiIsCiAgICByIlxiZGVjaGlydXJlIiwgciJcYmRlY2hpcmUiLAogICAgciJcYnNjaGV1ciIsIHIiXGJydXB0dXVyIiwgciJnZXNjaGV1cmQiLAogICAgciJyaXNzKGJpbGR1bmd8ZXxlcyk/XGIiLCByImVpbnJpc3MiLCByIlxicnVwdHVyIiwgciJ6ZXJyZWlzcyIsIHIiXGJsYXNpb24iLAogICAgciJcYnlpcnRpayIsIHIiXGJ5aXJ0aWciLCByIlxia29wbWFcYiIsIHIiYnV0dW5sdWsga2F5YmkiLCByIlxicnVwdHVydVxiIiwKICAgIHIiXGJwdWtudWNlIiwgciJcYnJ1cHR1ciIsIHIiXGJwcmVraWRcYiIsIHIiXGJwdWtvdGluIiwKICAgIHIiz4HOt86+zrciLCByIs+BzrfOvs65z4IiLCByIs+BzrfOs868zrEiLAogICAgciLRgNGD0L/RgtGD0YDQsCIsIHIi0YDQsNC30LrRitGB0LIiLCByItGA0LDQt9GA0LjQsiIsIHIi0YHQutGK0YHQsiIsCikKCkRFR0VOID0gX3J4KAogICAgciJkZWdlbmVyYXQiLCByIlxibXVjb2lkXGIiLCByIlxibXl4b2lkXGIiLCByIlxiZnJheSIsIHIiXGJmaXNzdXIiLAogICAgciJkZWplbmVyYXRpZiIsIHIiXGJtdWtvaWRcYiIsIHIiZGVnZW5lcmF0aXZuIiwgciLOtc66z4bPhc67IiwgciLQtNC10LPQtdC90LXRgNCw0YIiLAogICAgciJcYs68z4XOvs6/zrXOuc60IiwgciJcYs68z4XOvs+JzrQiLAogICAgciJcYm11Y28gP2lkZVxiIiwgciJhdWZnZWZhc2VydCIsCikKCklOSlVSWSA9IF9yeCgKICAgIHIiXGJpbmp1ciIsIHIiXGJzcHJhaW4iLCByIlxibGVzaW9uIiwgciJcYmxhc2lvbiIsIHIiXGJlZGVtYVxiIiwgciJcYm9lZGVtYVxiIiwKICAgIHIiXGJvZGVtXGIiLCByIlxiZWRlbVxiIiwgciJcYs6/zrnOtM63zrzOsSIsIHIiXGLQvtC00LXQvCIsIHIiXGLQtdC00LXQvCIsIHIiXGJzdHJhaW5cYiIsCiAgICByIlxiaGlnaCBzaWduYWxcYiIsIHIiXGJzaWduYWwgYWx0ZXJhdGlvblxiIiwgciJcYmhpcGVyaW50ZW5zIiwgciJcYmh5cGVyaW50ZW5zIiwKICAgIHIiYXVtZW50byBkZSBzZW5hbCIsIHIiYWx0ZXJhY2lvbiBkZSBzZW5hbCIsIHIiY2FtYmlvIGRlIHNlbmFsIiwKICAgIHIiXGJzaWduYWxhbmhlYnVuZyIsIHIiXGJzaWduYWxhbHRlcmF0aW9uIiwgciJ2ZXJob29nZCBzaWduYWFsIiwgciJzaW55YWwgYXJ0aXMiLAogICAgciLOsc+Fzr7Ot868zrXOvc6/IM+DzrfOvM6xIiwgciLQv9C+0LLQuNGI0LXQvSDRgdC40LPQvdCw0LsiLAogICAgciJcYnRoaWNrZW4iLCByIlxiemFkZWJsamFuamVcYiIsIHIiXGJ2ZXJkaWtraW5nXGIiLCByIlxiZGlzdGVuemlqIiwKICAgIHIiXGJsYWtzaXRlXGIiLCByIlxibGF4aXR5XGIiLCByIlxicGFydGlhbFxiIiwgciJcYnBhcmNpamFsbiIsIHIiXGJwYXJjaWFsIiwKICAgIHIiXGJwYXJ0aWVsIiwgciJcYnBhcnRpZWxsIiwKKQoKCkFOQVQgPSB7CiAgICAiQUNMIjogX3J4KAogICAgICAgIHIiYW50ZXJpb3IgY3J1Y2lhdGUiLCByIlxiYWNsXGIiLAogICAgICAgIHIiY3J1emFkbyBhbnRlcmlvciIsIHIiXGJsY2FcYiIsCiAgICAgICAgciJjcm9pc2UgYW50ZXJpZXVyIiwKICAgICAgICByInZvb3JzdGUga3J1aXNiYW5kIiwgciJcYnZrYlxiIiwKICAgICAgICByInZvcmRlcmVzIGtyZXV6YmFuZCIsIHIidm9yZGVyZW4ga3JldXpiYW5kIiwgciJ2b3JkZXJlIGtyZXV6YmFuZCIsCiAgICAgICAgciJvbiBjYXByYXoiLCByIlxib2NiXGIiLAogICAgICAgIHIicHJlZG5qaSBrcml6bmkiLCByInByZWRuamVnIGtyaXpuIiwKICAgICAgICByIs+Az4HOv8+DzrjOuVvOv86xXVteIF0qIM+HzrnOsc+Dz4QiLCByIs+Az4HOv8+DzrjOuc6/z4Ugz4fOuc6xz4PPhM6/z4UiLCByIs+HzrnOsc+Dz4TOv1teIF0qIM+Dz4XOvc60zrXPg868IiwKICAgICAgICAjICLPh865zrHPg8+Ezr/OuSDOus6xzrkgz4DOu86xzrPOuc6/zrkgz4PPhc69zrTOtc+DzrzOv865IiBzZXBhcmF0ZXMgdGhlIGFkamVjdGl2ZSBmcm9tIGl0cyBub3VuLCBzbyB0aGUKICAgICAgICAjIGFkamVjdGl2ZSBzdGVtIGhhcyB0byBzdGFuZCBhbG9uZS4gR3JlZWsgbWFya3MgY3J1Y2lhdGUgd2l0aCBpdCB1bmFtYmlndW91c2x5LgogICAgICAgIHIiXGLPh865zrHPg8+EXHcqIiwKICAgICAgICByItC/0YDQtdC00L3QsCDQutGA0YrRgdGC0L3QsCIsIHIi0L/RgNC10LTQvdCw0YLQsCDQutGA0YrRgdGC0L3QsCIsCiAgICAgICAgIyBQbHVyYWwsIHVucXVhbGlmaWVkOiByZXBvcnRzIHJvdXRpbmVseSBjbGVhciBib3RoIGNydWNpYXRlcyBpbiBvbmUgY2xhdXNlCiAgICAgICAgIyAoIkxpZ2FtZW50b3MgY3J1emFkb3MgeSBjb2xhdGVyYWxlcyBkZW50cm8gZGUgbGltaXRlcyBub3JtYWxlcyIpLCBzbyB0aGUKICAgICAgICAjIHBsdXJhbCBmb3JtIGhhcyB0byBtYXRjaCB3aXRob3V0IGEgc2lkZSBxdWFsaWZpZXIgb3IgdGhlIHdob2xlIGNsYXVzZSBpcyBsb3N0LgogICAgICAgIHIiY3J1Y2lhdGUgbGlnYW1lbnRzIiwgciJsaWdhbWVudG9zIGNydXphZG9zIiwgciJsaWdhbWVudHMgY3JvaXNlcyIsCiAgICAgICAgciJrcnVpc2JhbmRlbiIsIHIia3JldXpiYW5kZXIiLCByImNhcHJheiBiYWdsYXIiLCByImtyaXpuW2Etel0qIGxpZ2FtZW50W2Etel0qIiwKICAgICAgICByIs+HzrnOsc+Dz4TOv865IM+Dz4XOvc60zrXPg868IiwgciLPh865zrHPg8+Ez4nOvSDPg8+Fzr3OtM61z4POvCIsIHIi0LrRgNGK0YHRgtC90LjRgtC1INCy0YDRitC30LrQuCIsIHIi0LrRgNGK0YHRgtC90Lgg0LLRgNGK0LfQutC4IiwKICAgICksCiAgICAiTUNMIjogX3J4KAogICAgICAgIHIibWVkaWFsIGNvbGxhdGVyYWwiLCByIlxibWNsXGIiLCByInRpYmlhbCBjb2xsYXRlcmFsIiwKICAgICAgICByImNvbGF0ZXJhbCBtZWRpYWwiLCByImNvbGF0ZXJhbCBpbnRlcm5vIiwgciJcYmxjbVxiIiwKICAgICAgICByImNvbGxhdGVyYWwgbWVkaWFsIiwgciJjb2xsYXRlcmFsIGludGVybmUiLAogICAgICAgIHIibWVkaWFsZSBjb2xsYXRlcmFsZSIsIHIiYmlubmVuYmFuZCIsIHIiXGIobWVkaWFsZXxsYXRlcmFsZSkgYmFuZGVuXGIiLAogICAgICAgIHIiXGJjb2xsYXRlcmFsZSBiYW5kZW5cYiIsCiAgICAgICAgciJpbm5lbmJhbmQiLCByIm1lZGlhbGVzPyBrb2xsYXRlcmFsIiwKICAgICAgICByIlxiaWMgeWFuIGJhZyIsIHIibWVkaWFsIGtvbGxhdGVyYWwiLCByIlxiaXliXGIiLAogICAgICAgIHIibWVkaWphbG5pIGtvbGF0ZXJhbG4iLCByIm1lZGlqYWxub2cga29sYXRlcmFsbiIsCiAgICAgICAgciLOtc+Dz4kgz4DOu86xzrPOuSIsIHIizrXPg8+Jz4TOtc+BzrnOus6/IM+AzrvOsc6zzrkiLCByIlxiz4DOu86xzrPOuVx3KiDPg8+Fzr3OtM61z4POvCIsIHIiXGLPgM67zrHOs865zr/OuVxiIiwKICAgICAgICByItC80LXQtNC40LDQu9C10L0g0LrQvtC70LDRgtC10YDQsNC7IiwgciLQstGK0YLRgNC10YjQvdCwINGB0YLRgNCw0L3QuNGH0L3QsCIsIHIiXGLQutC+0LvQsNGC0LXRgNCw0LtcdyoiLAogICAgICAgICMgU2FtZSBwbHVyYWwgcGF0dGVybiBhcyB0aGUgY3J1Y2lhdGVzLgogICAgICAgICMgIkxpZ2FtZW50b3MgY3J1emFkb3MgeSBjb2xhdGVyYWxlcyIgc2VwYXJhdGVzIHRoZSBub3VuIGZyb20gaXRzIGFkamVjdGl2ZSwgc28KICAgICAgICAjIHRoZSBhZGplY3RpdmUgaGFzIHRvIHN0YW5kIGFsb25lIGFzIGEgY3VlLgogICAgICAgIHIiXGJjb2xhdGVyYWxlc1xiIiwgciJcYmNvbGxhdGVyYXV4XGIiLCByIlxiY29sbGF0ZXJhbGVuXGIiLCByIlxia29sYXRlcmFsbmlcYiIsCiAgICAgICAgciJjb2xsYXRlcmFsIGxpZ2FtZW50cyIsIHIibGlnYW1lbnRvcyBjb2xhdGVyYWxlcyIsIHIibGlnYW1lbnRzIGNvbGxhdGVyYXV4IiwKICAgICAgICByImNvbGxhdGVyYWxlIGJhbmRlbiIsIHIia29sbGF0ZXJhbGJhbmRlciIsIHIic2VpdGVuYmFuZGVyIiwgciJ5YW4gYmFnbGFyIiwKICAgICAgICByImtvbGF0ZXJhbG5bYS16XSogbGlnYW1lbnRbYS16XSoiLCByIs+AzrvOsc6zzrnOv865IM+Dz4XOvc60zrXPg868IiwgciLPgM67zrHOs865z4nOvSDPg8+Fzr3OtM61z4POvCIsCiAgICAgICAgciLQutC+0LvQsNGC0LXRgNCw0LvQvdC4INCy0YDRitC30LrQuCIsIHIi0YHRgtGA0LDQvdC40YfQvdC40YLQtSDQstGA0YrQt9C60LgiLAogICAgKSwKICAgICJNZWRpYWwgTWVuaXNjdXMiOiBfcngoCiAgICAgICAgciJtZWRpYWwgbWVuaXNjdXMiLCByIlxibW1cYig/PSB0ZWFyKSIsIHIibWVkaWFsIG1lbmlzYyIsCiAgICAgICAgciJtZW5pc2NvIG1lZGlhbCIsIHIibWVuaXNjbyBpbnRlcm5vIiwKICAgICAgICByIm1lbmlzcXVlIG1lZGlhbCIsIHIibWVuaXNxdWUgaW50ZXJuZSIsCiAgICAgICAgciJtZWRpYWxlIG1lbmlzY3VzIiwgciJiaW5uZW5tZW5pc2N1cyIsCiAgICAgICAgciJpbm5lbm1lbmlza3VzIiwgciJtZWRpYWxlbj8gbWVuaXNrdXMiLCByImlubmVubWVuaXNrdXNoaW50ZXJob3JuIiwKICAgICAgICByIm1lZHlhbCBtZW5pc2siLCByIlxiaWMgbWVuaXNrIiwKICAgICAgICByIm1lZGlqYWxuaSBtZW5pc2t1cyIsIHIibWVkaWphbG5vZyBtZW5pc2t1c2EiLCByIm1lZGlqYWxub20gbWVuaXNrdXN1IiwKICAgICAgICByIs61z4PPiSDOvM63zr3Ouc+DzroiLCByIs68zrfOvc65z4POulteIF0qIM+Ezr/PhSDOtc+Dz4kiLCByIs61z4PPiSDOtM65zrHOvM61z4HOuc+DzrzOsVteLl17MCw0MH3OvM63zr3Ouc+DzroiLAogICAgICAgIHIi0LzQtdC00LjQsNC70L3QuNGPINC80LXQvdC40YHQutGD0YEiLCByItC80LXQtNC40LDQu9C10L0g0LzQtdC90LjRgdC60YPRgSIsIHIi0LLRitGC0YDQtdGI0L3QuNGPINC80LXQvdC40YHQutGD0YEiLAogICAgKSwKICAgICJMYXRlcmFsIE1lbmlzY3VzIjogX3J4KAogICAgICAgIHIibGF0ZXJhbCBtZW5pc2N1cyIsIHIibGF0ZXJhbCBtZW5pc2MiLAogICAgICAgIHIibWVuaXNjbyBsYXRlcmFsIiwgciJtZW5pc2NvIGV4dGVybm8iLAogICAgICAgIHIibWVuaXNxdWUgbGF0ZXJhbCIsIHIibWVuaXNxdWUgZXh0ZXJuZSIsCiAgICAgICAgciJsYXRlcmFsZSBtZW5pc2N1cyIsIHIiYnVpdGVubWVuaXNjdXMiLAogICAgICAgIHIiYXVzc2VubWVuaXNrdXMiLCByImxhdGVyYWxlbj8gbWVuaXNrdXMiLAogICAgICAgIHIibGF0ZXJhbCBtZW5pc2siLCByIlxiZGlzIG1lbmlzayIsCiAgICAgICAgciJsYXRlcmFsbmkgbWVuaXNrdXMiLCByImxhdGVyYWxub2cgbWVuaXNrdXNhIiwgciJsYXRlcmFsbm9tIG1lbmlza3VzdSIsCiAgICAgICAgciLOtc6+z4kgzrzOt869zrnPg866IiwgciLOvM63zr3Ouc+DzrpbXiBdKiDPhM6/z4UgzrXOvs+JIiwgciLOtc6+z4kgzrTOuc6xzrzOtc+BzrnPg868zrFbXi5dezAsNDB9zrzOt869zrnPg866IiwKICAgICAgICByItC70LDRgtC10YDQsNC70L3QuNGPINC80LXQvdC40YHQutGD0YEiLCByItC70LDRgtC10YDQsNC70LXQvSDQvNC10L3QuNGB0LrRg9GBIiwgciLQstGK0L3RiNC90LjRjyDQvNC10L3QuNGB0LrRg9GBIiwKICAgICksCn0KCiMgT3N0ZW9hcnRocml0aXMgaXMgcmFyZWx5IHdyaXR0ZW4gYXMgIm9zdGVvYXJ0aHJpdGlzIi4gSXQgaXMgd3JpdHRlbiBhcyBjYXJ0aWxhZ2UgbG9zcywKIyBjaG9uZHJvcGF0aHkgZ3JhZGUsIGpvaW50IHNwYWNlIG5hcnJvd2luZywgb3Igb3N0ZW9waHl0ZXMgLSBzY29wZWQgdG8gYSBjb21wYXJ0bWVudC4KT0FfRVZJREVOQ0UgPSBfcngoCiAgICByIm9zdGVvYXJ0aHJpdCIsIHIiXGJhcnRocm9zIiwgciJcYmdvbmFydGhyb3MiLCByIlxib3N0ZW9hcnRocm9zIiwKICAgIHIiY2hvbmRyb3BhdGgiLCByImNob25kcm9tYWxhYyIsIHIiY29uZHJvcGF0IiwgciJjb25kcm9tYWxhYyIsCiAgICByImNhcnRpbGFnZSBsb3NzIiwgciJjYXJ0aWxhZ2UgdGhpbm5pbmciLCByImNob25kcmFsIChsb3NzfGRlZmVjdHx1bGNlcnx0aGlubmluZykiLAogICAgciJvc3Rlb3BoeXQiLCByIm9zdGVvZml0IiwgciJvc3Rlb2Z5dCIsIHIib3N0ZW9maXRvIiwgciJvc3Rlb3BoeXRlbiIsCiAgICByImpvaW50IHNwYWNlIG5hcnJvd2luZyIsIHIicGluemFtaWVudG8gYXJ0aWN1bGFyIiwKICAgIHIia2lraXJkYWsga2F5YiIsIHIia2lraXJkYWsgaW5jZWxtZSIsIHIia29uZHJvcGF0aSIsIHIia29uZHJhbCIsCiAgICByImtyYWFrYmVlbihsaWpkZW58dmVybGllcykiLCByImdvbmFydHJvc2UiLCByImFydHJvc2UiLAogICAgciJrbm9ycGVsKHZlcmx1c3R8c2NoYWRlbnxkZWZla3QpIiwgciJhcnRocm9zZSIsIHIiZ29uYXJ0aHJvc2UiLAogICAgciJocnNrYXZpYyIsIHIiaG9uZHJvbWFsYWMiLCByImFydHJveiIsIHIib3N0ZW9hcnRyaXQiLAogICAgciLPh86/zr3OtM+BW14gXSrPgM6xzrgiLCByIs6xz4HOuM+BzrnPhCIsIHIizrHPgc64z4HPic+DIiwgciLOv8+Dz4TOtc6/z4bPhc+EIiwKICAgIHIizrHPgc64z4HOuc66zr/PhSDPh86/zr3OtM+Bzr/PhSIsIHIizrXOvs6xzrvOtc65z4jOtyDPhM6/z4UgzrHPgc64z4HOuc66zr/PhSDPh86/zr3OtM+Bzr/PhSIsCiAgICByItCw0YDRgtGA0L7QtyIsIHIi0YXQvtC90LTRgNC+0L/QsNGCIiwgciLQvtGB0YLQtdC+0YTQuNGCIiwgciLRhdGA0YPRidGP0LtbXi5dezAsMzB9KNC40LfRgtGK0L180YPQstGA0LXQtHzQtNC10YTQtdC60YIpIiwKICAgIHIidWxjZXJhW3NdPyBjb25kcmFsIiwgciJjYXJ0aWxhZ29bXi5dezAsMjV9KHBlcmRpZGF8YWRlbGdheikiLAogICAgciJpY3JzIGdyYWRlIiwgciJvdXRlcmJyaWRnZSIsCikKCkNPTVBBUlRNRU5UID0gewogICAgIk1lZGlhbCBPQSI6IF9yeCgKICAgICAgICByIm1lZGlhbCAoZmVtb3JvdGliaWFsfHRpYmlvZmVtb3JhbHxjb21wYXJ0bWVudCkiLAogICAgICAgIHIiY29tcGFydGltZW50byBmZW1vcm90aWJpYWwgbWVkaWFsIiwgciJmZW1vcm90aWJpYWwgaW50ZXJubyIsCiAgICAgICAgciJtZWRpYWFsIGZlbW9yb3RpYmlhYWwiLCByIm1lZGlhbGUgZmVtb3JvdGliaWFsIiwKICAgICAgICByIm1lZGlhbCBmZW1vcm90aWJpYWwiLCByIm1lZGlhbGVuIGtvbXBhcnRpbWVudCIsIHIiaW5uZXJlW3NuXT8ga29tcGFydGltZW50IiwKICAgICAgICByIm1lZHlhbCBmZW1vcm90aWJpYWwiLCByImljIGtvbXBhcnRtYW4iLCByIm1lZHlhbCBrb21wYXJ0bWFuIiwKICAgICAgICByIm1lZGlqYWxuW14gXSogKGZlbW9yb3RpYml8b2RqZWxqfGtvbXBhcnRtKSIsCiAgICAgICAgciLOtc+Dz4kgzrTOuc6xzrzOtc+BzrnPg868zrEiLCByIs61z4PPiSDOus69zrfOvM65zrHOuSIsIHIizrXPg8+JIM68zrfPgc65zrHOuSIsCiAgICAgICAgciLQvNC10LTQuNCw0LvQvVteIF0qICjQutC+0LzQv9Cw0YDRgtC8fNC+0YLQtNC10Lt80YLQuNCx0LjQsNC7fNGE0LXQvNC+0YDQvtGC0LjQsSkiLAogICAgICAgIHIibWVkaWFsIChmZW1vcmFsfHRpYmlhbCkgKGNvbmR5bGV8cGxhdGVhdSkiLCByImNvbmRpbG8gZmVtb3JhbCBtZWRpYWwiLAogICAgICAgIHIibWVkaWFsZW4/IChmZW11cmtvbmR5bHx0aWJpYXBsYXRlYXUpIiwgciJtZWRpYWxlIGZlbW9yYWxlIGNvbmR5bCIsCiAgICApLAogICAgIkxhdGVyYWwgT0EiOiBfcngoCiAgICAgICAgciJsYXRlcmFsIChmZW1vcm90aWJpYWx8dGliaW9mZW1vcmFsfGNvbXBhcnRtZW50KSIsCiAgICAgICAgciJjb21wYXJ0aW1lbnRvIGZlbW9yb3RpYmlhbCBsYXRlcmFsIiwgciJmZW1vcm90aWJpYWwgZXh0ZXJubyIsCiAgICAgICAgciJsYXRlcmFhbCBmZW1vcm90aWJpYWFsIiwgciJsYXRlcmFsZSBmZW1vcm90aWJpYWwiLAogICAgICAgIHIibGF0ZXJhbCBmZW1vcm90aWJpYWwiLCByImxhdGVyYWxlbiBrb21wYXJ0aW1lbnQiLCByImF1c3NlcmVbc25dPyBrb21wYXJ0aW1lbnQiLAogICAgICAgIHIibGF0ZXJhbCBmZW1vcm90aWJpYWwiLCByImRpcyBrb21wYXJ0bWFuIiwgciJsYXRlcmFsIGtvbXBhcnRtYW4iLAogICAgICAgIHIibGF0ZXJhbG5bXiBdKiAoZmVtb3JvdGliaXxvZGplbGp8a29tcGFydG0pIiwKICAgICAgICByIs61zr7PiSDOtM65zrHOvM61z4HOuc+DzrzOsSIsIHIizrXOvs+JIM66zr3Ot868zrnOsc65IiwgciLOtc6+z4kgzrzOt8+BzrnOsc65IiwKICAgICAgICByItC70LDRgtC10YDQsNC70L1bXiBdKiAo0LrQvtC80L/QsNGA0YLQvHzQvtGC0LTQtdC7fNGC0LjQsdC40LDQu3zRhNC10LzQvtGA0L7RgtC40LEpIiwKICAgICAgICByImxhdGVyYWwgKGZlbW9yYWx8dGliaWFsKSAoY29uZHlsZXxwbGF0ZWF1KSIsIHIiY29uZGlsbyBmZW1vcmFsIGxhdGVyYWwiLAogICAgICAgIHIibGF0ZXJhbGVuPyAoZmVtdXJrb25keWx8dGliaWFwbGF0ZWF1KSIsIHIibGF0ZXJhbGUgZmVtb3JhbGUgY29uZHlsIiwKICAgICksCiAgICAiUEYgT0EiOiBfcngoCiAgICAgICAgciJwYXRlbGxvZmVtb3JhbCIsIHIiZmVtb3JvcGF0ZWxsYXIiLCByImZlbW9yb3BhdGVsYXIiLCByInBhdGVsb2ZlbW9yYWwiLAogICAgICAgIHIicmV0cm9wYXRlbGxhciIsIHIicmV0cm9yb3R1bGlhbiIsIHIiXGJ0cm9jaGxlYSIsIHIiXGJ0cm9jbGVhIiwgciJcYnRyb2tsZWEiLAogICAgICAgIHIiXGJwYXRlbGxhXGIiLCByIlxicGF0ZWxsYXJcYiIsIHIiXGJyb3R1bGlhbiIsIHIiXGJyb3R1bGFcYiIsIHIiXGJwYXRlbGVcYiIsCiAgICAgICAgciJcYnBhdGVsbGFlP1xiIiwgciJwYXRlbGxvZmVtb3JhYWwiLCByImZlbW9yb3BhdGVsbGFpciIsCiAgICAgICAgciLOtc+AzrnOs86/zr3Osc+EzrnOtCIsIHIizrzOt8+Bzr/Otc+AzrnOs86/zr3Osc+EzrnOtCIsIHIiz4TPgc6/z4fOuc67IiwKICAgICAgICByItC/0LDRgtC10LsiLCByItGE0LXQvNC+0YDQvtC/0LDRgtC10LsiLCByItGC0YDQvtC70YUiLAogICAgICAgIHIiYW50ZXJpb3IgY29tcGFydG1lbnQiLCByImNvbXBhcnRpbWVudG8gYW50ZXJpb3IiLCByInByZWRualteIF0qIG9kamVsamsiLAogICAgKSwKfQoKIyBTZWxmLWRlY2xhcmluZyBmaW5kaW5nczogdGhlIHRlcm0gaXRzZWxmIGlzIHRoZSBmaW5kaW5nLgpESVJFQ1QgPSB7CiAgICAiRWZmdXNpb24iOiBfcngoCiAgICAgICAgciJcYmVmZnVzaW9uIiwgciJqb2ludCBmbHVpZCIsIHIiaW50cmEgP2FydGljdWxhciBmbHVpZCIsIHIiXGJoeWRyb3BzXGIiLAogICAgICAgIHIiZGVycmFtZSBhcnRpY3VsYXIiLCByIlxiZGVycmFtZVxiIiwgciJsaXF1aWRvIGFydGljdWxhciIsCiAgICAgICAgciJlcGFuY2hlbWVudCIsCiAgICAgICAgciJnZXdyaWNodHN2b2NodCIsIHIiXGJ2b2NodFxiIiwgciJcYmh5ZHJvcHNcYiIsIHIiZ2V3cmljaHRzZWZmdXNpZSIsCiAgICAgICAgciJnZWxlbmtlcmd1c3MiLCByIlxiZXJndXNzXGIiLCByImdlbGVua3Nlcmd1IiwKICAgICAgICAjICJkaXogZWtsZW1pIGljaSBzaXZpIG1pa3RhcmkgLi4uIGFydG1pcyIgYW5kICJla2xlbSBpY2VyaXNpbmRlIHlheWdpbiBzaXZpCiAgICAgICAgIyBhcnRpc2kiIGJvdGggb2NjdXI7IHRoZSBub3VuIHRha2VzIGEgcG9zc2Vzc2l2ZSBzdWZmaXgsIHNvIGBla2xlbSBgIGFsb25lCiAgICAgICAgIyBtaXNzZXMuIE1hdGNoIHRoZSBzdGVtIHBsdXMgYW55IHN1ZmZpeC4KICAgICAgICByImVrbGVtXHcqIGljXHcqIHNpdmkiLCByImVmdXp5b24iLCByImVrbGVtIHNpdmlzaSIsCiAgICAgICAgciJzaXZpIChtaWt0YXJpfGFydGlzaXxiaXJpa2ltaSkiLCByInNpdmkgYXJ0aXMiLCByIlxic2l2aVxiW14uXXswLDI1fWFydG1pcyIsCiAgICAgICAgciJcYml6bGpldiIsIHIiXGJpemxpdiIsIHIiemdsb2JuW14gXSogdGVrdWNpbiIsIHIiXGJoaWRyb3BzXGIiLAogICAgICAgIHIizrHPgc64z4HOuc66W14gXSogz4XOs8+BIiwgciLPhc6zz4HOv8+FIM61zr3OtM6xz4HOuM+BzrnOus6xIiwgciLOtc69zrTOsc+BzrjPgc65zrpbXiBdKiDPhc6zz4EiLCByIs+Azr/Pg86/z4TOt8+EzrEgz4XOs8+Bzr/PhSIsCiAgICAgICAgciLOtc69zrTOsc+BzrjPgc65zroiLCByIs6xz4HOuM+BzrnOus63IM+Dz4XOu867zr/Os863IiwgciLPhc6zz4HOvyDPg8+EzrfOvSDOsc+BzrjPgc+Jz4POtyIsIHIiz4XOs8+Bzr/PhSDPg8+EzrfOvSDOsc+BzrjPgc+Jz4POtyIsCiAgICAgICAgciLRgdGC0LDQstC10L0g0LjQt9C70LjQsiIsIHIi0LjQt9C70LjQsiIsIHIi0YHRgtCw0LLQvdCwINGC0LXRh9C90L7RgdGCIiwgciLRgdC40L3QvtCy0LjQsNC70L3QsCDRgtC10YfQvdC+0YHRgiIsCiAgICApLAogICAgIlN5bm92aXRpcyI6IF9yeCgKICAgICAgICByInN5bm92aXQiLCByInNpbm92aXQiLCByInN5bm92aWFsICh0aGlja2VuaW5nfHByb2xpZmVyYXRpb258aHlwZXJ0cm9waCkiLAogICAgICAgIHIic3lub3ZpdGlzIiwgciJzeW5vdmlhbGU/ICh2ZXJkaWtraW5nfHByb2xpZmVyYXRpZSkiLAogICAgICAgIHIic3lub3ZpYWxpdGlzIiwgciJzeW5vdmlhbGlzKHZlcmRpY2t1bmd8cHJvbGlmZXJhdGlvbikiLAogICAgICAgIHIic2lub3ZpamFsaXRpcyIsIHIic2lub3ZpdGlzIiwgciJ6YWRlYmxqYW5qZSBzaW5vdmlqIiwKICAgICAgICByIs+FzrzOtc69zrnPhM65zrTOsSIsIHIiz4PPhc69zr/Oss65z4TOuc60zrEiLCByIs+FzrzOtc69zrnOulteIF0qIM+Fz4DOtc+Bz4TPgc6/z4YiLCByIs6xz4HOuM+BzrnOus6/z4Ugz4XOvM61zr0iLAogICAgICAgIHIi0YHQuNC90L7QstC40YIiLCByItGB0LjQvdC+0LLQuNCw0LtbXiBdKiAo0LfQsNC00LXQsdC10Lt80L/RgNC+0LvQuNGE0LXRgCkiLAogICAgICAgIHIidmVyZGlra2luZ2VuIHZhbiAoaGV0ICk/c3lub3ZpdW0iLCByInBhbm51cyIsCiAgICApLAogICAgIkJha2VyJ3MiOiBfcngoCiAgICAgICAgciJiYWtlciIsIHIicG9wbGl0ZWFsIGN5c3QiLCByInF1aXN0ZSBwb3BsaXRlbyIsIHIicXVpc3RlcyBwb3BsaXRlb3MiLAogICAgICAgIHIia3lzdGUgcG9wbGl0ZSIsIHIicG9wbGl0ZWFsZT8gY3lzdCIsIHIicG9wbGl0ZWFsenlzdGUiLCByImJha2VyenlzdGUiLAogICAgICAgIHIicG9wbGl0ZWFsIGtpc3QiLCByIlxiYmFrZXJvdmFcYiIsIHIicG9wbGl0ZWFsblteIF0qIGNpc3QiLAogICAgICAgIHIizrrPhc+Dz4TOtyBiYWtlciIsIHIiz4DOv867z4XPh8+Jz4HOtyDPg8+Fzr3Ov86yzrnOsc66zrcgzrrPhc+Dz4TOtyIsIHIizrrPhc+Dz4TOtyDPhM6/z4UgYmFrZXIiLAogICAgICAgIHIi0LrQuNGB0YLQsCDQvdCwINCx0LXQudC60YrRgCIsIHIi0LHQtdC50LrRitGA0L7QstCwINC60LjRgdGC0LAiLCByItC/0L7Qv9C70LjRgtC10LDQu9C90LAg0LrQuNGB0YLQsCIsCiAgICAgICAgciJnYXN0cm9jbmVtaW8gP3NlbWltZW1icmFub3MiLCByImdhc3Ryb2NuZW1pdXMgc2VtaW1lbWJyYW5vc3VzIGJ1cnMiLAogICAgKSwKICAgICJDb250dXNpb24iOiBfcngoCiAgICAgICAgciJcYmNvbnR1c2lvbiIsIHIiYm9uZSBicnVpc2UiLCByImJvbmUgbWFycm93IChvP2VkZW1hfGNvbnR1c2lvbikiLAogICAgICAgIHIiXGJrb250dXoiLCByIm1lZHVsYXIgYm9uZSBvP2VkZW1hIiwgciJtYXJyb3cgbz9lZGVtYSIsCiAgICAgICAgciJjb250dXNpb24gb3NlYSIsIHIiZWRlbWEgb3NlbyIsIHIiZWRlbWEgZGUgbWVkdWxhIG9zZWEiLAogICAgICAgIHIib2VkZW1lIG9zc2V1eCIsIHIiY29udHVzaW9uIG9zc2V1c2UiLAogICAgICAgIHIiYm90Y29udHVzaWUiLCByImJvdG9lZGVlbSIsIHIiYmVlbm1lcmdvZWRlZW0iLCByImJvdG1lcmdvZWRlZW0iLAogICAgICAgIHIia25vY2hlbm1hcmtvZGVtIiwgciJrbm9jaGVub2RlbSIsIHIia29udHVzaW9uIiwgciJib25lIGJydWlzZSIsCiAgICAgICAgciJrZW1payBrb250dXp5b251IiwgciJrZW1payBpbGlnaSBvZGVtaSIsIHIia2VtaWsgb2RlbWkiLAogICAgICAgIHIia29zdGFuaSBlZGVtIiwgciJlZGVtIGtvc3RpIiwgciJrb250dXppaiIsCiAgICAgICAgciLOv8+Dz4TOtc6/zrzPhc61zrvOuc66W14gXSogzr/Ouc60zrfOvM6xIiwgciLOv8+Dz4TOuc66zr8gzr/Ouc60zrfOvM6xIiwgciLOvM+FzrXOu865zrrOvyDOv865zrTOt868zrEiLAogICAgICAgIHIi0LrQvtGB0YLQvdC+0LzQvtC30YrRh9C10L0g0LXQtNC10LwiLCByItC60L7RgdGC0LXQvSDQtdC00LXQvCIsIHIi0LrQvtC90YLRg9C30LjQvtC90LXQvSIsCiAgICApLAogICAgIkZyYWN0dXJlIjogX3J4KAogICAgICAgIHIiXGJmcmFjdHVyIiwgciJcYmZyYWN0XGIiLAogICAgICAgIHIiXGJmcmFjdHVyYSIsIHIiXGJmcmFjdHVyYXNcYiIsCiAgICAgICAgciJcYmZyYWN0dXVyIiwgciJcYmJyZXVrXGIiLAogICAgICAgIHIiXGJmcmFrdHVyIiwgciJcYmJydWNoXGIiLAogICAgICAgIHIiXGJraXJpa1xiIiwgciJcYmtpcmlnaVxiIiwgciJcYmtpcmlrXGIiLAogICAgICAgIHIiXGJmcmFrdHVyIiwgciJcYnByaWplbG9tIiwgciJpbXByZXNpanNrW14gXSogZnJha3R1ciIsCiAgICAgICAgciLOus6xz4TOsc6zzrzOsSIsIHIizrrOsc+EzrHOs868zrHPhCIsCiAgICAgICAgciLRhNGA0LDQutGC0YPRgCIsIHIi0YHRh9GD0L/QstCw0L0iLCByItGE0LjRgdGD0YAiLAogICAgICAgIHIiaW5zdWZmaWNpZW5jeSBmcmFjdHVyZSIsIHIic3RyZXNzIGZyYWN0dXJlIiwgciJhdnVsc2lvbiBmcmFjdHVyZSIsCiAgICAgICAgciJzdWJjaG9uZHJhbCBmcmFjdHVyZSIsIHIic3Via29uZHJhbCBraXJpIiwKICAgICksCn0KCiMgVGVybXMgdGhhdCBsb29rIGxpa2UgYSBmaW5kaW5nIGJ1dCBhcmUgbm90IHRoZSBmaW5kaW5nIGJlaW5nIHNjb3JlZC4KREVDT1kgPSB7CiAgICAjIGBubyBmcmFjdHVyZWAgaXMgZGVsaWJlcmF0ZWx5IGFic2VudDogYSBkZWNveSBza2lwcyB0aGUgY2xhdXNlLCBzbyBsaXN0aW5nIGl0IGhlcmUKICAgICMgdHVybmVkIHRoZSBjb21tb25lc3QgRW5nbGlzaCBkZW5pYWwgaW50byBzaWxlbmNlLCBhbmQgdGhlIHN0dWR5IHRoZW4gcHVsbGVkIG9uIHRoZQogICAgIyBmcmFjdHVyZSBoZWFkIHdpdGggdGhlIHdlaWdodCBvZiBhIHJlcG9ydCB0aGF0IG5ldmVyIG1lbnRpb25lZCBmcmFjdHVyZXMgYXQgYWxsLgogICAgIyBgbWljcm9mcmFjdHVyYCBpcyBhIHN1cmdpY2FsIHByb2NlZHVyZSBhbmQgYGZyYWN0dXJlIHJpc2tgIGEgcHJlZGljdGlvbjsgYm90aCBzdGF5LgogICAgIkZyYWN0dXJlIjogX3J4KHIibWljcm9mcmFjdHVyIiwgciJcYmZyYWN0dXJlIChyaXNrfHByb3BoeWxhKSIpLAogICAgIkJha2VyJ3MiOiBfcngociJtZW5pc2NhbCBjeXN0IiwgciJxdWlzdGUgbWVuaXNjYWwiLCByImdhbmdsaW9uIiksCn0KClBBSVJFRCA9IHsiQUNMIiwgIk1DTCIsICJNZWRpYWwgTWVuaXNjdXMiLCAiTGF0ZXJhbCBNZW5pc2N1cyJ9Ck9BX1RBUkdFVFMgPSB7Ik1lZGlhbCBPQSIsICJMYXRlcmFsIE9BIiwgIlBGIE9BIn0KCgpTVEVNX01FTklTQ1VTID0gX3J4KHIibWVuaXNjXHcqIiwgciJtZW5pc2tcdyoiLCByIs68zrfOvc65z4POulx3KiIsIHIi0LzQtdC90LjRgdC6XHcqIikKU1RFTV9DUlVDSUFURSA9IF9yeChyImNydWNpYXRlIiwgciJjcnV6YWRvIiwgciJjcm9pc2UiLCByImtydWlzYmFuZCIsIHIia3JldXpiYW5kIiwKICAgICAgICAgICAgICAgICAgICByImNhcHJheiBiYWdcdyoiLCByImtyaXpuXHcqIiwgciLPh865zrHPg8+EXHcqIiwgciLQutGA0YrRgdGC0L1cdyoiLAogICAgICAgICAgICAgICAgICAgIHIiXGJhY2xcYiIsIHIiXGJwY2xcYiIsIHIiXGJsY2FcYiIsIHIiXGJsY3BcYiIsIHIiXGJ2a2JcYiIsCiAgICAgICAgICAgICAgICAgICAgciJcYmhrYlxiIiwgciJcYm9jYlxiIiwgciJcYmFjYlxiIikKU1RFTV9DT0xMQVRFUkFMID0gX3J4KHIiY29sbGF0ZXJhbFx3KiIsIHIiY29sYXRlcmFsXHcqIiwgciJrb2xsYXRlcmFsXHcqIiwKICAgICAgICAgICAgICAgICAgICAgIHIiY29sbGF0ZXJhbGVcdyoiLCByImtvbGF0ZXJhbG5cdyoiLCByInlhbiBiYWdcdyoiLAogICAgICAgICAgICAgICAgICAgICAgciLPgM67zrHOs865XHcqIiwgciLQutC+0LvQsNGC0LXRgNCw0LtcdyoiLCByItGB0YLRgNCw0L3QuNGHXHcqIiwKICAgICAgICAgICAgICAgICAgICAgIHIiaW5uZW5iYW5kXHcqIiwgciJhdXNzZW5iYW5kXHcqIiwgciJiaW5uZW5iYW5kXHcqIiwKICAgICAgICAgICAgICAgICAgICAgIHIiXGJtY2xcYiIsIHIiXGJsY2xcYiIsIHIiXGJsY21cYiIsIHIiXGJpeWJcYiIpCgpTSURFX01FRElBTCA9IF9yeChyIlxibWVkaWFsXHcqIiwgciJcYm1lZHlhbFx3KiIsIHIiXGJtZWRpamFsblx3KiIsIHIiXGJtZWRpYWFsXHcqIiwKICAgICAgICAgICAgICAgICAgciJcYm1lZGlhbGVcdyoiLCByIlxiaW50ZXJuW29hXVx3KiIsIHIiXGJpbnRlcm5lXHcqIiwgciJcYmlubmVuXHcqIiwKICAgICAgICAgICAgICAgICAgciJcYmljXGIiLCByIlxidW51dGFybmpcdyoiLCByIlxizrXPg8+JXHcqIiwgciJcYs61z4PPic+EzrXPgc65zrpcdyoiLAogICAgICAgICAgICAgICAgICByIlxi0LzQtdC00LjQsNC7XHcqIiwgciJcYtCy0YrRgtGA0LXRiFx3KiIsIHIiXGJ0aWJpYWwgY29sbGF0ZXJhbFxiIiwKICAgICAgICAgICAgICAgICAgciJcYmJpbm5lblx3KiIsIHIiXGJtZWRpYWFsXGIiKQpTSURFX0xBVEVSQUwgPSBfcngociJcYmxhdGVyYWxcdyoiLCByIlxiZXh0ZXJuW29hXVx3KiIsIHIiXGJleHRlcm5lXHcqIiwgciJcYmRpc1xiIiwKICAgICAgICAgICAgICAgICAgIHIiXGJsYXRlcmFsblx3KiIsIHIiXGJhdXNzZW5cdyoiLCByIlxiYnVpdGVuXHcqIiwgciJcYs61zr7PiVx3KiIsCiAgICAgICAgICAgICAgICAgICByIlxizrXOvs+Jz4TOtc+BzrnOulx3KiIsIHIiXGLQu9Cw0YLQtdGA0LDQu1x3KiIsIHIiXGLQstGK0L3RiNC9XHcqIiwKICAgICAgICAgICAgICAgICAgIHIiXGJmaWJ1bGFyIGNvbGxhdGVyYWxcYiIsIHIiXGJ2YW5qc2tcdyoiKQpTSURFX0FOVEVSSU9SID0gX3J4KHIiXGJhbnRlcmlvclx3KiIsIHIiXGJhbnRcYiIsIHIiXGJvblxiIiwgciJcYnByZWRualx3KiIsCiAgICAgICAgICAgICAgICAgICAgciJcYnZvcmRlclx3KiIsIHIiXGJ2b29yc3RlXGIiLCByIlxiz4DPgc6/z4POuM65XHcqIiwgciJcYtC/0YDQtdC00L1cdyoiLAogICAgICAgICAgICAgICAgICAgIHIiXGJhbnRlcml5b3JcdyoiLCByIlxiYXZhbnRcYiIsIHIiXGJhbnRbZcOpXXJpZXVyXHcqIikKCiMgVGhlIGNvbnRyYXJ5IG9mIFNJREVfQU5URVJJT1IsIG5lZWRlZCBvbmx5IHRvIHN0b3AgYSBzaWRlLWJsaW5kIGNydWNpYXRlIGN1ZSBmaXJpbmcgb24KIyB0aGUgcG9zdGVyaW9yIGxpZ2FtZW50LiBJdCBpcyBuZXZlciB1c2VkIHRvIGFzc2VydCBhIHRhcmdldCAtIHRoZXJlIGlzIG5vIFBDTCB0YXJnZXQgLQojIHNvIGl0IGlzIGRlbGliZXJhdGVseSBuYXJyb3c6IGBwb3N0ZXJpb3IgaG9ybmAgaXMgb25lIG9mIHRoZSBjb21tb25lc3QgcGhyYXNlcyBpbiBhCiMga25lZSByZXBvcnQgYW5kIG11c3Qgbm90IGJlIHJlYWQgYXMgYSBjcnVjaWF0ZSBxdWFsaWZpZXIsIHdoaWNoIGlzIHdoeSB0aGUgZ3VhcmQgYmVsb3cKIyB0ZXN0cyBwcm94aW1pdHkgdG8gdGhlIGNydWNpYXRlIHN0ZW0gcmF0aGVyIHRoYW4gcHJlc2VuY2UgaW4gdGhlIGNsYXVzZS4KU0lERV9QT1NURVJJT1IgPSBfcngociJcYnBvc3Rlcmlvclx3KiIsIHIiXGJwb3N0W2XDqV1yaWV1clx3KiIsIHIiXGJwb3N0ZXJpb3JlXHcqIiwKICAgICAgICAgICAgICAgICAgICAgciJcYmhpbnRlclx3KiIsIHIiXGJhY2h0ZXJzdGVcYiIsIHIiXGJhcmthXGIiLCByIlxic3RyYXpualx3KiIsCiAgICAgICAgICAgICAgICAgICAgIHIiXGJ6YWRualx3KiIsIHIiXGLOv8+AzrnPg864zrlcdyoiLCByIlxi0LfQsNC00L1cdyoiLCByIlxicG9zdGVyb1x3KiIpCgojIEZyYWN0dXJlIGlzIHRoZSB0YXJnZXQgd2hvc2Ugc3RlbSB2YXJpZXMgbW9zdCBhY3Jvc3MgdGhlIGNvcnB1cy4KU1RFTV9GUkFDVFVSRSA9IF9yeChyImZyYWN0dXJcdyoiLCByImZyYWt0dXJcdyoiLCByImZyYWN0dXVyXHcqIiwgciJcYmZyYWN0XGIiLAogICAgICAgICAgICAgICAgICAgIHIia2lyaVtrZ8SfXVx3KiIsIHIicHJpamVsb21cdyoiLCByImxvbSBrb3N0aSIsIHIiXGJicmV1a1x3KiIsCiAgICAgICAgICAgICAgICAgICAgciJcYmJydWNoXHcqIiwgciLOus6xz4TOsc6zzrzOsVx3KiIsIHIizrrOsc+EzrHOs868zrHPhFx3KiIsIHIi0YTRgNCw0LrRgtGD0YBcdyoiLAogICAgICAgICAgICAgICAgICAgICMgTk9UIGEgYmFyZSBgZmlzc3VyXHcqYDogImZpc3VyYXMgY29uZHJhbGVzIiBhbmQgImZ1bGwgdGhpY2tuZXNzCiAgICAgICAgICAgICAgICAgICAgIyBmaXNzdXJlcyBpbiB0aGUgYXJ0aWN1bGFyIGNhcnRpbGFnZSIgZGVzY3JpYmUgY2FydGlsYWdlLCBub3QgYm9uZS4KICAgICAgICAgICAgICAgICAgICAjIFRoZSBzdGVtIGhhcyB0byBiZSBhbmNob3JlZCB0byBhIGJvbmUgd29yZCB0byBtZWFuIGEgZnJhY3R1cmUuCiAgICAgICAgICAgICAgICAgICAgciLRgdGH0YPQv9Cy0LDQvVx3KiIsIHIiZmlzdXJcdyogKG9zZWF8b3NlYXN8a29zdCkiLCByImZpc3N1clx3KiBrb3N0IikKClNURU1fT0FfQ09NUEFSVE1FTlQgPSBfcngociJjb21wYXJ0bWVudFx3KiIsIHIiY29tcGFydGltZW50b1x3KiIsIHIiY29tcGFydGltZW50XHcqIiwKICAgICAgICAgICAgICAgICAgICAgICAgICByImtvbXBhcnRtYW5cdyoiLCByImtvbXBhcnRpbWVudFx3KiIsIHIib2RqZWxqXHcqIiwKICAgICAgICAgICAgICAgICAgICAgICAgICByIs60zrnOsc68zrXPgc65z4POvM6xXHcqIiwgciLQutC+0LzQv9Cw0YDRgtC8XHcqIiwgciJcYtC+0YLQtNC10LtcdyoiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHIiZmVtb3JvdGliaWFsXHcqIiwgciJmZW1vcm90aWJpYWFsXHcqIiwgciJ0aWJpb2ZlbW9yYWxcdyoiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHIiZmVtb3JvIHRpYmlhbFx3KiIsIHIizrrOvc63zrzOuc6xzrlcdyoiLCByIs68zrfPgc65zrHOuVx3KiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgciJmZW1vcmFsIGNvbmR5bFx3KiIsIHIidGliaWFsIHBsYXRlYXVcdyoiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHIiY29uZGlsbyBmZW1vcmFsIiwgciJwbGF0aWxsbyB0aWJpYWwiLCByInRpYmlhcGxhdGVhdVx3KiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgciJmZW11cmtvbmR5bFx3KiIsIHIiZmVtb3JhbG5lPyBrb25kaWxcdyoiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHIidGliaWphbG5cdyogcGxhdG8iLCByImZlbW9yYWwga29uZGlsXHcqIiwKICAgICAgICAgICAgICAgICAgICAgICAgICByInRpYmlhIHBsYXRvIiwgciJ0aWJ5YWwgcGxhdG8iKQoKCmRlZiBfZGlzdGFuY2UoY2xhdXNlOiBzdHIsIHN0ZW1fcng6IHJlLlBhdHRlcm4sIHF1YWxfcng6IHJlLlBhdHRlcm4sIHdpbmRvdzogaW50ID0gNTUpOgogICAgIiIiQ2hhcmFjdGVycyBmcm9tIHRoZSBuZWFyZXN0IHN0ZW0gdG8gdGhlIG5lYXJlc3QgcXVhbGlmaWVyLCBvciBOb25lIGlmIG5vbmUgaXMgbmVhci4KCiAgICBDaGFyYWN0ZXIgd2luZG93cyByYXRoZXIgdGhhbiB0b2tlbiB3aW5kb3dzLCBiZWNhdXNlIHdvcmQgb3JkZXIgZGlmZmVyczogRW5nbGlzaAogICAgcHV0cyB0aGUgc2lkZSBiZWZvcmUgdGhlIG5vdW4sIEdyZWVrIGFuZCBCdWxnYXJpYW4gb2Z0ZW4gYWZ0ZXIsIGFuZCBUdXJraXNoCiAgICBhdHRhY2hlcyBpdCBhcyBhIHNlcGFyYXRlIHByZWNlZGluZyBhZGplY3RpdmUuCgogICAgQSBkaXN0YW5jZSByYXRoZXIgdGhhbiBhIHllcy4gUHJlc2VuY2UgaXMgZW5vdWdoIHRvIGRlY2lkZSB0aGF0IGEgcXVhbGlmaWVyIGFwcGxpZXMKICAgIHRvIGEgc3RydWN0dXJlLCBidXQgbm90IGVub3VnaCB0byBkZWNpZGUgd2hpY2ggb2YgdHdvIHF1YWxpZmllcnMgYXBwbGllczogYSBrbmVlCiAgICByZXBvcnQgc2F5cyAiYW50ZXJpb3IgaG9ybiIgYW5kICJwb3N0ZXJpb3IgaG9ybiIgY29uc3RhbnRseSwgc28gYW55IHdpbmRvdyB3aWRlCiAgICBlbm91Z2ggdG8gY2F0Y2ggYSByZWFsIHNpZGUgd29yZCBhbHNvIGNhdGNoZXMgYW4gdW5yZWxhdGVkIG9uZSwgYW5kIHR3byBydWxlcyB0aGF0CiAgICBib3RoIGFuc3dlciAieWVzIiBjYW5ub3QgYmUgdG9sZCBhcGFydC4gQ29tcGFyaW5nIGhvdyBmYXIgYXdheSB0aGV5IGFyZSBjYW4uCiAgICAiIiIKICAgIGJlc3QgPSBOb25lCiAgICBmb3IgbSBpbiBzdGVtX3J4LmZpbmRpdGVyKGNsYXVzZSk6CiAgICAgICAgbG8gPSBtYXgoMCwgbS5zdGFydCgpIC0gd2luZG93KQogICAgICAgIGhpID0gbWluKGxlbihjbGF1c2UpLCBtLmVuZCgpICsgd2luZG93KQogICAgICAgIGZvciBxIGluIHF1YWxfcnguZmluZGl0ZXIoY2xhdXNlW2xvOmhpXSk6CiAgICAgICAgICAgIHFzLCBxZSA9IGxvICsgcS5zdGFydCgpLCBsbyArIHEuZW5kKCkKICAgICAgICAgICAgZCA9IDAgaWYgcXMgPCBtLmVuZCgpIGFuZCBxZSA+IG0uc3RhcnQoKSBlbHNlIFwKICAgICAgICAgICAgICAgIG1pbihhYnMobS5zdGFydCgpIC0gcWUpLCBhYnMocXMgLSBtLmVuZCgpKSkKICAgICAgICAgICAgYmVzdCA9IGQgaWYgYmVzdCBpcyBOb25lIGVsc2UgbWluKGJlc3QsIGQpCiAgICByZXR1cm4gYmVzdAoKCmRlZiBfbmVhcihjbGF1c2U6IHN0ciwgc3RlbV9yeDogcmUuUGF0dGVybiwgcXVhbF9yeDogcmUuUGF0dGVybiwgd2luZG93OiBpbnQgPSA1NSk6CiAgICAiIiJUcnVlIGlmIGEgc3RlbSBtYXRjaCBoYXMgYSBxdWFsaWZpZXIgd2l0aGluIGB3aW5kb3dgIGNoYXJhY3RlcnMgZWl0aGVyIHNpZGUuIiIiCiAgICByZXR1cm4gX2Rpc3RhbmNlKGNsYXVzZSwgc3RlbV9yeCwgcXVhbF9yeCwgd2luZG93KSBpcyBub3QgTm9uZQogICAgcmV0dXJuIEZhbHNlCgoKIyBjb25jZXB0IC0+IChzdGVtLCBzaWRlKSBwYWlycyB1c2VkIGluIGFkZGl0aW9uIHRvIHRoZSBwaHJhc2UgbGV4aWNvbnMgYWJvdmUKU1RFTV9SVUxFUyA9IHsKICAgICJBQ0wiOiAoU1RFTV9DUlVDSUFURSwgU0lERV9BTlRFUklPUiksCiAgICAiTUNMIjogKFNURU1fQ09MTEFURVJBTCwgU0lERV9NRURJQUwpLAogICAgIk1lZGlhbCBNZW5pc2N1cyI6IChTVEVNX01FTklTQ1VTLCBTSURFX01FRElBTCksCiAgICAiTGF0ZXJhbCBNZW5pc2N1cyI6IChTVEVNX01FTklTQ1VTLCBTSURFX0xBVEVSQUwpLAogICAgIk1lZGlhbCBPQSI6IChTVEVNX09BX0NPTVBBUlRNRU5ULCBTSURFX01FRElBTCksCiAgICAiTGF0ZXJhbCBPQSI6IChTVEVNX09BX0NPTVBBUlRNRU5ULCBTSURFX0xBVEVSQUwpLAp9CgoKU0VWX0xPVyA9IF9yeCgKICAgIHIiXGJzbWFsbFxiIiwgciJcYm1pbmltYWxcYiIsIHIiXGJ0cmFjZVxiIiwgciJcYm1pbGRcYiIsIHIiXGJzbGlnaHRcYiIsCiAgICByIlxidGlueVxiIiwgciJcYnNjYW50XGIiLCByIlxibWltaW1hbFxiIiwgciJcYmRpc2NyZXRlXGIiLCByIlxiZm9jYWxcYiIsCiAgICByIlxibGV2ZVxiIiwgciJcYm1pbmltIiwgciJcYnBlcXVlIiwgciJcYmxpZ2Vyb1xiIiwgciJcYmVzY2Fzb1xiIiwgciJcYmRpc2NyZXRvXGIiLAogICAgciJcYmhhZmlmXGIiLCByIlxibWluaW1hbFxiIiwgciJcYmF6IG1pa3RhcmRhXGIiLCByIlxic2lsaWtcYiIsCiAgICByIlxibWFuamFcYiIsIHIiXGJtYW5qaVxiIiwgciJcYmJsYWdvXGIiLCByIlxiZGlza3JldG4iLCByIlxibWFsb1xiIiwKICAgIHIiXGJnZXJpbmciLCByIlxiZGlza3JldCIsIHIiXGJrbGVpbmU/cj9cYiIsIHIiXGJ3ZW5pZ1xiIiwgciJcYnphcnRlP1xiIiwKICAgIHIiXGJiZXBlcmt0ZT9cYiIsIHIiXGJnZXJpbmdlXGIiLCByIlxid2VpbmlnXGIiLCByIlxibGljaHRlP1xiIiwKICAgIHIiXGLOt8+AzrkiLCByIlxizrzOuc66z4EiLCByIlxizrXOu86xz4fOuc+Dz4QiLAogICAgciJcYtC80LjQvdC40LzQsNC7IiwgciJcYtC70LXQuiIsIHIiXGLQvNCw0LvQuiIsIHIiXGLQvdC10LPQvtC70Y/QvCIsCikKClNFVl9ISUdIID0gX3J4KAogICAgciJcYmxhcmdlXGIiLCByIlxibWFya2VkXGIiLCByIlxibWFzc2l2ZVxiIiwgciJcYnNldmVyZVxiIiwgciJcYmV4dGVuc2l2ZVxiIiwKICAgIHIiXGJtb2RlcmF0ZVxiIiwgciJcYmdyb3NzXGIiLCByIlxic2lnbmlmaWNhbnRcYiIsIHIiXGJhYnVuZGFudFxiIiwgciJcYnRlbnNlXGIiLAogICAgciJcYm1vZGVyYWQiLCByIlxiaW1wb3J0YW50ZVxiIiwgciJcYnNldmVyYT9cYiIsIHIiXGJtYXJjYWQiLCByIlxiY3VhbnRpb3MiLAogICAgciJcYmJlbGlyZ2luXGIiLCByIlxieWF5Z2luXGIiLCByIlxiaWxlcmlcYiIsIHIiXGJjaWRkaVxiIiwgciJcYmJvbFxiIiwKICAgIHIiXGJvcHNlemFuXGIiLCByIlxidmVsaWtpXGIiLCByIlxiaXpyYXppdCIsIHIiXGJ6bmFjYWpuIiwgciJcYnVtamVyZW4iLAogICAgciJcYmF1c2dlcHJhZ3QiLCByIlxiZGV1dGxpY2giLCByIlxibWFzc2l2IiwgciJcYm1hc3NpZyIsIHIiXGJncm9zcyIsCiAgICByIlxidWl0Z2VicmVpZCIsIHIiXGJnZXZvcmRlcmQiLCByIlxidmVlbFxiIiwgciJcYm1hdGlnZT9cYiIsCiAgICByIlxizrzOtc+Ez4HOuSIsIHIiXGLOvM61zrPOsc67IiwgciJcYs61zrrPhM61z4TOsc68zrXOvSIsIHIiXGLOtc+FzrzOtc6zzrXOuCIsIHIiXGLPg86/zrLOsc+BIiwKICAgIHIiXGLQs9C+0LvRj9C8IiwgciJcYtC40LfRgNCw0LfQtdC9IiwgciJcYtC30L3QsNGH0LjQvCIsIHIiXGLRg9C80LXRgNC10L0iLCByIlxi0L7QsdC40LvQtdC9IiwKKQoKIyBPQSBpcyBvZnRlbiBhc3NlcnRlZCBmb3IgdGhlIHdob2xlIGpvaW50IHJhdGhlciB0aGFuIHBlciBjb21wYXJ0bWVudAojICgidHJpY29tcGFydG1lbnRhbCBvc3Rlb2FydGhyaXRpcyIsICJnb25hcnRocm9zZSIsICJpbmNpcGllbnQgT0Egb2YgYWxsIHRocmVlCiMgY29tcGFydG1lbnRzIikuIFRob3NlIHN0YXRlbWVudHMgYXJlIGV2aWRlbmNlIGZvciBhbGwgdGhyZWUgT0EgdGFyZ2V0cy4KR0xPQkFMX09BID0gX3J4KAogICAgciJ0cmkgP2NvbXBhcnRtZW50IiwgciJhbGwgdGhyZWUgY29tcGFydG1lbnQiLCByImdsb2JhbChpc2VkKT8gKG9hfG9zdGVvYXJ0aHJpdCkiLAogICAgciJcYmdvbmFydGhyb3MiLCByIlxiZ29uYXJ0cm9zIiwgciJcYmdvbmFydGhyb3NlIiwgciJcYmdvbmFydHJvc2UiLAogICAgciJvc3Rlb2FydGhyaXRpcyBvZiB0aGUga25lZSIsIHIiYXJ0cm9zaXMgKGRlIHwpKGxhICk/cm9kaWxsYSIsIHIia25lZSBvc3Rlb2FydGhyaXQiLAogICAgciJcYmRpeiBvc3Rlb2FydHJpdCIsIHIiXGJnb25hcnRyb3oiLCByImFydHJvemEga29samVuYSIsCiAgICByIs6/z4PPhM61zr/Osc+BzrjPgc65z4TOuc60zrEiLCByIs6xz4HOuM+BzrnPhM65zrTOsSDPhM6/z4UgzrPOv869zrHPhM6/z4IiLAogICAgciLQsNGA0YLRgNC+0LfQsCDQvdCwINC60L7Qu9GP0L3QvdCw0YLQsCIsIHIi0LPQvtC90LDRgNGC0YDQvtC3IiwKICAgIHIiZGVnZW5lcmF0aXZlIGpvaW50IGRpc2Vhc2UiLCByIlxiZGpkXGIiLAopCgojIEEgYmFyZSAiYm9uZSBtYXJyb3cgb2VkZW1hIiBpcyBub3QgYSBjb250dXNpb24gd2hlbiBpdCBzaXRzIHVuZGVyIGEgY2FydGlsYWdlCiMgZGVmZWN0OiBzdWJjaG9uZHJhbCBvZWRlbWEgYmVuZWF0aCBhIHdvcm4gY29tcGFydG1lbnQgaXMgcmVhY3RpdmUgZGVnZW5lcmF0aXZlIHNpZ25hbCwKIyBhbmQgcmVhZGluZyBpdCBhcyBhIGJydWlzZSB0dXJucyBldmVyeSBvc3Rlb2FydGhyaXRpYyBrbmVlIGludG8gYSB0cmF1bWEgY2FzZS4KREVHRU5FUkFUSVZFX01BUlJPVyA9IF9yeCgKICAgIHIic3ViY2hvbmRyYWwiLCByInN1YmNvbmRyYWwiLCByInN1YmtvbmRyYWwiLCByInN1cGtvbmRyYWxuIiwgciJzdWJjaG9uZHJhbG4iLAogICAgciLPhc+Azr/Ph86/zr3OtM+BzrkiLCByItGB0YPQsdGF0L7QvdC00YDQsNC7IiwgciJzdWJjaG9uZHJhbGU/IiwKICAgIHIiXGJjeXN0IiwgciJcYnF1aXN0IiwgciJcYnp5c3RlXGIiLCByIlxiY2lzdGljIiwgciJyZWFjdGl2ZSIsIHIicmVhY3Rpdm8iLAopCgpUUkFVTUEgPSBfcngoCiAgICByIlxiYnJ1aXNlXGIiLCByIlxiY29udHVzaW9uIiwgciJcYmtvbnR1eiIsIHIiXGJjb250dXNpb24gb3NlYVxiIiwKICAgIHIiXGJ0cmF1bWEiLCByIlxiaW1wYWN0aW9uXGIiLCByIlxicGl2b3Qgc2hpZnRcYiIsIHIiXGJraXNzaW5nXGIiLAogICAgciJcYmFjdXRlXGIiLCByIlxiYWd1ZG9cYiIsIHIiXGJha3V0IiwgciJcYnBpdm90IGtheW1hc2lcYiIsCiAgICByIlxiY29udHVzaW9uIG9zc2V1c2VcYiIsIHIiXGJib25lIGJydWlzZVxiIiwgciJcYmJvdGNvbnR1c2llXGIiLAogICAgciJcYtC60L7QvdGC0YPQt9C40L7QvSIsIHIiXGLOvM+JzrvPic+AIiwgciJcYmtvbnR1emlqIiwKKQoKCmRlZiBfcG9sYXJpdHkoY2xhdXNlOiBzdHIsIGFuY2hvcl9lbmQ6IGludCkgLT4gc3RyOgogICAgIiIiQ2xhc3NpZnkgb25lIGNsYXVzZSBhcyBwb3NpdGl2ZSwgbmVnYXRpdmUgb3IgdW5jZXJ0YWluIGZvciBhIG1hdGNoZWQgdGVybS4KCiAgICBTY29wZSBpcyB0aGUgd2hvbGUgY2xhdXNlLiBDbGF1c2Ugc2VnbWVudGF0aW9uIGFscmVhZHkga2VlcHMgc3RhdGVtZW50cyBzaG9ydCwgYW5kCiAgICBhIHdpbmRvdyBpbiBjaGFyYWN0ZXJzIG1pcy1zY29wZXMgYmFkbHkgYWNyb3NzIGxhbmd1YWdlcyB3aXRoIGRpZmZlcmVudCB3b3JkIG9yZGVycyAtCiAgICBUdXJraXNoIHB1dHMgaXRzIG5lZ2F0b3IgYXQgdGhlIGVuZCBvZiB0aGUgc2VudGVuY2UsIEVuZ2xpc2ggYXQgdGhlIGZyb250LgogICAgIiIiCiAgICBpZiBVTkNFUlRBSU4uc2VhcmNoKGNsYXVzZSk6CiAgICAgICAgcmV0dXJuICJ1bmNlcnRhaW4iCiAgICBpZiBORUdBVElPTi5zZWFyY2goY2xhdXNlKToKICAgICAgICByZXR1cm4gIm5lZ2F0aXZlIgogICAgaWYgTk9STUFMSVRZLnNlYXJjaChjbGF1c2UpOgogICAgICAgICMgIm1lbmlzY3VzIG5vcm1hbCIgbmVnYXRlczsgIm5vcm1hbCAuLi4gYnV0IHRlYXIiIGRvZXMgbm90LgogICAgICAgIGlmIFRFQVIuc2VhcmNoKGNsYXVzZSkgb3IgcmUuc2VhcmNoKHIiXGJncmFkZSBbMzRdXGIiLCBjbGF1c2UpOgogICAgICAgICAgICByZXR1cm4gInBvc2l0aXZlIgogICAgICAgIHJldHVybiAibmVnYXRpdmUiCiAgICByZXR1cm4gInBvc2l0aXZlIgoKCmNsYXNzIF9NYXRjaGVyOgogICAgIiIiUGhyYXNlIGxleGljb24gZmlyc3QsIHN0ZW0rc2lkZSBwcm94aW1pdHkgYXMgdGhlIGZhbGxiYWNrLgoKICAgIEV4cG9zZXMgYC5zZWFyY2hgIHNvIGl0IGRyb3BzIGludG8gdGhlIHNhbWUgc2xvdCBhcyBhIGNvbXBpbGVkIHBhdHRlcm4uCiAgICAiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZiwgcGhyYXNlX3J4LCBzdGVtPU5vbmUsIHNpZGU9Tm9uZSwgd2luZG93PTU1LCBjb250cmFyeT1Ob25lKToKICAgICAgICBzZWxmLnBocmFzZV9yeCA9IHBocmFzZV9yeAogICAgICAgIHNlbGYuc3RlbSA9IHN0ZW0KICAgICAgICBzZWxmLnNpZGUgPSBzaWRlCiAgICAgICAgc2VsZi53aW5kb3cgPSB3aW5kb3cKICAgICAgICBzZWxmLmNvbnRyYXJ5ID0gY29udHJhcnkKCiAgICBkZWYgc2VhcmNoKHNlbGYsIGNsYXVzZSk6CiAgICAgICAgbSA9IHNlbGYucGhyYXNlX3J4LnNlYXJjaChjbGF1c2UpCiAgICAgICAgaWYgbSBpcyBub3QgTm9uZSBhbmQgbm90IHNlbGYuX3dyb25nX3NpZGUoY2xhdXNlKToKICAgICAgICAgICAgcmV0dXJuIG0KICAgICAgICBpZiBzZWxmLnN0ZW0gaXMgbm90IE5vbmUgYW5kIF9uZWFyKGNsYXVzZSwgc2VsZi5zdGVtLCBzZWxmLnNpZGUsIHNlbGYud2luZG93KToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuc3RlbS5zZWFyY2goY2xhdXNlKQogICAgICAgIHJldHVybiBOb25lCgogICAgZGVmIF93cm9uZ19zaWRlKHNlbGYsIGNsYXVzZSk6CiAgICAgICAgIiIiVHJ1ZSB3aGVuIHRoZSBjbGF1c2UgbmFtZXMgdGhlIG90aGVyIG1lbWJlciBvZiB0aGlzIHN0cnVjdHVyZSdzIHBhaXIuCgogICAgICAgIFNvbWUgY3VlcyBpbiB0aGUgbGV4aWNvbiBhcmUgc2lkZS1ibGluZCBieSBkZXNpZ246IEdyZWVrIHNlcGFyYXRlcyB0aGUgYWRqZWN0aXZlCiAgICAgICAgZnJvbSBpdHMgbm91biAoImNydWNpYXRlIGFuZCBjb2xsYXRlcmFsIGxpZ2FtZW50cyIpLCBzbyB0aGUgYmFyZSBhZGplY3RpdmUgc3RlbQogICAgICAgIGhhcyB0byBzdGFuZCBhbG9uZSBvciB0aGUgY2xhdXNlIGlzIGxvc3QuIFRoYXQgc3RlbSB0aGVuIGFsc28gbWF0Y2hlcyB0aGUKICAgICAgICBwb3N0ZXJpb3IgY3J1Y2lhdGUgYW5kIHRoZSBsYXRlcmFsIGNvbGxhdGVyYWwsIG5laXRoZXIgb2Ygd2hpY2ggaXMgYSB0YXJnZXQgaGVyZSwKICAgICAgICBhbmQgYSBwb3NpdGl2ZSBvdXRyYW5rcyBldmVyeSBuZWdhdGl2ZSBpbiB0aGUgc2NvcmVyIC0gc28gb25lIFBDTCBjbGF1c2Ugd2FzCiAgICAgICAgZW5vdWdoIHRvIG92ZXJyaWRlIGFuIGV4cGxpY2l0ICJ0aGUgQUNMIGlzIG5vcm1hbCIuCgogICAgICAgIFRoZSB0ZXN0IGlzIHByb3hpbWl0eSB0byB0aGUgc3RydWN0dXJlJ3Mgb3duIHN0ZW0sIG5vdCBwcmVzZW5jZSBpbiB0aGUgY2xhdXNlLgogICAgICAgICJQb3N0ZXJpb3IgaG9ybiBvZiB0aGUgbWVkaWFsIG1lbmlzY3VzIiBhcHBlYXJzIGluIGEgbGFyZ2Ugc2hhcmUgb2Yga25lZSByZXBvcnRzCiAgICAgICAgYW5kIHNheXMgbm90aGluZyBhYm91dCBhIGNydWNpYXRlOyBvbmx5IGEgcXVhbGlmaWVyIHNpdHRpbmcgYmVzaWRlIHRoZSBsaWdhbWVudAogICAgICAgIHdvcmQgaXMgb25lLiBBIGNsYXVzZSBuYW1pbmcgYm90aCBzaWRlcyBrZWVwcyB0aGUgbWF0Y2gsIGJlY2F1c2UgaXQgZG9lcyBtZW50aW9uCiAgICAgICAgdGhpcyB0YXJnZXQuCiAgICAgICAgIiIiCiAgICAgICAgaWYgc2VsZi5jb250cmFyeSBpcyBOb25lIG9yIHNlbGYuc3RlbSBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICBvdGhlciA9IF9kaXN0YW5jZShjbGF1c2UsIHNlbGYuc3RlbSwgc2VsZi5jb250cmFyeSwgc2VsZi53aW5kb3cpCiAgICAgICAgaWYgb3RoZXIgaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgb3duID0gX2Rpc3RhbmNlKGNsYXVzZSwgc2VsZi5zdGVtLCBzZWxmLnNpZGUsIHNlbGYud2luZG93KQogICAgICAgICMgTm90ICJpcyB0aGUgb3RoZXIgc2lkZSBtZW50aW9uZWQiIGJ1dCAiaXMgaXQgdGhlIG5lYXJlciBvZiB0aGUgdHdvIi4gQSBjbGF1c2UKICAgICAgICAjIHJlYWRpbmcgInRlYXIgb2YgdGhlIHBvc3RlcmlvciBob3JuIG9mIHRoZSBtZWRpYWwgbWVuaXNjdXM7IHRoZSBjcnVjaWF0ZQogICAgICAgICMgbGlnYW1lbnRzIGFyZSBpbnRhY3QiIG1lbnRpb25zIHBvc3RlcmlvciwgYW5kIHVuZGVyIGEgcHJlc2VuY2UgdGVzdCB0aGF0IHdhcwogICAgICAgICMgZW5vdWdoIHRvIHN1cHByZXNzIHRoZSBjcnVjaWF0ZSBjdWUgLSB3aGljaCBpcyB0aGUgb3Bwb3NpdGUgb2YgdGhlIGludGVudCwKICAgICAgICAjIHNpbmNlIHRoZSBjbGF1c2UgZG9lcyBkZXNjcmliZSB0aGUgbGlnYW1lbnRzLiBUaWVzIGdvIHRvIGtlZXBpbmcgdGhlIG1hdGNoOgogICAgICAgICMgYSBjbGF1c2UgbmFtaW5nIGJvdGggc2lkZXMgZG9lcyBtZW50aW9uIHRoaXMgb25lLgogICAgICAgIHJldHVybiBvd24gaXMgTm9uZSBvciBvdGhlciA8IG93bgoKCiMgV2hpY2ggY3VlLCBpZiBpdCBzaXRzIGJlc2lkZSB0aGUgc3RydWN0dXJlJ3Mgc3RlbSwgbWVhbnMgdGhlIGNsYXVzZSBpcyBhYm91dCB0aGUgb3RoZXIKIyBtZW1iZXIgb2YgdGhlIHBhaXIuIE9ubHkgdGhlIHR3byBzdHJ1Y3R1cmVzIHdpdGggYSBzaWRlLWJsaW5kIGN1ZSBuZWVkIG9uZS4KQ09OVFJBUlkgPSB7IkFDTCI6IFNJREVfUE9TVEVSSU9SLCAiTUNMIjogU0lERV9MQVRFUkFMfQoKQU5BVF9NQVRDSCA9IHsKICAgIHRndDogX01hdGNoZXIoQU5BVFt0Z3RdLCAqU1RFTV9SVUxFU1t0Z3RdLCBjb250cmFyeT1DT05UUkFSWS5nZXQodGd0KSkKICAgIGZvciB0Z3QgaW4gUEFJUkVECn0KQ09NUEFSVE1FTlRfTUFUQ0ggPSB7CiAgICAiTWVkaWFsIE9BIjogX01hdGNoZXIoQ09NUEFSVE1FTlRbIk1lZGlhbCBPQSJdLCAqU1RFTV9SVUxFU1siTWVkaWFsIE9BIl0pLAogICAgIkxhdGVyYWwgT0EiOiBfTWF0Y2hlcihDT01QQVJUTUVOVFsiTGF0ZXJhbCBPQSJdLCAqU1RFTV9SVUxFU1siTGF0ZXJhbCBPQSJdKSwKICAgICJQRiBPQSI6IF9NYXRjaGVyKENPTVBBUlRNRU5UWyJQRiBPQSJdKSwKfQpESVJFQ1RfTUFUQ0ggPSB7CiAgICB0Z3Q6IF9NYXRjaGVyKF9yeChyeC5wYXR0ZXJuLCBTVEVNX0ZSQUNUVVJFLnBhdHRlcm4pIGlmIHRndCA9PSAiRnJhY3R1cmUiIGVsc2UgcngpCiAgICBmb3IgdGd0LCByeCBpbiBESVJFQ1QuaXRlbXMoKQp9CgoKZGVmIF9zZXZlcml0eShjbGF1c2U6IHN0cikgLT4gZmxvYXQ6CiAgICAiIiJXZWlnaHQgb25lIHBvc2l0aXZlIG1lbnRpb24gYnkgaG93IGVtcGhhdGljIHRoZSBzZW50ZW5jZSBpcy4KCiAgICBPcmRlcmVkLCBub3QgY2FsaWJyYXRlZC4gQSAibW9kZXJhdGUgZWZmdXNpb24iIG11c3Qgb3V0cmFuayBhICJ0cmFjZSBlZmZ1c2lvbiIgYW5kCiAgICBib3RoIG11c3Qgb3V0cmFuayBzaWxlbmNlOyB0aGUgYWJzb2x1dGUgbnVtYmVycyBkbyBub3QgbWF0dGVyIHRvIEFVQy4KICAgICIiIgogICAgaGlnaCA9IFNFVl9ISUdILnNlYXJjaChjbGF1c2UpIGlzIG5vdCBOb25lCiAgICBsb3cgPSBTRVZfTE9XLnNlYXJjaChjbGF1c2UpIGlzIG5vdCBOb25lCiAgICBpZiBoaWdoIGFuZCBub3QgbG93OgogICAgICAgIHJldHVybiAxLjAKICAgIGlmIGxvdyBhbmQgbm90IGhpZ2g6CiAgICAgICAgcmV0dXJuIDAuNDUKICAgIHJldHVybiAwLjc1ICAgICAgICAgICAgICAgICAgICAgICAjIHVucXVhbGlmaWVkIG1lbnRpb24KCgpkZWYgX3Njb3JlX2NsYXVzZXMoY2xzLCBhbmF0X3J4LCBwYXRoX3J4PU5vbmUsIGRlY295X3J4PU5vbmUsIGNvbnRleHRfcGVuYWx0eT1Ob25lLAogICAgICAgICAgICAgICAgICAgY29udGV4dF9ib251cz1Ob25lKToKICAgICIiIkFjY3VtdWxhdGUgZ3JhZGVkIGV2aWRlbmNlIG92ZXIgY2xhdXNlcyBmb3Igb25lIHRhcmdldC4KCiAgICBSZXR1cm5zIChzY29yZSwgY29uZmlkZW5jZSwgbl9wb3MsIG5fbmVnKS4gUG9zaXRpdmVzIGFyZSBncmFkZWQgYnkgc2V2ZXJpdHkgYW5kIGJ5CiAgICBvcHRpb25hbCBjb250ZXh0IHJlZ2V4ZXM7IG5lZ2F0aXZlcyBvbmx5IG1hdHRlciB3aGVuIG5vdGhpbmcgcG9zaXRpdmUgd2FzIGZvdW5kLAogICAgYmVjYXVzZSByZXBvcnRzIGFzc2VydCBub3JtYWxpdHkgZm9yIGV2ZXJ5IHN0cnVjdHVyZSB0aGV5IGNoZWNrLgogICAgIiIiCiAgICBuX3BvcyA9IG5fbmVnID0gbl91bmMgPSAwCiAgICBiZXN0ID0gMC4wCiAgICBmb3IgYyBpbiBjbHM6CiAgICAgICAgbSA9IGFuYXRfcnguc2VhcmNoKGMpCiAgICAgICAgaWYgbm90IG06CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgaWYgZGVjb3lfcnggaXMgbm90IE5vbmUgYW5kIGRlY295X3J4LnNlYXJjaChjKToKICAgICAgICAgICAgY29udGludWUKICAgICAgICBpZiBwYXRoX3J4IGlzIG5vdCBOb25lIGFuZCBub3QgcGF0aF9yeC5zZWFyY2goYyk6CiAgICAgICAgICAgIGlmIE5PUk1BTElUWS5zZWFyY2goYykgYW5kIG5vdCBORUdBVElPTi5zZWFyY2goYyk6CiAgICAgICAgICAgICAgICBuX25lZyArPSAxCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgcG9sID0gX3BvbGFyaXR5KGMsIG0uZW5kKCkpCiAgICAgICAgaWYgcG9sID09ICJwb3NpdGl2ZSI6CiAgICAgICAgICAgIG5fcG9zICs9IDEKICAgICAgICAgICAgdyA9IF9zZXZlcml0eShjKQogICAgICAgICAgICBpZiBjb250ZXh0X3BlbmFsdHkgaXMgbm90IE5vbmUgYW5kIGNvbnRleHRfcGVuYWx0eS5zZWFyY2goYyk6CiAgICAgICAgICAgICAgICB3ICo9IDAuNDUKICAgICAgICAgICAgaWYgY29udGV4dF9ib251cyBpcyBub3QgTm9uZSBhbmQgY29udGV4dF9ib251cy5zZWFyY2goYyk6CiAgICAgICAgICAgICAgICB3ID0gbWluKDEuMCwgdyAqIDEuMzUpCiAgICAgICAgICAgIGJlc3QgPSBtYXgoYmVzdCwgdykKICAgICAgICBlbGlmIHBvbCA9PSAibmVnYXRpdmUiOgogICAgICAgICAgICBuX25lZyArPSAxCiAgICAgICAgZWxzZToKICAgICAgICAgICAgbl91bmMgKz0gMQogICAgICAgICAgICBiZXN0ID0gbWF4KGJlc3QsIDAuMzApCgogICAgaWYgbl9wb3Mgb3Igbl91bmM6CiAgICAgICAgIyAwLjUyIC4uIDAuOTUsIG9yZGVyZWQgYnkgdGhlIHN0cm9uZ2VzdCBzaW5nbGUgbWVudGlvbiwgbnVkZ2VkIGJ5IHJlcGV0aXRpb24uCiAgICAgICAgc2NvcmUgPSBtaW4oMC45NSwgMC41MCArIDAuNDIgKiBiZXN0ICsgMC4wMyAqIG1pbihuX3BvcywgMykpCiAgICAgICAgY29uZiA9IG1pbigxLjAsIDAuNTUgKyAwLjE1ICogbl9wb3MpCiAgICBlbGlmIG5fbmVnOgogICAgICAgIHNjb3JlID0gbWF4KDAuMDQsIDAuMjAgLSAwLjA0ICogbl9uZWcpCiAgICAgICAgY29uZiA9IG1pbigwLjksIDAuNDUgKyAwLjEyICogbl9uZWcpCiAgICBlbHNlOgogICAgICAgIHNjb3JlLCBjb25mID0gMC4yOCwgMC4wNSAgICAgICAgICAjIHNpbGVuY2Ugc2l0cyBhYm92ZSBhc3NlcnRlZC1uZWdhdGl2ZQogICAgcmV0dXJuIHNjb3JlLCBjb25mLCBuX3Bvcywgbl9uZWcKCgpkZWYgZXh0cmFjdChyZXBvcnQ6IHN0cikgLT4gZGljdDoKICAgICIiIkV4dHJhY3QgdHdlbHZlIChzY29yZSwgY29uZmlkZW5jZSkgcGFpcnMgZnJvbSBvbmUgcmVwb3J0LiIiIgogICAgY2xzID0gY2xhdXNlcyhyZXBvcnQpCiAgICBvdXQgPSB7fQogICAgcGF0aF9wYWlyZWQgPSBfcngoVEVBUi5wYXR0ZXJuLCBERUdFTi5wYXR0ZXJuLCBJTkpVUlkucGF0dGVybikKCiAgICBmb3IgdGd0IGluIFRBUkdFVFM6CiAgICAgICAgaWYgdGd0IGluIFBBSVJFRDoKICAgICAgICAgICAgcywgYywgbnBvcywgbm5lZyA9IF9zY29yZV9jbGF1c2VzKGNscywgQU5BVF9NQVRDSFt0Z3RdLCBwYXRoX3BhaXJlZCkKICAgICAgICBlbGlmIHRndCBpbiBPQV9UQVJHRVRTOgogICAgICAgICAgICBzLCBjLCBucG9zLCBubmVnID0gX3Njb3JlX2NsYXVzZXMoY2xzLCBDT01QQVJUTUVOVF9NQVRDSFt0Z3RdLCBPQV9FVklERU5DRSkKICAgICAgICBlbGlmIHRndCA9PSAiQ29udHVzaW9uIjoKICAgICAgICAgICAgIyBSZWFjdGl2ZSBzdWJjaG9uZHJhbCBvZWRlbWEgdW5kZXIgYSBjYXJ0aWxhZ2UgZGVmZWN0IGlzIG9zdGVvYXJ0aHJpdGlzLAogICAgICAgICAgICAjIG5vdCBhIGJydWlzZS4gRXhwbGljaXQgdHJhdW1hIHdvcmRpbmcgcHVzaGVzIHRoZSBvdGhlciB3YXkuCiAgICAgICAgICAgIHMsIGMsIG5wb3MsIG5uZWcgPSBfc2NvcmVfY2xhdXNlcyhjbHMsIERJUkVDVF9NQVRDSFt0Z3RdLCBOb25lLCBERUNPWS5nZXQodGd0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRfcGVuYWx0eT1ERUdFTkVSQVRJVkVfTUFSUk9XLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dF9ib251cz1UUkFVTUEpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcywgYywgbnBvcywgbm5lZyA9IF9zY29yZV9jbGF1c2VzKGNscywgRElSRUNUX01BVENIW3RndF0sIE5vbmUsIERFQ09ZLmdldCh0Z3QpKQogICAgICAgIG91dFt0Z3RdID0gcwogICAgICAgIG91dFt0Z3QgKyAiX19jb25mIl0gPSBjCiAgICAgICAgb3V0W3RndCArICJfX25wb3MiXSA9IG5wb3MKICAgICAgICBvdXRbdGd0ICsgIl9fbm5lZyJdID0gbm5lZwoKICAgICMgLS0tIGNyb3NzLXRhcmdldCBjb3JyZWN0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyBBIHdob2xlLWpvaW50IG9zdGVvYXJ0aHJpdGlzIHN0YXRlbWVudCBpcyBldmlkZW5jZSBmb3IgZXZlcnkgY29tcGFydG1lbnQgdGhhdCB3YXMKICAgICMgbm90IHNlcGFyYXRlbHkgYXNzZXNzZWQuIFdpdGhvdXQgdGhpcywgImluY2lwaWVudCBPQSBvZiBhbGwgdGhyZWUgY29tcGFydG1lbnRzIgogICAgIyBzY29yZXMgemVybyBvbiBhbGwgdGhyZWUgT0EgdGFyZ2V0cy4KICAgIGdfaGl0cyA9IFtjIGZvciBjIGluIGNscyBpZiBHTE9CQUxfT0Euc2VhcmNoKGMpIGFuZCBfcG9sYXJpdHkoYywgMCkgPT0gInBvc2l0aXZlIl0KICAgIGlmIGdfaGl0czoKICAgICAgICBnc2NvcmUgPSAwLjUwICsgMC40MiAqIG1heChfc2V2ZXJpdHkoYykgZm9yIGMgaW4gZ19oaXRzKQogICAgICAgIGZvciB0Z3QgaW4gT0FfVEFSR0VUUzoKICAgICAgICAgICAgaWYgb3V0W3RndCArICJfX25wb3MiXSA9PSAwIGFuZCBvdXRbdGd0ICsgIl9fbm5lZyJdID09IDA6CiAgICAgICAgICAgICAgICBvdXRbdGd0XSA9IG1heChvdXRbdGd0XSwgZ3Njb3JlICogMC45MikKICAgICAgICAgICAgICAgIG91dFt0Z3QgKyAiX19jb25mIl0gPSBtYXgob3V0W3RndCArICJfX2NvbmYiXSwgMC40KQoKICAgICMgU3lub3ZpdGlzIGlzIGZyZXF1ZW50bHkgdmlzaWJsZSBvbiB0aGUgaW1hZ2VzIGFuZCBhYnNlbnQgZnJvbSB0aGUgdGV4dCwgc28gc2lsZW5jZQogICAgIyBpcyB3ZWFrIGV2aWRlbmNlIG9mIGFic2VuY2UgaGVyZSBpbiBhIHdheSBpdCBpcyBub3QgZm9yIG90aGVyIGZpbmRpbmdzLiBFZmZ1c2lvbiBpcwogICAgIyBpdHMgbW9zdCByZWxpYWJsZSB0ZXh0dWFsIHByb3h5IC0gdGhlIHR3byBzaGFyZSBhIG1lY2hhbmlzbSAtIHNvIGEgc2lsZW50IHN5bm92aXRpcwogICAgIyBpbmhlcml0cyBhIGZyYWN0aW9uIG9mIHRoZSBlZmZ1c2lvbiBldmlkZW5jZSBpbnN0ZWFkIG9mIGZhbGxpbmcgdG8gdGhlIGZsb29yLgogICAgaWYgb3V0WyJTeW5vdml0aXNfX25wb3MiXSA9PSAwIGFuZCBvdXRbIlN5bm92aXRpc19fbm5lZyJdID09IDA6CiAgICAgICAgb3V0WyJTeW5vdml0aXMiXSA9IG1heChvdXRbIlN5bm92aXRpcyJdLCAwLjI4ICsgMC40NSAqIChvdXRbIkVmZnVzaW9uIl0gLSAwLjI4KSkKCiAgICByZXR1cm4gb3V0CgoKIyA9PT09PT09PT09PT09PT09PSDpm4bmiJAgQVBJKOacrOS7k+W6k+aWsOWinizpnZ7np7vmpI3ku6PnoIEpID09PT09PT09PT09PT09PT09CgoKZGVmIHJlcG9ydF9zY29yZV90b190YXJnZXQocmVzOiBkaWN0LCB0Z3Q6IHN0cik6CiAgICAiIiLmioogZXh0cmFjdCgpIOeahOS4gOS4quebruagh+e7k+aenOaYoOWwhOS4uiBCQ0Ugc29mdCDnm67moIco5oiWIE5hTinjgIIKCiAgICBuX3Bvcz4wIC0+IOivgeaNruWIhuaVsCjpmLPmgKcsMC43Mn4wLjk1KQogICAgbl9wb3M9PTAg5LiUIG5fbmVnPjAgLT4g6K+B5o2u5YiG5pWwKOmYtOaApywwLjA0fjAuMjApCiAgICDlhbbkvZko5rKJ6buYL+S4jeehruWumiktPiBOYU466K+l5qC85LiN6L+b5o2f5aSxCiAgICAiIiIKICAgIG5wb3MgPSByZXMuZ2V0KHRndCArICJfX25wb3MiLCAwKQogICAgbm5lZyA9IHJlcy5nZXQodGd0ICsgIl9fbm5lZyIsIDApCiAgICBpZiBucG9zID4gMDoKICAgICAgICByZXR1cm4gZmxvYXQocmVzW3RndF0pCiAgICBpZiBubmVnID4gMDoKICAgICAgICByZXR1cm4gZmxvYXQocmVzW3RndF0pCiAgICByZXR1cm4gZmxvYXQoIm5hbiIpCgoKZGVmIF9leHRyYWN0X2NhY2hlZChyZXBvcnRzKToKICAgIHJldHVybiBbZXh0cmFjdChyKSBmb3IgciBpbiByZXBvcnRzXQoKCmRlZiBidWlsZF9wc2V1ZG9fdGFibGUodHJhaW5fZGYsIHJlcG9ydF9jb2w9IlJlcG9ydCIsIHZlcmJvc2U9VHJ1ZSk6CiAgICAiIiLku44gdHJhaW5fZGYg55qE5pS+5bCE5oql5ZGK55Sf5oiQ5Lyq5qCH562+6KGoKFN0dWR5SW5zdGFuY2VVSUQgKyBwc2V1ZG9fPDEyPinjgIIKCiAgICDov5Tlm54gRGF0YUZyYW1lO+WIhuaVsOWIlyBmbG9hdCzml6Dor4Hmja7moLzkuLogTmFO44CCCiAgICDlrpjmlrkgZ29sZCDnlLEgbG9hZF9sYWJlbHMg5LyY5YWI6KaG55uWLOatpOWkhOS4jeaOuuWSjOOAggogICAgIiIiCiAgICByZXBvcnRzID0gdHJhaW5fZGZbcmVwb3J0X2NvbF0uZmlsbG5hKCIiKS50b2xpc3QoKQogICAgdWlkcyA9IHRyYWluX2RmWyJTdHVkeUluc3RhbmNlVUlEIl0udG9saXN0KCkKICAgIHJlcyA9IF9leHRyYWN0X2NhY2hlZChyZXBvcnRzKQogICAgcm93cyA9IHt9CiAgICBjbnQgPSB7dDogWzAsIDAsIDBdIGZvciB0IGluIFRBUkdFVFN9ICAgIyBbcG9zLCBuZWcsIG5hbl0KICAgIGZvciB0IGluIFRBUkdFVFM6CiAgICAgICAgdmFscyA9IFtdCiAgICAgICAgZm9yIHIgaW4gcmVzOgogICAgICAgICAgICB2ID0gcmVwb3J0X3Njb3JlX3RvX3RhcmdldChyLCB0KQogICAgICAgICAgICBpZiBwZC5pc25hKHYpOgogICAgICAgICAgICAgICAgY250W3RdWzJdICs9IDEKICAgICAgICAgICAgZWxpZiB2ID4gMC41OgogICAgICAgICAgICAgICAgY250W3RdWzBdICs9IDEKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGNudFt0XVsxXSArPSAxCiAgICAgICAgICAgIHZhbHMuYXBwZW5kKHYpCiAgICAgICAgcm93c1sicHNldWRvXyIgKyB0XSA9IHZhbHMKICAgIG91dCA9IHBkLkRhdGFGcmFtZSh7IlN0dWR5SW5zdGFuY2VVSUQiOiB1aWRzLCAqKnJvd3N9KQogICAgaWYgdmVyYm9zZToKICAgICAgICBwcmludChmIlvmoIfnrb5dIOaKpeWRiuaKveWPluWZqChyc25hX3JlcG9ydF9sYWJlbHMpOntsZW4odWlkcyl9IHN0dWR5LCIKICAgICAgICAgICAgICBmIumbtuaMgui9vee6ryBDUFU75q+P55eF54G2IHBvcy9uZWcv5peg6K+B5o2uOiIpCiAgICAgICAgZm9yIHQgaW4gVEFSR0VUUzoKICAgICAgICAgICAgcCwgbiwgeiA9IGNudFt0XQogICAgICAgICAgICBwcmludChmIiAge3Q6MThzfSBwb3M9e3A6NWR9IG5lZz17bjo1ZH0g5peg6K+B5o2uPXt6OjVkfSIKICAgICAgICAgICAgICAgICAgZiIg6KaG55uWPXsocCtuKS9sZW4odWlkcykqMTAwOjUuMWZ9JSIpCiAgICByZXR1cm4gb3V0CgoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgICMgQ1BVIHNhbml0eTpweXRob24gcnNuYV9yZXBvcnRfbGFiZWxzLnB5CiAgICBkZiA9IHBkLnJlYWRfY3N2KCJ0cmFpbi5jc3YiLCBucm93cz0yMDApCiAgICB0YWIgPSBidWlsZF9wc2V1ZG9fdGFibGUoZGYsIHZlcmJvc2U9VHJ1ZSkKICAgIHByaW50KHRhYi5oZWFkKDYpLnRvX3N0cmluZygpKQo=')\nopen(\"/kaggle/working/rsna_report_labels.py\",\"wb\").write(base64.b64decode(\"\".join(parts)))\nprint(\"rsna_report_labels.py ->\", os.path.getsize(\"/kaggle/working/rsna_report_labels.py\")//1024, \"KB\")","metadata":{},"outputs":[],"execution_count":null},{"id":"3f4d5bea-6b2b-4ab1-9d64-1cfe9f3a2115","cell_type":"code","source":"import subprocess, sys, os\nos.chdir('/kaggle/working')\nprint('=== 运行 v5 probe: rsna_v3.py --planes sagittal --epochs 3 --folds 5 --only-fold 0 ===')\nr = subprocess.run([sys.executable,\"-u\",\"rsna_v3.py\",\n                    \"--planes\",\"sagittal\",\"--epochs\",\"3\",\"--folds\",\"5\",\n                    \"--only-fold\",\"0\",\"--batch\",\"8\",\"--n-clips\",\"2\",\"--verbose\"],\n                   capture_output=True, text=True)\nprint(r.stdout)\nif r.stderr: print('STDERR:', r.stderr[-2500:])\nimport pandas as pd\nsp='/kaggle/working/submission.csv'\nif os.path.isfile(sp):\n    sub=pd.read_csv(sp)\n    print('[提交文件]', sp, sub.shape)\n    print('列:', list(sub.columns))\n    print('NaN 总数:', int(sub.isna().sum().sum()))\nelse:\n    print('[警告] submission.csv 未生成!')\n","metadata":{},"outputs":[],"execution_count":null}]}