{"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","title":"RSNA EXP-001 fold0 probe GPU","slug":"rsna-exp001-fold0-probe-gpu"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# RSNA EXP-001 fold0 probe: artifact persistence + timing\n\n目的:验证 artifact 持久化链路 + 记录 fold0 真实 wall-clock。\n变更(2026-09-10, 本地干跑验证后):\n1. 修复 duplicate predict_test/plane_oof_auc 块;\n2. 包 torch 依赖类进 if HAS_TORCH: 使本地 --help 可测;\n3. @torch.no_grad 装饰器改为函数内 with 上下文;\n4. 每折保存 test_pred.npy / test_uid.csv / meta.json;\n5. experiment-level config.json + fold_assignment.csv;\n6. --resume-dir 支持跨 session 续训;\n7. UID-aligned ensemble 加载 + 缺失折容错.\n\n命令:python rsna_v3.py --planes sagittal --epochs 3 --folds 5 --only-fold 0 --batch 8 --n-clips 2 --verbose\n","metadata":{}},{"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},{"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},{"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+h5YiG5pWwKQoiIiIKaW1wb3J0IGFyZ3BhcnNlCmltcG9ydCBqc29uCmltcG9ydCBvcwppbXBvcnQgc3lzCmltcG9ydCB0aW1lCmltcG9ydCB3YXJuaW5ncwpmcm9tIHBhdGhsaWIgaW1wb3J0IFBhdGgKCmltcG9ydCBudW1weSBhcyBucAppbXBvcnQgcGFuZGFzIGFzIHBkCgp0cnk6CiAgICBpbXBvcnQgdG9yY2gKICAgIGltcG9ydCB0b3JjaC5ubiBhcyBubgogICAgZnJvbSB0b3JjaC51dGlscy5kYXRhIGltcG9ydCBEYXRhc2V0LCBEYXRhTG9hZGVyCiAgICBmcm9tIHRvcmNoLm9wdGltIGltcG9ydCBBZGFtVwogICAgZnJvbSB0b3JjaC5vcHRpbS5scl9zY2hlZHVsZXIgaW1wb3J0IENvc2luZUFubmVhbGluZ0xSCiAgICBIQVNfVE9SQ0ggPSBUcnVlCmV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgIEhBU19UT1JDSCA9IEZhbHNlCgp0cnk6CiAgICBpbXBvcnQgdG9yY2h2aXNpb24ubW9kZWxzIGFzIHR2bQogICAgSEFTX1RWID0gVHJ1ZQpleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBIQVNfVFYgPSBGYWxzZQoKdHJ5OgogICAgaW1wb3J0IHB5ZGljb20KICAgIEhBU19QWURJQ09NID0gVHJ1ZQpleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBIQVNfUFlESUNPTSA9IEZhbHNlCgp0cnk6CiAgICBpbXBvcnQgcnNuYV9yZXBvcnRfbGFiZWxzIGFzIFJMICAgIyDmiqXlkYrihpIxMiDnl4XngbblvLHmoIfnrb4o5LiOIHJzbmFfdjMucHkg5ZCM55uu5b2VKQogICAgSEFTX1JMID0gVHJ1ZQpleGNlcHQgSW1wb3J0RXJyb3I6CiAgICBIQVNfUkwgPSBGYWxzZQoKZnJvbSBza2xlYXJuLm1vZGVsX3NlbGVjdGlvbiBpbXBvcnQgR3JvdXBLRm9sZApmcm9tIHNrbGVhcm4ubWV0cmljcyBpbXBvcnQgcm9jX2F1Y19zY29yZQoKd2FybmluZ3MuZmlsdGVyd2FybmluZ3MoImlnbm9yZSIpCgpMQUJFTFMgPSBbIkFDTCIsICJNQ0wiLCAiTWVkaWFsIE1lbmlzY3VzIiwgIkxhdGVyYWwgTWVuaXNjdXMiLAogICAgICAgICAgIk1lZGlhbCBPQSIsICJMYXRlcmFsIE9BIiwgIlBGIE9BIiwgIkVmZnVzaW9uIiwgIlN5bm92aXRpcyIsCiAgICAgICAgICAiQmFrZXIncyIsICJDb250dXNpb24iLCAiRnJhY3R1cmUiXQpMQUJFTFNfRU4gPSBbIkFDTCIsICJNQ0wiLCAiTWVkaWFsTWVuaXNjdXMiLCAiTGF0ZXJhbE1lbmlzY3VzIiwKICAgICAgICAgICAgICJNZWRpYWxPQSIsICJMYXRlcmFsT0EiLCAiUEZPQSIsICJFZmZ1c2lvbiIsICJTeW5vdml0aXMiLAogICAgICAgICAgICAgIkJha2VycyIsICJDb250dXNpb24iLCAiRnJhY3R1cmUiXSAgIyDliJflkI3lronlhajljJYo5YaZ5o+Q5Lqk55SoKQpQTEFORVMgPSBbIkF4aWFsIiwgIlNhZ2l0dGFsIiwgIkNvcm9uYWwiXQoKSU1HX1NJWkUgPSAyMjQKQ0xJUCA9IDMgICAgICAgICAgIyDmr48gY2xpcCDliIfniYfmlbAocHJldi9jZW50ZXIvbmV4dCkKTUFYX1NFUklFUyA9IDQgICAgIyDmr48gc3R1ZHkg5q+P5Liq5bmz6Z2i5pyA5aSa5Y+W55qEIHNlcmllcyDmlbAodjIg5oyJ5bmz6Z2i5Y+WLOWNleW5s+mdoiBzZXJpZXMg5pu05bCRLDQg6Laz5aSfKQpGT0xEUyA9IDUKU0VFRCA9IDQyCgoKZGVmIHJlc29sdmVfcGF0aHMoKToKICAgICIiIuaVsOaNruWumuS9jemhuuW6jzoxKSAva2FnZ2xlL2lucHV0IOaMgui9vTsyKSBrYWdnbGVodWIg6Ieq5Yqo5LiL6L29OzMpIOacrOWcsCByc25hX2tuZWUvIOebruW9leOAgiIiIgogICAgIyAxKSBLYWdnbGUg5oyC6L29KOWFvOWuueWkmuWxguaMgui9vTova2FnZ2xlL2lucHV0LzzmlbDmja7lkI0+LyDmiJYgL2thZ2dsZS9pbnB1dC885YiG57G7Pi885pWw5o2u5ZCNPi8pCiAgICBpZiBvcy5wYXRoLmlzZGlyKCIva2FnZ2xlL2lucHV0Iik6CiAgICAgICAgZm9yIHN1YiBpbiBzb3J0ZWQob3MubGlzdGRpcigiL2thZ2dsZS9pbnB1dCIpKToKICAgICAgICAgICAgZCA9IG9zLnBhdGguam9pbigiL2thZ2dsZS9pbnB1dCIsIHN1YikKICAgICAgICAgICAgZm9yIGNhbmQgaW4gKGQsIG9zLnBhdGguam9pbihkLCBzdWIpKTogICMg5aSE55CGIEthZ2dsZSDlj4zlsYLmjILovb0KICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKG9zLnBhdGguam9pbihjYW5kLCAidHJhaW4uY3N2IikpOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBjYW5kLCAiL2thZ2dsZS93b3JraW5nIgogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKGQpOiAgIyDlho3lvoDkuIvkuIDlsYLmib4o5aaCIC9rYWdnbGUvaW5wdXQvY29tcGV0aXRpb25zLzxuYW1lPi8pCiAgICAgICAgICAgICAgICBmb3Igc3ViMiBpbiBzb3J0ZWQob3MubGlzdGRpcihkKSk6CiAgICAgICAgICAgICAgICAgICAgY2FuZCA9IG9zLnBhdGguam9pbihkLCBzdWIyKQogICAgICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKG9zLnBhdGguam9pbihjYW5kLCAidHJhaW4uY3N2IikpOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FuZCwgIi9rYWdnbGUvd29ya2luZyIKICAgICAgICBwcmludCgiW+iviuaWrV0gL2thZ2dsZS9pbnB1dCDlrZjlnKgs5L2G5rKh5om+5Yiw5ZCrIHRyYWluLmNzdiDnmoTnm67lvZXjgILlrp7pmYXmjILovb3lhoXlrrnlpoLkuIs6IiwgZmx1c2g9VHJ1ZSkKICAgICAgICBmb3Igc3ViIGluIHNvcnRlZChvcy5saXN0ZGlyKCIva2FnZ2xlL2lucHV0IikpOgogICAgICAgICAgICBwID0gb3MucGF0aC5qb2luKCIva2FnZ2xlL2lucHV0Iiwgc3ViKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbm5lciA9IG9zLmxpc3RkaXIocCkKICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgICAgICBpbm5lciA9IFsiKOaXoOazleivu+WPlikiXQogICAgICAgICAgICBwcmludChmIiAgL2thZ2dsZS9pbnB1dC97c3VifS8gIC0+ICB7aW5uZXJbOjhdfSIsIGZsdXNoPVRydWUpCiAgICAgICAgcHJpbnQoIlvor4rmlq1dIOWmguaenOS9oOaMgueahOaYryAn5L2c6ICF5pWw5o2u5YyFL+WIq+S6uueahCBrZXJuZWwg6L6T5Ye6Jywg6YeM6Z2i5rKh5pyJIHRyYWluLmNzdiDlkowgdHJhaW5fc2VyaWVzLywiLAogICAgICAgICAgICAgICLlv4XpobvmjILmr5TotZvmlbDmja7mnKzkvZMgcnNuYS1rbmVlLWFibm9ybWFsaXR5LWRldGVjdGlvbiAoQWRkIElucHV0IC0+IENvbXBldGl0aW9ucyDmoIfnrb7pobUpIiwgZmx1c2g9VHJ1ZSkKICAgICMgMikga2FnZ2xlaHViIOWFnOW6lTrmnKrmjILovb3ml7boh6rliqjkuIvovb3mr5TotZvmlbDmja4oS2FnZ2xlIE5vdGVib29rIOWGhee9ruWHreaNrikKICAgIHRyeToKICAgICAgICBpbXBvcnQga2FnZ2xlaHViCiAgICAgICAgZCA9IGthZ2dsZWh1Yi5jb21wZXRpdGlvbl9kb3dubG9hZCgicnNuYS1rbmVlLWFibm9ybWFsaXR5LWRldGVjdGlvbiIpCiAgICAgICAgaWYgb3MucGF0aC5leGlzdHMob3MucGF0aC5qb2luKGQsICJ0cmFpbi5jc3YiKSk6CiAgICAgICAgICAgIHByaW50KGYiW+i3r+W+hF0g5pyq5oyC6L29LOW3sueUqCBrYWdnbGVodWIg6I635Y+W5pWw5o2uOiB7ZH0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICByZXR1cm4gZCwgIi9rYWdnbGUvd29ya2luZyIKICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICAgICBwYXNzICAjIOacrOWcsOacquijhSBrYWdnbGVodWIKICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICBwcmludChmIlvmj5DnpLpdIGthZ2dsZWh1YiDkuIvovb3mlbDmja7lpLHotKU6IHtlfSIsIGZsdXNoPVRydWUpCiAgICAjIDMpIOacrOWcsOWbnumAgCjohJrmnKznm67lvZUgLyBjd2QgLyBjd2Qg5LiL55qEIHJzbmFfa25lZSDlrZDnm67lvZXpg73mib4pCiAgICBjYW5kcyA9IFtdCiAgICB0cnk6CiAgICAgICAgY2FuZHMuYXBwZW5kKG9zLnBhdGguZGlybmFtZShvcy5wYXRoLmFic3BhdGgoX19maWxlX18pKSkKICAgIGV4Y2VwdCBOYW1lRXJyb3I6CiAgICAgICAgcGFzcwogICAgY2FuZHMuYXBwZW5kKG9zLmdldGN3ZCgpKQogICAgZm9yIGJhc2UgaW4gbGlzdChjYW5kcyk6CiAgICAgICAgY2FuZHMuYXBwZW5kKG9zLnBhdGguam9pbihiYXNlLCAicnNuYV9rbmVlIikpCiAgICBzZWVuID0gc2V0KCkKICAgIGZvciBiYXNlIGluIGNhbmRzOgogICAgICAgIGlmIGJhc2UgaW4gc2VlbjoKICAgICAgICAgICAgY29udGludWUKICAgICAgICBzZWVuLmFkZChiYXNlKQogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKG9zLnBhdGguam9pbihiYXNlLCAidHJhaW4uY3N2IikpOgogICAgICAgICAgICByZXR1cm4gYmFzZSwgYmFzZQogICAgc3lzLmV4aXQoIuaJvuS4jeWIsOaVsOaNrjror7flhYjlnKjmr5TotZvpobXliqDlhaXmr5TotZvlubblkIzmhI/mlbDmja7op4TliJks5YaNIEFkZCBJbnB1dCDmjILovb0gIgogICAgICAgICAgICAgInJzbmEta25lZS1hYm5vcm1hbGl0eS1kZXRlY3Rpb2475pys5Zyw6K+35ZyoIHJzbmFfa25lZS8g5LiL6L+Q6KGM44CCIikKCgpfUFNFVURPX0ZJTEVTID0gKCJ0cmFpbl9mb2xkc193aXRoX3BzZXVkby5jc3YiLCAidHJhaW5fd2l0aF9wc2V1ZG8uY3N2IiwKICAgICAgICAgICAgICAgICAidHJhaW5fd2l0aF9zb2Z0X2xhYmVscy5jc3YiLCAidHJhaW5fcHNldWRvLmNzdiIpCl9TS0lQX0RJUlMgPSB7InRyYWluX3NlcmllcyIsICJ0ZXN0X3NlcmllcyJ9ICAjIERJQ09NIOWkp+ebruW9lSznu53kuI3ljrvpgY3ljoYKX1dFSUdIVF9FWFQgPSAoIi5wdGgiLCAiLnB0IiwgIi5ja3B0IiwgIi5wdGgudGFyIikgICMg56a757q/6aKE6K6t57uD5p2D6YeN5paH5Lu25omp5bGV5ZCNCgojIDEyIOagh+etvuWkmuivreiogOWFs+mUruivjeivjeWFuCjoi7Ev6KW/L+iNty/lvrcv5rOVKeKAlOKAlOmbtuaMgui9vei9r+agh+etvuWFnOW6lQojIOWRveS4rSDihpIg6auY572u5L+hLOacquWRveS4rSDihpIg5L2O572u5L+hKOi9r+agh+etvizkuI3nu5nnoawgMC8xLOmBv+WFjemUmeivjeivr+WvvCkKX1JFUE9SVF9LRVlXT1JEUyA9IHsKICAgICJBQ0wiOiBbImFjbCIsICJhbnRlcmlvciBjcnVjaWF0ZSIsICJjcnVjaWFkbyBhbnRlcmlvciIsICJ2b29yc3RlIGtydWlzYmFuZCIsCiAgICAgICAgICAgICJ2b3JkZXJlbiBrcmV1emJhbmQiLCAibGNhIiwgImxpZ2FtZW50IGNyb2lzw6kgYW50w6lyaWV1ciJdLAogICAgIk1DTCI6IFsibWNsIiwgIm1lZGlhbCBjb2xsYXRlcmFsIiwgImNvbGF0ZXJhbCBtZWRpYWwiLCAibWVkaWFsZSBjb2xsYXRlcmFsZSIsCiAgICAgICAgICAgICJpbm5lcmVzIHNlaXRlbmJhbmQiLCAibGlnYW1lbnQgY29sbGF0w6lyYWwgbcOpZGlhbCJdLAogICAgIk1lZGlhbCBNZW5pc2N1cyI6IFsibWVkaWFsIG1lbmlzY3VzIiwgIm1lbmlzY28gaW50ZXJubyIsICJtZW5pc2N1cyBtZWRpYWxpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJtZW5pc2t1cyBtZWRpYWwiLCAibWVuaXNxdWUgbcOpZGlhbCIsICJpbm5lciBtZW5pc2N1cyIsICJtZW5pc2NvIG1lZGlhbCJdLAogICAgIkxhdGVyYWwgTWVuaXNjdXMiOiBbImxhdGVyYWwgbWVuaXNjdXMiLCAibWVuaXNjbyBleHRlcm5vIiwgIm1lbmlzY3VzIGxhdGVyYWxpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAibWVuaXNrdXMgbGF0ZXJhbCIsICJtZW5pc3F1ZSBsYXTDqXJhbCIsICJvdXRlciBtZW5pc2N1cyJdLAogICAgIk1lZGlhbCBPQSI6IFsibWVkaWFsIG9zdGVvYXJ0aHJpdGlzIiwgImFydHJvc2lzIGZlbW9yb3RpYmlhbCBtZWRpYWwiLAogICAgICAgICAgICAgICAgICAibWVkaWFsZSBnb25hcnRyb3NlIiwgIm1lZGlhbGUgYXJ0aHJvc2UiLCAib3N0ZW9hcnRyaXRpcyBtZWRpYWwiLAogICAgICAgICAgICAgICAgICAibWVkaWFsIGNvbXBhcnRtZW50IG5hcnJvd2luZyIsICJtZWRpYWwgam9pbnQgc3BhY2UgbmFycm93aW5nIl0sCiAgICAiTGF0ZXJhbCBPQSI6IFsibGF0ZXJhbCBvc3Rlb2FydGhyaXRpcyIsICJhcnRyb3NpcyBmZW1vcm90aWJpYWwgbGF0ZXJhbCIsCiAgICAgICAgICAgICAgICAgICAibGF0ZXJhbGUgZ29uYXJ0cm9zZSIsICJsYXRlcmFsZSBhcnRocm9zZSIsICJsYXRlcmFsIGpvaW50IHNwYWNlIG5hcnJvd2luZyJdLAogICAgIlBGIE9BIjogWyJwYXRlbGxvZmVtb3JhbCBvc3Rlb2FydGhyaXRpcyIsICJhcnRyb3NpcyBwYXRlbG9mZW1vcmFsIiwKICAgICAgICAgICAgICAicGF0ZWxsb2ZlbW9yYWxlIGFydHJvc2UiLCAicGF0ZWxsb2ZlbW9yYWwgYXJ0aHJvc2UiLCAicGYgb2EiLAogICAgICAgICAgICAgICJwYXRlbGxvZmVtb3JhbCBuYXJyb3dpbmciLCAicGF0ZWxsb2ZlbW9yYWwgam9pbnQgc3BhY2UiXSwKICAgICJFZmZ1c2lvbiI6IFsiZWZmdXNpb24iLCAiZGVycmFtZSIsICJ2b2NodCIsICJlcmd1c3MiLCAiw6lwYW5jaGVtZW50IiwgImpvaW50IGVmZnVzaW9uIl0sCiAgICAiU3lub3ZpdGlzIjogWyJzeW5vdml0aXMiLCAic2lub3ZpdGlzIiwgInN5bm92aWFsZSIsICJzeW5vdmlhbCB0aGlja2VuaW5nIiwgInN5bm92aXRpcyJdLAogICAgIkJha2VyJ3MiOiBbImJha2VyIiwgInBvcGxpdGVhbCBjeXN0IiwgInF1aXN0ZSBkZSBiYWtlciIsICJiYWtlciBjeXN0Il0sCiAgICAiQ29udHVzaW9uIjogWyJjb250dXNpb24iLCAiYm9uZSBicnVpc2UiLCAiY29udHVzacOzbiIsICJrbmV1emluZyIsICJrb250dXNpb24iLAogICAgICAgICAgICAgICAgICAibWFycm93IGVkZW1hIiwgIsOzc2VvIiwgImJvbmUgYnJ1aXNpbmciXSwKICAgICJGcmFjdHVyZSI6IFsiZnJhY3R1cmUiLCAiZnJhY3R1cmEiLCAiZnJhY3R1dXIiLCAiZnJha3R1ciIsICJmcmFjdHVyZSBsaW5lIiwKICAgICAgICAgICAgICAgICAiZnJhY3R1cmUgbGluZSIsICJzdWJjaG9uZHJhbCBmcmFjdHVyZSJdLAp9CgoKZGVmIF9wc2V1ZG9fZnJvbV9yZXBvcnRzKHRyYWluX2NzdiwgY29uZl9oaXQ9MC45LCBjb25mX21pc3M9MC4xKToKICAgICIiIuS7juaUvuWwhOaKpeWRiuaWh+acrOeUqOWkmuivreiogOWFs+mUruivjeeUn+aIkCAxMiDmoIfnrb7ova/moIfnrb4o6Zu25oyC6L295YWc5bqVKeOAggoKICAgIOi/lOWbniBEYXRhRnJhbWUoU3R1ZHlJbnN0YW5jZVVJRCArIHBzZXVkb18qIOWIlynjgILlhbPplK7or43lkb3kuK3ihpJjb25mX2hpdCwKICAgIOacquWRveS4reKGkmNvbmZfbWlzcyjkuI3nu5nnoawgMC8xLOmZjeS9jumUmeivjeivr+WvvCnjgILlrpjmlrnlt7LmnInmoIfms6jnmoQgc3R1ZHkKICAgIOS7jeS7peWumOaWueS4uuWHhihsb2FkX2xhYmVscyDnmoTloavlhYXpgLvovpHkv53or4HlrpjmlrnkvJjlhYgp44CCCiAgICAiIiIKICAgIGlmICJSZXBvcnQiIG5vdCBpbiB0cmFpbl9jc3YuY29sdW1uczoKICAgICAgICByZXR1cm4gTm9uZQogICAgcmVwID0gdHJhaW5fY3N2WyJSZXBvcnQiXS5maWxsbmEoIiIpCiAgICByb3dzID0ge30KICAgIGZvciBsYWIsIGt3cyBpbiBfUkVQT1JUX0tFWVdPUkRTLml0ZW1zKCk6CiAgICAgICAgbG93ID0gW2subG93ZXIoKSBmb3IgayBpbiBrd3NdCiAgICAgICAgcm93c1tmInBzZXVkb197bGFifSJdID0gcmVwLmFwcGx5KAogICAgICAgICAgICBsYW1iZGEgdDogY29uZl9oaXQgaWYgYW55KGsgaW4gc3RyKHQpLmxvd2VyKCkgZm9yIGsgaW4gbG93KSBlbHNlIGNvbmZfbWlzcykKICAgIGRmID0gcGQuRGF0YUZyYW1lKHsiU3R1ZHlJbnN0YW5jZVVJRCI6IHRyYWluX2NzdlsiU3R1ZHlJbnN0YW5jZVVJRCJdLCAqKnJvd3N9KQogICAgcmV0dXJuIGRmCgoKZGVmIF9wcmludF9tb3VudF90cmVlKGJhc2U9Ii9rYWdnbGUvaW5wdXQiLCB0YWc9IuaVsOaNriIsIG1heF9maWxlcz02KToKICAgICIiIuaJk+WNsOaMgui9veebruW9leagkSjmnIDlpJrkuKTlsYIs5q+P55uu5b2V5YmN5Yeg5Liq5paH5Lu2KSzluK7nlKjmiLfnoa7orqTmjILovb3lhoXlrrnjgIIiIiIKICAgIGlmIG5vdCBvcy5wYXRoLmlzZGlyKGJhc2UpOgogICAgICAgIHByaW50KGYiW+iviuaWrS17dGFnfV0g55uu5b2V5LiN5a2Y5ZyoOiB7YmFzZX0iLCBmbHVzaD1UcnVlKQogICAgICAgIHJldHVybgogICAgcHJpbnQoZiJb6K+K5patLXt0YWd9XSAva2FnZ2xlL2lucHV0IOWunumZheaMgui9veWGheWuuToiLCBmbHVzaD1UcnVlKQogICAgZm9yIHN1YiBpbiBzb3J0ZWQob3MubGlzdGRpcihiYXNlKSk6CiAgICAgICAgcCA9IG9zLnBhdGguam9pbihiYXNlLCBzdWIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKHApOgogICAgICAgICAgICAgICAgaW5uZXIgPSBzb3J0ZWQob3MubGlzdGRpcihwKSlbOm1heF9maWxlc10KICAgICAgICAgICAgICAgIHByaW50KGYiICB7c3VifS8gLT4ge2lubmVyfSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBwcmludChmIiAge3N1Yn0gKOaWh+S7tikiLCBmbHVzaD1UcnVlKQogICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICBwcmludChmIiAge3N1Yn0gKOaXoOazleivu+WPlikiLCBmbHVzaD1UcnVlKQoKCmRlZiBfcHJpbnRfZGNtX3RyZWUocm9vdCwgdGFnPSJESUNPTSIsIG1heF9zaG93PTUpOgogICAgIiIi5omT5Y2wIHRyYWluX3NlcmllcyDnm67lvZXliY3lh6DlsYLnnJ/lrp7nu5PmnoQgKyDmir3moLcgLmRjbSDorqHmlbAs56Gu6K6kIERJQ09NIOW4g+WxgOOAggoKICAgIFJTTkEg5bi46KeB5biD5bGAOnRyYWluX3Nlcmllcy88U3R1ZHlJbnN0YW5jZVVJRD4vPFNlcmllc0luc3RhbmNlVUlEPi8qLmRjbSjkuKTlsYIpOwogICAg5Lmf5YW85a655LiA5bGCKDxTZXJpZXNJbnN0YW5jZVVJRD4vKi5kY20p5oiW5pu05rex5bGCLOi/memHjOaJk+WNsOWunumZheeci+WIsOeahOOAggogICAgIiIiCiAgICBkY20gPSBvcy5wYXRoLmpvaW4ocm9vdCwgInRyYWluX3NlcmllcyIpCiAgICBpZiBub3Qgb3MucGF0aC5pc2RpcihkY20pOgogICAgICAgIHByaW50KGYiW+iviuaWrS17dGFnfV0ge2RjbX0g5LiN5a2Y5ZyoISIsIGZsdXNoPVRydWUpCiAgICAgICAgcmV0dXJuCiAgICB0cnk6CiAgICAgICAgc3Vic19hbGwgPSBzb3J0ZWQob3MubGlzdGRpcihkY20pKQogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgc3Vic19hbGwgPSBbXQogICAgc3VicyA9IHN1YnNfYWxsWzptYXhfc2hvd10KICAgIHByaW50KGYiW+iviuaWrS17dGFnfV0ge2RjbX0iLCBmbHVzaD1UcnVlKQogICAgcHJpbnQoZiJb6K+K5patLXt0YWd9XSDlrZDnm67lvZUv5paH5Lu25pWwOiB7bGVuKHN1YnNfYWxsKX0s5qC35pysOiIsIGZsdXNoPVRydWUpCiAgICBmb3IgcyBpbiBzdWJzOgogICAgICAgIHNwID0gb3MucGF0aC5qb2luKGRjbSwgcykKICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKHNwKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgaW5uZXIgPSBzb3J0ZWQob3MubGlzdGRpcihzcCkpWzptYXhfc2hvd10KICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgICAgICBpbm5lciA9IFtdCiAgICAgICAgICAgIHByaW50KGYiICB7c30vIC0+IHtpbm5lcn0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICBmb3IgaXQgaW4gaW5uZXJbOjJdOgogICAgICAgICAgICAgICAgaXRwID0gb3MucGF0aC5qb2luKHNwLCBpdCkKICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguaXNkaXIoaXRwKToKICAgICAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzID0gc29ydGVkKG9zLmxpc3RkaXIoaXRwKSlbOjNdCiAgICAgICAgICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzID0gW10KICAgICAgICAgICAgICAgICAgICBwcmludChmIiAgICAgIHtpdH0vIC0+IHtmaWxlc30iLCBmbHVzaD1UcnVlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50KGYiICB7c30gKOaWh+S7tikiLCBmbHVzaD1UcnVlKQogICAgIyDmir3moLcgLmRjbSDorqHmlbA65YmNIDMgc3R1ZHkgw5cg5YmNIDMgc2VyaWVzCiAgICBuX2RjbSA9IDAKICAgIHRyeToKICAgICAgICBmb3IgcyBpbiBzdWJzX2FsbFs6M106CiAgICAgICAgICAgIHNwID0gb3MucGF0aC5qb2luKGRjbSwgcykKICAgICAgICAgICAgaWYgbm90IG9zLnBhdGguaXNkaXIoc3ApOgogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgZm9yIGl0IGluIHNvcnRlZChvcy5saXN0ZGlyKHNwKSlbOjNdOgogICAgICAgICAgICAgICAgaXRwID0gb3MucGF0aC5qb2luKHNwLCBpdCkKICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguaXNkaXIoaXRwKToKICAgICAgICAgICAgICAgICAgICBuX2RjbSArPSBzdW0oMSBmb3IgZiBpbiBvcy5saXN0ZGlyKGl0cCkgaWYgZi5sb3dlcigpLmVuZHN3aXRoKCIuZGNtIikpCiAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICBwYXNzCiAgICBwcmludChmIlvor4rmlq0te3RhZ31dIOaKveagtyAuZGNtIOaWh+S7tuaVsDoge25fZGNtfSjliY0gMyBzdHVkeSDDlyDliY0gMyBzZXJpZXMpIiwgZmx1c2g9VHJ1ZSkKCgpkZWYgX3NjYW5fb2ZmbGluZV93ZWlnaHRzKGJhc2U9Ii9rYWdnbGUvaW5wdXQiLCBkZXB0aD0wLCBtYXhfZGVwdGg9NCk6CiAgICAiIiLpgJLlvZLmiavmj4/mjILovb3nm67lvZXkuIvnmoTpooTorq3nu4PmnYPph43mlofku7YoLnB0aC8ucHQg562JKSzot7Pov4cgRElDT00g5aSn55uu5b2V44CCCgogICAg6L+U5ZueIFso57ud5a+56Lev5b6ELCDnm7jlr7kgL2thZ2dsZS9pbnB1dCDnmoTmj4/ov7ApXTvmib7kuI3liLDov5Tlm57nqbrliJfooajjgIIKICAgIOekvuWMuuaJk+WMheeahOemu+e6v+adg+mHjeaVsOaNrumbhijlpoIgbWF0dGVvbmFjY2FyYXRvL3Jlc25ldDM0LWltYWdlbmV0LXB0aOOAgQogICAgbWFyY3NoYWRlL3Jlc25ldC1wcmV0cmFpbmVkLXdlaWdodHMtaW1hZ2VuZXTjgIFweXRvcmNoL3Jlc25ldDM0KeaMgui9veWQjuWNs+WPr+iiq+aJq+WIsCwKICAgIOaXoOmcgOiBlOe9keOAggogICAgIiIiCiAgICBoaXRzID0gW10KICAgIGlmIGRlcHRoID4gbWF4X2RlcHRoIG9yIG5vdCBvcy5wYXRoLmlzZGlyKGJhc2UpOgogICAgICAgIHJldHVybiBoaXRzCiAgICB0cnk6CiAgICAgICAgZW50cmllcyA9IHNvcnRlZChvcy5saXN0ZGlyKGJhc2UpKQogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgcmV0dXJuIGhpdHMKICAgIGZvciBmbiBpbiBlbnRyaWVzOgogICAgICAgIHAgPSBvcy5wYXRoLmpvaW4oYmFzZSwgZm4pCiAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUocCkgYW5kIGZuLmxvd2VyKCkuZW5kc3dpdGgoX1dFSUdIVF9FWFQpOgogICAgICAgICAgICBoaXRzLmFwcGVuZCgocCwgb3MucGF0aC5yZWxwYXRoKHAsICIva2FnZ2xlL2lucHV0IikpKQogICAgICAgIGVsaWYgb3MucGF0aC5pc2RpcihwKSBhbmQgZm4gbm90IGluIF9TS0lQX0RJUlM6CiAgICAgICAgICAgIGhpdHMuZXh0ZW5kKF9zY2FuX29mZmxpbmVfd2VpZ2h0cyhwLCBkZXB0aCArIDEsIG1heF9kZXB0aCkpCiAgICByZXR1cm4gaGl0cwoKCmRlZiBfbG9hZF9zdGF0ZV9kaWN0X2Zyb21fZmlsZShwYXRoKToKICAgICIiIuS7juadg+mHjeaWh+S7tuivuyBzdGF0ZV9kaWN0KOWFvOWuuTrnm7TmjqUgc3RhdGVfZGljdCAvIOWMheWcqCBjaGVja3BvaW50IOmHjCAvIOWQhOenjeWJjee8gCnjgIIKCiAgICDor7vlj5blpLHotKXmiJbmoLzlvI/kuI3lr7nov5Tlm54gTm9uZeOAggogICAgIiIiCiAgICB0cnk6CiAgICAgICAgb2JqID0gdG9yY2gubG9hZChwYXRoLCBtYXBfbG9jYXRpb249ImNwdSIsIHdlaWdodHNfb25seT1UcnVlKQogICAgZXhjZXB0IFR5cGVFcnJvcjogICMg5pen54mIIHRvcmNoIOaXoCB3ZWlnaHRzX29ubHkg5Y+C5pWwCiAgICAgICAgb2JqID0gdG9yY2gubG9hZChwYXRoLCBtYXBfbG9jYXRpb249ImNwdSIpCiAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgcHJpbnQoZiJb5p2D6YeNXSB7cGF0aH0g6K+75Y+W5aSx6LSlOiB7ZX0iLCBmbHVzaD1UcnVlKQogICAgICAgIHJldHVybiBOb25lCiAgICBpZiBpc2luc3RhbmNlKG9iaiwgZGljdCkgYW5kICJzdGF0ZV9kaWN0IiBpbiBvYmo6CiAgICAgICAgb2JqID0gb2JqWyJzdGF0ZV9kaWN0Il0KICAgIGVsaWYgaXNpbnN0YW5jZShvYmosIGRpY3QpIGFuZCAibW9kZWxfc3RhdGVfZGljdCIgaW4gb2JqOgogICAgICAgIG9iaiA9IG9ialsibW9kZWxfc3RhdGVfZGljdCJdCiAgICBlbGlmIGlzaW5zdGFuY2Uob2JqLCBkaWN0KSBhbmQgIm1vZGVsIiBpbiBvYmogYW5kIGlzaW5zdGFuY2Uob2JqWyJtb2RlbCJdLCBkaWN0KToKICAgICAgICBvYmogPSBvYmpbIm1vZGVsIl0KICAgIGlmIG5vdCBpc2luc3RhbmNlKG9iaiwgZGljdCk6CiAgICAgICAgcmV0dXJuIE5vbmUKICAgICMg5Yml5bi46KeB5YmN57yAOm1vZHVsZS4gLyBtb2RlbC4gLyBiYWNrYm9uZS4o6Iul5pW05L2T5bim5YmN57yALOe7n+S4gOi/mOWOnykKICAgIG91dCA9IHt9CiAgICBmb3IgaywgdiBpbiBvYmouaXRlbXMoKToKICAgICAgICBmb3IgcHJlIGluICgibW9kdWxlLiIsICJtb2RlbC4iLCAiYmFja2JvbmUuIik6CiAgICAgICAgICAgIGlmIGsuc3RhcnRzd2l0aChwcmUpOgogICAgICAgICAgICAgICAgayA9IGtbbGVuKHByZSk6XQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBvdXRba10gPSB2CiAgICByZXR1cm4gb3V0CgoKZGVmIF90cnlfbG9hZF9vZmZsaW5lKG5ldCwgcGF0aHMpOgogICAgIiIi5oyJ5bqP5bCd6K+V5oqK5YCZ6YCJ56a757q/5p2D6YeN5Yqg6L296L+bIG5ldChzdGF0ZV9kaWN0IOe7k+aehOmhu+S4jiBSZXNOZXQzNCDljLnphY0p44CCCgogICAg6YCC6YWN6KeE5YiZKOmdouWQkeekvuWMuiBSU05BIOadg+mHjSzlpoIgYmFydW4yMTA0IOeahCBiZXN0X3Jlc25ldDM0X2ZvbGQwLnB0aCk6CiAgICAtIGNvbnYxLndlaWdodCDpgJrpgZPmlbDkuI3lkIzml7Y6cmVzaGFwZSttZWFuIOmAgumFjeWIsCBuZXQg55qEIGNvbnYxIOmAmumBk+aVsCjlpoIgMjTihpIzLAogICAgICBiYXJ1bjIxMDQg5pivIDggY2xpcCDDlyAzIOmAmumBk+eahCAyLjVEIOaooeWeiyk7CiAgICAtIGZjLiogLyBoZWFkLiogLyBjbGFzc2lmaWVyLiog5LiA5b6L5Yml56a7KOaIkeS7rOeahOaooeWei+S8muabv+aNouaIkCAxMiDlpLQpOwogICAg6L+U5ZueICjmmK/lkKbmiJDlip8sIOWRveS4reaPj+i/sCnjgIIKICAgICIiIgogICAgZm9yIHAsIGRlc2MgaW4gcGF0aHM6CiAgICAgICAgc2QgPSBfbG9hZF9zdGF0ZV9kaWN0X2Zyb21fZmlsZShwKQogICAgICAgIGlmIHNkIGlzIE5vbmU6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgIyAxKSDpgILphY0gY29udjE66YCa6YGT5pWw5LiN5ZCM5YiZIHJlc2hhcGUrbWVhbijlpoIgMjQg6YCa6YGTIOKGkiAzIOmAmumBkykKICAgICAgICBpZiAiY29udjEud2VpZ2h0IiBpbiBzZDoKICAgICAgICAgICAgdyA9IHNkWyJjb252MS53ZWlnaHQiXQogICAgICAgICAgICB0YXJnZXQgPSBuZXQuY29udjEud2VpZ2h0LnNoYXBlWzFdCiAgICAgICAgICAgIGlmIHcuc2hhcGVbMV0gIT0gdGFyZ2V0IGFuZCB3LnNoYXBlWzFdICUgdGFyZ2V0ID09IDA6CiAgICAgICAgICAgICAgICBCLCBDLCBILCBXID0gdy5zaGFwZQogICAgICAgICAgICAgICAgdzIgPSB3LnJlc2hhcGUoQiwgdGFyZ2V0LCBDIC8vIHRhcmdldCwgSCwgVykubWVhbihkaW09MikKICAgICAgICAgICAgICAgIHNkWyJjb252MS53ZWlnaHQiXSA9IHcyCiAgICAgICAgICAgICAgICBwcmludChmIlvmnYPph41dIHtkZXNjfSBjb252MSDpgJrpgZMge0N94oaSe3RhcmdldH0g5bmz5Z2H6YCC6YWNIiwgZmx1c2g9VHJ1ZSkKICAgICAgICAgICAgZWxpZiB3LnNoYXBlWzFdICE9IHRhcmdldDoKICAgICAgICAgICAgICAgIHNkLnBvcCgiY29udjEud2VpZ2h0IikgICMg5peg5rOV6YCC6YWNLOS4ouW8gyjnlKjpmo/mnLrliJ3lp4vljJYpCiAgICAgICAgIyAyKSDliaXnprsgZmMvaGVhZC9jbGFzc2lmaWVyKOaooeWei+S8muabv+aNouaIkCAxMiDlpLQpCiAgICAgICAgZm9yIGsgaW4gbGlzdChzZC5rZXlzKCkpOgogICAgICAgICAgICBpZiBrLnN0YXJ0c3dpdGgoKCJmYy4iLCAiaGVhZC4iLCAiY2xhc3NpZmllci4iKSk6CiAgICAgICAgICAgICAgICBzZC5wb3AoaykKICAgICAgICB0cnk6CiAgICAgICAgICAgIG1pc3NpbmcsIHVuZXhwZWN0ZWQgPSBuZXQubG9hZF9zdGF0ZV9kaWN0KHNkLCBzdHJpY3Q9RmFsc2UpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICBwcmludChmIlvmnYPph41dIHtkZXNjfSDkuI4gUmVzTmV0MzQg57uT5p6E5LiN5Yy56YWNOiB7ZX0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGV4ZW1wdCA9IHtrIGZvciBrIGluIG1pc3NpbmcgaWYgay5zdGFydHN3aXRoKCgiY29udjEuIiwgImZjLiIpKX0KICAgICAgICBpZiBub3QgdW5leHBlY3RlZCBhbmQgbGVuKG1pc3NpbmcpID09IGxlbihleGVtcHQpOgogICAgICAgICAgICBwcmludChmIlvmnYPph41dIOemu+e6v+mihOiuree7g+WKoOi9veaIkOWKnzoge2Rlc2N9ICjopobnm5Yge2xlbihzZCl9IOS4quWPguaVsOW8oOmHjykiLCBmbHVzaD1UcnVlKQogICAgICAgICAgICByZXR1cm4gVHJ1ZSwgZGVzYwogICAgICAgIHByaW50KGYiW+adg+mHjV0ge2Rlc2N9IOe7k+aehOS4jeWMuemFjShtaXNzaW5nIHtsZW4obWlzc2luZykgLSBsZW4oZXhlbXB0KX0g5Liq6Z2e6LGB5YWNIGtleSwgIgogICAgICAgICAgICAgIGYidW5leHBlY3RlZCB7bGVuKHVuZXhwZWN0ZWQpfSks5bCd6K+V5LiL5LiA5LiqIiwgZmx1c2g9VHJ1ZSkKICAgIHJldHVybiBGYWxzZSwgIiIKCgpkZWYgX3NjYW5fcHNldWRvKGJhc2UsIGRlcHRoPTAsIG1heF9kZXB0aD0zKToKICAgICIiIumAkuW9kuWcqOaMgui9veebruW9leS4i+aJvui9r+agh+etviBDU1Yo6ZmQ5Yi25rex5bqmLOi3s+i/hyBESUNPTSDnm67lvZUp44CCCgogICAg6L+U5ZueIChEYXRhRnJhbWUg5oiWIE5vbmUsIOadpea6kOaPj+i/sCnjgILor4bliKvop4TliJk65ZCrIFN0dWR5SW5zdGFuY2VVSUQg5LiU6Iez5bCR5pyJ5LiA5LiqCiAgICBwc2V1ZG9fIOWJjee8gOWIlyjlpoIgcHNldWRvX0FDTCnjgILmib7kuI3liLDov5Tlm54gKE5vbmUsICIiKeOAggoKICAgIOivhuWIq+aWueW8j+WPjOmAmumBkzoKICAgIDEuIOaWh+S7tuWQjeeZveWQjeWNlShfUFNFVURPX0ZJTEVTKeW/q+mAn+WRveS4rTsKICAgIDIuICoq5oyJ5YaF5a656K+G5YirKio65Lu75oSPICouY3N2IOWPquimgeihqOWktOWQqyBTdHVkeUluc3RhbmNlVUlEICsgcHNldWRvXyog5YiX5Y2z5ZG95LitCiAgICAgICAo5LiN5L6d6LWW5paH5Lu25ZCNLOekvuWMuuaVsOaNrumbhuaUueWQjS/mjaLnu5PmnoTkuZ/og73miavliLAp44CCCiAgICAiIiIKICAgIGlmIGRlcHRoID4gbWF4X2RlcHRoIG9yIG5vdCBvcy5wYXRoLmlzZGlyKGJhc2UpOgogICAgICAgIHJldHVybiBOb25lLCAiIgogICAgdHJ5OgogICAgICAgIGVudHJpZXMgPSBzb3J0ZWQob3MubGlzdGRpcihiYXNlKSkKICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgIHJldHVybiBOb25lLCAiIgogICAgIyDpgJrpgZMgMTrmlofku7blkI3nmb3lkI3ljZUo5ZCR5ZCO5YW85a65LOivu+WFqOmHjykKICAgIGZvciBmbiBpbiBfUFNFVURPX0ZJTEVTOgogICAgICAgIHAgPSBvcy5wYXRoLmpvaW4oYmFzZSwgZm4pCiAgICAgICAgaWYgb3MucGF0aC5leGlzdHMocCkgYW5kIG9zLnBhdGguaXNmaWxlKHApOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBjYW5kID0gcGQucmVhZF9jc3YocCkKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGlmICJTdHVkeUluc3RhbmNlVUlEIiBpbiBjYW5kLmNvbHVtbnMgYW5kIGFueSgKICAgICAgICAgICAgICAgICAgICBjLnN0YXJ0c3dpdGgoInBzZXVkb18iKSBmb3IgYyBpbiBjYW5kLmNvbHVtbnMpOgogICAgICAgICAgICAgICAgcmV0dXJuIGNhbmQsIG9zLnBhdGgucmVscGF0aChwLCAiL2thZ2dsZS9pbnB1dCIpCiAgICAjIOmAmumBkyAyOuaMieWGheWuueivhuWIqyjlj6ror7vooajlpLQgbnJvd3M9MyDliKTmlq0s5ZG95Lit5YaN5YWo6K+7KQogICAgZm9yIGZuIGluIGVudHJpZXM6CiAgICAgICAgaWYgbm90IGZuLmxvd2VyKCkuZW5kc3dpdGgoIi5jc3YiKToKICAgICAgICAgICAgY29udGludWUKICAgICAgICBwID0gb3MucGF0aC5qb2luKGJhc2UsIGZuKQogICAgICAgIGlmIG5vdCBvcy5wYXRoLmlzZmlsZShwKToKICAgICAgICAgICAgY29udGludWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIGhlYWQgPSBwZC5yZWFkX2NzdihwLCBucm93cz0zKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgaWYgIlN0dWR5SW5zdGFuY2VVSUQiIGluIGhlYWQuY29sdW1ucyBhbmQgYW55KAogICAgICAgICAgICAgICAgYy5zdGFydHN3aXRoKCJwc2V1ZG9fIikgZm9yIGMgaW4gaGVhZC5jb2x1bW5zKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgY2FuZCA9IHBkLnJlYWRfY3N2KHApCiAgICAgICAgICAgICAgICByZXR1cm4gY2FuZCwgb3MucGF0aC5yZWxwYXRoKHAsICIva2FnZ2xlL2lucHV0IikKICAgICAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICBmb3Igc3ViIGluIGVudHJpZXM6CiAgICAgICAgaWYgc3ViIGluIF9TS0lQX0RJUlM6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgY2FuZCwgc3JjID0gX3NjYW5fcHNldWRvKG9zLnBhdGguam9pbihiYXNlLCBzdWIpLCBkZXB0aCArIDEsIG1heF9kZXB0aCkKICAgICAgICBpZiBjYW5kIGlzIG5vdCBOb25lOgogICAgICAgICAgICByZXR1cm4gY2FuZCwgc3JjCiAgICByZXR1cm4gTm9uZSwgIiIKCgpkZWYgZmluZF9wc2V1ZG9fZGF0YXNldCgpOgogICAgIiIi5ZyoIC9rYWdnbGUvaW5wdXQg5LiL6YCS5b2S5omr5o+P56S+5Yy66L2v5qCH562+5pWw5o2u6ZuGKExMTSDku47miqXlkYrmj5Dlj5bnmoTkvKrmoIfnrb4p44CCCgogICAg5YW85a655Y2V5bGCKC9rYWdnbGUvaW5wdXQvPHNsdWc+LynkuI7lpJrlsYIoL2thZ2dsZS9pbnB1dC9kYXRhc2V0cy88c2x1Zz4vKeaMgui9veOAggogICAg6L+U5ZueIChEYXRhRnJhbWUg5oiWIE5vbmUsIOadpea6kOaPj+i/sCk75om+5LiN5Yiw6L+U5ZueIChOb25lLCAiIinjgIIKICAgICIiIgogICAgaWYgbm90IG9zLnBhdGguaXNkaXIoIi9rYWdnbGUvaW5wdXQiKToKICAgICAgICByZXR1cm4gTm9uZSwgIiIKICAgIHJldHVybiBfc2Nhbl9wc2V1ZG8oIi9rYWdnbGUvaW5wdXQiKQoKCmRlZiBsb2FkX2xhYmVscyhyb290LCBwc2V1ZG9fY29uZj0wLjAsIHVzZV9yZXBvcnRfbGFiZWxzPVRydWUpOgogICAgIiIi6L+U5ZueIHRyYWluIHN0dWR5IOe6p+agh+etviBEYXRhRnJhbWUo6KGMPVN0dWR5SW5zdGFuY2VVSUQsIOWIlz1MQUJFTFMsIOWIhuaVsC9OYU4p44CCCgogICAg5qCH562+5p2l5rqQ5LyY5YWI57qnKDIwMjYtMDktMDYg6LW3O+aXp+eahCLnpL7ljLrova/moIfnrb7mlbDmja7pm4Yi5pa55qGI5bey6K+B5Lyq5byD55So4oCU4oCUCiAgICBiYXJ1bjIxMDQg55qEIHBzZXVkb18qIDk4LjclIOaYr+Wtl+mdoiAwLjUg5q275YC844CB6Zu25aKe6YeP5L+h5oGvLOaYryBsb3NzIOaBkiAwLjY5MwogICAg55qE55yf5qC55ZugKToKICAgIDEuIOWumOaWuSB0cmFpbi5jc3Yg5qCH5rOoKDAvMSzku4UgNTgvNDQwNyDkvospOwogICAgMi4g5YaF572u5oql5ZGK6KeE5YiZ5oq95Y+W5ZmoIHJzbmFfcmVwb3J0X2xhYmVscyjnp7vmpI3oh6ogcnNuYS1rbmVlLWJhc2VsaW5lLXYxLAogICAgICAg5aSa6K+t6KiAL+aMieWPpeWQpuWumuaegeaApy/kuKXph43luqbliIbnuqcpOuWvueavj+S7veaUvuWwhOaKpeWRiuS6p+WHuiAxMiDnl4XngbYgc29mdCDliIbmlbAKICAgICAgICjpmLPmgKcgMC43Mn4wLjk1IC8g6Zi05oCnIDAuMDR+MC4yMCAvIOaXoOivgeaNrj1OYU4pOwogICAgICAg5a6Y5pa557y65aSx5qC855So5oq95Y+W5YiG5pWw5aGr5YWFLOaXoOivgeaNruagvOS/neaMgSBOYU4o5LiN6L+b5o2f5aSxLOeUsSB2YWxpZCDmjqnnoIHmjpLpmaQp44CCCiAgICAiIiIKICAgIHRyYWluID0gcGQucmVhZF9jc3Yob3MucGF0aC5qb2luKHJvb3QsICJ0cmFpbi5jc3YiKSkKICAgIGRmID0gdHJhaW5bWyJTdHVkeUluc3RhbmNlVUlEIl0gKyBMQUJFTFNdLmNvcHkoKQogICAgb2ZmaWNpYWxfY250ID0ge2M6IGludChkZltjXS5ub3RuYSgpLnN1bSgpKSBmb3IgYyBpbiBMQUJFTFN9CgogICAgaWYgbm90IHVzZV9yZXBvcnRfbGFiZWxzOgogICAgICAgIHByaW50KCJb5qCH562+XSAtLW5vLXJlcG9ydC1sYWJlbHM65LuF5a6Y5pa55qCH5rOo5Y+v55SoIikKICAgICAgICByZXR1cm4gZGYKICAgIGlmIG5vdCBIQVNfUkw6CiAgICAgICAgcHJpbnQoIlvmoIfnrb5dIOacquaJvuWIsCByc25hX3JlcG9ydF9sYWJlbHMucHko6ZyA5LiOIHJzbmFfdjMucHkg5ZCM55uu5b2VKSwiCiAgICAgICAgICAgICAgIuS7heWumOaWueagh+azqOWPr+eUqCIpCiAgICAgICAgcmV0dXJuIGRmCiAgICBpZiAiUmVwb3J0IiBub3QgaW4gdHJhaW4uY29sdW1uczoKICAgICAgICBwcmludCgiW+agh+etvl0gdHJhaW4uY3N2IOaXoCBSZXBvcnQg5YiXLOS7heWumOaWueagh+azqOWPr+eUqCIpCiAgICAgICAgcmV0dXJuIGRmCgogICAgcHNldWRvID0gUkwuYnVpbGRfcHNldWRvX3RhYmxlKHRyYWluLCB2ZXJib3NlPVRydWUpCiAgICBwc2V1ZG8gPSBwc2V1ZG8uc2V0X2luZGV4KCJTdHVkeUluc3RhbmNlVUlEIikKICAgIHByaW50KGYiW+agh+etvl0g5aGr5YWF57uf6K6hKHtsZW4oZGYpfSDkuKogc3R1ZHkpOiIpCiAgICBmb3IgYyBpbiBMQUJFTFM6CiAgICAgICAgbWFzayA9IGRmW2NdLmlzbmEoKS52YWx1ZXMKICAgICAgICBpZiBub3QgbWFzay5hbnkoKToKICAgICAgICAgICAgcHJpbnQoZiIgIHtjOjE4c30g5a6Y5pa55YWo6YePLOaXoOmcgOWhq+WFhSIpCiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgdWlkcyA9IGRmLmxvY1ttYXNrLCAiU3R1ZHlJbnN0YW5jZVVJRCJdCiAgICAgICAgdmFscyA9IHBzZXVkb1sicHNldWRvXyIgKyBjXS5yZWluZGV4KHVpZHMpLnZhbHVlcwogICAgICAgIG5fZmlsbCA9IGludChwZC5ub3RuYSh2YWxzKS5zdW0oKSkKICAgICAgICBkZi5sb2NbbWFzaywgY10gPSB2YWxzCiAgICAgICAgcHJpbnQoZiIgIHtjOjE4c30g5a6Y5pa5IHtvZmZpY2lhbF9jbnRbY106NGR9ICsg5oql5ZGK5oq95Y+W5aGr5YWFIHtuX2ZpbGw6NGR9IgogICAgICAgICAgICAgIGYiID0g5pyJ5pWIIHtpbnQoZGZbY10ubm90bmEoKS5zdW0oKSk6NWR9IikKICAgIHJldHVybiBkZgoKCl9EQ01fTUlTU19QUklOVEVEID0gW0ZhbHNlXSAgIyDlj6rmiZPljbDkuIDmrKEgRElDT00g5pyq5ZG95Lit6K+K5patLOmBv+WFjSAyIOS4hyBzZXJpZXMg5Yi35bGPCgoKZGVmIHJlYWRfZGljb21fc2xpY2VzKGRjbV9kaXIsIHNlcmllc191aWQsIHN0dWR5X3VpZD1Ob25lKToKICAgICIiIuivu+WPluS4gOS4qiBzZXJpZXMg55qE5omA5pyJ5YiH54mHLOaMieeJqeeQhuS9jee9ruaOkuW6jyzov5Tlm54gWyhwYXRoLCB6KV3jgIIKCiAgICDot6/lvoTlhbzlrrnlpJrnp40gS2FnZ2xlIOW4g+WxgCjlrp7mtYsgUlNOQSAyMDI2IOS4uuS4pOWxgik6CiAgICAgIDEpIDxkY21fZGlyPi88c2VyaWVzX3VpZD4vICAgICAgICAgICAgICAgICjml6flgYforr46c2VyaWVzIOebruW9leebtOaOpeaMgikKICAgICAgMikgPGRjbV9kaXI+LzxzdHVkeV91aWQ+LzxzZXJpZXNfdWlkPi8gICAgKFJTTkEg5qCH5YeGOnN0dWR5IOebruW9leS4i+WGjeaMgiBzZXJpZXMpCiAgICDmib7kuI3liLDmiJbor7vkuI3liLDov5Tlm54gW13jgIIKICAgICIiIgogICAgY2FuZHMgPSBbb3MucGF0aC5qb2luKGRjbV9kaXIsIHNlcmllc191aWQpXQogICAgaWYgc3R1ZHlfdWlkOgogICAgICAgIGNhbmRzLmFwcGVuZChvcy5wYXRoLmpvaW4oZGNtX2Rpciwgc3R1ZHlfdWlkLCBzZXJpZXNfdWlkKSkKICAgIHNkaXIgPSBuZXh0KChjIGZvciBjIGluIGNhbmRzIGlmIG9zLnBhdGguaXNkaXIoYykpLCBOb25lKQogICAgaWYgc2RpciBpcyBOb25lOgogICAgICAgIGlmIG5vdCBfRENNX01JU1NfUFJJTlRFRFswXToKICAgICAgICAgICAgX0RDTV9NSVNTX1BSSU5URURbMF0gPSBUcnVlCiAgICAgICAgICAgIHByaW50KGYiW+iviuaWrS1ESUNPTV0g5om+5LiN5YiwIHNlcmllcyDnm67lvZUs5bCd6K+V6L+HOiB7Y2FuZHN9IiwgZmx1c2g9VHJ1ZSkKICAgICAgICAgICAgcHJpbnQoZiJb6K+K5patLURJQ09NXSB7ZGNtX2Rpcn0g5piv5ZCm5a2Y5ZyoOiB7b3MucGF0aC5pc2RpcihkY21fZGlyKX0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBpbm5lciA9IHNvcnRlZChvcy5saXN0ZGlyKGRjbV9kaXIpKVs6OF0gaWYgb3MucGF0aC5pc2RpcihkY21fZGlyKSBlbHNlIFtdCiAgICAgICAgICAgICAgICBwcmludChmIlvor4rmlq0tRElDT01dIHtkY21fZGlyfSDlrp7pmYXlhoXlrrnmoLfmnKw6IHtpbm5lcn0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICBleGNlcHQgT1NFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICByZXR1cm4gW10KICAgIGZpbGVzID0gW29zLnBhdGguam9pbihzZGlyLCBmKSBmb3IgZiBpbiBvcy5saXN0ZGlyKHNkaXIpIGlmIGYubG93ZXIoKS5lbmRzd2l0aCgiLmRjbSIpXQogICAgaWYgbm90IGZpbGVzOgogICAgICAgIGlmIG5vdCBfRENNX01JU1NfUFJJTlRFRFswXToKICAgICAgICAgICAgX0RDTV9NSVNTX1BSSU5URURbMF0gPSBUcnVlCiAgICAgICAgICAgIHByaW50KGYiW+iviuaWrS1ESUNPTV0g55uu5b2V5a2Y5Zyo5L2G5pegIC5kY20g5paH5Lu2OiB7c2Rpcn0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICBwcmludChmIlvor4rmlq0tRElDT01dIOebruW9leWGheWuueagt+acrDoge3NvcnRlZChvcy5saXN0ZGlyKHNkaXIpKVs6OF19IiwgZmx1c2g9VHJ1ZSkKICAgICAgICByZXR1cm4gW10KICAgIHJvd3MgPSBbXQogICAgZm9yIGYgaW4gZmlsZXM6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBkID0gcHlkaWNvbS5kY21yZWFkKGYsIHN0b3BfYmVmb3JlX3BpeGVscz1GYWxzZSkKICAgICAgICAgICAgcG9zID0gZC5nZXQoIkltYWdlUG9zaXRpb25QYXRpZW50IikKICAgICAgICAgICAgeiA9IGZsb2F0KHBvc1syXSkgaWYgcG9zIGlzIG5vdCBOb25lIGFuZCBsZW4ocG9zKSA+PSAzIGVsc2UgTm9uZQogICAgICAgICAgICByb3dzLmFwcGVuZCgoZiwgeikpCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICAgICAgY29udGludWUKICAgIHJvd3Muc29ydChrZXk9bGFtYmRhIHI6IChyWzFdIGlzIE5vbmUsIHJbMV0gaWYgclsxXSBpcyBub3QgTm9uZSBlbHNlIDAuMCkpCiAgICByZXR1cm4gcm93cwoKCiMgLS0tLS0tLS0tLS0tLS0tLSBESUNPTSAtPiAyLjVEIGNsaXAg6aKE5aSE55CGIC0tLS0tLS0tLS0tLS0tLS0KCmRlZiB3aW5kb3dfYW5kX3Jlc2l6ZShkY20sIGltZ19zaXplPUlNR19TSVpFKToKICAgICIiIuWNleW8oOWIh+eJhzpSZXNjYWxlIOWQjueZvuWIhuS9jeeql+WPo+WMliAtPiBbMCwxXSAtPiByZXNpemUgMjI044CCIiIiCiAgICBhcnIgPSBkY20ucGl4ZWxfYXJyYXkuYXN0eXBlKG5wLmZsb2F0MzIpCiAgICBzbG9wZSA9IGZsb2F0KGRjbS5nZXQoIlJlc2NhbGVTbG9wZSIsIDEpKQogICAgaW50ZXIgPSBmbG9hdChkY20uZ2V0KCJSZXNjYWxlSW50ZXJjZXB0IiwgMCkpCiAgICBhcnIgPSBhcnIgKiBzbG9wZSArIGludGVyCiAgICBpZiBkY20uZ2V0KCJQaG90b21ldHJpY0ludGVycHJldGF0aW9uIikgPT0gIk1PTk9DSFJPTUUxIjoKICAgICAgICBhcnIgPSBhcnIubWF4KCkgLSBhcnIKICAgIGxvLCBoaSA9IG5wLnBlcmNlbnRpbGUoYXJyLCBbMSwgOTldKQogICAgYXJyID0gbnAuY2xpcCgoYXJyIC0gbG8pIC8gbWF4KGhpIC0gbG8sIDFlLTYpLCAwLCAxKQogICAgZnJvbSBQSUwgaW1wb3J0IEltYWdlCiAgICBpbWcgPSBJbWFnZS5mcm9tYXJyYXkoKGFyciAqIDI1NSkuYXN0eXBlKG5wLnVpbnQ4KSkucmVzaXplKChpbWdfc2l6ZSwgaW1nX3NpemUpLCBJbWFnZS5CSUxJTkVBUikKICAgIHJldHVybiBucC5hc2FycmF5KGltZywgZHR5cGU9bnAuZmxvYXQzMikgLyAyNTUuMAoKCmRlZiBtYWtlX2NsaXBzKHNlcmllc19yb3dzLCBuX2NsaXBzPTIsIGltZ19zaXplPUlNR19TSVpFKToKICAgICIiIuS7juaOkuW6j+WlveeahOWIh+eJh+WIl+ihqOeUn+aIkOiLpeW5siAzIOmAmumBkyBjbGlwKOebuOmCu+S4ieW8oCnjgIIiIiIKICAgIGNsaXBzID0gW10KICAgIHBhdGhzID0gW3JbMF0gZm9yIHIgaW4gc2VyaWVzX3Jvd3NdCiAgICBpZiBsZW4ocGF0aHMpIDwgQ0xJUDoKICAgICAgICByZXR1cm4gY2xpcHMKICAgIHN0ZXAgPSBtYXgoMSwgKGxlbihwYXRocykgLSAyKSAvLyBuX2NsaXBzKQogICAgZm9yIGMgaW4gcmFuZ2UoMSwgbGVuKHBhdGhzKSAtIDEsIHN0ZXApOgogICAgICAgIGlmIGxlbihjbGlwcykgPj0gbl9jbGlwczoKICAgICAgICAgICAgYnJlYWsKICAgICAgICBjaGFuID0gW10KICAgICAgICBvayA9IFRydWUKICAgICAgICBmb3IgayBpbiAoYyAtIDEsIGMsIGMgKyAxKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgZGNtID0gcHlkaWNvbS5kY21yZWFkKHBhdGhzW2tdKQogICAgICAgICAgICAgICAgY2hhbi5hcHBlbmQod2luZG93X2FuZF9yZXNpemUoZGNtLCBpbWdfc2l6ZSkpCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgICAgICBvayA9IEZhbHNlCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGlmIG9rOgogICAgICAgICAgICBjbGlwcy5hcHBlbmQobnAuc3RhY2soY2hhbiwgYXhpcz0wKSkgICMgKDMsIEgsIFcpCiAgICByZXR1cm4gY2xpcHMKCgppZiBIQVNfVE9SQ0g6CiAgICAjIC0tLS0tLS0tLS0tLS0tLS0g5pWw5o2u6ZuGKHYyOuaMieW5s+mdoui/h+a7pCBzZXJpZXMpIC0tLS0tLS0tLS0tLS0tLS0KCiAgICBjbGFzcyBLbmVlRGF0YXNldChEYXRhc2V0KToKICAgICAgICAiIiJzdHVkeSDnuqfmlbDmja7pm4Ys5Y+q5Y+W5oyH5a6aIEFuYXRvbWljYWxfUGxhbmUg55qEIHNlcmllcyzmi7zmiJAgKEMqMywgSCwgVynjgIIiIiIKCiAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIHN0dWRpZXMsIGxhYmVsc19kZiwgZGNtX3Jvb3QsIHNlcmllc19kZiwgcGxhbmUsCiAgICAgICAgICAgICAgICAgICAgIGhhc190YXJnZXRzPVRydWUsIG5fY2xpcHM9Mik6CiAgICAgICAgICAgIHNlbGYuc3R1ZGllcyA9IHN0dWRpZXMKICAgICAgICAgICAgc2VsZi5sYWJlbHNfZGYgPSBsYWJlbHNfZGYKICAgICAgICAgICAgc2VsZi5kY21fcm9vdCA9IGRjbV9yb290CiAgICAgICAgICAgIHNlbGYuc2VyaWVzX2RmID0gc2VyaWVzX2RmCiAgICAgICAgICAgIHNlbGYucGxhbmUgPSBwbGFuZQogICAgICAgICAgICBzZWxmLmhhc190YXJnZXRzID0gaGFzX3RhcmdldHMKICAgICAgICAgICAgc2VsZi5uX2NsaXBzID0gbl9jbGlwcwogICAgICAgICAgICBzZWxmLmNhY2hlID0ge30gICMg5q+P5oqY54us56uL57yT5a2YOmZvbGQg57uT5p2f6ZqPIGRhdGFzZXQg6YeK5pS+LOmBv+WFjSA1IOaKmOe0r+enryBPT00KICAgICAgICAgICAgIyDor4rmlq3orqHmlbA66K+75YiwIGNsaXAg55qEIHN0dWR5IC8g56m6IHN0dWR5IC8g57Sv6K6hIGNsaXAg5pWwCiAgICAgICAgICAgIHNlbGYubl9oaXQgPSAwCiAgICAgICAgICAgIHNlbGYubl9lbXB0eSA9IDAKICAgICAgICAgICAgc2VsZi5uX2NsaXBzX3RvdGFsID0gMAoKICAgICAgICBkZWYgc3RhdHMoc2VsZik6CiAgICAgICAgICAgICIiIui/lOWbniAo6K+75YiwIGNsaXAg55qEIHN0dWR5IOaVsCwg56m6IHN0dWR5IOaVsCwg5bmz5Z2HIGNsaXAg5pWwKSzpmLLmraLpnZnpu5jnmb3orq3nu4PjgIIiIiIKICAgICAgICAgICAgdG90YWwgPSBzZWxmLm5faGl0ICsgc2VsZi5uX2VtcHR5CiAgICAgICAgICAgIGF2ZyA9IChzZWxmLm5fY2xpcHNfdG90YWwgLyBzZWxmLm5faGl0KSBpZiBzZWxmLm5faGl0IGVsc2UgMC4wCiAgICAgICAgICAgIHJldHVybiBzZWxmLm5faGl0LCBzZWxmLm5fZW1wdHksIGF2ZwoKICAgICAgICBkZWYgX2xvYWRfc3R1ZHkoc2VsZiwgdWlkKToKICAgICAgICAgICAga2V5ID0gKHVpZCwgc2VsZi5wbGFuZSkKICAgICAgICAgICAgaWYga2V5IGluIHNlbGYuY2FjaGU6CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5jYWNoZVtrZXldCiAgICAgICAgICAgIHNyb3dzID0gc2VsZi5zZXJpZXNfZGZbc2VsZi5zZXJpZXNfZGZbIlN0dWR5SW5zdGFuY2VVSUQiXSA9PSB1aWRdCiAgICAgICAgICAgIGlmICJBbmF0b21pY2FsX1BsYW5lIiBpbiBzcm93cy5jb2x1bW5zOgogICAgICAgICAgICAgICAgc3Jvd3MgPSBzcm93c1tzcm93c1siQW5hdG9taWNhbF9QbGFuZSJdID09IHNlbGYucGxhbmVdCiAgICAgICAgICAgICAgICBzcm93cyA9IHNyb3dzLnNvcnRfdmFsdWVzKCJGbHVpZF9TZW5zaXRpdmUiLCBraW5kPSJzdGFibGUiKS5kcm9wX2R1cGxpY2F0ZXMoCiAgICAgICAgICAgICAgICAgICAgc3Vic2V0PVsiRmx1aWRfU2Vuc2l0aXZlIl0pLmhlYWQoTUFYX1NFUklFUykKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNyb3dzID0gc3Jvd3MuaGVhZChNQVhfU0VSSUVTKQogICAgICAgICAgICBjbGlwcyA9IFtdCiAgICAgICAgICAgIGZvciBfLCBzciBpbiBzcm93cy5pdGVycm93cygpOgogICAgICAgICAgICAgICAgc2lkID0gc3JbIlNlcmllc0luc3RhbmNlVUlEIl0KICAgICAgICAgICAgICAgIHJvd3MgPSByZWFkX2RpY29tX3NsaWNlcyhzZWxmLmRjbV9yb290LCBzaWQsIHN0dWR5X3VpZD11aWQpCiAgICAgICAgICAgICAgICBjbGlwcy5leHRlbmQobWFrZV9jbGlwcyhyb3dzLCBuX2NsaXBzPXNlbGYubl9jbGlwcykpCiAgICAgICAgICAgIHNlbGYuY2FjaGVbdWlkXSA9IGNsaXBzCiAgICAgICAgICAgICMg5LuF6aaW5qyh5Yqg6L296K6h5pWwKOe8k+WtmOWRveS4reS4jeWGjee0r+WKoCzpgb/lhY3lpJogZXBvY2gg6YeN5aSNKQogICAgICAgICAgICBpZiBjbGlwczoKICAgICAgICAgICAgICAgIHNlbGYubl9oaXQgKz0gMQogICAgICAgICAgICAgICAgc2VsZi5uX2NsaXBzX3RvdGFsICs9IGxlbihjbGlwcykKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYubl9lbXB0eSArPSAxCiAgICAgICAgICAgIHJldHVybiBjbGlwcwoKICAgICAgICBkZWYgX19sZW5fXyhzZWxmKToKICAgICAgICAgICAgcmV0dXJuIGxlbihzZWxmLnN0dWRpZXMpCgogICAgICAgIGRlZiBfX2dldGl0ZW1fXyhzZWxmLCBpKToKICAgICAgICAgICAgdWlkID0gc2VsZi5zdHVkaWVzW2ldCiAgICAgICAgICAgIGNsaXBzID0gc2VsZi5fbG9hZF9zdHVkeSh1aWQpICAjIOWRveS4rS/nqbrorqHmlbDlnKggX2xvYWRfc3R1ZHkg6aaW5qyh5Yqg6L295pe25a6M5oiQCiAgICAgICAgICAgIGluX2NoID0gc2VsZi5uX2NsaXBzICogQ0xJUCAgIyDovpPlhaXpgJrpgZPmlbA6Y2xpcCDmlbAgw5cg5q+PIGNsaXAgMyDliIfniYcKICAgICAgICAgICAgaWYgbm90IGNsaXBzOgogICAgICAgICAgICAgICAgeCA9IG5wLnplcm9zKChpbl9jaCwgSU1HX1NJWkUsIElNR19TSVpFKSwgZHR5cGU9bnAuZmxvYXQzMikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHggPSBucC5jb25jYXRlbmF0ZShjbGlwc1s6IHNlbGYubl9jbGlwc10sIGF4aXM9MCkgICMgKGsqMywgSCwgVykKICAgICAgICAgICAgICAgIHBhZCA9IGluX2NoIC0geC5zaGFwZVswXQogICAgICAgICAgICAgICAgaWYgcGFkID4gMDoKICAgICAgICAgICAgICAgICAgICB4ID0gbnAuY29uY2F0ZW5hdGUoW3gsIG5wLnplcm9zKChwYWQsIElNR19TSVpFLCBJTUdfU0laRSksIGR0eXBlPW5wLmZsb2F0MzIpXSkKICAgICAgICAgICAgICAgIGVsaWYgcGFkIDwgMDoKICAgICAgICAgICAgICAgICAgICB4ID0geFs6IGluX2NoXQogICAgICAgICAgICB4ID0gdG9yY2gudGVuc29yKHgsIGR0eXBlPXRvcmNoLmZsb2F0MzIpCiAgICAgICAgICAgIHkgPSB0b3JjaC56ZXJvcyhsZW4oTEFCRUxTKSwgZHR5cGU9dG9yY2guZmxvYXQzMikKICAgICAgICAgICAgdmFsaWQgPSB0b3JjaC56ZXJvcyhsZW4oTEFCRUxTKSwgZHR5cGU9dG9yY2guZmxvYXQzMikKICAgICAgICAgICAgaWYgc2VsZi5oYXNfdGFyZ2V0czoKICAgICAgICAgICAgICAgIHJvdyA9IHNlbGYubGFiZWxzX2RmW3NlbGYubGFiZWxzX2RmWyJTdHVkeUluc3RhbmNlVUlEIl0gPT0gdWlkXQogICAgICAgICAgICAgICAgaWYgbGVuKHJvdyk6CiAgICAgICAgICAgICAgICAgICAgZm9yIGosIGMgaW4gZW51bWVyYXRlKExBQkVMUyk6CiAgICAgICAgICAgICAgICAgICAgICAgIHYgPSByb3cuaWxvY1swXVtjXQogICAgICAgICAgICAgICAgICAgICAgICBpZiBwZC5ub3RuYSh2KToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlbal0gPSBmbG9hdCh2KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRbal0gPSAxLjAKICAgICAgICAgICAgcmV0dXJuIHgsIHksIHZhbGlkCgoKICAgICMgLS0tLS0tLS0tLS0tLS0tLSDmqKHlnosgLS0tLS0tLS0tLS0tLS0tLQoKICAgIF9QUkVUUkFJTkVEX1RSSUVEID0gW0ZhbHNlXSAgIyDmqKHlnZfnuqfmoIflv5c65LiL6L295aSx6LSl6L+H5LiA5qyh5bCx5LiN5YaN5Y+N5aSN6YeN6K+VCgoKICAgIGRlZiBfYnVpbGRfcmVzbmV0MzQodXNlX3ByZXRyYWluZWQ9RmFsc2UsIG9mZmxpbmVfcGF0aHM9Tm9uZSk6CiAgICAgICAgIiIi5p6E6YCgIFJlc05ldDM0IOW5tuWKoOi9vSBJbWFnZU5ldCDpooTorq3nu4PmnYPph43jgIIKCiAgICAgICAg5p2D6YeN5p2l5rqQ5LyY5YWI57qnOgogICAgICAgIDEuIG9mZmxpbmVfcGF0aHM65oyC6L2955qE56a757q/5p2D6YeN5paH5Lu2KOaJq+aPjyAva2FnZ2xlL2lucHV0IOW+l+WIsCzml6DpnIDogZTnvZEpOwogICAgICAgIDIuIHVzZV9wcmV0cmFpbmVkPVRydWU66IGU572R5LiL6L29IHRvcmNodmlzaW9uIOadg+mHjSjluKbph43or5Us5aSx6LSl5Zue6YCA6ZqP5py6KTsKICAgICAgICAzLiDlkKbliJnpmo/mnLrliJ3lp4vljJbjgIIKICAgICAgICDmiJDlip/liqDovb3lkI7mnYPph43nlLEgdG9yY2gg57yT5a2YLOWQjue7rSBmb2xkIOenkuWKoOi9veOAggogICAgICAgICIiIgogICAgICAgIG5ldCA9IHR2bS5yZXNuZXQzNCh3ZWlnaHRzPU5vbmUpCiAgICAgICAgaWYgb2ZmbGluZV9wYXRoczoKICAgICAgICAgICAgb2ssIGRlc2MgPSBfdHJ5X2xvYWRfb2ZmbGluZShuZXQsIG9mZmxpbmVfcGF0aHMpCiAgICAgICAgICAgIGlmIG9rOgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldAogICAgICAgICAgICBwcmludChmIlvmnYPph41dIOemu+e6v+WAmemAieWdh+S4jeWMuemFjSh7ZGVzY30pLOWbnumAgOWIsOmaj+acui/ogZTnvZHot6/lvoQiLCBmbHVzaD1UcnVlKQogICAgICAgIGlmIG5vdCB1c2VfcHJldHJhaW5lZDoKICAgICAgICAgICAgcHJpbnQoIlvmnYPph41dIOacquW8gOWQryAtLXByZXRyYWluZWQg5LiU5peg56a757q/5p2D6YeNLOS9v+eUqOmaj+acuuWIneWni+WMliIKICAgICAgICAgICAgICAgICAgIijkuI3ogZTnvZE75aaC6ZyA6aKE6K6t57uD6K+35YqgIC0tcHJldHJhaW5lZCDlubblvIDlkK8gSW50ZXJuZXQsIgogICAgICAgICAgICAgICAgICAi5oiW5oyC6L2956a757q/5p2D6YeN5pWw5o2u6ZuGKSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIHJldHVybiBuZXQKICAgICAgICBpZiBfUFJFVFJBSU5FRF9UUklFRFswXToKICAgICAgICAgICAgcmV0dXJuIG5ldCAgIyDkuYvliY3lt7Lnoa7orqTkuIvovb3kuI3kuoYs55u05o6l6ZqP5py6CiAgICAgICAgZm9yIGF0dGVtcHQgaW4gcmFuZ2UoMSwgNCk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG5ldCA9IHR2bS5yZXNuZXQzNCh3ZWlnaHRzPXR2bS5SZXNOZXQzNF9XZWlnaHRzLklNQUdFTkVUMUtfVjEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBoYXNhdHRyKHR2bSwgIlJlc05ldDM0X1dlaWdodHMiKSBlbHNlIE5vbmUpCiAgICAgICAgICAgICAgICByZXR1cm4gbmV0CiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgICAgIHByaW50KGYiW+adg+mHjV0gUmVzTmV0MzQg6aKE6K6t57uD5LiL6L295aSx6LSlKOesrCB7YXR0ZW1wdH0vMyDmrKEpOiB7ZX0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICAgICAgdGltZS5zbGVlcCg1KQogICAgICAgIF9QUkVUUkFJTkVEX1RSSUVEWzBdID0gVHJ1ZQogICAgICAgIHByaW50KCJb5p2D6YeNXSAzIOasoeWdh+Wksei0pSzmlLnnlKjpmo/mnLrliJ3lp4vljJYo57K+5bqm5Lya5piO5pi+5LiL6ZmNO+W7uuiurumHjeivleaIluaMgui9vemihOiuree7g+adg+mHjeaVsOaNrumbhikiLCBmbHVzaD1UcnVlKQogICAgICAgIHJldHVybiB0dm0ucmVzbmV0MzQod2VpZ2h0cz1Ob25lKQoKCiAgICBjbGFzcyBLbmVlTW9kZWwobm4uTW9kdWxlKToKICAgICAgICAiIiJSZXNOZXQzNCDlhbHkuqsgYmFja2JvbmUgKyDlhajlsYDmsaDljJYgKyAxMiBzaWdtb2lkIOWktCjmr4/kuKrlubPpnaLkuIDkuKrlrp7kvosp44CCIiIiCgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBudW1fbGFiZWxzPWxlbihMQUJFTFMpLCBjaGFubmVscz1DTElQLCBwcmV0cmFpbmVkPUZhbHNlLCBvZmZsaW5lX3BhdGhzPU5vbmUpOgogICAgICAgICAgICBzdXBlcigpLl9faW5pdF9fKCkKICAgICAgICAgICAgaWYgSEFTX1RWOgogICAgICAgICAgICAgICAgc2VsZi5iYWNrYm9uZSA9IF9idWlsZF9yZXNuZXQzNCh1c2VfcHJldHJhaW5lZD1wcmV0cmFpbmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZsaW5lX3BhdGhzPW9mZmxpbmVfcGF0aHMpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByYWlzZSBSdW50aW1lRXJyb3IoIumcgOimgSB0b3JjaHZpc2lvbijor7flnKggS2FnZ2xlIE5vdGVib29rIEdQVSDnjq/looPov5DooYwpIikKICAgICAgICAgICAgY29udjFfdyA9IHNlbGYuYmFja2JvbmUuY29udjEud2VpZ2h0ICAjIOS/neeVmemihOiuree7gyBjb252MSDmnYPph40KICAgICAgICAgICAgc2VsZi5iYWNrYm9uZS5jb252MSA9IG5uLkNvbnYyZChjaGFubmVscywgNjQsIGtlcm5lbF9zaXplPTcsIHN0cmlkZT0yLCBwYWRkaW5nPTMsIGJpYXM9RmFsc2UpCiAgICAgICAgICAgIGlmIGNvbnYxX3cuc2hhcGUgPT0gc2VsZi5iYWNrYm9uZS5jb252MS53ZWlnaHQuc2hhcGU6ICAjIGNoYW5uZWxzPT0zIOaXtuebtOaOpeayv+eUqAogICAgICAgICAgICAgICAgc2VsZi5iYWNrYm9uZS5jb252MS53ZWlnaHQuZGF0YS5jb3B5Xyhjb252MV93LmRhdGEpCiAgICAgICAgICAgIGVsaWYgY2hhbm5lbHMgJSAzID09IDAgYW5kIGNvbnYxX3cuc2hhcGVbMV0gPT0gMzoKICAgICAgICAgICAgICAgICMgMi41RCDpgJrpgZPmianlsZU65oqKIDMg6YCa6YGT6aKE6K6t57uD5p2D6YeN5aSN5Yi2IG5fY2xpcHMg5Lu9KOW4uOingeWBmuazlSkKICAgICAgICAgICAgICAgIHJlcCA9IGNoYW5uZWxzIC8vIDMKICAgICAgICAgICAgICAgIHNlbGYuYmFja2JvbmUuY29udjEud2VpZ2h0LmRhdGEuY29weV8oY29udjFfdy5yZXBlYXQoMSwgcmVwLCAxLCAxKSkKICAgICAgICAgICAgICAgIHByaW50KGYiW+adg+mHjV0gY29udjEg6aKE6K6t57uD5p2D6YeN5aSN5Yi2IHtyZXB9IOS7veaJqeWxleWIsCB7Y2hhbm5lbHN9IOmAmumBkyIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIHNlbGYuYmFja2JvbmUuZmMgPSBubi5JZGVudGl0eSgpCiAgICAgICAgICAgIHNlbGYuaGVhZCA9IG5uLkxpbmVhcig1MTIsIG51bV9sYWJlbHMpCgogICAgICAgIGRlZiBmb3J3YXJkKHNlbGYsIHgpOgogICAgICAgICAgICBmZWF0ID0gc2VsZi5iYWNrYm9uZSh4KSAgIyAoQiwgNTEyKQogICAgICAgICAgICByZXR1cm4gc2VsZi5oZWFkKGZlYXQpICAgIyBsb2dpdHMgKEIsIDEyKQoKCgojIC0tLS0tLS0tLS0tLS0tLS0g6K6t57uDIC8g6aqM6K+BIC0tLS0tLS0tLS0tLS0tLS0KCmRlZiB0cmFpbl9lcG9jaChtb2RlbCwgbG9hZGVyLCBvcHQsIGNyaXQsIGRldmljZSk6CiAgICBtb2RlbC50cmFpbigpCiAgICB0b3QsIGNudCA9IDAuMCwgMAogICAgZm9yIHgsIHksIHZhbGlkIGluIGxvYWRlcjoKICAgICAgICB4LCB5LCB2YWxpZCA9IHgudG8oZGV2aWNlKSwgeS50byhkZXZpY2UpLCB2YWxpZC50byhkZXZpY2UpCiAgICAgICAgb3B0Lnplcm9fZ3JhZCgpCiAgICAgICAgb3V0ID0gbW9kZWwoeCkKICAgICAgICBpZiB2YWxpZC5zdW0oKSA9PSAwOgogICAgICAgICAgICBjb250aW51ZQogICAgICAgIGxvc3MgPSAoY3JpdChvdXQsIHkpICogdmFsaWQpLnN1bSgpIC8gdmFsaWQuc3VtKCkKICAgICAgICBsb3NzLmJhY2t3YXJkKCkKICAgICAgICBvcHQuc3RlcCgpCiAgICAgICAgdG90ICs9IGxvc3MuaXRlbSgpICogbGVuKHgpCiAgICAgICAgY250ICs9IGxlbih4KQogICAgcmV0dXJuIHRvdCAvIG1heChjbnQsIDEpCgoKZGVmIHByZWRpY3QobW9kZWwsIGxvYWRlciwgZGV2aWNlKToKICAgIG1vZGVsLmV2YWwoKQogICAgcm93cyA9IFtdCiAgICB3aXRoIHRvcmNoLm5vX2dyYWQoKToKICAgICAgICBmb3IgeCwgXywgXyBpbiBsb2FkZXI6CiAgICAgICAgICAgIHggPSB4LnRvKGRldmljZSkKICAgICAgICAgICAgb3V0ID0gdG9yY2guc2lnbW9pZChtb2RlbCh4KSkKICAgICAgICAgICAgIyAuY3B1KCkudG9saXN0KCkg6ICM6Z2eIC5jcHUoKS5udW1weSgpOnRvcmNoIDIuMi4wK2N1MTE4IOe8luS6jiBudW1weTEueCwKICAgICAgICAgICAgIyDlnKggS2FnZ2xlIG51bXB5Mi4wLjIg5LiLIHRvcmNo4oaSbnVtcHkgaW50ZXJvcCDltKk7dG9saXN0IOe6ryBDKysg6Lev5b6E5a6J5YWo44CCCiAgICAgICAgICAgIHJvd3MuZXh0ZW5kKG91dC5jcHUoKS50b2xpc3QoKSkKICAgIHJldHVybiBucC5hc2FycmF5KHJvd3MsIGR0eXBlPW5wLmZsb2F0MzIpIGlmIHJvd3MgZWxzZSBucC56ZXJvcygoMCwgbGVuKExBQkVMUykpLCBkdHlwZT1ucC5mbG9hdDMyKQoKCmRlZiBydW5fZm9sZChtb2RlbCwgdHJhaW5fZHMsIHZhbF9kcywgZGV2aWNlLCBhcmdzKToKICAgIHRyYWluX2xvYWRlciA9IERhdGFMb2FkZXIodHJhaW5fZHMsIGJhdGNoX3NpemU9YXJncy5iYXRjaCwgc2h1ZmZsZT1UcnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1fd29ya2Vycz1hcmdzLndvcmtlcnMsIGRyb3BfbGFzdD1GYWxzZSkKICAgIHZhbF9sb2FkZXIgPSBEYXRhTG9hZGVyKHZhbF9kcywgYmF0Y2hfc2l6ZT1hcmdzLmJhdGNoLCBzaHVmZmxlPUZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtX3dvcmtlcnM9YXJncy53b3JrZXJzLCBkcm9wX2xhc3Q9RmFsc2UpCiAgICBvcHQgPSBBZGFtVyhtb2RlbC5wYXJhbWV0ZXJzKCksIGxyPWFyZ3MubHIsIHdlaWdodF9kZWNheT0xZS00KQogICAgc2NoZWQgPSBDb3NpbmVBbm5lYWxpbmdMUihvcHQsIFRfbWF4PWFyZ3MuZXBvY2hzKQogICAgY3JpdCA9IG5uLkJDRVdpdGhMb2dpdHNMb3NzKHJlZHVjdGlvbj0ibm9uZSIpCiAgICBmb3IgZXAgaW4gcmFuZ2UoYXJncy5lcG9jaHMpOgogICAgICAgIHQwID0gdGltZS50aW1lKCkKICAgICAgICBsb3NzID0gdHJhaW5fZXBvY2gobW9kZWwsIHRyYWluX2xvYWRlciwgb3B0LCBjcml0LCBkZXZpY2UpCiAgICAgICAgc2NoZWQuc3RlcCgpCiAgICAgICAgaWYgYXJncy52ZXJib3NlOgogICAgICAgICAgICBwcmludChmIiAgZXBvY2gge2VwICsgMX0ve2FyZ3MuZXBvY2hzfSBsb3NzIHtsb3NzOi40Zn0gKHt0aW1lLnRpbWUoKSAtIHQwOi4wZn1zKSIsIGZsdXNoPVRydWUpCiAgICB2YWxfcHJlZCA9IHByZWRpY3QobW9kZWwsIHZhbF9sb2FkZXIsIGRldmljZSkKICAgICMgRElDT00g5ZG95Lit6K+K5patOuiuree7gyvpqozor4Hlt7Lov63ku6Plrozmr5Us5q2k5pe26K6h5pWw5omN5YeG56GuCiAgICB0aCwgZWgsIGF0ID0gdHJhaW5fZHMuc3RhdHMoKQogICAgdmgsIGV2LCBhdiA9IHZhbF9kcy5zdGF0cygpCiAgICBwcmludChmIlvmlbDmja5dIHRyYWluIOWRveS4rSB7dGh9L3tsZW4odHJhaW5fZHMpfSBzdHVkeSjnqboge2VofSwg5bmz5Z2HIHthdDouMWZ9IGNsaXApIHwgIgogICAgICAgICAgZiJ2YWwg5ZG95LitIHt2aH0ve2xlbih2YWxfZHMpfSBzdHVkeSjnqboge2V2fSkiLCBmbHVzaD1UcnVlKQogICAgaWYgdGggPT0gMCBvciB2aCA9PSAwOgogICAgICAgIHByaW50KCJb6K2m5ZGKXSDmnInmipggRElDT00g5YWo6YOo5rKh6K+75YiwKOWRveS4rSAwKeKAlOKAlOi+k+WFpeWwhuaYr+WFqOmbtizliIbmlbDlv4XnhLYgfjAuNSEiLCBmbHVzaD1UcnVlKQogICAgdmFsX3VpZCA9IG5wLmFycmF5KHZhbF9kcy5zdHVkaWVzKSAgIyBzaHVmZmxlPUZhbHNlLOmhuuW6j+S4juaVsOaNrumbhuS4gOiHtAogICAgcmV0dXJuIHZhbF9wcmVkLCB2YWxfdWlkCgoKIyAtLS0tLS0tLS0tLS0tLS0tIOaOqOeQhiAvIOiejeWQiCAvIOaPkOS6pCAtLS0tLS0tLS0tLS0tLS0tCgpkZWYgcHJlZGljdF90ZXN0KG1vZGVsLCB0ZXN0X2RmLCBzZXJpZXNfZGYsIHJvb3QsIGRldmljZSwgcGxhbmUsIG5fY2xpcHM9Mik6CiAgICAiIiLlr7kgdGVzdCDmr4/kuKogc3R1ZHkg5oyJ5oyH5a6a5bmz6Z2i5pS26ZuGIGNsaXBzLOmihOa1iyAxMiDkuKrmpoLnjofjgIIiIiIKICAgIGRzID0gS25lZURhdGFzZXQodGVzdF9kZlsiU3R1ZHlJbnN0YW5jZVVJRCJdLnRvbGlzdCgpLCBOb25lLCByb290LCBzZXJpZXNfZGYsCiAgICAgICAgICAgICAgICAgICAgIHBsYW5lLCBoYXNfdGFyZ2V0cz1GYWxzZSwgbl9jbGlwcz1uX2NsaXBzKQogICAgbG9hZGVyID0gRGF0YUxvYWRlcihkcywgYmF0Y2hfc2l6ZT0xNiwgc2h1ZmZsZT1GYWxzZSwgbnVtX3dvcmtlcnM9MCkKICAgIHJldHVybiBwcmVkaWN0KG1vZGVsLCBsb2FkZXIsIGRldmljZSkKCgpkZWYgcGxhbmVfb29mX2F1Yyhvb2YsIGxhYmVsc19kZiwgdWlkX2xpc3QpOgogICAgIiIi6K6h566X5LiA5Liq5bmz6Z2i5qih5Z6L5Zyo5oyH5a6aIHN0dWR5IOWtkOmbhuS4iueahOWuj+W5s+WdhyBPT0YgQVVDKOWPqueul+acieagh+azqOeahOWIlynjgIIKCiAgICBsYWJlbHNfZGYg5b+F6aG75piv44CQ5a6Y5pa5IGdvbGQg5Y6f5aeL6KGo44CRKDAvMS9OYU4s5aaCIHRyYWluX2NzdiDljp/liJcpLOS4jeiDveS8oAogICAgbG9hZF9sYWJlbHMg5aGr5YWF5ZCO55qEIHNvZnQg6KGo4oCU4oCUc29mdCDkvKrmoIfnrb7ml6LpnZ4gZ3JvdW5kIHRydXRoLOS5n+S8muiuqQogICAgcm9jX2F1Y19zY29yZSDltKkoY29udGludW91cynjgII1OCDkvovlsI/moLfmnKzkuIvmn5DliJflj6/og73lj6rmnInljZXkuIDnsbvliKss6Lez6L+H6K+l5YiX44CCCiAgICAiIiIKICAgIGF1Y3MgPSBbXQogICAgZm9yIGosIGMgaW4gZW51bWVyYXRlKExBQkVMUyk6CiAgICAgICAgeV90cnVlID0gbGFiZWxzX2RmLnNldF9pbmRleCgiU3R1ZHlJbnN0YW5jZVVJRCIpW2NdLnJlaW5kZXgodWlkX2xpc3QpLnZhbHVlcy5hc3R5cGUoZmxvYXQpCiAgICAgICAgdmFsaWQgPSB+bnAuaXNuYW4oeV90cnVlKQogICAgICAgIGlmIHZhbGlkLnN1bSgpID49IDIwOgogICAgICAgICAgICB5diA9IHlfdHJ1ZVt2YWxpZF0KICAgICAgICAgICAgaWYgbGVuKG5wLnVuaXF1ZSh5dikpIDwgMjoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGF1Y3MuYXBwZW5kKHJvY19hdWNfc2NvcmUoeXYsIG9vZlt2YWxpZCwgal0pKQogICAgcmV0dXJuIGZsb2F0KG5wLm1lYW4oYXVjcykpIGlmIGF1Y3MgZWxzZSAwLjAKCgojIC0tLS0tLS0tLS0tLS0tLS0gYXJ0aWZhY3QgLyByZXN1bWUgLyBlbnNlbWJsZSBoZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0KCmRlZiBfYXJ0aWZhY3Rfcm9vdChhcmdzKToKICAgIGJhc2UgPSBQYXRoKGdldGF0dHIoYXJncywgImFydGlmYWN0X2RpciIsICIiKSBvciAiYXJ0aWZhY3RzIikKICAgIGV4cCA9IGdldGF0dHIoYXJncywgImV4cGVyaW1lbnRfaWQiLCAiZXhwXzAwMV81Zm9sZF9zYWdpdHRhbCIpCiAgICByZXR1cm4gYmFzZSAvIGV4cAoKCmRlZiBfZm9sZF9tZXRhX3BhdGgoYXJ0aWZhY3Rfcm9vdCwgZm9sZCk6CiAgICByZXR1cm4gYXJ0aWZhY3Rfcm9vdCAvIGYiZm9sZHtmb2xkfSIgLyAibWV0YS5qc29uIgoKCmRlZiBfaXNfZm9sZF9kb25lKGFydGlmYWN0X3Jvb3QsIGZvbGQpOgogICAgcCA9IF9mb2xkX21ldGFfcGF0aChhcnRpZmFjdF9yb290LCBmb2xkKQogICAgaWYgbm90IHAuZXhpc3RzKCk6CiAgICAgICAgcmV0dXJuIEZhbHNlCiAgICB0cnk6CiAgICAgICAgbWV0YSA9IGpzb24ubG9hZHMocC5yZWFkX3RleHQoZW5jb2Rpbmc9InV0Zi04IikpCiAgICAgICAgcmV0dXJuIG1ldGEuZ2V0KCJjb21wbGV0aW9uX3N0YXR1cyIpID09ICJkb25lIgogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICByZXR1cm4gRmFsc2UKCgpkZWYgX3NhdmVfZm9sZF9hcnRpZmFjdChhcnRpZmFjdF9yb290LCBmb2xkLCB0ZXN0X3ByZWQsIHRlc3RfdWlkcywgbWV0YSk6CiAgICBmb2xkX2RpciA9IGFydGlmYWN0X3Jvb3QgLyBmImZvbGR7Zm9sZH0iCiAgICBmb2xkX2Rpci5ta2RpcihwYXJlbnRzPVRydWUsIGV4aXN0X29rPVRydWUpCiAgICBucC5zYXZlKHN0cihmb2xkX2RpciAvICJ0ZXN0X3ByZWQubnB5IiksIHRlc3RfcHJlZC5hc3R5cGUobnAuZmxvYXQzMikpCiAgICBwZC5EYXRhRnJhbWUoeyJTdHVkeUluc3RhbmNlVUlEIjogdGVzdF91aWRzfSkudG9fY3N2KAogICAgICAgIGZvbGRfZGlyIC8gInRlc3RfdWlkLmNzdiIsIGluZGV4PUZhbHNlCiAgICApCiAgICBtZXRhWyJjb21wbGV0aW9uX3N0YXR1cyJdID0gImRvbmUiCiAgICBtZXRhWyJwcmVkaWN0aW9uX3NoYXBlIl0gPSBsaXN0KHRlc3RfcHJlZC5zaGFwZSkKICAgIChmb2xkX2RpciAvICJtZXRhLmpzb24iKS53cml0ZV90ZXh0KAogICAgICAgIGpzb24uZHVtcHMobWV0YSwgZW5zdXJlX2FzY2lpPUZhbHNlLCBpbmRlbnQ9MiksIGVuY29kaW5nPSJ1dGYtOCIKICAgICkKCgpkZWYgX2xvYWRfZm9sZF9wcmVkaWN0aW9ucyhhcnRpZmFjdF9yb290LCBmb2xkLCBjYW5vbmljYWxfdWlkcyk6CiAgICBmb2xkX2RpciA9IGFydGlmYWN0X3Jvb3QgLyBmImZvbGR7Zm9sZH0iCiAgICBwcmVkID0gbnAubG9hZChmb2xkX2RpciAvICJ0ZXN0X3ByZWQubnB5IikKICAgIHVpZHMgPSBwZC5yZWFkX2Nzdihmb2xkX2RpciAvICJ0ZXN0X3VpZC5jc3YiKVsiU3R1ZHlJbnN0YW5jZVVJRCJdLnRvbGlzdCgpCiAgICBpZiBwcmVkLnNoYXBlICE9IChsZW4oY2Fub25pY2FsX3VpZHMpLCBsZW4oTEFCRUxTKSk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcihmImZvbGR7Zm9sZH0gc2hhcGUgbWlzbWF0Y2g6IHtwcmVkLnNoYXBlfSB2cyBleHBlY3RlZCB7KGxlbihjYW5vbmljYWxfdWlkcyksIGxlbihMQUJFTFMpKX0iKQogICAgaWYgdWlkcyAhPSBjYW5vbmljYWxfdWlkczoKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKGYiZm9sZHtmb2xkfSBVSUQgb3JkZXIgbWlzbWF0Y2giKQogICAgaWYgbm90IG5wLmlzZmluaXRlKHByZWQpLmFsbCgpOgogICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoZiJmb2xke2ZvbGR9IGNvbnRhaW5zIE5hTi9JbmYiKQogICAgaWYgcHJlZC5taW4oKSA8IDAgb3IgcHJlZC5tYXgoKSA+IDE6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcihmImZvbGR7Zm9sZH0gcHJlZGljdGlvbnMgb3V0IG9mIFswLDFdIikKICAgIHJldHVybiBwcmVkCgoKZGVmIF9zYXZlX2V4cGVyaW1lbnRfbWV0YShhcnRpZmFjdF9yb290LCB0cmFpbl9mb2xkX3VpZHMsIHRlc3RfdWlkcywgYXJncyk6CiAgICBtZXRhID0gewogICAgICAgICJleHBlcmltZW50X2lkIjogZ2V0YXR0cihhcmdzLCAiZXhwZXJpbWVudF9pZCIsICJleHBfMDAxXzVmb2xkX3NhZ2l0dGFsIiksCiAgICAgICAgImdpdF9jb21taXQiOiBfX2dpdF9jb21taXQoKSwKICAgICAgICAiYXJncyI6IHZhcnMoYXJncyksCiAgICAgICAgImxhYmVscyI6IExBQkVMUywKICAgICAgICAidHJhaW5fZm9sZDBfdWlkcyI6IHRyYWluX2ZvbGRfdWlkcywKICAgICAgICAidGVzdF91aWRzIjogdGVzdF91aWRzLAogICAgfQogICAgKGFydGlmYWN0X3Jvb3QgLyAiY29uZmlnLmpzb24iKS53cml0ZV90ZXh0KAogICAgICAgIGpzb24uZHVtcHMobWV0YSwgZW5zdXJlX2FzY2lpPUZhbHNlLCBpbmRlbnQ9MiksIGVuY29kaW5nPSJ1dGYtOCIKICAgICkKICAgIHBkLkRhdGFGcmFtZSh7IlN0dWR5SW5zdGFuY2VVSUQiOiB0ZXN0X3VpZHN9KS50b19jc3YoCiAgICAgICAgYXJ0aWZhY3Rfcm9vdCAvICJ0ZXN0X3VpZC5jc3YiLCBpbmRleD1GYWxzZQogICAgKQogICAgZm9sZF9yb3dzID0gW10KICAgIGZvciBrIGluIHJhbmdlKGFyZ3MuZm9sZHMpOgogICAgICAgIGZvbGRfcm93cy5hcHBlbmQoeyJmb2xkIjogaywgInRyYWluX3VpZHMiOiB0cmFpbl9mb2xkX3VpZHNba119KQogICAgcGQuRGF0YUZyYW1lKGZvbGRfcm93cykudG9fY3N2KGFydGlmYWN0X3Jvb3QgLyAiZm9sZF9hc3NpZ25tZW50LmNzdiIsIGluZGV4PUZhbHNlKQoKCmRlZiBfbWF5YmVfa2FnZ2xlX2RhdGFzZXRfdmVyc2lvbihhcnRpZmFjdF9yb290LCBtZXNzYWdlKToKICAgIGlmIG9zLmVudmlyb24uZ2V0KCJLQUdHTEVfS0VSTkVMX1JVTl9UWVBFIikgIT0gIkludGVyYWN0aXZlIjoKICAgICAgICByZXR1cm4KICAgIHNsdWcgPSBvcy5lbnZpcm9uLmdldCgiS0FHR0xFX0tFUk5FTF9TTFVHIiwgInJzbmEtYXJ0aWZhY3RzLXRtcCIpCiAgICBvd25lciA9IG9zLmVudmlyb24uZ2V0KCJLQUdHTEVfVVNFUk5BTUUiLCAieml5aW1pbmciKQogICAgZGF0YXNldF9pZCA9IGYie293bmVyfS97c2x1Z30iCiAgICB0cnk6CiAgICAgICAgc3VicHJvY2Vzcy5ydW4oCiAgICAgICAgICAgIFsKICAgICAgICAgICAgICAgICJrYWdnbGUiLAogICAgICAgICAgICAgICAgImRhdGFzZXRzIiwKICAgICAgICAgICAgICAgICJ2ZXJzaW9uIiwKICAgICAgICAgICAgICAgICItcCIsCiAgICAgICAgICAgICAgICBzdHIoYXJ0aWZhY3Rfcm9vdCksCiAgICAgICAgICAgICAgICAiLW0iLAogICAgICAgICAgICAgICAgbWVzc2FnZSwKICAgICAgICAgICAgICAgICItLWRpci1tb2RlIiwKICAgICAgICAgICAgICAgICJ0YXIiLAogICAgICAgICAgICBdLAogICAgICAgICAgICBjaGVjaz1UcnVlLAogICAgICAgICAgICBjYXB0dXJlX291dHB1dD1UcnVlLAogICAgICAgICkKICAgICAgICBwcmludChmIlthcnRpZmFjdF0gdXBsb2FkZWQgZGF0YXNldCB2ZXJzaW9uOiB7ZGF0YXNldF9pZH0iLCBmbHVzaD1UcnVlKQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHByaW50KGYiW2FydGlmYWN0XSBkYXRhc2V0IHVwbG9hZCBza2lwcGVkOiB7ZX0iLCBmbHVzaD1UcnVlKQoKCmRlZiBfX2dpdF9jb21taXQoKToKICAgIHRyeToKICAgICAgICBpbXBvcnQgc3VicHJvY2VzcwogICAgICAgIHJldHVybiBzdWJwcm9jZXNzLmNoZWNrX291dHB1dCgKICAgICAgICAgICAgWyJnaXQiLCAicmV2LXBhcnNlIiwgIkhFQUQiXSwgdGV4dD1UcnVlCiAgICAgICAgKS5zdHJpcCgpCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiAidW5rbm93biIKCgpkZWYgbWFpbigpOgogICAgYXAgPSBhcmdwYXJzZS5Bcmd1bWVudFBhcnNlcigpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tZXBvY2hzIiwgdHlwZT1pbnQsIGRlZmF1bHQ9MikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1iYXRjaCIsIHR5cGU9aW50LCBkZWZhdWx0PTgpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tbHIiLCB0eXBlPWZsb2F0LCBkZWZhdWx0PTNlLTQpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0td29ya2VycyIsIHR5cGU9aW50LCBkZWZhdWx0PTApCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tbi1jbGlwcyIsIHR5cGU9aW50LCBkZWZhdWx0PTIpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tc2VlZCIsIHR5cGU9aW50LCBkZWZhdWx0PVNFRUQpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tZm9sZHMiLCB0eXBlPWludCwgZGVmYXVsdD1GT0xEUykKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1vbmx5LWZvbGQiLCB0eXBlPWludCwgZGVmYXVsdD0tMSwKICAgICAgICAgICAgICAgICAgICBoZWxwPSLlj6rot5HmjIflrprmipgo5YW25L2Z6Lez6L+HO+m7mOiupCAtMT3lhajpg6gp44CC5o6i6Lev55SoOi0tZm9sZHMgNSAtLW9ubHktZm9sZCAwIOiureesrCAwIOaKmCIKICAgICAgICAgICAgICAgICAgICAgICAgICIodHJhaW4gNC81IOS4juato+W8j+WQjOWIhuW4gyksdGVzdCDmjqjnkIbnlKjor6XmipjmqKHlnovlh7rmj5DkuqQiKQogICAgYXAuYWRkX2FyZ3VtZW50KCItLXBsYW5lcyIsIHR5cGU9c3RyLCBkZWZhdWx0PSIsIi5qb2luKFBMQU5FUyksCiAgICAgICAgICAgICAgICAgICAgaGVscD0i6YCX5Y+35YiG6ZqU55qE5bmz6Z2i5a2Q6ZuGLOWmgiBheGlhbCxzYWdpdHRhbCjlsI/lhpks5LiN5Yy65YiG5aSn5bCP5YaZKSIpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tZnVzZSIsIHR5cGU9c3RyLCBkZWZhdWx0PSJ3ZWlnaHQiLAogICAgICAgICAgICAgICAgICAgIGNob2ljZXM9WyJ3ZWlnaHQiLCAibWVhbiJdLAogICAgICAgICAgICAgICAgICAgIGhlbHA9IuW5s+mdouiejeWQiOaWueW8jzp3ZWlnaHQ95oyJIE9PRiBBVUMg5Yqg5p2DO21lYW49566A5Y2V5bmz5Z2HIikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1wc2V1ZG8tY29uZiIsIHR5cGU9ZmxvYXQsIGRlZmF1bHQ9MC4wLAogICAgICAgICAgICAgICAgICAgIGhlbHA9IuS8quagh+etvue9ruS/oeW6pui/h+a7pOmYiOWAvCgwPeS4jei/h+a7pDswLjU95Lii5byD572u5L+h5bqmPDAuNeeahOS8quagh+etvikiKQogICAgYXAuYWRkX2FyZ3VtZW50KCItLW5vLXJlcG9ydC1sYWJlbHMiLCBhY3Rpb249InN0b3JlX3RydWUiLAogICAgICAgICAgICAgICAgICAgIGhlbHA9IuemgeeUqOWGhee9ruaKpeWRiuWFs+mUruivjei9r+agh+etvuWFnOW6lSjpu5jorqTlvIDlkK865pyq5oyC56S+5Yy65pWw5o2u6ZuG5pe2IgogICAgICAgICAgICAgICAgICAgICAgICAgIuiHquWKqOS7jiA0NDA3IOS7veaUvuWwhOaKpeWRiueUn+aIkOi9r+agh+etvizpm7bmjILovb0pIikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS12ZXJib3NlIiwgYWN0aW9uPSJzdG9yZV90cnVlIikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1wcmV0cmFpbmVkIiwgYWN0aW9uPSJzdG9yZV90cnVlIiwKICAgICAgICAgICAgICAgICAgICBoZWxwPSLlsJ3or5XkuIvovb0gSW1hZ2VOZXQg6aKE6K6t57uD5p2D6YeNKOmcgOW8gOWQryBJbnRlcm5ldCk76buY6K6k6ZqP5py65Yid5aeL5YyW5LiN6IGU572RIikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1vZmZsaW5lLXdlaWdodHMiLCB0eXBlPXN0ciwgZGVmYXVsdD0iIiwKICAgICAgICAgICAgICAgICAgICBoZWxwPSLpgJflj7fliIbpmpTnmoTnprvnur/mnYPph40gLnB0aCDot6/lvoQo5LyY5YWI57qn5pyA6auYKTvnlZnnqbrliJnoh6rliqjmiavmj4/mjILovb3nm67lvZUiKQogICAgYXAuYWRkX2FyZ3VtZW50KCItLW5vLW9mZmxpbmUtc2NhbiIsIGFjdGlvbj0ic3RvcmVfdHJ1ZSIsCiAgICAgICAgICAgICAgICAgICAgaGVscD0i56aB55So6Ieq5Yqo5omr5o+PIC9rYWdnbGUvaW5wdXQg5LiL55qE56a757q/5p2D6YeN5paH5Lu2IikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1kYXRhIiwgdHlwZT1zdHIsIGRlZmF1bHQ9IiIsCiAgICAgICAgICAgICAgICAgICAgaGVscD0i5pi+5byP5oyH5a6a5pWw5o2u5qC555uu5b2VKOWmgiBrYWdnbGVodWIuY29tcGV0aXRpb25fZG93bmxvYWQg6L+U5Zue55qEIHBhdGgpLCIKICAgICAgICAgICAgICAgICAgICAgICAgICLmjIflrprlkI7ot7Pov4foh6rliqjmn6Xmib4iKQogICAgYXAuYWRkX2FyZ3VtZW50KCItLWFydGlmYWN0LWRpciIsIHR5cGU9c3RyLCBkZWZhdWx0PSJhcnRpZmFjdHMiLAogICAgICAgICAgICAgICAgICAgIGhlbHA9ImFydGlmYWN0IOagueebruW9lSjpu5jorqQgYXJ0aWZhY3RzKSIpCiAgICBhcC5hZGRfYXJndW1lbnQoIi0tZXhwZXJpbWVudC1pZCIsIHR5cGU9c3RyLCBkZWZhdWx0PSJleHBfMDAxXzVmb2xkX3NhZ2l0dGFsIiwKICAgICAgICAgICAgICAgICAgICBoZWxwPSJleHBlcmltZW50IElEKOeUqOS6jiBhcnRpZmFjdCDlrZDnm67lvZUpIikKICAgIGFwLmFkZF9hcmd1bWVudCgiLS1yZXN1bWUtZGlyIiwgdHlwZT1zdHIsIGRlZmF1bHQ9IiIsCiAgICAgICAgICAgICAgICAgICAgaGVscD0i5bey5pyJIGFydGlmYWN0IOebruW9lSzlkK/liqjml7bmiavmj48gbWV0YS5qc29uIOi3s+i/h+W3suWujOaIkCBmb2xkIikKICAgIGFyZ3MsIF8gPSBhcC5wYXJzZV9rbm93bl9hcmdzKCkKCiAgICByZXN1bWVfcm9vdCA9IFBhdGgoYXJncy5yZXN1bWVfZGlyKSBpZiBhcmdzLnJlc3VtZV9kaXIgZWxzZSBOb25lCiAgICBpZiByZXN1bWVfcm9vdCBhbmQgYXJncy5hcnRpZmFjdF9kaXIgYW5kIG5vdCBhcmdzLmV4cGVyaW1lbnRfaWQ6CiAgICAgICAgYXJncy5leHBlcmltZW50X2lkID0gcmVzdW1lX3Jvb3QubmFtZQoKICAgIGlmIG5vdCBIQVNfVE9SQ0ggb3Igbm90IEhBU19UViBvciBub3QgSEFTX1BZRElDT006CiAgICAgICAgc3lzLmV4aXQoIuS+nei1lue8uuWksTror7flnKggS2FnZ2xlIE5vdGVib29rKEdQVSnnjq/looPov5DooYwodG9yY2gvdG9yY2h2aXNpb24vcHlkaWNvbSk75pys5Zyw5LuF5Y+v5YGa5pWw5o2u5bGC6aqM6K+B44CCIikKCiAgICBucC5yYW5kb20uc2VlZChhcmdzLnNlZWQpCiAgICB0b3JjaC5tYW51YWxfc2VlZChhcmdzLnNlZWQpCgogICAgaWYgYXJncy5kYXRhOgogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKG9zLnBhdGguam9pbihhcmdzLmRhdGEsICJ0cmFpbi5jc3YiKSk6CiAgICAgICAgICAgIHJvb3QsIG91dCA9IGFyZ3MuZGF0YSwgYXJncy5kYXRhCiAgICAgICAgICAgIHByaW50KGYiW+aVsOaNrl0g5L2/55SoIC0tZGF0YSDmjIflrprnm67lvZU6IHtyb290fSIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc3lzLmV4aXQoZiItLWRhdGEg5oyH5a6a55uu5b2VIHthcmdzLmRhdGF9IOS4i+ayoeaciSB0cmFpbi5jc3Ys6K+35qOA5p+l6Lev5b6EIikKICAgIGVsc2U6CiAgICAgICAgcm9vdCwgb3V0ID0gcmVzb2x2ZV9wYXRocygpCiAgICBwcmludChmIlvmlbDmja5dIHJvb3Q9e3Jvb3R9ICBvdXQ9e291dH0iKQoKICAgIHRyYWluX2NzdiA9IHBkLnJlYWRfY3N2KG9zLnBhdGguam9pbihyb290LCAidHJhaW4uY3N2IikpCiAgICBsYWJlbHNfZGYgPSBsb2FkX2xhYmVscyhyb290LCBwc2V1ZG9fY29uZj1hcmdzLnBzZXVkb19jb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlX3JlcG9ydF9sYWJlbHM9bm90IGFyZ3Mubm9fcmVwb3J0X2xhYmVscykKICAgIHNlcmllc19kZiA9IHBkLnJlYWRfY3N2KG9zLnBhdGguam9pbihyb290LCAidHJhaW5fc2VyaWVzLmNzdiIpKQogICAgdGVzdF9kZiA9IHBkLnJlYWRfY3N2KG9zLnBhdGguam9pbihyb290LCAidGVzdC5jc3YiKSkKICAgIHRlc3Rfc2VyaWVzID0gcGQucmVhZF9jc3Yob3MucGF0aC5qb2luKHJvb3QsICJ0ZXN0X3Nlcmllcy5jc3YiKSkKICAgIGRjbV90cmFpbiA9IG9zLnBhdGguam9pbihyb290LCAidHJhaW5fc2VyaWVzIikKICAgIGRjbV90ZXN0ID0gb3MucGF0aC5qb2luKHJvb3QsICJ0ZXN0X3NlcmllcyIpCiAgICBwcmludChmIlvmlbDmja5dIHRyYWluIHtsZW4odHJhaW5fY3N2KX0gc3R1ZHkgLyB0ZXN0IHtsZW4odGVzdF9kZil9IHN0dWR5IC8gc2VyaWVzIHtsZW4oc2VyaWVzX2RmKX0iKQogICAgX3ByaW50X2RjbV90cmVlKHJvb3QsICJESUNPTSIpICAjIOaJk+WNsCB0cmFpbl9zZXJpZXMg55yf5a6e55uu5b2V57uT5p6ELOehruiupOW4g+WxgAoKICAgIHBsYW5lcyA9IFtwLnN0cmlwKCkudGl0bGUoKSBmb3IgcCBpbiBhcmdzLnBsYW5lcy5zcGxpdCgiLCIpIGlmIHAuc3RyaXAoKV0KICAgIHBsYW5lcyA9IFtwIGZvciBwIGluIHBsYW5lcyBpZiBwIGluIFBMQU5FU10KICAgIGlmIG5vdCBwbGFuZXM6CiAgICAgICAgc3lzLmV4aXQoZiItLXBsYW5lcyDml6DmlYgs5Y+v6YCJOiB7UExBTkVTfSIpCiAgICBwcmludChmIlvlubPpnaJdIOS9v+eUqCB7cGxhbmVzfSIpCgogICAgZGV2aWNlID0gdG9yY2guZGV2aWNlKCJjdWRhIiBpZiB0b3JjaC5jdWRhLmlzX2F2YWlsYWJsZSgpIGVsc2UgImNwdSIpCiAgICBwcmludChmIlvorr7lpIddIHtkZXZpY2V9IikKCiAgICAjIOemu+e6v+mihOiuree7g+adg+mHjTrmmL7lvI/mjIflrprkvJjlhYgs5ZCm5YiZ6Ieq5Yqo5omr5o+PIC9rYWdnbGUvaW5wdXQKICAgIG9mZmxpbmVfcGF0aHMgPSBbXQogICAgaWYgYXJncy5vZmZsaW5lX3dlaWdodHMuc3RyaXAoKToKICAgICAgICBmb3IgcCBpbiBbeC5zdHJpcCgpIGZvciB4IGluIGFyZ3Mub2ZmbGluZV93ZWlnaHRzLnNwbGl0KCIsIikgaWYgeC5zdHJpcCgpXToKICAgICAgICAgICAgaWYgb3MucGF0aC5pc2ZpbGUocCk6CiAgICAgICAgICAgICAgICBvZmZsaW5lX3BhdGhzLmFwcGVuZCgocCwgcCkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBwcmludChmIlvmnYPph41dIC0tb2ZmbGluZS13ZWlnaHRzIOaMh+WumueahOaWh+S7tuS4jeWtmOWcqCzot7Pov4c6IHtwfSIsIGZsdXNoPVRydWUpCiAgICBlbGlmIG5vdCBhcmdzLm5vX29mZmxpbmVfc2NhbjoKICAgICAgICBvZmZsaW5lX3BhdGhzID0gX3NjYW5fb2ZmbGluZV93ZWlnaHRzKCkKICAgICAgICBpZiBvZmZsaW5lX3BhdGhzOgogICAgICAgICAgICBwcmludChmIlvmnYPph41dIOiHquWKqOaJq+aPj+WIsCB7bGVuKG9mZmxpbmVfcGF0aHMpfSDkuKrnprvnur/mnYPph43lgJnpgIk6IiwgZmx1c2g9VHJ1ZSkKICAgICAgICAgICAgZm9yIHAsIGRlc2MgaW4gb2ZmbGluZV9wYXRoc1s6Nl06CiAgICAgICAgICAgICAgICBwcmludChmIiAge2Rlc2N9IiwgZmx1c2g9VHJ1ZSkKICAgICAgICAgICAgaWYgbGVuKG9mZmxpbmVfcGF0aHMpID4gNjoKICAgICAgICAgICAgICAgIHByaW50KGYiICAuLi4g5YWxIHtsZW4ob2ZmbGluZV9wYXRocyl9IOS4qiIsIGZsdXNoPVRydWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcHJpbnQoIlvmnYPph41dIOacquWcqOaMgui9veebruW9leWPkeeOsOemu+e6v+adg+mHjSjlj6/mjILovb3npL7ljLrmiZPljIXnmoQgcmVzbmV0MzQg5p2D6YeN5pWw5o2u6ZuGKSIsIGZsdXNoPVRydWUpCiAgICAgICAgICAgIF9wcmludF9tb3VudF90cmVlKCIva2FnZ2xlL2lucHV0IiwgIuadg+mHjSIpCgogICAgZ2tmID0gR3JvdXBLRm9sZChuX3NwbGl0cz1hcmdzLmZvbGRzKQogICAgZ3JvdXBzID0gdHJhaW5fY3N2WyJTdHVkeUluc3RhbmNlVUlEIl0udmFsdWVzCgogICAgIyDmr4/kuKrlubPpnaLni6znq4vot5Hmipgs6K6w5b2VIE9PRiDkuI4gdGVzdCDpooTmtYsKICAgIHBsYW5lX29vZiwgcGxhbmVfdGVzdCwgcGxhbmVfYXVjLCBwbGFuZV91aWRzID0ge30sIHt9LCB7fSwge30KICAgIGZvciBwbGFuZSBpbiBwbGFuZXM6CiAgICAgICAgcHJpbnQoZiJcbiMjIyMjIyMjIyMg5bmz6Z2iOiB7cGxhbmV9ICMjIyMjIyMjIyMiKQogICAgICAgIG9vZiA9IG5wLnplcm9zKChsZW4odHJhaW5fY3N2KSwgbGVuKExBQkVMUykpKQogICAgICAgIGFydGlmYWN0X3Jvb3QgPSBfYXJ0aWZhY3Rfcm9vdChhcmdzKQogICAgICAgIGNhbm9uaWNhbF90ZXN0X3VpZHMgPSB0ZXN0X2RmWyJTdHVkeUluc3RhbmNlVUlEIl0udG9saXN0KCkKICAgICAgICB0cmFpbl9mb2xkX3VpZHMgPSBbXQogICAgICAgIGZvciBrLCAodHJfaWR4LCB2YV9pZHgpIGluIGVudW1lcmF0ZShna2Yuc3BsaXQodHJhaW5fY3N2LCBncm91cHM9Z3JvdXBzKSk6CiAgICAgICAgICAgIHRyX3N0dWRpZXMgPSB0cmFpbl9jc3YuaWxvY1t0cl9pZHhdWyJTdHVkeUluc3RhbmNlVUlEIl0udG9saXN0KCkKICAgICAgICAgICAgdmFfc3R1ZGllcyA9IHRyYWluX2Nzdi5pbG9jW3ZhX2lkeF1bIlN0dWR5SW5zdGFuY2VVSUQiXS50b2xpc3QoKQogICAgICAgICAgICB0cmFpbl9mb2xkX3VpZHMuYXBwZW5kKHRyX3N0dWRpZXMpCiAgICAgICAgICAgIGlmIGFyZ3Mub25seV9mb2xkID49IDAgYW5kIGsgIT0gYXJncy5vbmx5X2ZvbGQ6CiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBpZiByZXN1bWVfcm9vdCBhbmQgX2lzX2ZvbGRfZG9uZShhcnRpZmFjdF9yb290LCBrKToKICAgICAgICAgICAgICAgIHByaW50KGYiW2FydGlmYWN0XSBmb2xkIHtrfSBkb25lLCBza2lwIiwgZmx1c2g9VHJ1ZSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIHRyX2RzID0gS25lZURhdGFzZXQodHJfc3R1ZGllcywgbGFiZWxzX2RmLCBkY21fdHJhaW4sIHNlcmllc19kZiwgcGxhbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9jbGlwcz1hcmdzLm5fY2xpcHMpCiAgICAgICAgICAgIHZhX2RzID0gS25lZURhdGFzZXQodmFfc3R1ZGllcywgbGFiZWxzX2RmLCBkY21fdHJhaW4sIHNlcmllc19kZiwgcGxhbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9jbGlwcz1hcmdzLm5fY2xpcHMpCiAgICAgICAgICAgIG1vZGVsID0gS25lZU1vZGVsKHByZXRyYWluZWQ9YXJncy5wcmV0cmFpbmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZsaW5lX3BhdGhzPW9mZmxpbmVfcGF0aHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzPWFyZ3Mubl9jbGlwcyAqIENMSVApLnRvKGRldmljZSkKICAgICAgICAgICAgcHJpbnQoZiJb5oqYIHtrICsgMX0ve2FyZ3MuZm9sZHN9XSB7cGxhbmV9IHRyYWluIHtsZW4odHJfZHMpfSAvIHZhbCB7bGVuKHZhX2RzKX0iLCBmbHVzaD1UcnVlKQogICAgICAgICAgICB0MCA9IHRpbWUudGltZSgpCiAgICAgICAgICAgIHZhbF9wcmVkLCB2YWxfdWlkID0gcnVuX2ZvbGQobW9kZWwsIHRyX2RzLCB2YV9kcywgZGV2aWNlLCBhcmdzKQogICAgICAgICAgICBmb2xkX3RyYWluX3RpbWUgPSB0aW1lLnRpbWUoKSAtIHQwCiAgICAgICAgICAgIGZvciBqLCB1aWQgaW4gZW51bWVyYXRlKHZhbF91aWQpOgogICAgICAgICAgICAgICAgcm93ID0gbnAud2hlcmUodHJhaW5fY3N2WyJTdHVkeUluc3RhbmNlVUlEIl0udmFsdWVzID09IHVpZClbMF0KICAgICAgICAgICAgICAgIGlmIGxlbihyb3cpOgogICAgICAgICAgICAgICAgICAgIG9vZltyb3dbMF1dID0gdmFsX3ByZWRbal0KICAgICAgICAgICAgdDAgPSB0aW1lLnRpbWUoKQogICAgICAgICAgICB0ZXN0X3ByZWQgPSBwcmVkaWN0X3Rlc3QobW9kZWwsIHRlc3RfZGYsIHRlc3Rfc2VyaWVzLCBkY21fdGVzdCwgZGV2aWNlLCBwbGFuZSwgbl9jbGlwcz1hcmdzLm5fY2xpcHMpCiAgICAgICAgICAgIGZvbGRfaW5mZXJlbmNlX3RpbWUgPSB0aW1lLnRpbWUoKSAtIHQwCiAgICAgICAgICAgIG1ldGEgPSB7CiAgICAgICAgICAgICAgICAiZm9sZCI6IGssCiAgICAgICAgICAgICAgICAicGxhbmUiOiBwbGFuZSwKICAgICAgICAgICAgICAgICJuX2NsaXBzIjogYXJncy5uX2NsaXBzLAogICAgICAgICAgICAgICAgImltYWdlX3NpemUiOiBJTUdfU0laRSwKICAgICAgICAgICAgICAgICJlcG9jaHMiOiBhcmdzLmVwb2NocywKICAgICAgICAgICAgICAgICJiYXRjaF9zaXplIjogYXJncy5iYXRjaCwKICAgICAgICAgICAgICAgICJzZWVkIjogYXJncy5zZWVkLAogICAgICAgICAgICAgICAgImdpdF9jb21taXQiOiBfX2dpdF9jb21taXQoKSwKICAgICAgICAgICAgICAgICJmb2xkX3RyYWluX3RpbWVfc2VjIjogZm9sZF90cmFpbl90aW1lLAogICAgICAgICAgICAgICAgImZvbGRfaW5mZXJlbmNlX3RpbWVfc2VjIjogZm9sZF9pbmZlcmVuY2VfdGltZSwKICAgICAgICAgICAgfQogICAgICAgICAgICBfc2F2ZV9mb2xkX2FydGlmYWN0KGFydGlmYWN0X3Jvb3QsIGssIHRlc3RfcHJlZCwgY2Fub25pY2FsX3Rlc3RfdWlkcywgbWV0YSkKICAgICAgICAgICAgcHJpbnQoZiJbYXJ0aWZhY3RdIHNhdmVkIGZvbGR7a30gLT4ge2FydGlmYWN0X3Jvb3QgLyBmJ2ZvbGR7a30nfSIsIGZsdXNoPVRydWUpCiAgICAgICAgIyBleHBlcmltZW50LWxldmVsIG1ldGEgb25jZSBwZXIgcGxhbmUKICAgICAgICBfc2F2ZV9leHBlcmltZW50X21ldGEoYXJ0aWZhY3Rfcm9vdCwgdHJhaW5fZm9sZF91aWRzLCBjYW5vbmljYWxfdGVzdF91aWRzLCBhcmdzKQogICAgICAgIHByaW50KGYiW2FydGlmYWN0XSBzYXZlZCBleHBlcmltZW50IG1ldGEgLT4ge2FydGlmYWN0X3Jvb3R9IiwgZmx1c2g9VHJ1ZSkKICAgICAgICAjIOivpeW5s+mdoiBPT0YgQVVDKOWuj+W5s+WdhykKICAgICAgICB1aWRfbGlzdCA9IHRyYWluX2NzdlsiU3R1ZHlJbnN0YW5jZVVJRCJdLnRvbGlzdCgpCiAgICAgICAgaWYgYXJncy5vbmx5X2ZvbGQgPj0gMDoKICAgICAgICAgICAgcHJpbnQoZiJbe3BsYW5lfV0g5o6i6Lev5qih5byPKC0tb25seS1mb2xkIHthcmdzLm9ubHlfZm9sZH0pOk9PRiDljZXmipjkuI3lrozmlbQsIgogICAgICAgICAgICAgICAgICBmIui3s+i/hyBPT0YgQVVDKOadg+mHjeiusCAwPeWdh+etiSk7dGVzdCDmjqjnkIbnlKjor6XmipjmqKHlnosiKQogICAgICAgICAgICBhdWMgPSAwLjAKICAgICAgICBlbHNlOgogICAgICAgICAgICBhdWMgPSBwbGFuZV9vb2ZfYXVjKG9vZiwgdHJhaW5fY3N2W1siU3R1ZHlJbnN0YW5jZVVJRCJdICsgTEFCRUxTXSwgdWlkX2xpc3QpCiAgICAgICAgICAgIHByaW50KGYiW3twbGFuZX1dIE9PRiDlro/lubPlnYcgQVVDIHthdWM6LjRmfSIpCiAgICAgICAgcGxhbmVfb29mW3BsYW5lXSwgcGxhbmVfYXVjW3BsYW5lXSwgcGxhbmVfdWlkc1twbGFuZV0gPSBvb2YsIGF1YywgdWlkX2xpc3QKICAgICAgICAjIGxvYWQgc2F2ZWQgZm9sZCBwcmVkaWN0aW9ucyBmb3IgdGhpcyBwbGFuZQogICAgICAgIHBlcl9mb2xkID0gW10KICAgICAgICBtaXNzaW5nID0gW10KICAgICAgICBmb3IgayBpbiByYW5nZShhcmdzLmZvbGRzKToKICAgICAgICAgICAgcCA9IGFydGlmYWN0X3Jvb3QgLyBmImZvbGR7a30iIC8gInRlc3RfcHJlZC5ucHkiCiAgICAgICAgICAgIGlmIG5vdCBwLmV4aXN0cygpOgogICAgICAgICAgICAgICAgbWlzc2luZy5hcHBlbmQoaykKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHBlcl9mb2xkLmFwcGVuZChfbG9hZF9mb2xkX3ByZWRpY3Rpb25zKGFydGlmYWN0X3Jvb3QsIGssIGNhbm9uaWNhbF90ZXN0X3VpZHMpKQogICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgICAgICBtaXNzaW5nLmFwcGVuZChrKQogICAgICAgICAgICAgICAgcHJpbnQoZiJbZW5zZW1ibGVdIGZvbGR7a30gaW52YWxpZDoge2V9IiwgZmx1c2g9VHJ1ZSkKICAgICAgICBpZiBsZW4obWlzc2luZykgPT0gYXJncy5mb2xkczoKICAgICAgICAgICAgc3lzLmV4aXQoZiJbZW5zZW1ibGVdIG5vIHZhbGlkIGZvbGQgcHJlZGljdGlvbnMgYXZhaWxhYmxlIHVuZGVyIHthcnRpZmFjdF9yb290fSIpCiAgICAgICAgaWYgbWlzc2luZzoKICAgICAgICAgICAgcHJpbnQoZiJbZW5zZW1ibGVdIG1pc3NpbmcgZm9sZHM6IHttaXNzaW5nfTsgZW5zZW1ibGUgd2l0aCBhdmFpbGFibGUgZm9sZHMgb25seSIsIGZsdXNoPVRydWUpCiAgICAgICAgcGxhbmVfdGVzdFtwbGFuZV0gPSBucC5tZWFuKHBlcl9mb2xkLCBheGlzPTApIGlmIHBlcl9mb2xkIGVsc2UgTm9uZQogICAgICAgIGlmIHBsYW5lX3Rlc3RbcGxhbmVdIGlzIG5vdCBOb25lOgogICAgICAgICAgICBwcmludChmIltlbnNlbWJsZV0ge3BsYW5lfSBlbnNlbWJsZWQgZnJvbSB7bGVuKHBlcl9mb2xkKX0gZm9sZHMsIHNoYXBlPXtwbGFuZV90ZXN0W3BsYW5lXS5zaGFwZX0iKQoKICAgICMg6J6N5ZCICiAgICBpZiBhcmdzLmZ1c2UgPT0gIndlaWdodCI6CiAgICAgICAgd3N1bSA9IHN1bShtYXgoYSwgMWUtNikgZm9yIGEgaW4gcGxhbmVfYXVjLnZhbHVlcygpKQogICAgICAgIHdlaWdodHMgPSB7cDogbWF4KGEsIDFlLTYpIC8gd3N1bSBmb3IgcCwgYSBpbiBwbGFuZV9hdWMuaXRlbXMoKX0KICAgICAgICBwcmludChmIlvono3lkIhdIE9PRiBBVUMg5Yqg5p2DOiB7IHtwOiByb3VuZCh3LCA0KSBmb3IgcCwgdyBpbiB3ZWlnaHRzLml0ZW1zKCl9IH0iKQogICAgZWxzZToKICAgICAgICB3ZWlnaHRzID0ge3A6IDEuMCAvIGxlbihwbGFuZXMpIGZvciBwIGluIHBsYW5lc30KICAgICAgICBwcmludCgiW+iejeWQiF0g566A5Y2V5bmz5Z2HIikKICAgIGZ1c2VkID0gbnAuemVyb3NfbGlrZShwbGFuZV90ZXN0W3BsYW5lc1swXV0pCiAgICBmb3IgcCwgdyBpbiB3ZWlnaHRzLml0ZW1zKCk6CiAgICAgICAgZnVzZWQgKz0gdyAqIHBsYW5lX3Rlc3RbcF0KICAgIHN1YiA9IHBkLkRhdGFGcmFtZSh7IlN0dWR5SW5zdGFuY2VVSUQiOiB0ZXN0X2RmWyJTdHVkeUluc3RhbmNlVUlEIl0sICoqewogICAgICAgIExBQkVMU1tqXTogZnVzZWRbOiwgal0gZm9yIGogaW4gcmFuZ2UobGVuKExBQkVMUykpfX0pCiAgICBzdWJfcGF0aCA9IG9zLnBhdGguam9pbihvdXQsICJzdWJtaXNzaW9uLmNzdiIpCiAgICBzdWIudG9fY3N2KHN1Yl9wYXRoLCBpbmRleD1GYWxzZSkKICAgIHByaW50KGYiXG7mj5DkuqTmlofku7blt7LnlJ/miJA6IHtzdWJfcGF0aH0gIHNoYXBlPXtzdWIuc2hhcGV9IikKCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbWFpbigpCg==\")\npath = \"/kaggle/working/rsna_v3.py\"\nwith open(path, \"w\", encoding=\"utf-8\") as f:\n    f.write(base64.b64decode(parts[0]).decode(\"utf-8\"))\nprint(f\"wrote rsna_v3.py ({os.path.getsize(path)} bytes)\")\n","metadata":{},"outputs":[],"execution_count":null},{"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},{"cell_type":"code","source":"import subprocess, sys, os\nos.chdir(\"/kaggle/working\")\nprint(\"=== 运行 EXP-001 fold0 probe: rsna_v3.py --planes sagittal --epochs 3 --folds 5 --only-fold 0 --batch 8 --n-clips 2 --verbose ===\")\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\n# 检查 artifact 落盘\nimport glob, json\nartifact_root = \"/kaggle/working/artifacts/exp_001_5fold_sagittal\"\npatterns = [\n    f\"{artifact_root}/fold0/test_pred.npy\",\n    f\"{artifact_root}/fold0/test_uid.csv\",\n    f\"{artifact_root}/fold0/meta.json\",\n    f\"{artifact_root}/config.json\",\n    f\"{artifact_root}/fold_assignment.csv\",\n]\nfor p in patterns:\n    if os.path.exists(p):\n        size = os.path.getsize(p)\n        print(f\"[artifact] OK {p} ({size} bytes)\")\n    else:\n        print(f\"[artifact] MISSING {p}\")\n\n# 打印 meta.json 时间\nmeta_path = f\"{artifact_root}/fold0/meta.json\"\nif os.path.isfile(meta_path):\n    meta = json.load(open(meta_path, \"r\", encoding=\"utf-8\"))\n    print(\"[timing] train:\", meta.get(\"fold_train_time_sec\"), \"inference:\", meta.get(\"fold_inference_time_sec\"))\n","metadata":{},"outputs":[],"execution_count":null}]}