Калькулятор парциального давления газа
Расчёт парциального давления каждого компонента газовой смеси по закону Дальтона — через мольные доли или объёмные проценты, с выбором единиц измерения.
Результаты расчёта
—
Введите данные и нажмите «Рассчитать»
Как пользоваться калькулятором
1
Укажите общее давление газовой смеси в удобных единицах (кПа, атм, мм рт. ст., бар). Например, для сухого воздуха на уровне моря это 101,325 кПа или 1 атм.
2
Выберите режим ввода: через количество вещества (моль) или через объёмные доли (%). Для идеальных газов объёмная доля численно равна мольной доле.
3
Заполните данные для каждого компонента смеси. Минимум — два компонента. Можно добавить дополнительные кнопкой «Добавить компонент». Названия газов опциональны и нужны только для наглядности.
4
Нажмите «Рассчитать». Калькулятор проверит корректность данных, сумму долей (для объёмных процентов — 100%) и выведет парциальное давление каждого газа в выбранных единицах.
Примеры использования
Сухой атмосферный воздух (уровень моря)
Дано: Pобщ = 101,325 кПа. Азот (N₂) — 3,76 моль, Кислород (O₂) — 1,00 моль, Аргон (Ar) — 0,04 моль.
Результат: P(N₂) ≈ 79,12 кПа, P(O₂) ≈ 21,06 кПа, P(Ar) ≈ 0,84 кПа.
Газовая смесь для сварки (Ar + CO₂)
Дано: Pобщ = 150 бар. Аргон — 82% об., CO₂ — 18% об.
Результат: P(Ar) = 123 бар, P(CO₂) = 27 бар.
Дыхательная смесь для дайвинга (Nitrox 32)
Дано: Pобщ = 200 бар. Кислород — 32% об., Азот — 68% об.
Результат: P(O₂) = 64 бар, P(N₂) = 136 бар. Внимание: парциальное давление кислорода выше 1,4–1,6 бар требует осторожности при погружениях.
Важные нюансы
- Закон Дальтона справедлив для идеальных газов. При высоких давлениях и низких температурах реальные газы могут отклоняться от расчётных значений. Для технических расчётов до 10 атм точность достаточна.
- Сумма парциальных давлений всегда равна общему давлению смеси. Если результат показывает отклонение более чем на 0,5% — проверьте исходные данные.
- Объёмная доля = мольная доля только для идеальных газов при одинаковых условиях. Калькулятор использует это допущение в соответствующем режиме.
- Единицы измерения: результат выводится в тех же единицах, что и исходное общее давление. При необходимости пересчёта используйте соотношение: 1 атм = 101,325 кПа = 760 мм рт. ст. = 1,01325 бар.
- Техника безопасности: При работе с газами под давлением всегда соблюдайте правила эксплуатации баллонов и редукторов. Данный калькулятор предназначен для учебных и ознакомительных целей.
Источники данных
- IUPAC Gold Book — определение закона Дальтона и парциального давления (Dalton's law of partial pressures). IUPAC Compendium of Chemical Terminology.
- NIST Chemistry WebBook — стандартные справочные данные по термодинамическим свойствам газов. National Institute of Standards and Technology.
- CRC Handbook of Chemistry and Physics — фундаментальные константы и свойства газовых смесей, молярные массы компонентов воздуха.
- Общая химия: учебное пособие — Глинка Н.Л. «Общая химия», раздел «Газовые законы. Закон Дальтона». Расчёт основан на стандартных химических формулах и школьно-вузовских справочных значениях.
Калькулятор парциального давления газа позволяет быстро определить парциальное давление каждого компонента газовой смеси по закону Дальтона. Инструмент подходит для студентов химических и технических специальностей, инженеров, технологов, а также для специалистов по газоснабжению и дайвингу. Расчёт ведётся как через количество вещества в молях, так и через объёмные проценты — два наиболее распространённых способа задания состава смеси. Результат мгновенно выводится в выбранных единицах давления с автоматической проверкой корректности суммы долей.
CiAgICAoZnVuY3Rpb24oKSB7CiAgICAgICAgLy8g0K3Qu9C10LzQtdC90YLRiyBET00KICAgICAgICBjb25zdCB0b3RhbFByZXNzdXJlSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG90YWwtcHJlc3N1cmUnKTsKICAgICAgICBjb25zdCBwcmVzc3VyZVVuaXRTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHJlc3N1cmUtdW5pdCcpOwogICAgICAgIGNvbnN0IGNvbXBvbmVudHNDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY29tcG9uZW50cy1jb250YWluZXInKTsKICAgICAgICBjb25zdCBhZGRDb21wb25lbnRCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYWRkLWNvbXBvbmVudC1idG4nKTsKICAgICAgICBjb25zdCBjYWxjdWxhdGVCdG4gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2FsY3VsYXRlLWJ0bicpOwogICAgICAgIGNvbnN0IHJlc2V0QnRuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Jlc2V0LWJ0bicpOwogICAgICAgIGNvbnN0IHJlc3VsdHNHcmlkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Jlc3VsdHMtZ3JpZCcpOwogICAgICAgIGNvbnN0IHJlc3VsdFN1bW1hcnkgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVzdWx0LXN1bW1hcnknKTsKICAgICAgICBjb25zdCByZXN1bHRTdW1tYXJ5VGV4dCA9IHJlc3VsdFN1bW1hcnkgPyByZXN1bHRTdW1tYXJ5LnF1ZXJ5U2VsZWN0b3IoJy5ubi1nZW4tY2FsLXJlc3VsdC1zdW1tYXJ5LXRleHQnKSA6IG51bGw7CiAgICAgICAgY29uc3QgZ2xvYmFsRXJyb3IgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZ2xvYmFsLWVycm9yJyk7CiAgICAgICAgY29uc3QgdG90YWxQcmVzc3VyZUVycm9yID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RvdGFsLXByZXNzdXJlLWVycm9yJyk7CiAgICAgICAgY29uc3QgbW9kZVJhZGlvcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W25hbWU9Im1vZGUiXScpOwoKICAgICAgICBsZXQgY29tcG9uZW50Q291bnRlciA9IDI7IC8vINCd0LDRh9Cw0LvRjNC90L7QtSDQutC+0LvQuNGH0LXRgdGC0LLQviDQutC+0LzQv9C+0L3QtdC90YLQvtCyCiAgICAgICAgY29uc3QgTUFYX0NPTVBPTkVOVFMgPSAxMDsKCiAgICAgICAgLy8g0KLQtdC60YPRidC40Lkg0YDQtdC20LjQvAogICAgICAgIGZ1bmN0aW9uIGdldEN1cnJlbnRNb2RlKCkgewogICAgICAgICAgICBmb3IgKGNvbnN0IHJhZGlvIG9mIG1vZGVSYWRpb3MpIHsKICAgICAgICAgICAgICAgIGlmIChyYWRpby5jaGVja2VkKSByZXR1cm4gcmFkaW8udmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICdtb2xlcyc7CiAgICAgICAgfQoKICAgICAgICAvLyDQn9C10YDQtdC60LvRjtGH0LXQvdC40LUg0LLQuNC00LjQvNC+0YHRgtC4INC/0L7Qu9C10Lkg0LIg0LfQsNCy0LjRgdC40LzQvtGB0YLQuCDQvtGCINGA0LXQttC40LzQsAogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZUNvbXBvbmVudEZpZWxkc1Zpc2liaWxpdHkoKSB7CiAgICAgICAgICAgIGNvbnN0IG1vZGUgPSBnZXRDdXJyZW50TW9kZSgpOwogICAgICAgICAgICBjb25zdCBjb21wb25lbnRzID0gY29tcG9uZW50c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcubm4tZ2VuLWNhbC1jb21wb25lbnQnKTsKICAgICAgICAgICAgY29tcG9uZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGNvbXApIHsKICAgICAgICAgICAgICAgIGNvbnN0IG1vbGVzR3JvdXAgPSBjb21wLnF1ZXJ5U2VsZWN0b3IoJy5ubi1nZW4tY2FsLWZpZWxkLWdyb3VwOm50aC1vZi10eXBlKDIpJyk7CiAgICAgICAgICAgICAgICBjb25zdCB2b2x1bWVHcm91cCA9IGNvbXAucXVlcnlTZWxlY3RvcignLmNvbXAtdm9sdW1lLWdyb3VwJyk7CiAgICAgICAgICAgICAgICBjb25zdCBtb2xlc0lucHV0ID0gY29tcC5xdWVyeVNlbGVjdG9yKCcuY29tcC1tb2xlcy1maWVsZCcpOwogICAgICAgICAgICAgICAgY29uc3Qgdm9sdW1lSW5wdXQgPSBjb21wLnF1ZXJ5U2VsZWN0b3IoJy5jb21wLXZvbHVtZS1maWVsZCcpOwogICAgICAgICAgICAgICAgY29uc3QgbW9sZXNFcnJvciA9IGNvbXAucXVlcnlTZWxlY3RvcignLmNvbXAtZXJyb3InKTsKICAgICAgICAgICAgICAgIGNvbnN0IHZvbHVtZUVycm9yID0gY29tcC5xdWVyeVNlbGVjdG9yKCcuY29tcC12b2x1bWUtZXJyb3InKTsKCiAgICAgICAgICAgICAgICBpZiAobW9kZSA9PT0gJ21vbGVzJykgewogICAgICAgICAgICAgICAgICAgIGlmIChtb2xlc0dyb3VwKSBtb2xlc0dyb3VwLnN0eWxlLmRpc3BsYXkgPSAnJzsKICAgICAgICAgICAgICAgICAgICBpZiAodm9sdW1lR3JvdXApIHZvbHVtZUdyb3VwLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgICAgICAgICAgICAgaWYgKG1vbGVzSW5wdXQpIG1vbGVzSW5wdXQucmVxdWlyZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGlmICh2b2x1bWVJbnB1dCkgdm9sdW1lSW5wdXQucmVxdWlyZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBpZiAobW9sZXNFcnJvcikgbW9sZXNFcnJvci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOwogICAgICAgICAgICAgICAgICAgIGlmICh2b2x1bWVFcnJvcikgdm9sdW1lRXJyb3Iuc3R5bGUuZGlzcGxheSA9ICdub25lJzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG1vbGVzR3JvdXApIG1vbGVzR3JvdXAuc3R5bGUuZGlzcGxheSA9ICdub25lJzsKICAgICAgICAgICAgICAgICAgICBpZiAodm9sdW1lR3JvdXApIHZvbHVtZUdyb3VwLnN0eWxlLmRpc3BsYXkgPSAnJzsKICAgICAgICAgICAgICAgICAgICBpZiAobW9sZXNJbnB1dCkgbW9sZXNJbnB1dC5yZXF1aXJlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGlmICh2b2x1bWVJbnB1dCkgdm9sdW1lSW5wdXQucmVxdWlyZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGlmIChtb2xlc0Vycm9yKSBtb2xlc0Vycm9yLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgICAgICAgICAgICAgaWYgKHZvbHVtZUVycm9yKSB2b2x1bWVFcnJvci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIC8vINCh0L7Qt9C00LDQvdC40LUg0L3QvtCy0L7Qs9C+INC60L7QvNC/0L7QvdC10L3RgtCwCiAgICAgICAgZnVuY3Rpb24gY3JlYXRlQ29tcG9uZW50SFRNTChpbmRleCkgewogICAgICAgICAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICAgICAgICAgIGRpdi5jbGFzc05hbWUgPSAnbm4tZ2VuLWNhbC1jb21wb25lbnQnOwogICAgICAgICAgICBkaXYuc2V0QXR0cmlidXRlKCdkYXRhLWluZGV4JywgaW5kZXgpOwogICAgICAgICAgICBkaXYuaW5uZXJIVE1MID0KICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPSJubi1nZW4tY2FsLWNvbXBvbmVudC1oZWFkZXIiPicgKwogICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPSJubi1nZW4tY2FsLWNvbXBvbmVudC10aXRsZSI+0JrQvtC80L/QvtC90LXQvdGCICcgKyAoaW5kZXggKyAxKSArICc8L3NwYW4+JyArCiAgICAgICAgICAgICAgICAoaW5kZXggPj0gMiA/ICc8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5uLWdlbi1jYWwtcmVtb3ZlLWJ0biI+0KPQtNCw0LvQuNGC0Yw8L2J1dHRvbj4nIDogJycpICsKICAgICAgICAgICAgICAgICc8L2Rpdj4nICsKICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPSJubi1nZW4tY2FsLWZpZWxkLWdyb3VwIj4nICsKICAgICAgICAgICAgICAgICc8bGFiZWwgY2xhc3M9Im5uLWdlbi1jYWwtbGFiZWwiIGZvcj0iY29tcC1uYW1lLScgKyBpbmRleCArICciPtCd0LDQt9Cy0LDQvdC40LUg0LPQsNC30LAgKNC90LXQvtCx0Y/Qt9Cw0YLQtdC70YzQvdC+KTwvbGFiZWw+JyArCiAgICAgICAgICAgICAgICAnPGlucHV0IHR5cGU9InRleHQiIGlkPSJjb21wLW5hbWUtJyArIGluZGV4ICsgJyIgY2xhc3M9Im5uLWdlbi1jYWwtZmllbGQiIHBsYWNlaG9sZGVyPSLQvdCw0L/RgNC40LzQtdGALCDQk9C10LvQuNC5IiBtYXhsZW5ndGg9IjYwIj4nICsKICAgICAgICAgICAgICAgICc8L2Rpdj4nICsKICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPSJubi1nZW4tY2FsLWZpZWxkLWdyb3VwIj4nICsKICAgICAgICAgICAgICAgICc8bGFiZWwgY2xhc3M9Im5uLWdlbi1jYWwtbGFiZWwiIGZvcj0iY29tcC1tb2xlcy0nICsgaW5kZXggKyAnIj7QmtC+0LvQuNGH0LXRgdGC0LLQviDQstC10YnQtdGB0YLQstCwICjQvNC+0LvRjCk8L2xhYmVsPicgKwogICAgICAgICAgICAgICAgJzxpbnB1dCB0eXBlPSJudW1iZXIiIGlkPSJjb21wLW1vbGVzLScgKyBpbmRleCArICciIGNsYXNzPSJubi1nZW4tY2FsLWZpZWxkIGNvbXAtbW9sZXMtZmllbGQiIHBsYWNlaG9sZGVyPSIwLjAwIiBzdGVwPSJhbnkiIG1pbj0iMCIgdmFsdWU9IiI+JyArCiAgICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9Im5uLWdlbi1jYWwtZXJyb3ItbXNnIGNvbXAtZXJyb3IiIHN0eWxlPSJkaXNwbGF5Om5vbmU7Ij48L3NwYW4+JyArCiAgICAgICAgICAgICAgICAnPC9kaXY+JyArCiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz0ibm4tZ2VuLWNhbC1maWVsZC1ncm91cCBjb21wLXZvbHVtZS1ncm91cCIgc3R5bGU9ImRpc3BsYXk6bm9uZTsiPicgKwogICAgICAgICAgICAgICAgJzxsYWJlbCBjbGFzcz0ibm4tZ2VuLWNhbC1sYWJlbCIgZm9yPSJjb21wLXZvbHVtZS0nICsgaW5kZXggKyAnIj7QntCx0YrRkdC80L3QsNGPINC00L7Qu9GPICglKTwvbGFiZWw+JyArCiAgICAgICAgICAgICAgICAnPGlucHV0IHR5cGU9Im51bWJlciIgaWQ9ImNvbXAtdm9sdW1lLScgKyBpbmRleCArICciIGNsYXNzPSJubi1nZW4tY2FsLWZpZWxkIGNvbXAtdm9sdW1lLWZpZWxkIiBwbGFjZWhvbGRlcj0iMC4wMCIgc3RlcD0iYW55IiBtaW49IjAiIG1heD0iMTAwIiB2YWx1ZT0iIj4nICsKICAgICAgICAgICAgICAgICc8c3BhbiBjbGFzcz0ibm4tZ2VuLWNhbC1lcnJvci1tc2cgY29tcC12b2x1bWUtZXJyb3IiIHN0eWxlPSJkaXNwbGF5Om5vbmU7Ij48L3NwYW4+JyArCiAgICAgICAgICAgICAgICAnPC9kaXY+JzsKICAgICAgICAgICAgcmV0dXJuIGRpdjsKICAgICAgICB9CgogICAgICAgIC8vINCU0L7QsdCw0LLQu9C10L3QuNC1INC60L7QvNC/0L7QvdC10L3RgtCwCiAgICAgICAgZnVuY3Rpb24gYWRkQ29tcG9uZW50KCkgewogICAgICAgICAgICBpZiAoY29tcG9uZW50Q291bnRlciA+PSBNQVhfQ09NUE9ORU5UUykgewogICAgICAgICAgICAgICAgc2hvd0dsb2JhbEVycm9yKCfQnNCw0LrRgdC40LzQsNC70YzQvdC+0LUg0LrQvtC70LjRh9C10YHRgtCy0L4g0LrQvtC80L/QvtC90LXQvdGC0L7QsiDigJQgJyArIE1BWF9DT01QT05FTlRTKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbmV3Q29tcCA9IGNyZWF0ZUNvbXBvbmVudEhUTUwoY29tcG9uZW50Q291bnRlcik7CiAgICAgICAgICAgIGNvbXBvbmVudHNDb250YWluZXIuYXBwZW5kQ2hpbGQobmV3Q29tcCk7CiAgICAgICAgICAgIGNvbXBvbmVudENvdW50ZXIrKzsKICAgICAgICAgICAgdXBkYXRlQ29tcG9uZW50RmllbGRzVmlzaWJpbGl0eSgpOwogICAgICAgICAgICB1cGRhdGVSZW1vdmVCdXR0b25zKCk7CiAgICAgICAgICAgIGF0dGFjaFJlbW92ZUV2ZW50cygpOwogICAgICAgIH0KCiAgICAgICAgLy8g0J7QsdC90L7QstC70LXQvdC40LUg0LrQvdC+0L/QvtC6INGD0LTQsNC70LXQvdC40Y8gKNC80LjQvdC40LzRg9C8IDIg0LrQvtC80L/QvtC90LXQvdGC0LApCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlUmVtb3ZlQnV0dG9ucygpIHsKICAgICAgICAgICAgdmFyIGNvbXBvbmVudHMgPSBjb21wb25lbnRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5ubi1nZW4tY2FsLWNvbXBvbmVudCcpOwogICAgICAgICAgICBjb21wb25lbnRzLmZvckVhY2goZnVuY3Rpb24oY29tcCkgewogICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gcGFyc2VJbnQoY29tcC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaW5kZXgnKSwgMTApOwogICAgICAgICAgICAgICAgdmFyIGhlYWRlciA9IGNvbXAucXVlcnlTZWxlY3RvcignLm5uLWdlbi1jYWwtY29tcG9uZW50LWhlYWRlcicpOwogICAgICAgICAgICAgICAgdmFyIGV4aXN0aW5nQnRuID0gY29tcC5xdWVyeVNlbGVjdG9yKCcubm4tZ2VuLWNhbC1yZW1vdmUtYnRuJyk7CiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPj0gMiAmJiBjb21wb25lbnRzLmxlbmd0aCA+IDIpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWV4aXN0aW5nQnRuICYmIGhlYWRlcikgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYnRuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ0bi50eXBlID0gJ2J1dHRvbic7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ0bi5jbGFzc05hbWUgPSAnbm4tZ2VuLWNhbC1yZW1vdmUtYnRuJzsKICAgICAgICAgICAgICAgICAgICAgICAgYnRuLnRleHRDb250ZW50ID0gJ9Cj0LTQsNC70LjRgtGMJzsKICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyLmFwcGVuZENoaWxkKGJ0bik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ29tcG9uZW50KGNvbXApOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ0J0bikgZXhpc3RpbmdCdG4ucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLy8g0KPQtNCw0LvQtdC90LjQtSDQutC+0LzQv9C+0L3QtdC90YLQsAogICAgICAgIGZ1bmN0aW9uIHJlbW92ZUNvbXBvbmVudChjb21wRWxlbWVudCkgewogICAgICAgICAgICB2YXIgY29tcG9uZW50cyA9IGNvbXBvbmVudHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnLm5uLWdlbi1jYWwtY29tcG9uZW50Jyk7CiAgICAgICAgICAgIGlmIChjb21wb25lbnRzLmxlbmd0aCA8PSAyKSByZXR1cm47CiAgICAgICAgICAgIGNvbXBFbGVtZW50LnJlbW92ZSgpOwogICAgICAgICAgICByZWluZGV4Q29tcG9uZW50cygpOwogICAgICAgICAgICB1cGRhdGVSZW1vdmVCdXR0b25zKCk7CiAgICAgICAgfQoKICAgICAgICAvLyDQn9C10YDQtdC90YPQvNC10YDQsNGG0LjRjyDQv9C+0YHQu9C1INGD0LTQsNC70LXQvdC40Y8KICAgICAgICBmdW5jdGlvbiByZWluZGV4Q29tcG9uZW50cygpIHsKICAgICAgICAgICAgdmFyIGNvbXBvbmVudHMgPSBjb21wb25lbnRzQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5ubi1nZW4tY2FsLWNvbXBvbmVudCcpOwogICAgICAgICAgICBjb21wb25lbnRzLmZvckVhY2goZnVuY3Rpb24oY29tcCwgaWR4KSB7CiAgICAgICAgICAgICAgICBjb21wLnNldEF0dHJpYnV0ZSgnZGF0YS1pbmRleCcsIGlkeCk7CiAgICAgICAgICAgICAgICB2YXIgdGl0bGVTcGFuID0gY29tcC5xdWVyeVNlbGVjdG9yKCcubm4tZ2VuLWNhbC1jb21wb25lbnQtdGl0bGUnKTsKICAgICAgICAgICAgICAgIGlmICh0aXRsZVNwYW4pIHRpdGxlU3Bhbi50ZXh0Q29udGVudCA9ICfQmtC+0LzQv9C+0L3QtdC90YIgJyArIChpZHggKyAxKTsKICAgICAgICAgICAgICAgIHZhciBuYW1lSW5wdXQgPSBjb21wLnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W3R5cGU9InRleHQiXScpOwogICAgICAgICAgICAgICAgdmFyIG1vbGVzSW5wdXQgPSBjb21wLnF1ZXJ5U2VsZWN0b3IoJy5jb21wLW1vbGVzLWZpZWxkJyk7CiAgICAgICAgICAgICAgICB2YXIgdm9sdW1lSW5wdXQgPSBjb21wLnF1ZXJ5U2VsZWN0b3IoJy5jb21wLXZvbHVtZS1maWVsZCcpOwogICAgICAgICAgICAgICAgaWYgKG5hbWVJbnB1dCkgbmFtZUlucHV0LmlkID0gJ2NvbXAtbmFtZS0nICsgaWR4OwogICAgICAgICAgICAgICAgaWYgKG1vbGVzSW5wdXQpIG1vbGVzSW5wdXQuaWQgPSAnY29tcC1tb2xlcy0nICsgaWR4OwogICAgICAgICAgICAgICAgaWYgKHZvbHVtZUlucHV0KSB2b2x1bWVJbnB1dC5pZCA9ICdjb21wLXZvbHVtZS0nICsgaWR4OwogICAgICAgICAgICAgICAgdmFyIGxhYmVscyA9IGNvbXAucXVlcnlTZWxlY3RvckFsbCgnbGFiZWwnKTsKICAgICAgICAgICAgICAgIGxhYmVscy5mb3JFYWNoKGZ1bmN0aW9uKGxibCkgewogICAgICAgICAgICAgICAgICAgIGlmIChsYmwuaHRtbEZvciAmJiBsYmwuaHRtbEZvci5pbmRleE9mKCdjb21wLW5hbWUtJykgIT09IC0xKSBsYmwuaHRtbEZvciA9ICdjb21wLW5hbWUtJyArIGlkeDsKICAgICAgICAgICAgICAgICAgICBpZiAobGJsLmh0bWxGb3IgJiYgbGJsLmh0bWxGb3IuaW5kZXhPZignY29tcC1tb2xlcy0nKSAhPT0gLTEpIGxibC5odG1sRm9yID0gJ2NvbXAtbW9sZXMtJyArIGlkeDsKICAgICAgICAgICAgICAgICAgICBpZiAobGJsLmh0bWxGb3IgJiYgbGJsLmh0bWxGb3IuaW5kZXhPZignY29tcC12b2x1bWUtJykgIT09IC0xKSBsYmwuaHRtbEZvciA9ICdjb21wLXZvbHVtZS0nICsgaWR4OwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBjb21wb25lbnRDb3VudGVyID0gY29tcG9uZW50cy5sZW5ndGg7CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBhdHRhY2hSZW1vdmVFdmVudHMoKSB7CiAgICAgICAgICAgIHZhciByZW1vdmVCdG5zID0gY29tcG9uZW50c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcubm4tZ2VuLWNhbC1yZW1vdmUtYnRuJyk7CiAgICAgICAgICAgIHJlbW92ZUJ0bnMuZm9yRWFjaChmdW5jdGlvbihidG4pIHsKICAgICAgICAgICAgICAgIGJ0bi5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHJlbW92ZUhhbmRsZXIpOwogICAgICAgICAgICAgICAgYnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgcmVtb3ZlSGFuZGxlcik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gcmVtb3ZlSGFuZGxlcihlKSB7CiAgICAgICAgICAgIHZhciBidG4gPSBlLnRhcmdldDsKICAgICAgICAgICAgdmFyIGNvbXAgPSBidG4uY2xvc2VzdCgnLm5uLWdlbi1jYWwtY29tcG9uZW50Jyk7CiAgICAgICAgICAgIGlmIChjb21wKSByZW1vdmVDb21wb25lbnQoY29tcCk7CiAgICAgICAgfQoKICAgICAgICAvLyDQodC60YDRi9GC0Ywg0LLRgdC1INC+0YjQuNCx0LrQuAogICAgICAgIGZ1bmN0aW9uIGhpZGVBbGxFcnJvcnMoKSB7CiAgICAgICAgICAgIGlmIChnbG9iYWxFcnJvcikgZ2xvYmFsRXJyb3Iuc3R5bGUuZGlzcGxheSA9ICdub25lJzsKICAgICAgICAgICAgaWYgKHRvdGFsUHJlc3N1cmVFcnJvcikgdG90YWxQcmVzc3VyZUVycm9yLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgICAgIHZhciBhbGxDb21wRXJyb3JzID0gY29tcG9uZW50c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuY29tcC1lcnJvciwgLmNvbXAtdm9sdW1lLWVycm9yJyk7CiAgICAgICAgICAgIGFsbENvbXBFcnJvcnMuZm9yRWFjaChmdW5jdGlvbihlbCkgeyBlbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOyB9KTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIHNob3dHbG9iYWxFcnJvcihtc2cpIHsKICAgICAgICAgICAgaWYgKGdsb2JhbEVycm9yKSB7CiAgICAgICAgICAgICAgICBnbG9iYWxFcnJvci50ZXh0Q29udGVudCA9IG1zZzsKICAgICAgICAgICAgICAgIGdsb2JhbEVycm9yLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBzaG93VG90YWxQcmVzc3VyZUVycm9yKG1zZykgewogICAgICAgICAgICBpZiAodG90YWxQcmVzc3VyZUVycm9yKSB7CiAgICAgICAgICAgICAgICB0b3RhbFByZXNzdXJlRXJyb3IudGV4dENvbnRlbnQgPSBtc2c7CiAgICAgICAgICAgICAgICB0b3RhbFByZXNzdXJlRXJyb3Iuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIHNob3dDb21wb25lbnRFcnJvcihjb21wLCBtb2RlLCBtc2cpIHsKICAgICAgICAgICAgaWYgKG1vZGUgPT09ICdtb2xlcycpIHsKICAgICAgICAgICAgICAgIHZhciBlcnJFbCA9IGNvbXAucXVlcnlTZWxlY3RvcignLmNvbXAtZXJyb3InKTsKICAgICAgICAgICAgICAgIGlmIChlcnJFbCkgewogICAgICAgICAgICAgICAgICAgIGVyckVsLnRleHRDb250ZW50ID0gbXNnOwogICAgICAgICAgICAgICAgICAgIGVyckVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGVyckVsID0gY29tcC5xdWVyeVNlbGVjdG9yKCcuY29tcC12b2x1bWUtZXJyb3InKTsKICAgICAgICAgICAgICAgIGlmIChlcnJFbCkgewogICAgICAgICAgICAgICAgICAgIGVyckVsLnRleHRDb250ZW50ID0gbXNnOwogICAgICAgICAgICAgICAgICAgIGVyckVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyDQktCw0LvQuNC00LDRhtC40Y8g0Lgg0YDQsNGB0YfRkdGCCiAgICAgICAgZnVuY3Rpb24gY2FsY3VsYXRlKCkgewogICAgICAgICAgICBoaWRlQWxsRXJyb3JzKCk7CgogICAgICAgICAgICAvLyDQn9GA0L7QstC10YDQutCwINC+0LHRidC10LPQviDQtNCw0LLQu9C10L3QuNGPCiAgICAgICAgICAgIHZhciB0b3RhbFByZXNzdXJlUmF3ID0gdG90YWxQcmVzc3VyZUlucHV0LnZhbHVlLnRyaW0oKTsKICAgICAgICAgICAgaWYgKHRvdGFsUHJlc3N1cmVSYXcgPT09ICcnKSB7CiAgICAgICAgICAgICAgICBzaG93VG90YWxQcmVzc3VyZUVycm9yKCfQktCy0LXQtNC40YLQtSDQvtCx0YnQtdC1INC00LDQstC70LXQvdC40LUg0YHQvNC10YHQuC4nKTsKICAgICAgICAgICAgICAgIHRvdGFsUHJlc3N1cmVJbnB1dC5mb2N1cygpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB0b3RhbFByZXNzdXJlID0gcGFyc2VGbG9hdCh0b3RhbFByZXNzdXJlUmF3KTsKICAgICAgICAgICAgaWYgKGlzTmFOKHRvdGFsUHJlc3N1cmUpIHx8IHRvdGFsUHJlc3N1cmUgPD0gMCkgewogICAgICAgICAgICAgICAgc2hvd1RvdGFsUHJlc3N1cmVFcnJvcign0J7QsdGJ0LXQtSDQtNCw0LLQu9C10L3QuNC1INC00L7Qu9C20L3QviDQsdGL0YLRjCDQv9C+0LvQvtC20LjRgtC10LvRjNC90YvQvCDRh9C40YHQu9C+0LwuJyk7CiAgICAgICAgICAgICAgICB0b3RhbFByZXNzdXJlSW5wdXQuZm9jdXMoKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodG90YWxQcmVzc3VyZSA+IDFlNikgewogICAgICAgICAgICAgICAgc2hvd1RvdGFsUHJlc3N1cmVFcnJvcign0KHQu9C40YjQutC+0Lwg0LHQvtC70YzRiNC+0LUg0LfQvdCw0YfQtdC90LjQtSDQtNCw0LLQu9C10L3QuNGPLiDQn9GA0L7QstC10YDRjNGC0LUg0LTQsNC90L3Ri9C1LicpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbW9kZSA9IGdldEN1cnJlbnRNb2RlKCk7CiAgICAgICAgICAgIHZhciBjb21wb25lbnRzID0gY29tcG9uZW50c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcubm4tZ2VuLWNhbC1jb21wb25lbnQnKTsKICAgICAgICAgICAgdmFyIGNvbXBEYXRhID0gW107CgogICAgICAgICAgICBpZiAobW9kZSA9PT0gJ21vbGVzJykgewogICAgICAgICAgICAgICAgdmFyIHRvdGFsTW9sZXMgPSAwOwogICAgICAgICAgICAgICAgdmFyIGFsbFZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29tcG9uZW50cy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBjb21wID0gY29tcG9uZW50c1tpXTsKICAgICAgICAgICAgICAgICAgICB2YXIgbW9sZXNJbnB1dCA9IGNvbXAucXVlcnlTZWxlY3RvcignLmNvbXAtbW9sZXMtZmllbGQnKTsKICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZUlucHV0ID0gY29tcC5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPSJ0ZXh0Il0nKTsKICAgICAgICAgICAgICAgICAgICB2YXIgcmF3VmFsID0gbW9sZXNJbnB1dCA/IG1vbGVzSW5wdXQudmFsdWUudHJpbSgpIDogJyc7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJhd1ZhbCA9PT0gJycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0NvbXBvbmVudEVycm9yKGNvbXAsICdtb2xlcycsICfQktCy0LXQtNC40YLQtSDQutC+0LvQuNGH0LXRgdGC0LLQviDQstC10YnQtdGB0YLQstCwLicpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWxsVmFsaWQgJiYgbW9sZXNJbnB1dCkgbW9sZXNJbnB1dC5mb2N1cygpOwogICAgICAgICAgICAgICAgICAgICAgICBhbGxWYWxpZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbCA9IHBhcnNlRmxvYXQocmF3VmFsKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYU4odmFsKSB8fCB2YWwgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dDb21wb25lbnRFcnJvcihjb21wLCAnbW9sZXMnLCAn0JrQvtC70LjRh9C10YHRgtCy0L4g0LLQtdGJ0LXRgdGC0LLQsCDQtNC+0LvQttC90L4g0LHRi9GC0Ywg0L3QtdC+0YLRgNC40YbQsNGC0LXQu9GM0L3Ri9C8INGH0LjRgdC70L7QvC4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFsbFZhbGlkICYmIG1vbGVzSW5wdXQpIG1vbGVzSW5wdXQuZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgYWxsVmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBuYW1lID0gbmFtZUlucHV0ID8gbmFtZUlucHV0LnZhbHVlLnRyaW0oKSA6ICcnOwogICAgICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSAnJykgbmFtZSA9ICfQmtC+0LzQv9C+0L3QtdC90YIgJyArIChpICsgMSk7CiAgICAgICAgICAgICAgICAgICAgY29tcERhdGEucHVzaCh7IG5hbWU6IG5hbWUsIHZhbHVlOiB2YWwgfSk7CiAgICAgICAgICAgICAgICAgICAgdG90YWxNb2xlcyArPSB2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWFsbFZhbGlkKSByZXR1cm47CiAgICAgICAgICAgICAgICBpZiAodG90YWxNb2xlcyA8PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgc2hvd0dsb2JhbEVycm9yKCfQodGD0LzQvNCw0YDQvdC+0LUg0LrQvtC70LjRh9C10YHRgtCy0L4g0LLQtdGJ0LXRgdGC0LLQsCDQtNC+0LvQttC90L4g0LHRi9GC0Ywg0LHQvtC70YzRiNC1INC90YPQu9GPLicpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vINCg0LDRgdGH0ZHRgiDQv9Cw0YDRhtC40LDQu9GM0L3Ri9GFINC00LDQstC70LXQvdC40LkKICAgICAgICAgICAgICAgIGRpc3BsYXlSZXN1bHRzKGNvbXBEYXRhLCB0b3RhbE1vbGVzLCB0b3RhbFByZXNzdXJlLCAnbW9sZXMnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vINCe0LHRitGR0LzQvdGL0LUg0LTQvtC70LgKICAgICAgICAgICAgICAgIHZhciB0b3RhbFZvbHVtZVBlcmNlbnQgPSAwOwogICAgICAgICAgICAgICAgdmFyIGFsbFZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgY29tcG9uZW50cy5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHZhciBjb21wViA9IGNvbXBvbmVudHNbal07CiAgICAgICAgICAgICAgICAgICAgdmFyIHZvbHVtZUlucHV0ID0gY29tcFYucXVlcnlTZWxlY3RvcignLmNvbXAtdm9sdW1lLWZpZWxkJyk7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5hbWVJbnB1dFYgPSBjb21wVi5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPSJ0ZXh0Il0nKTsKICAgICAgICAgICAgICAgICAgICB2YXIgcmF3VmFsViA9IHZvbHVtZUlucHV0ID8gdm9sdW1lSW5wdXQudmFsdWUudHJpbSgpIDogJyc7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJhd1ZhbFYgPT09ICcnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dDb21wb25lbnRFcnJvcihjb21wViwgJ3ZvbHVtZScsICfQktCy0LXQtNC40YLQtSDQvtCx0YrRkdC80L3Rg9GOINC00L7Qu9GOLicpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWxsVmFsaWQgJiYgdm9sdW1lSW5wdXQpIHZvbHVtZUlucHV0LmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFsbFZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgdmFsViA9IHBhcnNlRmxvYXQocmF3VmFsVik7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmFOKHZhbFYpIHx8IHZhbFYgPCAwIHx8IHZhbFYgPiAxMDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0NvbXBvbmVudEVycm9yKGNvbXBWLCAndm9sdW1lJywgJ9Ce0LHRitGR0LzQvdCw0Y8g0LTQvtC70Y8g0LTQvtC70LbQvdCwINCx0YvRgtGMINGH0LjRgdC70L7QvCDQvtGCIDAg0LTQviAxMDAlLicpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWxsVmFsaWQgJiYgdm9sdW1lSW5wdXQpIHZvbHVtZUlucHV0LmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFsbFZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZVYgPSBuYW1lSW5wdXRWID8gbmFtZUlucHV0Vi52YWx1ZS50cmltKCkgOiAnJzsKICAgICAgICAgICAgICAgICAgICBpZiAobmFtZVYgPT09ICcnKSBuYW1lViA9ICfQmtC+0LzQv9C+0L3QtdC90YIgJyArIChqICsgMSk7CiAgICAgICAgICAgICAgICAgICAgY29tcERhdGEucHVzaCh7IG5hbWU6IG5hbWVWLCB2YWx1ZTogdmFsViB9KTsKICAgICAgICAgICAgICAgICAgICB0b3RhbFZvbHVtZVBlcmNlbnQgKz0gdmFsVjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghYWxsVmFsaWQpIHJldHVybjsKICAgICAgICAgICAgICAgIGlmIChNYXRoLmFicyh0b3RhbFZvbHVtZVBlcmNlbnQgLSAxMDApID4gMC41KSB7CiAgICAgICAgICAgICAgICAgICAgc2hvd0dsb2JhbEVycm9yKCfQodGD0LzQvNCwINC+0LHRitGR0LzQvdGL0YUg0LTQvtC70LXQuSDQtNC+0LvQttC90LAg0LHRi9GC0Ywg0YDQsNCy0L3QsCAxMDAlICjRgdC10LnRh9Cw0YE6ICcgKyB0b3RhbFZvbHVtZVBlcmNlbnQudG9GaXhlZCgyKSArICclKS4g0J/RgNC+0LLQtdGA0YzRgtC1INC00LDQvdC90YvQtS4nKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodG90YWxWb2x1bWVQZXJjZW50IDw9IDApIHsKICAgICAgICAgICAgICAgICAgICBzaG93R2xvYmFsRXJyb3IoJ9Ch0YPQvNC80LAg0L7QsdGK0ZHQvNC90YvRhSDQtNC+0LvQtdC5INC00L7Qu9C20L3QsCDQsdGL0YLRjCDQsdC+0LvRjNGI0LUg0L3Rg9C70Y8uJyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGlzcGxheVJlc3VsdHMoY29tcERhdGEsIHRvdGFsVm9sdW1lUGVyY2VudCwgdG90YWxQcmVzc3VyZSwgJ3ZvbHVtZScpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBkaXNwbGF5UmVzdWx0cyhjb21wRGF0YSwgdG90YWxWYWx1ZSwgdG90YWxQcmVzc3VyZSwgbW9kZSkgewogICAgICAgICAgICB2YXIgdW5pdCA9IHByZXNzdXJlVW5pdFNlbGVjdC52YWx1ZTsKICAgICAgICAgICAgdmFyIHVuaXRMYWJlbCA9IGdldFVuaXRMYWJlbCh1bml0KTsKICAgICAgICAgICAgdmFyIGh0bWwgPSAnJzsKICAgICAgICAgICAgdmFyIHN1bVBhcnRpYWxQcmVzc3VyZSA9IDA7CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBEYXRhLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgZnJhY3Rpb247CiAgICAgICAgICAgICAgICBpZiAobW9kZSA9PT0gJ21vbGVzJykgewogICAgICAgICAgICAgICAgICAgIGZyYWN0aW9uID0gY29tcERhdGFbaV0udmFsdWUgLyB0b3RhbFZhbHVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBmcmFjdGlvbiA9IGNvbXBEYXRhW2ldLnZhbHVlIC8gMTAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHBhcnRpYWxQcmVzc3VyZSA9IGZyYWN0aW9uICogdG90YWxQcmVzc3VyZTsKICAgICAgICAgICAgICAgIHN1bVBhcnRpYWxQcmVzc3VyZSArPSBwYXJ0aWFsUHJlc3N1cmU7CiAgICAgICAgICAgICAgICB2YXIgZm9ybWF0dGVkUHJlc3N1cmUgPSBmb3JtYXROdW1iZXIocGFydGlhbFByZXNzdXJlKTsKICAgICAgICAgICAgICAgIGh0bWwgKz0gJzxkaXYgY2xhc3M9Im5uLWdlbi1jYWwtcmVzdWx0LWl0ZW0iPicgKwogICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPSJubi1nZW4tY2FsLXJlc3VsdC12YWx1ZSI+JyArIGZvcm1hdHRlZFByZXNzdXJlICsgJzwvZGl2PicgKwogICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPSJubi1nZW4tY2FsLXJlc3VsdC1sYWJlbCI+JyArIGVzY2FwZUhUTUwoY29tcERhdGFbaV0ubmFtZSkgKyAnPC9kaXY+JyArCiAgICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9Im5uLWdlbi1jYWwtcmVzdWx0LXVuaXQiPicgKyB1bml0TGFiZWwgKyAnPC9kaXY+JyArCiAgICAgICAgICAgICAgICAgICAgJzwvZGl2Pic7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vINCh0YLRgNC+0LrQsCDRgSDRgdGD0LzQvNC+0LkKICAgICAgICAgICAgdmFyIGRpZmZlcmVuY2UgPSBNYXRoLmFicyhzdW1QYXJ0aWFsUHJlc3N1cmUgLSB0b3RhbFByZXNzdXJlKTsKICAgICAgICAgICAgdmFyIHRvbGVyYW5jZSA9IE1hdGgubWF4KDAuMDA1LCB0b3RhbFByZXNzdXJlICogMC4wMDEpOwogICAgICAgICAgICB2YXIgc3VtQ2hlY2tUZXh0ID0gJyc7CiAgICAgICAgICAgIGlmIChkaWZmZXJlbmNlIDw9IHRvbGVyYW5jZSkgewogICAgICAgICAgICAgICAgc3VtQ2hlY2tUZXh0ID0gJ+KckyDQodGD0LzQvNCwINC/0LDRgNGG0LjQsNC70YzQvdGL0YUg0LTQsNCy0LvQtdC90LjQuSDRgdC+0LLQv9Cw0LTQsNC10YIg0YEg0L7QsdGJ0LjQvCDQtNCw0LLQu9C10L3QuNC10LwgKCcgKyBmb3JtYXROdW1iZXIodG90YWxQcmVzc3VyZSkgKyAnICcgKyB1bml0TGFiZWwgKyAnKS4nOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3VtQ2hlY2tUZXh0ID0gJ+KaoCDQodGD0LzQvNCwINC/0LDRgNGG0LjQsNC70YzQvdGL0YUg0LTQsNCy0LvQtdC90LjQuTogJyArIGZvcm1hdE51bWJlcihzdW1QYXJ0aWFsUHJlc3N1cmUpICsgJyAnICsgdW5pdExhYmVsICsgJyAo0L7RgtC60LvQvtC90LXQvdC40LUgJyArIGZvcm1hdE51bWJlcihkaWZmZXJlbmNlKSArICcgJyArIHVuaXRMYWJlbCArICcpLic7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJlc3VsdHNHcmlkLmlubmVySFRNTCA9IGh0bWw7CiAgICAgICAgICAgIGlmIChyZXN1bHRTdW1tYXJ5ICYmIHJlc3VsdFN1bW1hcnlUZXh0KSB7CiAgICAgICAgICAgICAgICByZXN1bHRTdW1tYXJ5VGV4dC50ZXh0Q29udGVudCA9IHN1bUNoZWNrVGV4dDsKICAgICAgICAgICAgICAgIHJlc3VsdFN1bW1hcnkuc3R5bGUuZGlzcGxheSA9ICcnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhpZGVBbGxFcnJvcnMoKTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGdldFVuaXRMYWJlbCh1bml0KSB7CiAgICAgICAgICAgIHN3aXRjaCAodW5pdCkgewogICAgICAgICAgICAgICAgY2FzZSAna3BhJzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ9C60J/QsCc7CiAgICAgICAgICAgICAgICBjYXNlICdhdG0nOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAn0LDRgtC8JzsKICAgICAgICAgICAgICAgIGNhc2UgJ21taGcnOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAn0LzQvCDRgNGCLiDRgdGCLic7CiAgICAgICAgICAgICAgICBjYXNlICdiYXInOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAn0LHQsNGAJzsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuaXQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGZvcm1hdE51bWJlcihudW0pIHsKICAgICAgICAgICAgaWYgKG51bSA9PT0gMCkgcmV0dXJuICcwJzsKICAgICAgICAgICAgaWYgKE1hdGguYWJzKG51bSkgPj0gMTAwMCkgcmV0dXJuIG51bS50b0ZpeGVkKDEpOwogICAgICAgICAgICBpZiAoTWF0aC5hYnMobnVtKSA+PSAxMDApIHJldHVybiBudW0udG9GaXhlZCgyKTsKICAgICAgICAgICAgaWYgKE1hdGguYWJzKG51bSkgPj0gMSkgcmV0dXJuIG51bS50b0ZpeGVkKDMpOwogICAgICAgICAgICBpZiAoTWF0aC5hYnMobnVtKSA+PSAwLjAxKSByZXR1cm4gbnVtLnRvRml4ZWQoNCk7CiAgICAgICAgICAgIHJldHVybiBudW0udG9FeHBvbmVudGlhbCg0KTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGVzY2FwZUhUTUwoc3RyKSB7CiAgICAgICAgICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgICAgICAgICAgZGl2LnRleHRDb250ZW50ID0gc3RyOwogICAgICAgICAgICByZXR1cm4gZGl2LmlubmVySFRNTDsKICAgICAgICB9CgogICAgICAgIC8vINCh0LHRgNC+0YEKICAgICAgICBmdW5jdGlvbiByZXNldEFsbCgpIHsKICAgICAgICAgICAgaGlkZUFsbEVycm9ycygpOwogICAgICAgICAgICB0b3RhbFByZXNzdXJlSW5wdXQudmFsdWUgPSAnMTAxLjMyNSc7CiAgICAgICAgICAgIHByZXNzdXJlVW5pdFNlbGVjdC52YWx1ZSA9ICdrcGEnOwogICAgICAgICAgICAvLyDQodCx0YDQvtGBINGA0LXQttC40LzQsCDQvdCwINC80L7Qu9C4CiAgICAgICAgICAgIG1vZGVSYWRpb3MuZm9yRWFjaChmdW5jdGlvbihyKSB7IHIuY2hlY2tlZCA9IChyLnZhbHVlID09PSAnbW9sZXMnKTsgfSk7CiAgICAgICAgICAgIC8vINCj0LTQsNC70Y/QtdC8INCy0YHQtSDQutC+0LzQv9C+0L3QtdC90YLRiyDQutGA0L7QvNC1INC/0LXRgNCy0YvRhSDQtNCy0YPRhQogICAgICAgICAgICB2YXIgY29tcG9uZW50cyA9IGNvbXBvbmVudHNDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnLm5uLWdlbi1jYWwtY29tcG9uZW50Jyk7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSBjb21wb25lbnRzLmxlbmd0aCAtIDE7IGkgPj0gMjsgaS0tKSB7CiAgICAgICAgICAgICAgICBjb21wb25lbnRzW2ldLnJlbW92ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbXBvbmVudENvdW50ZXIgPSAyOwogICAgICAgICAgICAvLyDQodCx0YDQvtGBINC/0L7Qu9C10Lkg0L/QtdGA0LLRi9GFINC00LLRg9GFINC60L7QvNC/0L7QvdC10L3RgtC+0LIKICAgICAgICAgICAgdmFyIGZpcnN0VHdvID0gY29tcG9uZW50c0NvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcubm4tZ2VuLWNhbC1jb21wb25lbnQnKTsKICAgICAgICAgICAgaWYgKGZpcnN0VHdvLmxlbmd0aCA+PSAyKSB7CiAgICAgICAgICAgICAgICB2YXIgY29tcDAgPSBmaXJzdFR3b1swXTsKICAgICAgICAgICAgICAgIHZhciBjb21wMSA9IGZpcnN0VHdvWzFdOwogICAgICAgICAgICAgICAgdmFyIG5hbWUwID0gY29tcDAucXVlcnlTZWxlY3RvcignaW5wdXRbdHlwZT0idGV4dCJdJyk7CiAgICAgICAgICAgICAgICB2YXIgbmFtZTEgPSBjb21wMS5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPSJ0ZXh0Il0nKTsKICAgICAgICAgICAgICAgIHZhciBtb2xlczAgPSBjb21wMC5xdWVyeVNlbGVjdG9yKCcuY29tcC1tb2xlcy1maWVsZCcpOwogICAgICAgICAgICAgICAgdmFyIG1vbGVzMSA9IGNvbXAxLnF1ZXJ5U2VsZWN0b3IoJy5jb21wLW1vbGVzLWZpZWxkJyk7CiAgICAgICAgICAgICAgICB2YXIgdm9sMCA9IGNvbXAwLnF1ZXJ5U2VsZWN0b3IoJy5jb21wLXZvbHVtZS1maWVsZCcpOwogICAgICAgICAgICAgICAgdmFyIHZvbDEgPSBjb21wMS5xdWVyeVNlbGVjdG9yKCcuY29tcC12b2x1bWUtZmllbGQnKTsKICAgICAgICAgICAgICAgIGlmIChuYW1lMCkgbmFtZTAudmFsdWUgPSAnJzsKICAgICAgICAgICAgICAgIGlmIChuYW1lMSkgbmFtZTEudmFsdWUgPSAnJzsKICAgICAgICAgICAgICAgIGlmIChtb2xlczApIG1vbGVzMC52YWx1ZSA9ICczLjc2JzsKICAgICAgICAgICAgICAgIGlmIChtb2xlczEpIG1vbGVzMS52YWx1ZSA9ICcxLjAwJzsKICAgICAgICAgICAgICAgIGlmICh2b2wwKSB2b2wwLnZhbHVlID0gJzc5JzsKICAgICAgICAgICAgICAgIGlmICh2b2wxKSB2b2wxLnZhbHVlID0gJzIxJzsKICAgICAgICAgICAgfQogICAgICAgICAgICB1cGRhdGVDb21wb25lbnRGaWVsZHNWaXNpYmlsaXR5KCk7CiAgICAgICAgICAgIHVwZGF0ZVJlbW92ZUJ1dHRvbnMoKTsKICAgICAgICAgICAgcmVzdWx0c0dyaWQuaW5uZXJIVE1MID0gJzxkaXYgY2xhc3M9Im5uLWdlbi1jYWwtcmVzdWx0LWl0ZW0iPjxkaXYgY2xhc3M9Im5uLWdlbi1jYWwtcmVzdWx0LXZhbHVlIj7igJQ8L2Rpdj48ZGl2IGNsYXNzPSJubi1nZW4tY2FsLXJlc3VsdC1sYWJlbCI+0JLQstC10LTQuNGC0LUg0LTQsNC90L3Ri9C1INC4INC90LDQttC80LjRgtC1IMKr0KDQsNGB0YHRh9C40YLQsNGC0YzCuzwvZGl2PjxkaXYgY2xhc3M9Im5uLWdlbi1jYWwtcmVzdWx0LXVuaXQiPjwvZGl2PjwvZGl2Pic7CiAgICAgICAgICAgIGlmIChyZXN1bHRTdW1tYXJ5KSByZXN1bHRTdW1tYXJ5LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAgICAgfQoKICAgICAgICAvLyDQntCx0YDQsNCx0L7RgtGH0LjQutC4INGB0L7QsdGL0YLQuNC5CiAgICAgICAgYWRkQ29tcG9uZW50QnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYWRkQ29tcG9uZW50KTsKICAgICAgICBjYWxjdWxhdGVCdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBjYWxjdWxhdGUpOwogICAgICAgIHJlc2V0QnRuLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgcmVzZXRBbGwpOwoKICAgICAgICBtb2RlUmFkaW9zLmZvckVhY2goZnVuY3Rpb24ocmFkaW8pIHsKICAgICAgICAgICAgcmFkaW8uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB1cGRhdGVDb21wb25lbnRGaWVsZHNWaXNpYmlsaXR5KCk7CiAgICAgICAgICAgICAgICBoaWRlQWxsRXJyb3JzKCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0pOwoKICAgICAgICAvLyDQmNC90LjRhtC40LDQu9C40LfQsNGG0LjRjwogICAgICAgIHVwZGF0ZUNvbXBvbmVudEZpZWxkc1Zpc2liaWxpdHkoKTsKICAgICAgICB1cGRhdGVSZW1vdmVCdXR0b25zKCk7CiAgICB9KSgpOwo=