공고 2,696건
아파트 분양가 추이
2020년부터 청약홈 공고의 분양가를 시도·연도별로 묶었습니다.
전국 민영 (2026(~10월))
2,613만원
전용 평당 · 84㎡ 약 6.6억
서울 민영 (2026(~10월))
7,948만원
84㎡ 약 20.2억
전국 2020년 대비
+46%
2020년 1,784만원
분석한 공고
2,696건
2020.01 ~ 26.10
- 민영 아파트 분양가(전용 평당, 주택형 최고가 기준)는 전국 2020년 1,784만원 → 2026(~10월) 2,613만원으로 +46%입니다. 전용 84㎡로 환산하면 약 4.5억 → 6.6억입니다.
- 서울은 3,379만원 → 7,948만원(+135%), 84㎡ 환산 약 20.2억입니다.
- 경기는 1,868만원 → 2,810만원(+50%)입니다.
- 공급(공고 기준 총 세대)은 2020년 234,039세대, 2025년 148,745세대였습니다.
시도별 연도별 분양가 (민영, 전용 평당 · 만원)
칸 아래 작은 숫자는 공고 수입니다. 공고가 5건 안 되는 해는 비웠습니다. 고가 단지 몇 곳이 한 해 값을 크게 끌어올리기도 합니다. 2026*는 10월 공고까지. 84㎡ 환산은 가장 최근 값으로 계산했습니다.
| 지역 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026* | 84㎡ 환산 |
|---|---|---|---|---|---|---|---|---|
| 전국 | 1,784415건 | 1,722456건 | 1,967447건 | 2,202270건 | 2,451306건 | 2,583260건 | 2,613218건 | 6.6억 |
| 수도권 | 2,127182건 | 1,885165건 | 2,227173건 | 2,820140건 | 2,778150건 | 2,773122건 | 3,085107건 | 7.8억 |
| 지방 | 1,525233건 | 1,577291건 | 1,840274건 | 1,888130건 | 2,174156건 | 2,227138건 | 2,263111건 | 5.8억 |
| 서울 | 3,37931건 | 3,79913건 | 4,39819건 | 4,86432건 | 6,53333건 | 6,33917건 | 7,94823건 | 20.2억 |
| 경기 | 1,868120건 | 1,818114건 | 2,123120건 | 2,57684건 | 2,45092건 | 2,74282건 | 2,81066건 | 7.1억 |
| 인천 | 2,09031건 | 2,19638건 | 2,13834건 | 2,30624건 | 2,64225건 | 2,50423건 | 2,96718건 | 7.5억 |
| 부산 | 1,94731건 | 2,15522건 | 2,30422건 | 2,68820건 | 2,99024건 | 3,26929건 | 3,12519건 | 7.9억 |
| 대구 | 2,12748건 | 2,13447건 | 2,42429건 | —1건 | 2,85711건 | 3,1759건 | —4건 | 8.1억 |
| 광주 | 1,76810건 | 2,05114건 | 2,29113건 | 2,61416건 | 2,60315건 | 2,5129건 | 2,6926건 | 6.8억 |
| 대전 | 1,5028건 | 1,86411건 | 2,02915건 | 2,3246건 | 2,50117건 | 2,4807건 | 2,6657건 | 6.8억 |
| 울산 | 2,03311건 | 1,7169건 | 2,62815건 | 2,5358건 | 2,82014건 | 2,81715건 | 2,9229건 | 7.4억 |
| 세종 | —1건 | —4건 | —4건 | —0건 | —0건 | —2건 | —1건 | — |
| 강원 | 1,24111건 | 1,33622건 | 1,72717건 | 2,11912건 | 1,87711건 | 2,2067건 | 2,1496건 | 5.5억 |
| 충북 | 1,1649건 | 1,22215건 | 1,39820건 | 1,63212건 | 1,7959건 | 1,9247건 | —2건 | 4.9억 |
| 충남 | 1,23627건 | 1,31628건 | 1,67126건 | 1,69612건 | 1,80720건 | 2,02513건 | 2,22221건 | 5.6억 |
| 전북 | 1,11213건 | 1,29020건 | 1,36016건 | 1,4999건 | 1,60210건 | 2,0117건 | 2,0005건 | 5.1억 |
| 전남 | 1,27118건 | 1,30520건 | 1,52424건 | —4건 | 1,79810건 | 1,6337건 | —4건 | 4.1억 |
| 경북 | 1,28721건 | 1,41431건 | 1,65622건 | 1,6588건 | —4건 | 1,71810건 | 1,9826건 | 5.0억 |
| 경남 | 1,39918건 | 1,43337건 | 1,71331건 | 1,70513건 | 1,7668건 | 1,97013건 | 2,09415건 | 5.3억 |
| 제주 | 2,1467건 | 2,34411건 | 2,51120건 | 2,1399건 | —3건 | —3건 | 2,3826건 | 6.1억 |
최근 1년 평당 분양가 높은 공고 TOP 20
| # | 단지 | 지역 | 공고일 | 평당(전용) | 84㎡ 환산 | |
|---|---|---|---|---|---|---|
| 1 | 써밋 더힐 | 서울 | 26-05-15 | 12,270만 | 31.2억 | |
| 2 | 반포 래미안 트리니원 | 서울 | 25-10-31 | 11,516만 | 29.3억 | 상한제 |
| 3 | 역삼센트럴자이 | 서울 | 25-12-05 | 10,944만 | 27.8억 | 상한제 |
| 4 | 드파인 아르티아 | 서울 | 26-06-19 | 10,862만 | 27.6억 | |
| 5 | 더샵 분당하이스트 | 경기 | 26-09-11 | 10,834만 | 27.5억 | |
| 6 | 오티에르 반포 | 서울 | 26-03-31 | 10,727만 | 27.3억 | 상한제 |
| 7 | 아크로 리버스카이 | 서울 | 26-05-13 | 10,687만 | 27.2억 | |
| 8 | 아크로 드 서초 | 서울 | 26-03-20 | 10,384만 | 26.4억 | 상한제 |
| 9 | 써밋 클라비온 | 서울 | 26-08-07 | 10,210만 | 25.9억 | |
| 10 | 라클라체자이드파인 | 서울 | 26-04-03 | 10,058만 | 25.6억 | |
| 11 | 더샵 분당티에르원 | 경기 | 25-10-31 | 9,887만 | 25.1억 | |
| 12 | 충정로역자이르네 | 서울 | 26-08-07 | 9,548만 | 24.3억 | |
| 13 | 공덕역자이르네 | 서울 | 26-04-17 | 9,441만 | 24.0억 | |
| 14 | 동작 센트럴 동문 디 이스트 | 서울 | 26-07-02 | 9,054만 | 23.0억 | |
| 15 | 이촌 르엘 | 서울 | 26-03-30 | 8,905만 | 22.6억 | 상한제 |
| 16 | 더샵 분당센트로 | 경기 | 25-12-31 | 8,416만 | 21.4억 | |
| 17 | 더샵 신길센트럴시티 | 서울 | 26-03-20 | 7,948만 | 20.2억 | |
| 18 | 래미안 엘라비네 | 서울 | 26-03-06 | 7,135만 | 18.1억 | |
| 19 | 월계 중흥S-클래스 리비에르 | 서울 | 26-07-16 | 6,965만 | 17.7억 | |
| 20 | 장위 푸르지오 마크원 | 서울 | 26-06-19 | 6,887만 | 17.5억 |
연도별 분양 공고·공급 세대
민영·공공을 합친 아파트 분양주택 공고 수와 공고에 적힌 총 공급 세대입니다(임대 제외).
| 연도 | 공고 | 공급 세대 |
|---|---|---|
| 2020 | 462 | 234,039 |
| 2021 | 485 | 254,482 |
| 2022 | 508 | 237,172 |
| 2023 | 312 | 138,726 |
| 2024 | 347 | 164,148 |
| 2025 | 329 | 148,745 |
| 2026(~10월) | 253 | 117,683 |
이 숫자는 무엇인가요
- 한국부동산원 청약홈의 아파트 입주자모집공고(분양주택, 임대 제외)에서 주택형별 최고 분양가를 전용면적 평으로 나눴습니다. 같은 단지라도 저층은 이보다 싸고, 발코니 확장비·옵션은 빠져 있어 실제 부담은 더 큽니다.
- 공고 하나의 평당가는 주택형별 값을 공급 세대로 가중한 중앙값이고, 지역·연도 값은 그 공고별 평당가의 중앙값입니다(공고 한 건이 한 표). 평균이 아니라 가운데 값이라 초고가 단지 한두 곳의 영향이 줄어듭니다.
- 민영 주택만 줄 세웠습니다. 국민주택·공공분양(신혼희망타운·토지임대부 등)은 가격 체계가 달라 섞지 않았습니다.
- 공식 통계인 HUG ‘민간아파트 분양가격 동향'(공급면적 기준 평균)과는 기준이 달라 숫자가 다릅니다. 전용 기준이라 공급면적 기준보다 높게 보입니다.
- ’84㎡ 환산’은 평당가에 전용 84㎡(약 25.4평)를 곱한 참고값입니다.
관련: 입주 예정 아파트 · 지금 분양 중인 공고 · 분양가 대비 지금 시세 · 청약 일정 · 경쟁률 순위. 출처: 한국부동산원 청약홈 분양정보(공공데이터포털). 매일 아침 갱신.
자주 묻는 질문
서울 아파트 분양가는 평당 얼마인가요?
2026(~10월) 청약홈 공고 기준 서울 민영 아파트의 전용 평당 분양가(주택형 최고가 기준, 공고별 중앙값)는 7,948만원입니다. 전용 84㎡로 환산하면 약 20.2억입니다. 발코니 확장비·옵션은 포함되지 않습니다.
분양가는 몇 년 사이 얼마나 올랐나요?
전국 민영 아파트 기준 2020년 1,784만원에서 2026(~10월) 2,613만원으로 +46% 변했습니다(전용 평당).
dmFyIFRIRU1FX0lDTz1mdW5jdGlvbih0KXtyZXR1cm4gdD09PSdkYXJrJz8nPHN2ZyBjbGFzcz0idHBoLWkgaWNvLXMiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMS43IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGFyaWEtaGlkZGVuPSJ0cnVlIj48cGF0aCBkPSJNMjAgMTQuNUE4LjUgOC41IDAgMCAxIDkuNSA0YTguNSA4LjUgMCAxIDAgMTAuNSAxMC41eiIvPjwvc3ZnPic6dD09PSdsaWdodCc/JzxzdmcgY2xhc3M9InRwaC1pIGljby1zIiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjEuNyIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBhcmlhLWhpZGRlbj0idHJ1ZSI+PHBhdGggZD0iTTEyIDcuNWE0LjUgNC41IDAgMSAwIDAgOSA0LjUgNC41IDAgMCAwIDAtOXpNMTIgMnYyTTEyIDIwdjJNNC4yIDQuMmwxLjQgMS40TTE4LjQgMTguNGwxLjQgMS40TTIgMTJoMk0yMCAxMmgyTTQuMiAxOS44bDEuNC0xLjRNMTguNCA1LjZsMS40LTEuNCIvPjwvc3ZnPic6JzxzdmcgY2xhc3M9InRwaC1pIGljby1zIiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjEuNyIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBhcmlhLWhpZGRlbj0idHJ1ZSI+PHBhdGggZD0iTTEyIDNhOSA5IDAgMSAwIDAgMTggOSA5IDAgMCAwIDAtMTh6TTEyIDN2MThhOSA5IDAgMCAwIDAtMTh6Ii8+PC9zdmc+Jzt9OwoKdmFyICQ9ZnVuY3Rpb24oaSl7cmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0cGgtJytpKTt9Owp2YXIgdj1mdW5jdGlvbihpKXt2YXIgZT0kKGkpO3JldHVybiBlPygrZS52YWx1ZXx8MCk6MDt9Owp2YXIgcz1mdW5jdGlvbihpKXt2YXIgZT0kKGkpO3JldHVybiBlP2UudmFsdWU6Jyc7fTsKdmFyIGY9ZnVuY3Rpb24obil7cmV0dXJuIE1hdGgucm91bmQobikudG9Mb2NhbGVTdHJpbmcoJ2tvLUtSJykrJ+ybkCc7fTsKdmFyIGZkPWZ1bmN0aW9uKG4sZCl7cmV0dXJuIG4udG9Mb2NhbGVTdHJpbmcoJ2tvLUtSJyx7bWF4aW11bUZyYWN0aW9uRGlnaXRzOmR8fDF9KTt9Owp2YXIgY3V0MTA9ZnVuY3Rpb24oeCl7cmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yb3VuZCh4KS8xMCkqMTA7fTsKdmFyIHNldD1mdW5jdGlvbihpLHQpe3ZhciBlPSQoaSk7aWYoIWUpcmV0dXJuO2lmKGk9PT0nbWFpbicpe2NvdW50VXAoZSx0KTt9ZWxzZXtlLnRleHRDb250ZW50PXQ7fX07CgovKiDslYjsoITtlZwg7KCA7J6l7IaMIOygkeq3vCDigJQg7Iuc7YGs66a/IOuqqOuTnC/ssKjri6gg7ZmY6rK97JeQ7ISc64+EIOyjveyngCDslYrqsowgKi8KdmFyIHN0b3JlPXsKICBnZXQ6ZnVuY3Rpb24oayl7dHJ5e3JldHVybiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShrKTt9Y2F0Y2goZSl7cmV0dXJuIG51bGw7fX0sCiAgc2V0OmZ1bmN0aW9uKGssdmFsKXt0cnl7bG9jYWxTdG9yYWdlLnNldEl0ZW0oayx2YWwpO31jYXRjaChlKXt9fSwKICBkZWw6ZnVuY3Rpb24oayl7dHJ5e2xvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGspO31jYXRjaChlKXt9fQp9OwoKdmFyIHRvYXN0PWZ1bmN0aW9uKG1zZyl7CiAgdmFyIHQ9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRwaC10b2FzdCcpOwogIGlmKCF0KXt0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO3QuY2xhc3NOYW1lPSd0cGgtdG9hc3QnO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodCk7fQogIHQudGV4dENvbnRlbnQ9bXNnO3QuY2xhc3NMaXN0LmFkZCgnc2hvdycpOwogIGNsZWFyVGltZW91dCh0Ll9oKTt0Ll9oPXNldFRpbWVvdXQoZnVuY3Rpb24oKXt0LmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTt9LDE5MDApOwp9OwoKLyog7YWM66eIIO2GoOq4gDog7Iuc7Iqk7YWcIOyEpOyglSDihpIg65287J207Yq4IOKGkiDri6Ttgawg7Iic7ZmYICovCmZ1bmN0aW9uIGluaXRUaGVtZShyb290KXsKICB2YXIgSz0ndHBoLXRoZW1lJywgY3VyPXN0b3JlLmdldChLKTsKICBpZihjdXIpIHJvb3Quc2V0QXR0cmlidXRlKCdkYXRhLXRoZW1lJyxjdXIpOwogIHZhciBiPSQoJ3RoZW1lJyk7CiAgaWYoIWIpIHJldHVybjsKICB2YXIgbGFiZWw9ZnVuY3Rpb24oKXsKICAgIHZhciB0PXJvb3QuZ2V0QXR0cmlidXRlKCdkYXRhLXRoZW1lJyk7CiAgICBiLmlubmVySFRNTD1USEVNRV9JQ08odCkrJyA8c3Bhbj4nKyh0PT09J2RhcmsnPyfri6TtgawnOnQ9PT0nbGlnaHQnPyfrnbzsnbTtirgnOifsnpDrj5knKSsnPC9zcGFuPic7CiAgfTsKICBsYWJlbCgpOwogIGIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGZ1bmN0aW9uKCl7CiAgICB2YXIgdD1yb290LmdldEF0dHJpYnV0ZSgnZGF0YS10aGVtZScpOwogICAgdmFyIG54PSF0PydsaWdodCc6dD09PSdsaWdodCc/J2RhcmsnOicnOwogICAgaWYobngpe3Jvb3Quc2V0QXR0cmlidXRlKCdkYXRhLXRoZW1lJyxueCk7c3RvcmUuc2V0KEssbngpO30KICAgIGVsc2V7cm9vdC5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnKTtzdG9yZS5kZWwoSyk7fQogICAgbGFiZWwoKTsKICB9KTsKfQoKLyog7J6F66Cl6rCSIOKGlCBVUkwg7YyM652866+47YSwIOKGlCBsb2NhbFN0b3JhZ2UgKi8KZnVuY3Rpb24gaW5pdFN0YXRlKHNsdWcsIGlkcywgb25jaGFuZ2UpewogIHZhciBLRVk9J3RwaC1pbi0nK3NsdWcsIHE9bmV3IFVSTFNlYXJjaFBhcmFtcyhsb2NhdGlvbi5zZWFyY2gpLCB1c2VkPWZhbHNlOwogIGlkcy5mb3JFYWNoKGZ1bmN0aW9uKGkpewogICAgdmFyIGU9JChpKTsgaWYoIWUpIHJldHVybjsKICAgIGlmKHEuaGFzKGkpKXsgZS52YWx1ZT1xLmdldChpKTsgdXNlZD10cnVlOyB9CiAgfSk7CiAgaWYoIXVzZWQpewogICAgdmFyIHJhdz1zdG9yZS5nZXQoS0VZKTsKICAgIGlmKHJhdyl7IHRyeXsgdmFyIG89SlNPTi5wYXJzZShyYXcpOwogICAgICBpZHMuZm9yRWFjaChmdW5jdGlvbihpKXsgdmFyIGU9JChpKTsgaWYoZSYmb1tpXSE9PXVuZGVmaW5lZCYmb1tpXSE9PScnKSBlLnZhbHVlPW9baV07IH0pOwogICAgfWNhdGNoKGUpe30gfQogIH0KICB2YXIgc2F2ZT1mdW5jdGlvbigpewogICAgdmFyIG89e307IGlkcy5mb3JFYWNoKGZ1bmN0aW9uKGkpeyB2YXIgZT0kKGkpOyBpZihlKSBvW2ldPWUudmFsdWU7IH0pOwogICAgc3RvcmUuc2V0KEtFWSwgSlNPTi5zdHJpbmdpZnkobykpOwogIH07CiAgdmFyIHNoYXJlPSQoJ3NoYXJlJyk7CiAgaWYoc2hhcmUpIHNoYXJlLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJyxmdW5jdGlvbigpewogICAgdmFyIHA9bmV3IFVSTFNlYXJjaFBhcmFtcygpOwogICAgaWRzLmZvckVhY2goZnVuY3Rpb24oaSl7IHZhciBlPSQoaSk7IGlmKGUpIHAuc2V0KGksZS52YWx1ZSk7IH0pOwogICAgdmFyIHVybD1sb2NhdGlvbi5vcmlnaW4rbG9jYXRpb24ucGF0aG5hbWUrJz8nK3AudG9TdHJpbmcoKTsKICAgIHZhciBkb25lPWZ1bmN0aW9uKCl7dG9hc3QoJ+unge2BrOulvCDrs7XsgqztlojsirXri4jri6QnKTt9OwogICAgaWYobmF2aWdhdG9yLmNsaXBib2FyZCYmbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQpewogICAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dCh1cmwpLnRoZW4oZG9uZSxmdW5jdGlvbigpe3Byb21wdCgn7JWE656YIOyjvOyGjOulvCDrs7XsgqztlZjshLjsmpQnLHVybCk7fSk7CiAgICB9IGVsc2UgcHJvbXB0KCfslYTrnpgg7KO87IaM66W8IOuzteyCrO2VmOyEuOyalCcsdXJsKTsKICB9KTsKICB2YXIgY29weT0kKCdjb3B5Jyk7CiAgaWYoY29weSkgY29weS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsZnVuY3Rpb24oKXsKICAgIHZhciBsaW5lcz1bZG9jdW1lbnQudGl0bGUuc3BsaXQoJ3wnKVswXS50cmltKCldOwogICAgaWRzLmZvckVhY2goZnVuY3Rpb24oaSl7CiAgICAgIHZhciBlPSQoaSk7IGlmKCFlKSByZXR1cm47CiAgICAgIHZhciBsYWI9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbGFiZWxbZm9yPXRwaC0nK2krJ10nKTsKICAgICAgdmFyIHZhbD1lLnRhZ05hbWU9PT0nU0VMRUNUJz9lLm9wdGlvbnNbZS5zZWxlY3RlZEluZGV4XS50ZXh0OigrZS52YWx1ZXx8MCkudG9Mb2NhbGVTdHJpbmcoJ2tvLUtSJyk7CiAgICAgIGlmKGxhYikgbGluZXMucHVzaCgnwrcgJytsYWIudGV4dENvbnRlbnQudHJpbSgpKyc6ICcrdmFsKTsKICAgIH0pOwogICAgbGluZXMucHVzaCgnJyk7CiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudHBoLXRvdGFsJykuZm9yRWFjaChmdW5jdGlvbih0KXsKICAgICAgdmFyIGw9dC5xdWVyeVNlbGVjdG9yKCcubCcpLCB2YWw9dC5xdWVyeVNlbGVjdG9yKCcudicpOwogICAgICBpZihsJiZ2YWwpIGxpbmVzLnB1c2gobC50ZXh0Q29udGVudC50cmltKCkrJzogJyt2YWwudGV4dENvbnRlbnQudHJpbSgpKTsKICAgIH0pOwogICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnRwaC1wYWdlIHRhYmxlJykuZm9yRWFjaChmdW5jdGlvbih0Yil7CiAgICAgIHRiLnF1ZXJ5U2VsZWN0b3JBbGwoJ3RyJykuZm9yRWFjaChmdW5jdGlvbih0cil7CiAgICAgICAgdmFyIHRkPXRyLnF1ZXJ5U2VsZWN0b3JBbGwoJ3RkJyk7CiAgICAgICAgaWYodGQubGVuZ3RoPT09MikgbGluZXMucHVzaCgnwrcgJyt0ZFswXS50ZXh0Q29udGVudC50cmltKCkrJzogJyt0ZFsxXS50ZXh0Q29udGVudC50cmltKCkpOwogICAgICB9KTsKICAgIH0pOwogICAgbGluZXMucHVzaCgnJywgbG9jYXRpb24ub3JpZ2luK2xvY2F0aW9uLnBhdGhuYW1lKTsKICAgIHZhciB0eHQ9bGluZXMuam9pbignXG4nKTsKICAgIHZhciBkb25lPWZ1bmN0aW9uKCl7dG9hc3QoJ+qysOqzvOulvCDrs7XsgqztlojsirXri4jri6QnKTt9OwogICAgaWYobmF2aWdhdG9yLmNsaXBib2FyZCYmbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQpIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHR4dCkudGhlbihkb25lLGRvbmUpOwogICAgZWxzZSB7IHZhciB0YT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpOyB0YS52YWx1ZT10eHQ7IGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGEpOwogICAgICAgICAgIHRhLnNlbGVjdCgpOyB0cnl7ZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2NvcHknKTt9Y2F0Y2goZSl7fSB0YS5yZW1vdmUoKTsgZG9uZSgpOyB9CiAgfSk7CiAgdmFyIHJlc2V0PSQoJ3Jlc2V0Jyk7CiAgaWYocmVzZXQpIHJlc2V0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJyxmdW5jdGlvbigpewogICAgc3RvcmUuZGVsKEtFWSk7IGxvY2F0aW9uLmhyZWY9bG9jYXRpb24ucGF0aG5hbWU7CiAgfSk7CiAgcmV0dXJuIHNhdmU7Cn0KCi8qIOq4iOyVoSDsnoXroKUg67CRIOu5oOuluCDsobDsoJUg7LmpICovCmZ1bmN0aW9uIGluaXRDaGlwcyhvbmNoYW5nZSl7CiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnRwaC1jaGlwJykuZm9yRWFjaChmdW5jdGlvbihjKXsKICAgIGMuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGZ1bmN0aW9uKCl7CiAgICAgIHZhciBlPSQoYy5kYXRhc2V0LnQpOyBpZighZSkgcmV0dXJuOwogICAgICB2YXIgZD1jLmRhdGFzZXQuZDsKICAgICAgZS52YWx1ZSA9IGQ9PT0nMCcgPyAwIDogTWF0aC5tYXgoMCwoK2UudmFsdWV8fDApKygrZCkpOwogICAgICBvbmNoYW5nZSgpOwogICAgfSk7CiAgfSk7Cn0KCi8qIOyeheugpeqwkuydhCDsgqzrnozsnbQg7J2964qUIOusuOyepeycvOuhnCAoMywwMDAsMDAwIOKGkiAzMDDrp4zsm5ApICovCmZ1bmN0aW9uIGtvck1vbmV5KG4pewogIG49TWF0aC5yb3VuZChuKTsgaWYoIW4pIHJldHVybiAnMOybkCc7CiAgdmFyIGVvaz1NYXRoLmZsb29yKG4vMTAwMDAwMDAwKSwgbWFuPU1hdGguZmxvb3IoKG4lMTAwMDAwMDAwKS8xMDAwMCksIHdvbj1uJTEwMDAwLCBwPVtdOwogIGlmKGVvaykgcC5wdXNoKGVvaysn7Ja1Jyk7CiAgaWYobWFuKSBwLnB1c2gobWFuLnRvTG9jYWxlU3RyaW5nKCdrby1LUicpKyfrp4wnKTsKICBpZih3b24pIHAucHVzaCh3b24udG9Mb2NhbGVTdHJpbmcoJ2tvLUtSJykpOwogIHJldHVybiBwLmpvaW4oJyAnKSsn7JuQJzsKfQpmdW5jdGlvbiBpbml0UmVhZChtYXApewogIE9iamVjdC5rZXlzKG1hcCkuZm9yRWFjaChmdW5jdGlvbihpZCl7CiAgICB2YXIgZT0kKGlkKSwgb3V0PSQobWFwW2lkXSk7IGlmKCFlfHwhb3V0KSByZXR1cm47CiAgICB2YXIgdXBkPWZ1bmN0aW9uKCl7IG91dC50ZXh0Q29udGVudCA9ICgrZS52YWx1ZT4wKSA/IGtvck1vbmV5KCtlLnZhbHVlKSA6ICcnOyB9OwogICAgZS5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsdXBkKTsgdXBkKCk7CiAgfSk7Cn0KCgovKiDsiKvsnpAg7Lm07Jq07Yq47JeFIOKAlCDqsrDqs7zqsIAg67CU64CUIOuVjCDrtoDrk5zrn73qsowgKi8KZnVuY3Rpb24gY291bnRVcChlbCwgdGV4dCl7CiAgaWYoIWVsKSByZXR1cm47CiAgdmFyIHByZXY9ZWwuX3Jhd3x8JycsIGN1cj10ZXh0OwogIGVsLl9yYXc9Y3VyOwogIHZhciBwbj1wYXJzZUZsb2F0KFN0cmluZyhwcmV2KS5yZXBsYWNlKC9bXjAtOS4tXS9nLCcnKSk7CiAgdmFyIGNuPXBhcnNlRmxvYXQoU3RyaW5nKGN1cikucmVwbGFjZSgvW14wLTkuLV0vZywnJykpOwogIHZhciByZWR1Y2U9d2luZG93Lm1hdGNoTWVkaWEmJndpbmRvdy5tYXRjaE1lZGlhKCcocHJlZmVycy1yZWR1Y2VkLW1vdGlvbjogcmVkdWNlKScpLm1hdGNoZXM7CiAgaWYocmVkdWNlfHwhaXNGaW5pdGUocG4pfHwhaXNGaW5pdGUoY24pfHxwbj09PWNufHxNYXRoLmFicyhjbi1wbik8MSl7ZWwudGV4dENvbnRlbnQ9Y3VyO3JldHVybjt9CiAgdmFyIHByZT1jdXIuc2xpY2UoMCxjdXIuc2VhcmNoKC9bMC05LV0vKSk7CiAgdmFyIHBvc3Q9Y3VyLnNsaWNlKGN1ci5zZWFyY2goL1swLTldW14wLTldKiQvKSsxKS5yZXBsYWNlKC9eWzAtOV0vLCcnKTsKICB2YXIgc3VmZml4PWN1ci5yZXBsYWNlKC9eW14wLTktXSovLCcnKS5yZXBsYWNlKC9eWzAtOSwuXC1dKy8sJycpOwogIHZhciB0MD1udWxsLCBkdXI9MzgwOwogIGNhbmNlbEFuaW1hdGlvbkZyYW1lKGVsLl9hZnx8MCk7CiAgZnVuY3Rpb24gc3RlcCh0KXsKICAgIGlmKCF0MCkgdDA9dDsKICAgIHZhciBrPU1hdGgubWluKDEsKHQtdDApL2R1ciksIGU9MS1NYXRoLnBvdygxLWssMyk7CiAgICB2YXIgdmFsPXBuKyhjbi1wbikqZTsKICAgIGVsLnRleHRDb250ZW50PXByZStNYXRoLnJvdW5kKHZhbCkudG9Mb2NhbGVTdHJpbmcoJ2tvLUtSJykrc3VmZml4OwogICAgaWYoazwxKSBlbC5fYWY9cmVxdWVzdEFuaW1hdGlvbkZyYW1lKHN0ZXApOyBlbHNlIGVsLnRleHRDb250ZW50PWN1cjsKICB9CiAgZWwuX2FmPXJlcXVlc3RBbmltYXRpb25GcmFtZShzdGVwKTsKfQoKLyog66qo67CU7J28IOqzoOyglSDqsrDqs7zrsJQgKyDrp6gg7JyE66GcICovCmZ1bmN0aW9uIGluaXRTdGlja3kocm9vdCwgbGFiZWwpewogIGlmKCFyb290KSByZXR1cm47CiAgdmFyIG1haW49JCgnbWFpbicpOyBpZighbWFpbikgcmV0dXJuOwogIHZhciBiYXI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgYmFyLmNsYXNzTmFtZT0ndHBoLXN0aWNreSc7CiAgYmFyLmlubmVySFRNTD0nPGRpdiBjbGFzcz0ibCI+JytsYWJlbCsnPC9kaXY+PGRpdiBjbGFzcz0idiIgaWQ9InRwaC1zdGlja3l2Ij7igKY8L2Rpdj4nOwogIHJvb3QuYXBwZW5kQ2hpbGQoYmFyKTsKICB2YXIgdG9wPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpOwogIHRvcC50eXBlPSdidXR0b24nOyB0b3AuY2xhc3NOYW1lPSd0cGgtdG9wJzsgdG9wLnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcsJ+unqCDsnITroZwnKTsKICB0b3AuaW5uZXJIVE1MPSc8c3ZnIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTEyIDE5VjUiLz48cGF0aCBkPSJNNSAxMmw3LTcgNyA3Ii8+PC9zdmc+JzsKICB0b3AuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGZ1bmN0aW9uKCl7d2luZG93LnNjcm9sbFRvKHt0b3A6MCxiZWhhdmlvcjonc21vb3RoJ30pO30pOwogIHJvb3QuYXBwZW5kQ2hpbGQodG9wKTsKICB2YXIgc3Y9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RwaC1zdGlja3l2Jyk7CiAgdmFyIHN5bmM9ZnVuY3Rpb24oKXsKICAgIGlmKHN2JiZzdi50ZXh0Q29udGVudCE9PW1haW4udGV4dENvbnRlbnQpIHN2LnRleHRDb250ZW50PW1haW4udGV4dENvbnRlbnQ7CiAgICB2YXIgcj1tYWluLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgYmFyLmNsYXNzTGlzdC50b2dnbGUoJ29uJywgci5ib3R0b208NTYpOwogICAgdG9wLmNsYXNzTGlzdC50b2dnbGUoJ29uJywgd2luZG93LnNjcm9sbFk+NTAwKTsKICB9OwogIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLHN5bmMse3Bhc3NpdmU6dHJ1ZX0pOwogIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLHN5bmMpOwogIGlmKHdpbmRvdy5NdXRhdGlvbk9ic2VydmVyKSBuZXcgTXV0YXRpb25PYnNlcnZlcihzeW5jKS5vYnNlcnZlKG1haW4se2NoaWxkTGlzdDp0cnVlLGNoYXJhY3RlckRhdGE6dHJ1ZSxzdWJ0cmVlOnRydWV9KTsKICBzeW5jKCk7Cn0KCi8qIOKUgOKUgCDssKjtirgg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgIOyDieydgCBDU1Mg67OA7IiYIC0tczEvLS1zMi8tLXMzICjqsoDspp3rkJwg7Lm07YWM6rOg66asIO2MlOugiO2KuCkuCiAgIOqzhOyXtOydtCAy6rCcIOydtOyDgeydtOuptCDrspTroYDrpbwg7ZWt7IOBIOu2meydtOqzoCwg6rCS7J2AIO2RnOyXkOuPhCDqt7jrjIDroZwg7J6I64ukLiAqLwp2YXIgU1ZHTlM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJzsKZnVuY3Rpb24gZWwodCxhKXt2YXIgZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHTlMsdCk7Zm9yKHZhciBrIGluIGEpZS5zZXRBdHRyaWJ1dGUoayxhW2tdKTtyZXR1cm4gZTt9CgpmdW5jdGlvbiB0aXAoYm94KXsKICB2YXIgdD1ib3gucXVlcnlTZWxlY3RvcignLnRwaC10aXAnKTsKICBpZighdCl7dD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTt0LmNsYXNzTmFtZT0ndHBoLXRpcCc7Ym94LmFwcGVuZENoaWxkKHQpO30KICByZXR1cm4gdDsKfQpmdW5jdGlvbiBzaG93VGlwKGJveCx4LHksaHRtbCl7CiAgdmFyIHQ9dGlwKGJveCk7IHQuaW5uZXJIVE1MPWh0bWw7IHQuc3R5bGUub3BhY2l0eT0nMSc7CiAgdmFyIHc9dC5vZmZzZXRXaWR0aCwgYnc9Ym94LmNsaWVudFdpZHRoOwogIHQuc3R5bGUubGVmdD1NYXRoLm1heCg0LE1hdGgubWluKGJ3LXctNCx4LXcvMikpKydweCc7CiAgdC5zdHlsZS50b3A9TWF0aC5tYXgoMix5LXQub2Zmc2V0SGVpZ2h0LTEwKSsncHgnOwp9CmZ1bmN0aW9uIGhpZGVUaXAoYm94KXt2YXIgdD1ib3gucXVlcnlTZWxlY3RvcignLnRwaC10aXAnKTtpZih0KXQuc3R5bGUub3BhY2l0eT0nMCc7fQoKLyog7IS466GcIOuIhOyggSDrp4nrjIAg4oCUIGNhdHM6W+udvOuyqF0sIHNlcmllczpbe25hbWUsY2xzLGRhdGE6W119XSAqLwpmdW5jdGlvbiBzdGFja0NoYXJ0KGJveElkLCBjYXRzLCBzZXJpZXMsIGZtdCl7CiAgdmFyIGJveD0kKGJveElkKTsgaWYoIWJveCkgcmV0dXJuOwogIGJveC5xdWVyeVNlbGVjdG9yQWxsKCdzdmcsLnRwaC1sZWdlbmQnKS5mb3JFYWNoKGZ1bmN0aW9uKG4pe24ucmVtb3ZlKCk7fSk7CiAgdmFyIFc9NjYwLEg9MjM2LFBMPTgsUFI9OCxQVD0xNCxQQj0yNjsKICB2YXIgbj1jYXRzLmxlbmd0aDsgaWYoIW4pIHJldHVybjsKICB2YXIgdG90YWxzPWNhdHMubWFwKGZ1bmN0aW9uKF8saSl7cmV0dXJuIHNlcmllcy5yZWR1Y2UoZnVuY3Rpb24oYSxzKXtyZXR1cm4gYSsocy5kYXRhW2ldfHwwKTt9LDApO30pOwogIHZhciBtYXg9TWF0aC5tYXguYXBwbHkobnVsbCx0b3RhbHMpfHwxOwogIHZhciBpdz1XLVBMLVBSLCBpaD1ILVBULVBCOwogIHZhciBidz1NYXRoLm1heCg2LE1hdGgubWluKDQ2LGl3L24qMC42OCkpLCBzdGVwPWl3L247CiAgdmFyIHN2Zz1lbCgnc3ZnJyx7dmlld0JveDonMCAwICcrVysnICcrSCxyb2xlOidpbWcnfSk7CiAgZm9yKHZhciBnPTA7Zzw9MztnKyspewogICAgdmFyIGd5PVBUK2loKmcvMzsKICAgIHN2Zy5hcHBlbmRDaGlsZChlbCgnbGluZScse3gxOlBMLHkxOmd5LHgyOlctUFIseTI6Z3ksJ2NsYXNzJzonZ2wnfSkpOwogIH0KICBjYXRzLmZvckVhY2goZnVuY3Rpb24oYyxpKXsKICAgIHZhciBjeD1QTCtzdGVwKmkrc3RlcC8yLCB5PVBUK2loLCBhY2M9MDsKICAgIHNlcmllcy5mb3JFYWNoKGZ1bmN0aW9uKHMsc2kpewogICAgICB2YXIgdmFsPXMuZGF0YVtpXXx8MDsgaWYodmFsPD0wKSByZXR1cm47CiAgICAgIHZhciBoPXZhbC9tYXgqaWg7IHktPWg7IGFjYys9dmFsOwogICAgICB2YXIgaXNUb3AgPSBzaT09PXNlcmllcy5sZW5ndGgtMSB8fCAhc2VyaWVzLnNsaWNlKHNpKzEpLnNvbWUoZnVuY3Rpb24oeil7cmV0dXJuICh6LmRhdGFbaV18fDApPjA7fSk7CiAgICAgIHZhciByPWVsKCdyZWN0Jyx7eDpjeC1idy8yLHk6eSx3aWR0aDpidyxoZWlnaHQ6TWF0aC5tYXgoMSxoKSwnY2xhc3MnOnMuY2xzLAogICAgICAgICAgICAgICAgICAgICAgIHJ4OmlzVG9wPzQ6MCxyeTppc1RvcD80OjB9KTsKICAgICAgc3ZnLmFwcGVuZENoaWxkKHIpOwogICAgfSk7CiAgICB2YXIgaGl0PWVsKCdyZWN0Jyx7eDpjeC1zdGVwLzIrMSx5OlBULHdpZHRoOnN0ZXAtMixoZWlnaHQ6aWgsJ2NsYXNzJzonaGl0J30pOwogICAgaGl0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsZnVuY3Rpb24oZXYpewogICAgICB2YXIgYnI9Ym94LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgICB2YXIgcm93cz1zZXJpZXMubWFwKGZ1bmN0aW9uKHMpewogICAgICAgIHJldHVybiAnPHNwYW4gc3R5bGU9ImRpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjhweDtoZWlnaHQ6OHB4O2JvcmRlci1yYWRpdXM6MnB4OycKICAgICAgICAgICAgICsgJ2JhY2tncm91bmQ6dmFyKC0tJytzLmNscysnKTttYXJnaW4tcmlnaHQ6NnB4Ij48L3NwYW4+JytzLm5hbWUrJyAnK2ZtdChzLmRhdGFbaV18fDApOwogICAgICB9KS5qb2luKCc8YnI+Jyk7CiAgICAgIHNob3dUaXAoYm94LGV2LmNsaWVudFgtYnIubGVmdCxldi5jbGllbnRZLWJyLnRvcCwKICAgICAgICAgICAgICAnPGI+JytjKyc8L2I+PGJyPicrcm93cysnPGJyPu2VqeqzhCAnK2ZtdChhY2MpKTsKICAgIH0pOwogICAgaGl0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLGZ1bmN0aW9uKCl7aGlkZVRpcChib3gpO30pOwogICAgc3ZnLmFwcGVuZENoaWxkKGhpdCk7CiAgICBpZihuPD0xNHx8aSVNYXRoLmNlaWwobi8xMik9PT0wKQogICAgICBzdmcuYXBwZW5kQ2hpbGQoT2JqZWN0LmFzc2lnbihlbCgndGV4dCcse3g6Y3gseTpILTgsJ2NsYXNzJzonbGInLCd0ZXh0LWFuY2hvcic6J21pZGRsZSd9KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3RleHRDb250ZW50OmN9KSk7CiAgfSk7CiAgYm94LmFwcGVuZENoaWxkKHN2Zyk7CiAgYm94LmFwcGVuZENoaWxkKGxlZ2VuZChzZXJpZXMpKTsKfQoKLyog6rCA66GcIOuIhOyggSDrp4nrjIAo6rWs7ISxKSDigJQgc2Vnczpbe25hbWUsY2xzLHZhbHVlfV0gwrcg7KeB7KCRIOudvOuyqCAqLwpmdW5jdGlvbiBoU3RhY2soYm94SWQsIHNlZ3MsIGZtdCl7CiAgdmFyIGJveD0kKGJveElkKTsgaWYoIWJveCkgcmV0dXJuOwogIGJveC5xdWVyeVNlbGVjdG9yQWxsKCdzdmcsLnRwaC1sZWdlbmQnKS5mb3JFYWNoKGZ1bmN0aW9uKG4pe24ucmVtb3ZlKCk7fSk7CiAgdmFyIHRvdGFsPXNlZ3MucmVkdWNlKGZ1bmN0aW9uKGEscyl7cmV0dXJuIGErTWF0aC5tYXgoMCxzLnZhbHVlKTt9LDApfHwxOwogIHZhciBXPTY2MCxIPTY0LFBMPTgsUFI9OCxCSD0zNCxUWT0xMjsKICB2YXIgc3ZnPWVsKCdzdmcnLHt2aWV3Qm94OicwIDAgJytXKycgJytILHJvbGU6J2ltZyd9KTsKICB2YXIgeD1QTCwgaXc9Vy1QTC1QUjsKICBzZWdzLmZvckVhY2goZnVuY3Rpb24ocyxpKXsKICAgIHZhciB3PU1hdGgubWF4KDAscy52YWx1ZSkvdG90YWwqaXc7IGlmKHc8PTApIHJldHVybjsKICAgIHZhciBmaXJzdD1pPT09MCwgbGFzdD1pPT09c2Vncy5sZW5ndGgtMTsKICAgIHN2Zy5hcHBlbmRDaGlsZChlbCgncmVjdCcse3g6eCx5OlRZLHdpZHRoOncsaGVpZ2h0OkJILCdjbGFzcyc6cy5jbHMsCiAgICAgIHJ4OihmaXJzdHx8bGFzdCk/NDowLHJ5OihmaXJzdHx8bGFzdCk/NDowfSkpOwogICAgdmFyIHBjdD1zLnZhbHVlL3RvdGFsKjEwMDsKICAgIGlmKHBjdD49OSkKICAgICAgc3ZnLmFwcGVuZENoaWxkKE9iamVjdC5hc3NpZ24oZWwoJ3RleHQnLHt4Ongrdy8yLHk6VFkrQkgvMis0LCdjbGFzcyc6J3ZsJywKICAgICAgICAndGV4dC1hbmNob3InOidtaWRkbGUnLGZpbGw6JyNmZmYnfSkse3RleHRDb250ZW50OnBjdC50b0ZpeGVkKDApKyclJ30pKTsKICAgIHZhciBoaXQ9ZWwoJ3JlY3QnLHt4OngseTpUWSx3aWR0aDp3LGhlaWdodDpCSCwnY2xhc3MnOidoaXQnfSk7CiAgICAoZnVuY3Rpb24oc2VnLHB4LHB3KXsKICAgICAgaGl0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsZnVuY3Rpb24oZXYpewogICAgICAgIHZhciBicj1ib3guZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgICAgICAgc2hvd1RpcChib3gsZXYuY2xpZW50WC1ici5sZWZ0LGV2LmNsaWVudFktYnIudG9wLAogICAgICAgICAgJzxiPicrc2VnLm5hbWUrJzwvYj48YnI+JytmbXQoc2VnLnZhbHVlKSsnIMK3ICcrKHNlZy52YWx1ZS90b3RhbCoxMDApLnRvRml4ZWQoMSkrJyUnKTsKICAgICAgfSk7CiAgICAgIGhpdC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJyxmdW5jdGlvbigpe2hpZGVUaXAoYm94KTt9KTsKICAgIH0pKHMseCx3KTsKICAgIHN2Zy5hcHBlbmRDaGlsZChoaXQpOwogICAgeCs9dzsKICB9KTsKICBib3guYXBwZW5kQ2hpbGQoc3ZnKTsKICBib3guYXBwZW5kQ2hpbGQobGVnZW5kKHNlZ3MubWFwKGZ1bmN0aW9uKHMpe3JldHVybiB7bmFtZTpzLm5hbWUrJyAnK2ZtdChzLnZhbHVlKSxjbHM6cy5jbHN9O30pKSk7Cn0KCi8qIOyEoO2YlSDstpTsnbQg7LCo7Yq4IOKAlCBzZXJpZXM6W3tuYW1lLGNscyxkYXRhOltdfV0sIGNhdHM6W+udvOuyqF0gKi8KZnVuY3Rpb24gbGluZUNoYXJ0KGJveElkLCBjYXRzLCBzZXJpZXMsIGZtdCl7CiAgdmFyIGJveD0kKGJveElkKTsgaWYoIWJveCkgcmV0dXJuOwogIGJveC5xdWVyeVNlbGVjdG9yQWxsKCdzdmcsLnRwaC1sZWdlbmQnKS5mb3JFYWNoKGZ1bmN0aW9uKG4pe24ucmVtb3ZlKCk7fSk7CiAgdmFyIG49Y2F0cy5sZW5ndGg7IGlmKG48MikgcmV0dXJuOwogIHZhciBXPTY2MCxIPTI0MCxQTD01NCxQUj0xMixQVD0xNCxQQj0yNjsKICB2YXIgYWxsPVtdOyBzZXJpZXMuZm9yRWFjaChmdW5jdGlvbihzKXthbGw9YWxsLmNvbmNhdChzLmRhdGEuZmlsdGVyKGZ1bmN0aW9uKHYpe3JldHVybiB2IT1udWxsO30pKTt9KTsKICBpZighYWxsLmxlbmd0aCkgcmV0dXJuOwogIHZhciBteD1NYXRoLm1heC5hcHBseShudWxsLGFsbCksIG1uPU1hdGgubWluLmFwcGx5KG51bGwsYWxsKTsKICB2YXIgcGFkPShteC1tbikqMC4xNXx8bXgqMC4wMnx8MTsgbXgrPXBhZDsgbW49TWF0aC5tYXgoMCxtbi1wYWQpOwogIHZhciBpdz1XLVBMLVBSLCBpaD1ILVBULVBCOwogIHZhciBYPWZ1bmN0aW9uKGkpe3JldHVybiBQTCtpdyoobj09PTE/MC41OmkvKG4tMSkpO307CiAgdmFyIFk9ZnVuY3Rpb24odil7cmV0dXJuIFBUK2loKigxLSh2LW1uKS8oKG14LW1uKXx8MSkpO307CiAgdmFyIHN2Zz1lbCgnc3ZnJyx7dmlld0JveDonMCAwICcrVysnICcrSCxyb2xlOidpbWcnfSk7CiAgZm9yKHZhciBnPTA7Zzw9NDtnKyspewogICAgdmFyIGd2PW1uKyhteC1tbikqZy80LCBneT1ZKGd2KTsKICAgIHN2Zy5hcHBlbmRDaGlsZChlbCgnbGluZScse3gxOlBMLHkxOmd5LHgyOlctUFIseTI6Z3ksJ2NsYXNzJzonZ2wnfSkpOwogICAgc3ZnLmFwcGVuZENoaWxkKE9iamVjdC5hc3NpZ24oZWwoJ3RleHQnLHt4OlBMLTgseTpneSs0LCdjbGFzcyc6J2xiJywndGV4dC1hbmNob3InOidlbmQnfSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dGV4dENvbnRlbnQ6TWF0aC5yb3VuZChndikudG9Mb2NhbGVTdHJpbmcoJ2tvLUtSJyl9KSk7CiAgfQogIHNlcmllcy5mb3JFYWNoKGZ1bmN0aW9uKHMpewogICAgdmFyIGQ9JycsIHN0YXJ0ZWQ9ZmFsc2U7CiAgICBzLmRhdGEuZm9yRWFjaChmdW5jdGlvbih2LGkpewogICAgICBpZih2PT1udWxsKSByZXR1cm47CiAgICAgIGQrPShzdGFydGVkPydMJzonTScpK1goaSkudG9GaXhlZCgxKSsnICcrWSh2KS50b0ZpeGVkKDEpKycgJzsgc3RhcnRlZD10cnVlOwogICAgfSk7CiAgICBpZihkKSBzdmcuYXBwZW5kQ2hpbGQoZWwoJ3BhdGgnLHtkOmQsZmlsbDonbm9uZScsJ3N0cm9rZSc6J3ZhcigtLScrcy5jbHMrJyknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cm9rZS13aWR0aCc6Mi4yLCdzdHJva2UtbGluZWpvaW4nOidyb3VuZCcsJ3N0cm9rZS1saW5lY2FwJzoncm91bmQnfSkpOwogICAgdmFyIGxhc3Q9cy5kYXRhLmxlbmd0aC0xOwogICAgaWYocy5kYXRhW2xhc3RdIT1udWxsKQogICAgICBzdmcuYXBwZW5kQ2hpbGQoZWwoJ2NpcmNsZScse2N4OlgobGFzdCksY3k6WShzLmRhdGFbbGFzdF0pLHI6NCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsOid2YXIoLS0nK3MuY2xzKycpJyxzdHJva2U6J3ZhcigtLXN1cmZhY2UpJywnc3Ryb2tlLXdpZHRoJzoyfSkpOwogIH0pOwogIGNhdHMuZm9yRWFjaChmdW5jdGlvbihjLGkpewogICAgaWYobj4xMCAmJiBpJU1hdGguY2VpbChuLzcpIT09MCAmJiBpIT09bi0xKSByZXR1cm47CiAgICBzdmcuYXBwZW5kQ2hpbGQoT2JqZWN0LmFzc2lnbihlbCgndGV4dCcse3g6WChpKSx5OkgtOCwnY2xhc3MnOidsYicsJ3RleHQtYW5jaG9yJzonbWlkZGxlJ30pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3RleHRDb250ZW50OmN9KSk7CiAgfSk7CiAgZm9yKHZhciBpPTA7aTxuO2krKyl7CiAgICAoZnVuY3Rpb24oaWR4KXsKICAgICAgdmFyIGhpdD1lbCgncmVjdCcse3g6WChpZHgpLWl3LyhuLTEpLzIseTpQVCx3aWR0aDppdy8obi0xKXx8MjAsaGVpZ2h0OmloLCdjbGFzcyc6J2hpdCd9KTsKICAgICAgaGl0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsZnVuY3Rpb24oZXYpewogICAgICAgIHZhciBicj1ib3guZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgICAgICAgdmFyIHJvd3M9c2VyaWVzLm1hcChmdW5jdGlvbihzKXsKICAgICAgICAgIHJldHVybiAnPHNwYW4gc3R5bGU9ImRpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjhweDtoZWlnaHQ6OHB4O2JvcmRlci1yYWRpdXM6MnB4OycKICAgICAgICAgICAgICAgKyAnYmFja2dyb3VuZDp2YXIoLS0nK3MuY2xzKycpO21hcmdpbi1yaWdodDo2cHgiPjwvc3Bhbj4nK3MubmFtZSsnICcKICAgICAgICAgICAgICAgKyAocy5kYXRhW2lkeF09PW51bGw/Jy0nOmZtdChzLmRhdGFbaWR4XSkpOwogICAgICAgIH0pLmpvaW4oJzxicj4nKTsKICAgICAgICBzaG93VGlwKGJveCxldi5jbGllbnRYLWJyLmxlZnQsZXYuY2xpZW50WS1ici50b3AsJzxiPicrY2F0c1tpZHhdKyc8L2I+PGJyPicrcm93cyk7CiAgICAgIH0pOwogICAgICBoaXQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsZnVuY3Rpb24oKXtoaWRlVGlwKGJveCk7fSk7CiAgICAgIHN2Zy5hcHBlbmRDaGlsZChoaXQpOwogICAgfSkoaSk7CiAgfQogIGJveC5hcHBlbmRDaGlsZChzdmcpOwogIGJveC5hcHBlbmRDaGlsZChsZWdlbmQoc2VyaWVzKSk7Cn0KCmZ1bmN0aW9uIGxlZ2VuZChpdGVtcyl7CiAgdmFyIGQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7IGQuY2xhc3NOYW1lPSd0cGgtbGVnZW5kJzsKICBpdGVtcy5mb3JFYWNoKGZ1bmN0aW9uKHMpewogICAgdmFyIHNwPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTsKICAgIHNwLmlubmVySFRNTD0nPGkgc3R5bGU9ImJhY2tncm91bmQ6dmFyKC0tJytzLmNscysnKSI+PC9pPicrcy5uYW1lOwogICAgZC5hcHBlbmRDaGlsZChzcCk7CiAgfSk7CiAgcmV0dXJuIGQ7Cn0KLyogMuywqCDrqZTribQ6IO2YhOyerCDtg63snbQg7Zy064yA7Y+wIO2ZlOuptCDrsJYo7Jik66W47Kq9KeyXkCDsnojsnLzrqbQg6rCA66Gc66GcIOuLueqyqCDrs7TsnbTqsowg7ZWc64ukKO2OmOydtOyngOuKlCDshLjroZzroZwg7JuA7KeB7J207KeAIOyViuuKlOuLpCkgKi8KKGZ1bmN0aW9uKCl7CiAgdmFyIGE9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRwaC1zdWJuYXYgYVthcmlhLWN1cnJlbnRdJyk7IGlmKCFhKSByZXR1cm47CiAgdmFyIHc9YS5wYXJlbnROb2RlLCBhcj1hLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCB3cj13LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogIGlmKGFyLnJpZ2h0PndyLnJpZ2h0LTh8fGFyLmxlZnQ8d3IubGVmdCkgdy5zY3JvbGxMZWZ0Kz1hci5sZWZ0LXdyLmxlZnQtKHcuY2xpZW50V2lkdGgtYS5vZmZzZXRXaWR0aCkvMjsKfSkoKTsKaW5pdFRoZW1lKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50cGgtcGFnZScpKTs=