@excalidraw/excalidraw 0.12.0-fd946ad → 0.12.0-fdc462e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/CHANGELOG.md +11 -850
  2. package/README.md +25 -11
  3. package/dist/excalidraw-assets/locales/ar-SA-json-6ffeaa9e26c2b7330686.js +1 -0
  4. package/dist/excalidraw-assets/locales/bg-BG-json-fbf6d2bf83c4515ebafd.js +1 -0
  5. package/dist/excalidraw-assets/locales/bn-BD-json-9660edf4f9c5c3fa09f8.js +1 -0
  6. package/dist/excalidraw-assets/locales/ca-ES-json-660f4a27f14ae032f524.js +1 -0
  7. package/dist/excalidraw-assets/locales/cs-CZ-json-7d148472909389dd280c.js +1 -0
  8. package/dist/excalidraw-assets/locales/da-DK-json-10334bd5451bdc83fb4a.js +1 -0
  9. package/dist/excalidraw-assets/locales/de-DE-json-cd6a62a79609bc57697a.js +1 -0
  10. package/dist/excalidraw-assets/locales/el-GR-json-a7b859391ac05d909fdf.js +1 -0
  11. package/dist/excalidraw-assets/locales/es-ES-json-812c9fcccc4550e0e87c.js +1 -0
  12. package/dist/excalidraw-assets/locales/eu-ES-json-4b83e0e39ff358e41e57.js +1 -0
  13. package/dist/excalidraw-assets/locales/fa-IR-json-078dbd1fe9b8bb5a198a.js +1 -0
  14. package/dist/excalidraw-assets/locales/fi-FI-json-70202ae5946ce3b701c3.js +1 -0
  15. package/dist/excalidraw-assets/locales/fr-FR-json-593cbb471dcbd3415acc.js +1 -0
  16. package/dist/excalidraw-assets/locales/gl-ES-json-022ea7861fff2205d681.js +1 -0
  17. package/dist/excalidraw-assets/locales/he-IL-json-bd267ab47c66aa865d61.js +1 -0
  18. package/dist/excalidraw-assets/locales/hi-IN-json-3253b42b857f7d697a17.js +1 -0
  19. package/dist/excalidraw-assets/locales/hu-HU-json-7682d17d39a5d4e81db3.js +1 -0
  20. package/dist/excalidraw-assets/locales/id-ID-json-cf7b7a1d260657b7f48d.js +1 -0
  21. package/dist/excalidraw-assets/locales/it-IT-json-17067e488b7b42ed8585.js +1 -0
  22. package/dist/excalidraw-assets/locales/ja-JP-json-77b53a6596535fe2f0f9.js +1 -0
  23. package/dist/excalidraw-assets/locales/kab-KAB-json-b7c0fda12f95048622f2.js +1 -0
  24. package/dist/excalidraw-assets/locales/kk-KZ-json-754a1a92ec1065f31d3d.js +1 -0
  25. package/dist/excalidraw-assets/locales/ko-KR-json-ae943359b26f9ea208de.js +1 -0
  26. package/dist/excalidraw-assets/locales/lt-LT-json-f79704ea6f1a9210a637.js +1 -0
  27. package/dist/excalidraw-assets/locales/lv-LV-json-8154a6d9cdd04d190900.js +1 -0
  28. package/dist/excalidraw-assets/locales/mr-IN-json-a3a6ffee6ae2aa509e8b.js +1 -0
  29. package/dist/excalidraw-assets/locales/my-MM-json-cdcb60976a56fa6f7c97.js +1 -0
  30. package/dist/excalidraw-assets/locales/nb-NO-json-7a0ea24170387ac4ca6e.js +1 -0
  31. package/dist/excalidraw-assets/locales/nl-NL-json-a2b6473ccab62e9eaf72.js +1 -0
  32. package/dist/excalidraw-assets/locales/nn-NO-json-6145a1539034ce59ae52.js +1 -0
  33. package/dist/excalidraw-assets/locales/oc-FR-json-7f2a9a6e8c562d638936.js +1 -0
  34. package/dist/excalidraw-assets/locales/pa-IN-json-62611111c1ca22fc6d9a.js +1 -0
  35. package/dist/excalidraw-assets/locales/pl-PL-json-2c4f46b66947644b5f4e.js +1 -0
  36. package/dist/excalidraw-assets/locales/pt-BR-json-c504d580b290f29aec0d.js +1 -0
  37. package/dist/excalidraw-assets/locales/pt-PT-json-f68a4b23e6c8ba9937ba.js +1 -0
  38. package/dist/excalidraw-assets/locales/ro-RO-json-e1864108128e05214f5e.js +1 -0
  39. package/dist/excalidraw-assets/locales/ru-RU-json-d9a3269846d87a9ab50f.js +1 -0
  40. package/dist/excalidraw-assets/locales/si-LK-json-f58a27ca64b62d14d616.js +1 -0
  41. package/dist/excalidraw-assets/locales/sk-SK-json-5b585cac266b5b49fb0e.js +1 -0
  42. package/dist/excalidraw-assets/locales/sl-SI-json-cd0df9f835277c536509.js +1 -0
  43. package/dist/excalidraw-assets/locales/sv-SE-json-e44b56cdbdbf8aba6482.js +1 -0
  44. package/dist/excalidraw-assets/locales/ta-IN-json-0a3bd23deed6c9275f14.js +1 -0
  45. package/dist/excalidraw-assets/locales/tr-TR-json-2361be22b6b45118cff9.js +1 -0
  46. package/dist/excalidraw-assets/locales/uk-UA-json-0bc0a23d6421eea6b7f5.js +1 -0
  47. package/dist/excalidraw-assets/locales/vi-VN-json-599cf6c1eb6b566f7c1a.js +1 -0
  48. package/dist/excalidraw-assets/locales/zh-CN-json-5d3b5822d355de9d7625.js +1 -0
  49. package/dist/excalidraw-assets/locales/zh-HK-json-0efec5474936a109241d.js +1 -0
  50. package/dist/excalidraw-assets/locales/zh-TW-json-4262eec09b4d3d5dfa94.js +1 -0
  51. package/dist/excalidraw-assets/vendor-cb04f63875674d708080.js +2 -0
  52. package/dist/excalidraw-assets/{vendor-52b1f3361986b6c6a4fe.js.LICENSE.txt → vendor-cb04f63875674d708080.js.LICENSE.txt} +0 -0
  53. package/dist/excalidraw-assets-dev/locales/ar-SA-json-e18bf994a8a492e04c5b.js +22 -0
  54. package/dist/excalidraw-assets-dev/locales/bg-BG-json-c4822083b66facc7138b.js +22 -0
  55. package/dist/excalidraw-assets-dev/locales/bn-BD-json-ebadec70518ef5b5fc5b.js +22 -0
  56. package/dist/excalidraw-assets-dev/locales/ca-ES-json-81a1896a4b8113466237.js +22 -0
  57. package/dist/excalidraw-assets-dev/locales/cs-CZ-json-67246c64d571f677019b.js +22 -0
  58. package/dist/excalidraw-assets-dev/locales/da-DK-json-4e6dd750a31d070daec9.js +22 -0
  59. package/dist/excalidraw-assets-dev/locales/de-DE-json-d0676faf8f1e90d3ce34.js +22 -0
  60. package/dist/excalidraw-assets-dev/locales/el-GR-json-9185ceab00e1598333d4.js +22 -0
  61. package/dist/excalidraw-assets-dev/locales/es-ES-json-a2870461506d73f41a72.js +22 -0
  62. package/dist/excalidraw-assets-dev/locales/eu-ES-json-3530634f7d5a3db297de.js +22 -0
  63. package/dist/excalidraw-assets-dev/locales/fa-IR-json-66f5b4a41dc3aa7c8c45.js +22 -0
  64. package/dist/excalidraw-assets-dev/locales/fi-FI-json-7885764c835895664e0b.js +22 -0
  65. package/dist/excalidraw-assets-dev/locales/fr-FR-json-ccb5eda23a779eb1880a.js +22 -0
  66. package/dist/excalidraw-assets-dev/locales/gl-ES-json-ab9c245372378f5f8c9b.js +22 -0
  67. package/dist/excalidraw-assets-dev/locales/he-IL-json-7bfd6ca43596df3a84a1.js +22 -0
  68. package/dist/excalidraw-assets-dev/locales/hi-IN-json-5148be3454f39f9bffb0.js +22 -0
  69. package/dist/excalidraw-assets-dev/locales/hu-HU-json-f6436471ba8cccff3ac4.js +22 -0
  70. package/dist/excalidraw-assets-dev/locales/id-ID-json-9328a35688d0537730ae.js +22 -0
  71. package/dist/excalidraw-assets-dev/locales/it-IT-json-11bf19dfe8d8d38e6cec.js +22 -0
  72. package/dist/excalidraw-assets-dev/locales/ja-JP-json-c670cda6d6c171611c79.js +22 -0
  73. package/dist/excalidraw-assets-dev/locales/kab-KAB-json-396d5e8936a8362b536c.js +22 -0
  74. package/dist/excalidraw-assets-dev/locales/kk-KZ-json-7c301df4020cd7c670e2.js +22 -0
  75. package/dist/excalidraw-assets-dev/locales/ko-KR-json-d6850be7bac8fc43af84.js +22 -0
  76. package/dist/excalidraw-assets-dev/locales/lt-LT-json-263c5629ddf0ee7d7572.js +22 -0
  77. package/dist/excalidraw-assets-dev/locales/lv-LV-json-44a18e46e8c68310c7c8.js +22 -0
  78. package/dist/excalidraw-assets-dev/locales/mr-IN-json-b0cd94322c2b39884d52.js +22 -0
  79. package/dist/excalidraw-assets-dev/locales/my-MM-json-b0c8ffa53fa7c9f7fc4d.js +22 -0
  80. package/dist/excalidraw-assets-dev/locales/nb-NO-json-216bb67091fd4a2e70e6.js +22 -0
  81. package/dist/excalidraw-assets-dev/locales/nl-NL-json-820135e0dcbb62d8f23c.js +22 -0
  82. package/dist/excalidraw-assets-dev/locales/nn-NO-json-059b39da1c7b19e93db6.js +22 -0
  83. package/dist/excalidraw-assets-dev/locales/oc-FR-json-54a63799c742875f8b9b.js +22 -0
  84. package/dist/excalidraw-assets-dev/locales/pa-IN-json-e535caa54102fbcee393.js +22 -0
  85. package/dist/excalidraw-assets-dev/locales/pl-PL-json-73e6bd0c53922c9c71ba.js +22 -0
  86. package/dist/excalidraw-assets-dev/locales/pt-BR-json-19be79102dd3cb5a95dc.js +22 -0
  87. package/dist/excalidraw-assets-dev/locales/pt-PT-json-4b8554cd18248130c618.js +22 -0
  88. package/dist/excalidraw-assets-dev/locales/ro-RO-json-718b6921865260332b51.js +22 -0
  89. package/dist/excalidraw-assets-dev/locales/ru-RU-json-f941229aeb3c961f6afe.js +22 -0
  90. package/dist/excalidraw-assets-dev/locales/si-LK-json-2f1de88a189ba6ba696d.js +22 -0
  91. package/dist/excalidraw-assets-dev/locales/sk-SK-json-733bf7834531da06e409.js +22 -0
  92. package/dist/excalidraw-assets-dev/locales/sl-SI-json-302c47db8bdde83cfd9a.js +22 -0
  93. package/dist/excalidraw-assets-dev/locales/sv-SE-json-a3fbe43174a0b8c11dbe.js +22 -0
  94. package/dist/excalidraw-assets-dev/locales/ta-IN-json-97dde0a466b7ef9a293c.js +22 -0
  95. package/dist/excalidraw-assets-dev/locales/tr-TR-json-04ae317f3b25dd551c7b.js +22 -0
  96. package/dist/excalidraw-assets-dev/locales/uk-UA-json-fb4ddced83dd1b4e6d50.js +22 -0
  97. package/dist/excalidraw-assets-dev/locales/vi-VN-json-5d796333807e34aee311.js +22 -0
  98. package/dist/excalidraw-assets-dev/locales/zh-CN-json-5cc1474f0523d903964f.js +22 -0
  99. package/dist/excalidraw-assets-dev/locales/zh-HK-json-66e5d1f5e052d9b895e2.js +22 -0
  100. package/dist/excalidraw-assets-dev/locales/zh-TW-json-a05cd2023060266e8e0e.js +22 -0
  101. package/dist/excalidraw-assets-dev/{vendor-c0592035c3911af79359.js → vendor-e6df8519da951026ff69.js} +1 -1
  102. package/dist/excalidraw.development.js +68 -68
  103. package/dist/excalidraw.production.min.js +1 -1
  104. package/dist/excalidraw.production.min.js.LICENSE.txt +0 -9
  105. package/package.json +1 -1
  106. package/types/actions/actionAddToLibrary.d.ts +3 -3
  107. package/types/actions/actionBoundText.d.ts +1 -1
  108. package/types/actions/actionCanvas.d.ts +8 -8
  109. package/types/actions/actionClipboard.d.ts +6 -6
  110. package/types/actions/actionDeleteSelected.d.ts +4 -4
  111. package/types/actions/actionExport.d.ts +10 -10
  112. package/types/actions/actionFinalize.d.ts +2 -2
  113. package/types/actions/actionLinearEditor.d.ts +114 -0
  114. package/types/actions/actionMenu.d.ts +3 -3
  115. package/types/actions/actionProperties.d.ts +13 -13
  116. package/types/actions/actionStyles.d.ts +1 -1
  117. package/types/actions/actionToggleGridMode.d.ts +1 -1
  118. package/types/actions/actionToggleLock.d.ts +1 -1
  119. package/types/actions/actionToggleStats.d.ts +1 -1
  120. package/types/actions/actionToggleViewMode.d.ts +1 -1
  121. package/types/actions/actionToggleZenMode.d.ts +1 -1
  122. package/types/actions/index.d.ts +1 -0
  123. package/types/actions/types.d.ts +1 -1
  124. package/types/appState.d.ts +1 -1
  125. package/types/components/Actions.d.ts +13 -2
  126. package/types/components/App.d.ts +2 -0
  127. package/types/components/BackgroundPickerAndDarkModeToggle.d.ts +1 -6
  128. package/types/components/Footer.d.ts +9 -0
  129. package/types/components/InitializeApp.d.ts +2 -0
  130. package/types/components/LayerUI.d.ts +1 -2
  131. package/types/components/LibraryMenu.d.ts +1 -2
  132. package/types/components/LoadingMessage.d.ts +2 -0
  133. package/types/components/MobileMenu.d.ts +3 -4
  134. package/types/components/Stats.d.ts +1 -1
  135. package/types/constants.d.ts +12 -1
  136. package/types/data/blob.d.ts +1 -1
  137. package/types/element/Hyperlink.d.ts +2 -3
  138. package/types/element/bounds.d.ts +1 -1
  139. package/types/element/image.d.ts +1 -1
  140. package/types/element/linearElementEditor.d.ts +20 -9
  141. package/types/element/newElement.d.ts +6 -1
  142. package/types/element/textElement.d.ts +6 -2
  143. package/types/element/transformHandles.d.ts +2 -2
  144. package/types/element/types.d.ts +3 -2
  145. package/types/math.d.ts +8 -1
  146. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{ar-SA-json-4ff31c0432fe4c84d726.d.ts → ar-SA-json-6ffeaa9e26c2b7330686.d.ts} +0 -0
  147. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{bg-BG-json-1c6eb789a5c90a61edf8.d.ts → bg-BG-json-fbf6d2bf83c4515ebafd.d.ts} +0 -0
  148. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{bn-BD-json-aa99c5a33f005fb00c6b.d.ts → bn-BD-json-9660edf4f9c5c3fa09f8.d.ts} +0 -0
  149. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{ca-ES-json-32cf66a0dfdbbafb6903.d.ts → ca-ES-json-660f4a27f14ae032f524.d.ts} +0 -0
  150. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{cs-CZ-json-304d08cac870aa0684ec.d.ts → cs-CZ-json-7d148472909389dd280c.d.ts} +0 -0
  151. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{da-DK-json-80c7153473e1427a9a3b.d.ts → da-DK-json-10334bd5451bdc83fb4a.d.ts} +0 -0
  152. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{de-DE-json-9b88838b2648d7d61f1b.d.ts → de-DE-json-cd6a62a79609bc57697a.d.ts} +0 -0
  153. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{el-GR-json-74f57c0f8b11ac1b6dde.d.ts → el-GR-json-a7b859391ac05d909fdf.d.ts} +0 -0
  154. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{es-ES-json-ffb4e65453db2f3058d4.d.ts → es-ES-json-812c9fcccc4550e0e87c.d.ts} +0 -0
  155. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{eu-ES-json-a61838a778c9eacb61ec.d.ts → eu-ES-json-4b83e0e39ff358e41e57.d.ts} +0 -0
  156. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{fa-IR-json-2d0cb1044744ed8e4139.d.ts → fa-IR-json-078dbd1fe9b8bb5a198a.d.ts} +0 -0
  157. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{fi-FI-json-32bcb6481756ef8af590.d.ts → fi-FI-json-70202ae5946ce3b701c3.d.ts} +0 -0
  158. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{fr-FR-json-935424b03b86c1d82dcd.d.ts → fr-FR-json-593cbb471dcbd3415acc.d.ts} +0 -0
  159. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{gl-ES-json-5b417484d91976bce190.d.ts → gl-ES-json-022ea7861fff2205d681.d.ts} +0 -0
  160. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{he-IL-json-3f5bfefb1ad0baf19b6c.d.ts → he-IL-json-bd267ab47c66aa865d61.d.ts} +0 -0
  161. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{hi-IN-json-71a38dbb2202baec2bad.d.ts → hi-IN-json-3253b42b857f7d697a17.d.ts} +0 -0
  162. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{hu-HU-json-e1275f2b1e6ae6ef4427.d.ts → hu-HU-json-7682d17d39a5d4e81db3.d.ts} +0 -0
  163. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{id-ID-json-da38cd847aaf195c3c20.d.ts → id-ID-json-cf7b7a1d260657b7f48d.d.ts} +0 -0
  164. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{it-IT-json-10923c290e23bd31a5b4.d.ts → it-IT-json-17067e488b7b42ed8585.d.ts} +0 -0
  165. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{ja-JP-json-4c357f8206b88dc44840.d.ts → ja-JP-json-77b53a6596535fe2f0f9.d.ts} +0 -0
  166. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{kab-KAB-json-8303afee283a95237f2b.d.ts → kab-KAB-json-b7c0fda12f95048622f2.d.ts} +0 -0
  167. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{kk-KZ-json-ccf0876179807d1d685a.d.ts → kk-KZ-json-754a1a92ec1065f31d3d.d.ts} +0 -0
  168. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{ko-KR-json-f27d159b2556809076aa.d.ts → ko-KR-json-ae943359b26f9ea208de.d.ts} +0 -0
  169. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{lt-LT-json-7277ad8dae6d3e6607b3.d.ts → lt-LT-json-f79704ea6f1a9210a637.d.ts} +0 -0
  170. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{lv-LV-json-cc5e03ed2a09f8f8b60b.d.ts → lv-LV-json-8154a6d9cdd04d190900.d.ts} +0 -0
  171. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{mr-IN-json-cb316f30d7b40d3e6766.d.ts → mr-IN-json-a3a6ffee6ae2aa509e8b.d.ts} +0 -0
  172. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{my-MM-json-5dcc8e9cb97a4aa1d8bc.d.ts → my-MM-json-cdcb60976a56fa6f7c97.d.ts} +0 -0
  173. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{nb-NO-json-61192c4af6e2231d38ae.d.ts → nb-NO-json-7a0ea24170387ac4ca6e.d.ts} +0 -0
  174. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{nl-NL-json-861ac93c048b5296b791.d.ts → nl-NL-json-a2b6473ccab62e9eaf72.d.ts} +0 -0
  175. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{nn-NO-json-808362c0cd4eccb6a885.d.ts → nn-NO-json-6145a1539034ce59ae52.d.ts} +0 -0
  176. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{oc-FR-json-d5706569ab4023f94c66.d.ts → oc-FR-json-7f2a9a6e8c562d638936.d.ts} +0 -0
  177. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{pa-IN-json-eb38ce8bfc1b974c1455.d.ts → pa-IN-json-62611111c1ca22fc6d9a.d.ts} +0 -0
  178. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{pl-PL-json-55d8dd8a44917364ef63.d.ts → pl-PL-json-2c4f46b66947644b5f4e.d.ts} +0 -0
  179. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{pt-BR-json-686219f43cd76123b7fa.d.ts → pt-BR-json-c504d580b290f29aec0d.d.ts} +0 -0
  180. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{pt-PT-json-be4502ca3a1250845c39.d.ts → pt-PT-json-f68a4b23e6c8ba9937ba.d.ts} +0 -0
  181. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{ro-RO-json-232ea1e0c18745ec6ed9.d.ts → ro-RO-json-e1864108128e05214f5e.d.ts} +0 -0
  182. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{ru-RU-json-ce5fedd8812aa76a0b41.d.ts → ru-RU-json-d9a3269846d87a9ab50f.d.ts} +0 -0
  183. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{si-LK-json-f48a64dfd1cb9c075d2e.d.ts → si-LK-json-f58a27ca64b62d14d616.d.ts} +0 -0
  184. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{sk-SK-json-537132ec043d4db7f328.d.ts → sk-SK-json-5b585cac266b5b49fb0e.d.ts} +0 -0
  185. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{sl-SI-json-b69c9fd9b85dac1310c6.d.ts → sl-SI-json-cd0df9f835277c536509.d.ts} +0 -0
  186. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{sv-SE-json-9a8520b202b7181625cf.d.ts → sv-SE-json-e44b56cdbdbf8aba6482.d.ts} +0 -0
  187. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{ta-IN-json-15175d03785f7a482568.d.ts → ta-IN-json-0a3bd23deed6c9275f14.d.ts} +0 -0
  188. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{tr-TR-json-c53ae37e848043dd0b89.d.ts → tr-TR-json-2361be22b6b45118cff9.d.ts} +0 -0
  189. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{uk-UA-json-15fda426e55236408ef9.d.ts → uk-UA-json-0bc0a23d6421eea6b7f5.d.ts} +0 -0
  190. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{vi-VN-json-5c276b534d762658589c.d.ts → vi-VN-json-599cf6c1eb6b566f7c1a.d.ts} +0 -0
  191. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{zh-CN-json-0e3236ea93581e6ac2d3.d.ts → zh-CN-json-5d3b5822d355de9d7625.d.ts} +0 -0
  192. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{zh-HK-json-9e8b36ecb4c8399449b1.d.ts → zh-HK-json-0efec5474936a109241d.d.ts} +0 -0
  193. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{zh-TW-json-441a30840e0721d7f2e2.d.ts → zh-TW-json-4262eec09b4d3d5dfa94.d.ts} +0 -0
  194. package/types/packages/excalidraw/dist/excalidraw-assets/{vendor-52b1f3361986b6c6a4fe.d.ts → vendor-cb04f63875674d708080.d.ts} +0 -0
  195. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ar-SA-json-c8fa653de4977a22dad1.d.ts → ar-SA-json-e18bf994a8a492e04c5b.d.ts} +0 -0
  196. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{bg-BG-json-d7e517c7462119871c76.d.ts → bg-BG-json-c4822083b66facc7138b.d.ts} +0 -0
  197. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{bn-BD-json-02993b6dba9e7f115b53.d.ts → bn-BD-json-ebadec70518ef5b5fc5b.d.ts} +0 -0
  198. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ca-ES-json-7aabb5b31e7a995a90e3.d.ts → ca-ES-json-81a1896a4b8113466237.d.ts} +0 -0
  199. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{cs-CZ-json-a9cc158d187424de71d7.d.ts → cs-CZ-json-67246c64d571f677019b.d.ts} +0 -0
  200. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{da-DK-json-81b641c9b272e91762b8.d.ts → da-DK-json-4e6dd750a31d070daec9.d.ts} +0 -0
  201. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{de-DE-json-e9f68b4434bb76d28151.d.ts → de-DE-json-d0676faf8f1e90d3ce34.d.ts} +0 -0
  202. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{el-GR-json-2bc44d5450554154e110.d.ts → el-GR-json-9185ceab00e1598333d4.d.ts} +0 -0
  203. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{es-ES-json-9e5e962b234d2fa5aac2.d.ts → es-ES-json-a2870461506d73f41a72.d.ts} +0 -0
  204. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{eu-ES-json-05199638b0e1e11061f3.d.ts → eu-ES-json-3530634f7d5a3db297de.d.ts} +0 -0
  205. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{fa-IR-json-2a69e87cf2308b8e78f5.d.ts → fa-IR-json-66f5b4a41dc3aa7c8c45.d.ts} +0 -0
  206. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{fi-FI-json-6f0f0bcd3593bcc8930a.d.ts → fi-FI-json-7885764c835895664e0b.d.ts} +0 -0
  207. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{fr-FR-json-f53c7082a6f8691b7258.d.ts → fr-FR-json-ccb5eda23a779eb1880a.d.ts} +0 -0
  208. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{gl-ES-json-5295fdf24f032f998f75.d.ts → gl-ES-json-ab9c245372378f5f8c9b.d.ts} +0 -0
  209. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{he-IL-json-19fae6e424c8b418735d.d.ts → he-IL-json-7bfd6ca43596df3a84a1.d.ts} +0 -0
  210. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{hi-IN-json-f04242b20685f34378a5.d.ts → hi-IN-json-5148be3454f39f9bffb0.d.ts} +0 -0
  211. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{hu-HU-json-c8014a1b2a44d4885691.d.ts → hu-HU-json-f6436471ba8cccff3ac4.d.ts} +0 -0
  212. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{id-ID-json-bcd3ce43f1dbefe3f4d0.d.ts → id-ID-json-9328a35688d0537730ae.d.ts} +0 -0
  213. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{it-IT-json-946dc662ecab93b77e69.d.ts → it-IT-json-11bf19dfe8d8d38e6cec.d.ts} +0 -0
  214. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ja-JP-json-77b3461742458e757b59.d.ts → ja-JP-json-c670cda6d6c171611c79.d.ts} +0 -0
  215. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{kab-KAB-json-5e733b113476a350e900.d.ts → kab-KAB-json-396d5e8936a8362b536c.d.ts} +0 -0
  216. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{kk-KZ-json-5ec5044574589896438e.d.ts → kk-KZ-json-7c301df4020cd7c670e2.d.ts} +0 -0
  217. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ko-KR-json-09de6762eea271167b56.d.ts → ko-KR-json-d6850be7bac8fc43af84.d.ts} +0 -0
  218. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{lt-LT-json-a17971ff33b8929e96d3.d.ts → lt-LT-json-263c5629ddf0ee7d7572.d.ts} +0 -0
  219. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{lv-LV-json-2d1a7d044c33d030ecca.d.ts → lv-LV-json-44a18e46e8c68310c7c8.d.ts} +0 -0
  220. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{mr-IN-json-ed8cde2f50a5f3c08e85.d.ts → mr-IN-json-b0cd94322c2b39884d52.d.ts} +0 -0
  221. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{my-MM-json-600fc533d1a1c8d3e2f9.d.ts → my-MM-json-b0c8ffa53fa7c9f7fc4d.d.ts} +0 -0
  222. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{nb-NO-json-c7c63cfd529a92ac3510.d.ts → nb-NO-json-216bb67091fd4a2e70e6.d.ts} +0 -0
  223. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{nl-NL-json-7e7200dded88b465781e.d.ts → nl-NL-json-820135e0dcbb62d8f23c.d.ts} +0 -0
  224. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{nn-NO-json-d654941277fcbace33bf.d.ts → nn-NO-json-059b39da1c7b19e93db6.d.ts} +0 -0
  225. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{oc-FR-json-2d347b7f54a867a5478f.d.ts → oc-FR-json-54a63799c742875f8b9b.d.ts} +0 -0
  226. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{pa-IN-json-63518bb328bf8b92790c.d.ts → pa-IN-json-e535caa54102fbcee393.d.ts} +0 -0
  227. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{pl-PL-json-92de366ba93223fa3d6a.d.ts → pl-PL-json-73e6bd0c53922c9c71ba.d.ts} +0 -0
  228. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{pt-BR-json-5e4c8cd83b785ed859c2.d.ts → pt-BR-json-19be79102dd3cb5a95dc.d.ts} +0 -0
  229. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{pt-PT-json-a7f89a1c6f1c380141e5.d.ts → pt-PT-json-4b8554cd18248130c618.d.ts} +0 -0
  230. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ro-RO-json-6903d070f824f8b91709.d.ts → ro-RO-json-718b6921865260332b51.d.ts} +0 -0
  231. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ru-RU-json-110d8aec7823819bf4e3.d.ts → ru-RU-json-f941229aeb3c961f6afe.d.ts} +0 -0
  232. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{si-LK-json-ad2dff740d16a23684ff.d.ts → si-LK-json-2f1de88a189ba6ba696d.d.ts} +0 -0
  233. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{sk-SK-json-209333495d21be527f89.d.ts → sk-SK-json-733bf7834531da06e409.d.ts} +0 -0
  234. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{sl-SI-json-76bdeb34579c5b1f944f.d.ts → sl-SI-json-302c47db8bdde83cfd9a.d.ts} +0 -0
  235. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{sv-SE-json-6e768d07fff4e3ed6560.d.ts → sv-SE-json-a3fbe43174a0b8c11dbe.d.ts} +0 -0
  236. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ta-IN-json-059a459deba6d6230393.d.ts → ta-IN-json-97dde0a466b7ef9a293c.d.ts} +0 -0
  237. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{tr-TR-json-7cc28f1f798ef2dd9864.d.ts → tr-TR-json-04ae317f3b25dd551c7b.d.ts} +0 -0
  238. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{uk-UA-json-80b2990c3144c6bb1270.d.ts → uk-UA-json-fb4ddced83dd1b4e6d50.d.ts} +0 -0
  239. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{vi-VN-json-670ecb0ad40c0453bdfd.d.ts → vi-VN-json-5d796333807e34aee311.d.ts} +0 -0
  240. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{zh-CN-json-26caa1a6379860230513.d.ts → zh-CN-json-5cc1474f0523d903964f.d.ts} +0 -0
  241. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{zh-HK-json-179f6dc61b14b96215fa.d.ts → zh-HK-json-66e5d1f5e052d9b895e2.d.ts} +0 -0
  242. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{zh-TW-json-2aeeb73d79793ee69bfc.d.ts → zh-TW-json-a05cd2023060266e8e0e.d.ts} +0 -0
  243. package/types/packages/excalidraw/dist/excalidraw-assets-dev/{vendor-c0592035c3911af79359.d.ts → vendor-e6df8519da951026ff69.d.ts} +0 -0
  244. package/types/packages/utils.d.ts +4 -1
  245. package/types/points.d.ts +1 -1
  246. package/types/types.d.ts +1 -2
  247. package/dist/excalidraw-assets/locales/ar-SA-json-4ff31c0432fe4c84d726.js +0 -1
  248. package/dist/excalidraw-assets/locales/bg-BG-json-1c6eb789a5c90a61edf8.js +0 -1
  249. package/dist/excalidraw-assets/locales/bn-BD-json-aa99c5a33f005fb00c6b.js +0 -1
  250. package/dist/excalidraw-assets/locales/ca-ES-json-32cf66a0dfdbbafb6903.js +0 -1
  251. package/dist/excalidraw-assets/locales/cs-CZ-json-304d08cac870aa0684ec.js +0 -1
  252. package/dist/excalidraw-assets/locales/da-DK-json-80c7153473e1427a9a3b.js +0 -1
  253. package/dist/excalidraw-assets/locales/de-DE-json-9b88838b2648d7d61f1b.js +0 -1
  254. package/dist/excalidraw-assets/locales/el-GR-json-74f57c0f8b11ac1b6dde.js +0 -1
  255. package/dist/excalidraw-assets/locales/es-ES-json-ffb4e65453db2f3058d4.js +0 -1
  256. package/dist/excalidraw-assets/locales/eu-ES-json-a61838a778c9eacb61ec.js +0 -1
  257. package/dist/excalidraw-assets/locales/fa-IR-json-2d0cb1044744ed8e4139.js +0 -1
  258. package/dist/excalidraw-assets/locales/fi-FI-json-32bcb6481756ef8af590.js +0 -1
  259. package/dist/excalidraw-assets/locales/fr-FR-json-935424b03b86c1d82dcd.js +0 -1
  260. package/dist/excalidraw-assets/locales/gl-ES-json-5b417484d91976bce190.js +0 -1
  261. package/dist/excalidraw-assets/locales/he-IL-json-3f5bfefb1ad0baf19b6c.js +0 -1
  262. package/dist/excalidraw-assets/locales/hi-IN-json-71a38dbb2202baec2bad.js +0 -1
  263. package/dist/excalidraw-assets/locales/hu-HU-json-e1275f2b1e6ae6ef4427.js +0 -1
  264. package/dist/excalidraw-assets/locales/id-ID-json-da38cd847aaf195c3c20.js +0 -1
  265. package/dist/excalidraw-assets/locales/it-IT-json-10923c290e23bd31a5b4.js +0 -1
  266. package/dist/excalidraw-assets/locales/ja-JP-json-4c357f8206b88dc44840.js +0 -1
  267. package/dist/excalidraw-assets/locales/kab-KAB-json-8303afee283a95237f2b.js +0 -1
  268. package/dist/excalidraw-assets/locales/kk-KZ-json-ccf0876179807d1d685a.js +0 -1
  269. package/dist/excalidraw-assets/locales/ko-KR-json-f27d159b2556809076aa.js +0 -1
  270. package/dist/excalidraw-assets/locales/lt-LT-json-7277ad8dae6d3e6607b3.js +0 -1
  271. package/dist/excalidraw-assets/locales/lv-LV-json-cc5e03ed2a09f8f8b60b.js +0 -1
  272. package/dist/excalidraw-assets/locales/mr-IN-json-cb316f30d7b40d3e6766.js +0 -1
  273. package/dist/excalidraw-assets/locales/my-MM-json-5dcc8e9cb97a4aa1d8bc.js +0 -1
  274. package/dist/excalidraw-assets/locales/nb-NO-json-61192c4af6e2231d38ae.js +0 -1
  275. package/dist/excalidraw-assets/locales/nl-NL-json-861ac93c048b5296b791.js +0 -1
  276. package/dist/excalidraw-assets/locales/nn-NO-json-808362c0cd4eccb6a885.js +0 -1
  277. package/dist/excalidraw-assets/locales/oc-FR-json-d5706569ab4023f94c66.js +0 -1
  278. package/dist/excalidraw-assets/locales/pa-IN-json-eb38ce8bfc1b974c1455.js +0 -1
  279. package/dist/excalidraw-assets/locales/pl-PL-json-55d8dd8a44917364ef63.js +0 -1
  280. package/dist/excalidraw-assets/locales/pt-BR-json-686219f43cd76123b7fa.js +0 -1
  281. package/dist/excalidraw-assets/locales/pt-PT-json-be4502ca3a1250845c39.js +0 -1
  282. package/dist/excalidraw-assets/locales/ro-RO-json-232ea1e0c18745ec6ed9.js +0 -1
  283. package/dist/excalidraw-assets/locales/ru-RU-json-ce5fedd8812aa76a0b41.js +0 -1
  284. package/dist/excalidraw-assets/locales/si-LK-json-f48a64dfd1cb9c075d2e.js +0 -1
  285. package/dist/excalidraw-assets/locales/sk-SK-json-537132ec043d4db7f328.js +0 -1
  286. package/dist/excalidraw-assets/locales/sl-SI-json-b69c9fd9b85dac1310c6.js +0 -1
  287. package/dist/excalidraw-assets/locales/sv-SE-json-9a8520b202b7181625cf.js +0 -1
  288. package/dist/excalidraw-assets/locales/ta-IN-json-15175d03785f7a482568.js +0 -1
  289. package/dist/excalidraw-assets/locales/tr-TR-json-c53ae37e848043dd0b89.js +0 -1
  290. package/dist/excalidraw-assets/locales/uk-UA-json-15fda426e55236408ef9.js +0 -1
  291. package/dist/excalidraw-assets/locales/vi-VN-json-5c276b534d762658589c.js +0 -1
  292. package/dist/excalidraw-assets/locales/zh-CN-json-0e3236ea93581e6ac2d3.js +0 -1
  293. package/dist/excalidraw-assets/locales/zh-HK-json-9e8b36ecb4c8399449b1.js +0 -1
  294. package/dist/excalidraw-assets/locales/zh-TW-json-441a30840e0721d7f2e2.js +0 -1
  295. package/dist/excalidraw-assets/vendor-52b1f3361986b6c6a4fe.js +0 -2
  296. package/dist/excalidraw-assets-dev/locales/ar-SA-json-c8fa653de4977a22dad1.js +0 -22
  297. package/dist/excalidraw-assets-dev/locales/bg-BG-json-d7e517c7462119871c76.js +0 -22
  298. package/dist/excalidraw-assets-dev/locales/bn-BD-json-02993b6dba9e7f115b53.js +0 -22
  299. package/dist/excalidraw-assets-dev/locales/ca-ES-json-7aabb5b31e7a995a90e3.js +0 -22
  300. package/dist/excalidraw-assets-dev/locales/cs-CZ-json-a9cc158d187424de71d7.js +0 -22
  301. package/dist/excalidraw-assets-dev/locales/da-DK-json-81b641c9b272e91762b8.js +0 -22
  302. package/dist/excalidraw-assets-dev/locales/de-DE-json-e9f68b4434bb76d28151.js +0 -22
  303. package/dist/excalidraw-assets-dev/locales/el-GR-json-2bc44d5450554154e110.js +0 -22
  304. package/dist/excalidraw-assets-dev/locales/es-ES-json-9e5e962b234d2fa5aac2.js +0 -22
  305. package/dist/excalidraw-assets-dev/locales/eu-ES-json-05199638b0e1e11061f3.js +0 -22
  306. package/dist/excalidraw-assets-dev/locales/fa-IR-json-2a69e87cf2308b8e78f5.js +0 -22
  307. package/dist/excalidraw-assets-dev/locales/fi-FI-json-6f0f0bcd3593bcc8930a.js +0 -22
  308. package/dist/excalidraw-assets-dev/locales/fr-FR-json-f53c7082a6f8691b7258.js +0 -22
  309. package/dist/excalidraw-assets-dev/locales/gl-ES-json-5295fdf24f032f998f75.js +0 -22
  310. package/dist/excalidraw-assets-dev/locales/he-IL-json-19fae6e424c8b418735d.js +0 -22
  311. package/dist/excalidraw-assets-dev/locales/hi-IN-json-f04242b20685f34378a5.js +0 -22
  312. package/dist/excalidraw-assets-dev/locales/hu-HU-json-c8014a1b2a44d4885691.js +0 -22
  313. package/dist/excalidraw-assets-dev/locales/id-ID-json-bcd3ce43f1dbefe3f4d0.js +0 -22
  314. package/dist/excalidraw-assets-dev/locales/it-IT-json-946dc662ecab93b77e69.js +0 -22
  315. package/dist/excalidraw-assets-dev/locales/ja-JP-json-77b3461742458e757b59.js +0 -22
  316. package/dist/excalidraw-assets-dev/locales/kab-KAB-json-5e733b113476a350e900.js +0 -22
  317. package/dist/excalidraw-assets-dev/locales/kk-KZ-json-5ec5044574589896438e.js +0 -22
  318. package/dist/excalidraw-assets-dev/locales/ko-KR-json-09de6762eea271167b56.js +0 -22
  319. package/dist/excalidraw-assets-dev/locales/lt-LT-json-a17971ff33b8929e96d3.js +0 -22
  320. package/dist/excalidraw-assets-dev/locales/lv-LV-json-2d1a7d044c33d030ecca.js +0 -22
  321. package/dist/excalidraw-assets-dev/locales/mr-IN-json-ed8cde2f50a5f3c08e85.js +0 -22
  322. package/dist/excalidraw-assets-dev/locales/my-MM-json-600fc533d1a1c8d3e2f9.js +0 -22
  323. package/dist/excalidraw-assets-dev/locales/nb-NO-json-c7c63cfd529a92ac3510.js +0 -22
  324. package/dist/excalidraw-assets-dev/locales/nl-NL-json-7e7200dded88b465781e.js +0 -22
  325. package/dist/excalidraw-assets-dev/locales/nn-NO-json-d654941277fcbace33bf.js +0 -22
  326. package/dist/excalidraw-assets-dev/locales/oc-FR-json-2d347b7f54a867a5478f.js +0 -22
  327. package/dist/excalidraw-assets-dev/locales/pa-IN-json-63518bb328bf8b92790c.js +0 -22
  328. package/dist/excalidraw-assets-dev/locales/pl-PL-json-92de366ba93223fa3d6a.js +0 -22
  329. package/dist/excalidraw-assets-dev/locales/pt-BR-json-5e4c8cd83b785ed859c2.js +0 -22
  330. package/dist/excalidraw-assets-dev/locales/pt-PT-json-a7f89a1c6f1c380141e5.js +0 -22
  331. package/dist/excalidraw-assets-dev/locales/ro-RO-json-6903d070f824f8b91709.js +0 -22
  332. package/dist/excalidraw-assets-dev/locales/ru-RU-json-110d8aec7823819bf4e3.js +0 -22
  333. package/dist/excalidraw-assets-dev/locales/si-LK-json-ad2dff740d16a23684ff.js +0 -22
  334. package/dist/excalidraw-assets-dev/locales/sk-SK-json-209333495d21be527f89.js +0 -22
  335. package/dist/excalidraw-assets-dev/locales/sl-SI-json-76bdeb34579c5b1f944f.js +0 -22
  336. package/dist/excalidraw-assets-dev/locales/sv-SE-json-6e768d07fff4e3ed6560.js +0 -22
  337. package/dist/excalidraw-assets-dev/locales/ta-IN-json-059a459deba6d6230393.js +0 -22
  338. package/dist/excalidraw-assets-dev/locales/tr-TR-json-7cc28f1f798ef2dd9864.js +0 -22
  339. package/dist/excalidraw-assets-dev/locales/uk-UA-json-80b2990c3144c6bb1270.js +0 -22
  340. package/dist/excalidraw-assets-dev/locales/vi-VN-json-670ecb0ad40c0453bdfd.js +0 -22
  341. package/dist/excalidraw-assets-dev/locales/zh-CN-json-26caa1a6379860230513.js +0 -22
  342. package/dist/excalidraw-assets-dev/locales/zh-HK-json-179f6dc61b14b96215fa.js +0 -22
  343. package/dist/excalidraw-assets-dev/locales/zh-TW-json-2aeeb73d79793ee69bfc.js +0 -22
@@ -14,7 +14,7 @@
14
14
  \***********************************************/
15
15
  /***/ ((module) => {
16
16
 
17
- eval("/*!\n\npica\nhttps://github.com/nodeca/pica\n\n*/\n\n(function(f){if(true){module.exports=f()}else { var g; }})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=undefined;if(!f&&c)return require(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=undefined,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){\n// Collection of math functions\n//\n// 1. Combine components together\n// 2. Has async init to load wasm modules\n//\n'use strict';\n\nvar inherits = _dereq_('inherits');\n\nvar Multimath = _dereq_('multimath');\n\nvar mm_unsharp_mask = _dereq_('./mm_unsharp_mask');\n\nvar mm_resize = _dereq_('./mm_resize');\n\nfunction MathLib(requested_features) {\n var __requested_features = requested_features || [];\n\n var features = {\n js: __requested_features.indexOf('js') >= 0,\n wasm: __requested_features.indexOf('wasm') >= 0\n };\n Multimath.call(this, features);\n this.features = {\n js: features.js,\n wasm: features.wasm && this.has_wasm()\n };\n this.use(mm_unsharp_mask);\n this.use(mm_resize);\n}\n\ninherits(MathLib, Multimath);\n\nMathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {\n var result = this.resize(options, cache);\n\n if (options.unsharpAmount) {\n this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);\n }\n\n return result;\n};\n\nmodule.exports = MathLib;\n\n},{\"./mm_resize\":4,\"./mm_unsharp_mask\":9,\"inherits\":19,\"multimath\":20}],2:[function(_dereq_,module,exports){\n// Resize convolvers, pure JS implementation\n//\n'use strict'; // Precision of fixed FP values\n//var FIXED_FRAC_BITS = 14;\n\nfunction clampTo8(i) {\n return i < 0 ? 0 : i > 255 ? 255 : i;\n} // Convolve image in horizontal directions and transpose output. In theory,\n// transpose allow:\n//\n// - use the same convolver for both passes (this fails due different\n// types of input array and temporary buffer)\n// - making vertical pass by horisonltal lines inprove CPU cache use.\n//\n// But in real life this doesn't work :)\n//\n\n\nfunction convolveHorizontally(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n} // Technically, convolvers are the same. But input array and temporary\n// buffer can be of different type (especially, in old browsers). So,\n// keep code in separate functions to avoid deoptimizations & speed loss.\n\n\nfunction convolveVertically(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n}\n\nmodule.exports = {\n convolveHorizontally: convolveHorizontally,\n convolveVertically: convolveVertically\n};\n\n},{}],3:[function(_dereq_,module,exports){\n// This is autogenerated file from math.wasm, don't edit.\n//\n'use strict';\n/* eslint-disable max-len */\n\nmodule.exports = 'AGFzbQEAAAAADAZkeWxpbmsAAAAAAAEXA2AAAGAGf39/f39/AGAHf39/f39/fwACDwEDZW52Bm1lbW9yeQIAAAMEAwABAgYGAX8AQQALB1cFEV9fd2FzbV9jYWxsX2N0b3JzAAAIY29udm9sdmUAAQpjb252b2x2ZUhWAAIMX19kc29faGFuZGxlAwAYX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzAAAK7AMDAwABC8YDAQ9/AkAgA0UNACAERQ0AA0AgDCENQQAhE0EAIQcDQCAHQQJqIQYCfyAHQQF0IAVqIgcuAQIiFEUEQEGAwAAhCEGAwAAhCUGAwAAhCkGAwAAhCyAGDAELIBIgBy4BAGohCEEAIQsgFCEHQQAhDiAGIQlBACEPQQAhEANAIAUgCUEBdGouAQAiESAAIAhBAnRqKAIAIgpBGHZsIBBqIRAgCkH/AXEgEWwgC2ohCyAKQRB2Qf8BcSARbCAPaiEPIApBCHZB/wFxIBFsIA5qIQ4gCEEBaiEIIAlBAWohCSAHQQFrIgcNAAsgC0GAQGshCCAOQYBAayEJIA9BgEBrIQogEEGAQGshCyAGIBRqCyEHIAEgDUECdGogCUEOdSIGQf8BIAZB/wFIGyIGQQAgBkEAShtBCHRBgP4DcSAKQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EQdEGAgPwHcSALQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EYdHJyIAhBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobcjYCACADIA1qIQ0gE0EBaiITIARHDQALIAxBAWoiDCACbCESIAMgDEcNAAsLCx4AQQAgAiADIAQgBSAAEAEgAkEAIAQgBSAGIAEQAQs=';\n\n},{}],4:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = {\n name: 'resize',\n fn: _dereq_('./resize'),\n wasm_fn: _dereq_('./resize_wasm'),\n wasm_src: _dereq_('./convolve_wasm_base64')\n};\n\n},{\"./convolve_wasm_base64\":3,\"./resize\":5,\"./resize_wasm\":8}],5:[function(_dereq_,module,exports){\n'use strict';\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nvar convolveHorizontally = _dereq_('./convolve').convolveHorizontally;\n\nvar convolveVertically = _dereq_('./convolve').convolveVertically;\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nmodule.exports = function resize(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0;\n var offsetY = options.offsetY || 0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY);\n var tmp = new Uint8Array(destW * srcH * 4); // To use single function we need src & tmp of the same type.\n // But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep\n // vertical and horizontal passes separately to avoid deoptimization.\n\n convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);\n convolveVertically(tmp, dest, srcH, destW, destH, filtersY); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./convolve\":2,\"./resize_filter_gen\":6}],6:[function(_dereq_,module,exports){\n// Calculate convolution filters for each destination point,\n// and pack data to Int16Array:\n//\n// [ shift, length, data..., shift2, length2, data..., ... ]\n//\n// - shift - offset in src image\n// - length - filter length (in src points)\n// - data - filter values sequence\n//\n'use strict';\n\nvar FILTER_INFO = _dereq_('./resize_filter_info'); // Precision of fixed FP values\n\n\nvar FIXED_FRAC_BITS = 14;\n\nfunction toFixedPoint(num) {\n return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));\n}\n\nmodule.exports = function resizeFilterGen(quality, srcSize, destSize, scale, offset) {\n var filterFunction = FILTER_INFO[quality].filter;\n var scaleInverted = 1.0 / scale;\n var scaleClamped = Math.min(1.0, scale); // For upscale\n // Filter window (averaging interval), scaled to src image\n\n var srcWindow = FILTER_INFO[quality].win / scaleClamped;\n var destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;\n var leftNotEmpty, rightNotEmpty, filterShift, filterSize;\n var maxFilterElementSize = Math.floor((srcWindow + 1) * 2);\n var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);\n var packedFilterPtr = 0;\n var slowCopy = !packedFilter.subarray || !packedFilter.set; // For each destination pixel calculate source range and built filter values\n\n for (destPixel = 0; destPixel < destSize; destPixel++) {\n // Scaling should be done relative to central pixel point\n srcPixel = (destPixel + 0.5) * scaleInverted + offset;\n srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));\n srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));\n filterElementSize = srcLast - srcFirst + 1;\n floatFilter = new Float32Array(filterElementSize);\n fxpFilter = new Int16Array(filterElementSize);\n total = 0.0; // Fill filter values for calculated range\n\n for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {\n floatVal = filterFunction((pxl + 0.5 - srcPixel) * scaleClamped);\n total += floatVal;\n floatFilter[idx] = floatVal;\n } // Normalize filter, convert to fixed point and accumulate conversion error\n\n\n filterTotal = 0;\n\n for (idx = 0; idx < floatFilter.length; idx++) {\n filterVal = floatFilter[idx] / total;\n filterTotal += filterVal;\n fxpFilter[idx] = toFixedPoint(filterVal);\n } // Compensate normalization error, to minimize brightness drift\n\n\n fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal); //\n // Now pack filter to useable form\n //\n // 1. Trim heading and tailing zero values, and compensate shitf/length\n // 2. Put all to single array in this format:\n //\n // [ pos shift, data length, value1, value2, value3, ... ]\n //\n\n leftNotEmpty = 0;\n\n while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {\n leftNotEmpty++;\n }\n\n if (leftNotEmpty < fxpFilter.length) {\n rightNotEmpty = fxpFilter.length - 1;\n\n while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {\n rightNotEmpty--;\n }\n\n filterShift = srcFirst + leftNotEmpty;\n filterSize = rightNotEmpty - leftNotEmpty + 1;\n packedFilter[packedFilterPtr++] = filterShift; // shift\n\n packedFilter[packedFilterPtr++] = filterSize; // size\n\n if (!slowCopy) {\n packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);\n packedFilterPtr += filterSize;\n } else {\n // fallback for old IE < 11, without subarray/set methods\n for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {\n packedFilter[packedFilterPtr++] = fxpFilter[idx];\n }\n }\n } else {\n // zero data, write header only\n packedFilter[packedFilterPtr++] = 0; // shift\n\n packedFilter[packedFilterPtr++] = 0; // size\n }\n }\n\n return packedFilter;\n};\n\n},{\"./resize_filter_info\":7}],7:[function(_dereq_,module,exports){\n// Filter definitions to build tables for\n// resizing convolvers.\n//\n// Presets for quality 0..3. Filter functions + window size\n//\n'use strict';\n\nmodule.exports = [{\n // Nearest neibor (Box)\n win: 0.5,\n filter: function filter(x) {\n return x >= -0.5 && x < 0.5 ? 1.0 : 0.0;\n }\n}, {\n // Hamming\n win: 1.0,\n filter: function filter(x) {\n if (x <= -1.0 || x >= 1.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * (0.54 + 0.46 * Math.cos(xpi / 1.0));\n }\n}, {\n // Lanczos, win = 2\n win: 2.0,\n filter: function filter(x) {\n if (x <= -2.0 || x >= 2.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 2.0) / (xpi / 2.0);\n }\n}, {\n // Lanczos, win = 3\n win: 3.0,\n filter: function filter(x) {\n if (x <= -3.0 || x >= 3.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 3.0) / (xpi / 3.0);\n }\n}];\n\n},{}],8:[function(_dereq_,module,exports){\n'use strict';\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nfunction asUint8Array(src) {\n return new Uint8Array(src.buffer, 0, src.byteLength);\n}\n\nvar IS_LE = true; // should not crash everything on module load in old browsers\n\ntry {\n IS_LE = new Uint32Array(new Uint8Array([1, 0, 0, 0]).buffer)[0] === 1;\n} catch (__) {}\n\nfunction copyInt16asLE(src, target, target_offset) {\n if (IS_LE) {\n target.set(asUint8Array(src), target_offset);\n return;\n }\n\n for (var ptr = target_offset, i = 0; i < src.length; i++) {\n var data = src[i];\n target[ptr++] = data & 0xFF;\n target[ptr++] = data >> 8 & 0xFF;\n }\n}\n\nmodule.exports = function resize_wasm(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0.0;\n var offsetY = options.offsetY || 0.0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY); // destination is 0 too.\n\n var src_offset = 0; // buffer between convolve passes\n\n var tmp_offset = this.__align(src_offset + Math.max(src.byteLength, dest.byteLength));\n\n var filtersX_offset = this.__align(tmp_offset + srcH * destW * 4);\n\n var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);\n\n var alloc_bytes = filtersY_offset + filtersY.byteLength;\n\n var instance = this.__instance('resize', alloc_bytes); //\n // Fill memory block with data to process\n //\n\n\n var mem = new Uint8Array(this.__memory.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer); // 32-bit copy is much faster in chrome\n\n var src32 = new Uint32Array(src.buffer);\n mem32.set(src32); // We should guarantee LE bytes order. Filters are not big, so\n // speed difference is not significant vs direct .set()\n\n copyInt16asLE(filtersX, mem, filtersX_offset);\n copyInt16asLE(filtersY, mem, filtersY_offset); //\n // Now call webassembly method\n // emsdk does method names with '_'\n\n var fn = instance.exports.convolveHV || instance.exports._convolveHV;\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH); //\n // Copy data back to typed array\n //\n // 32-bit copy is much faster in chrome\n\n var dest32 = new Uint32Array(dest.buffer);\n dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW)); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./resize_filter_gen\":6}],9:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = {\n name: 'unsharp_mask',\n fn: _dereq_('./unsharp_mask'),\n wasm_fn: _dereq_('./unsharp_mask_wasm'),\n wasm_src: _dereq_('./unsharp_mask_wasm_base64')\n};\n\n},{\"./unsharp_mask\":10,\"./unsharp_mask_wasm\":11,\"./unsharp_mask_wasm_base64\":12}],10:[function(_dereq_,module,exports){\n// Unsharp mask filter\n//\n// http://stackoverflow.com/a/23322820/1031804\n// USM(O) = O + (2 * (Amount / 100) * (O - GB))\n// GB - gaussian blur.\n//\n// Image is converted from RGB to HSV, unsharp mask is applied to the\n// brightness channel and then image is converted back to RGB.\n//\n'use strict';\n\nvar glur_mono16 = _dereq_('glur/mono16');\n\nfunction hsv_v16(img, width, height) {\n var size = width * height;\n var out = new Uint16Array(size);\n var r, g, b, max;\n\n for (var i = 0; i < size; i++) {\n r = img[4 * i];\n g = img[4 * i + 1];\n b = img[4 * i + 2];\n max = r >= g && r >= b ? r : g >= b && g >= r ? g : b;\n out[i] = max << 8;\n }\n\n return out;\n}\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n var v1, v2, vmul;\n var diff, iTimes4;\n\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var brightness = hsv_v16(img, width, height);\n var blured = new Uint16Array(brightness); // copy, because blur modify src\n\n glur_mono16(blured, width, height, radius);\n var amountFp = amount / 100 * 0x1000 + 0.5 | 0;\n var thresholdFp = threshold << 8;\n var size = width * height;\n /* eslint-disable indent */\n\n for (var i = 0; i < size; i++) {\n v1 = brightness[i];\n diff = v1 - blured[i];\n\n if (Math.abs(diff) >= thresholdFp) {\n // add unsharp mask to the brightness channel\n v2 = v1 + (amountFp * diff + 0x800 >> 12); // Both v1 and v2 are within [0.0 .. 255.0] (0000-FF00) range, never going into\n // [255.003 .. 255.996] (FF01-FFFF). This allows to round this value as (x+.5)|0\n // later without overflowing.\n\n v2 = v2 > 0xff00 ? 0xff00 : v2;\n v2 = v2 < 0x0000 ? 0x0000 : v2; // Avoid division by 0. V=0 means rgb(0,0,0), unsharp with unsharpAmount>0 cannot\n // change this value (because diff between colors gets inflated), so no need to verify correctness.\n\n v1 = v1 !== 0 ? v1 : 1; // Multiplying V in HSV model by a constant is equivalent to multiplying each component\n // in RGB by the same constant (same for HSL), see also:\n // https://beesbuzz.biz/code/16-hsv-color-transforms\n\n vmul = (v2 << 12) / v1 | 0; // Result will be in [0..255] range because:\n // - all numbers are positive\n // - r,g,b <= (v1/256)\n // - r,g,b,(v1/256),(v2/256) <= 255\n // So highest this number can get is X*255/X+0.5=255.5 which is < 256 and rounds down.\n\n iTimes4 = i * 4;\n img[iTimes4] = img[iTimes4] * vmul + 0x800 >> 12; // R\n\n img[iTimes4 + 1] = img[iTimes4 + 1] * vmul + 0x800 >> 12; // G\n\n img[iTimes4 + 2] = img[iTimes4 + 2] * vmul + 0x800 >> 12; // B\n }\n }\n};\n\n},{\"glur/mono16\":18}],11:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var pixels = width * height;\n var img_bytes_cnt = pixels * 4;\n var hsv_bytes_cnt = pixels * 2;\n var blur_bytes_cnt = pixels * 2;\n var blur_line_byte_cnt = Math.max(width, height) * 4; // float32 array\n\n var blur_coeffs_byte_cnt = 8 * 4; // float32 array\n\n var img_offset = 0;\n var hsv_offset = img_bytes_cnt;\n var blur_offset = hsv_offset + hsv_bytes_cnt;\n var blur_tmp_offset = blur_offset + blur_bytes_cnt;\n var blur_line_offset = blur_tmp_offset + blur_bytes_cnt;\n var blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;\n\n var instance = this.__instance('unsharp_mask', img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt, {\n exp: Math.exp\n }); // 32-bit copy is much faster in chrome\n\n\n var img32 = new Uint32Array(img.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer);\n mem32.set(img32); // HSL\n\n var fn = instance.exports.hsv_v16 || instance.exports._hsv_v16;\n fn(img_offset, hsv_offset, width, height); // BLUR\n\n fn = instance.exports.blurMono16 || instance.exports._blurMono16;\n fn(hsv_offset, blur_offset, blur_tmp_offset, blur_line_offset, blur_coeffs_offset, width, height, radius); // UNSHARP\n\n fn = instance.exports.unsharp || instance.exports._unsharp;\n fn(img_offset, img_offset, hsv_offset, blur_offset, width, height, amount, threshold); // 32-bit copy is much faster in chrome\n\n img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));\n};\n\n},{}],12:[function(_dereq_,module,exports){\n// This is autogenerated file from math.wasm, don't edit.\n//\n'use strict';\n/* eslint-disable max-len */\n\nmodule.exports = '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';\n\n},{}],13:[function(_dereq_,module,exports){\n'use strict';\n\nvar GC_INTERVAL = 100;\n\nfunction Pool(create, idle) {\n this.create = create;\n this.available = [];\n this.acquired = {};\n this.lastId = 1;\n this.timeoutId = 0;\n this.idle = idle || 2000;\n}\n\nPool.prototype.acquire = function () {\n var _this = this;\n\n var resource;\n\n if (this.available.length !== 0) {\n resource = this.available.pop();\n } else {\n resource = this.create();\n resource.id = this.lastId++;\n\n resource.release = function () {\n return _this.release(resource);\n };\n }\n\n this.acquired[resource.id] = resource;\n return resource;\n};\n\nPool.prototype.release = function (resource) {\n var _this2 = this;\n\n delete this.acquired[resource.id];\n resource.lastUsed = Date.now();\n this.available.push(resource);\n\n if (this.timeoutId === 0) {\n this.timeoutId = setTimeout(function () {\n return _this2.gc();\n }, GC_INTERVAL);\n }\n};\n\nPool.prototype.gc = function () {\n var _this3 = this;\n\n var now = Date.now();\n this.available = this.available.filter(function (resource) {\n if (now - resource.lastUsed > _this3.idle) {\n resource.destroy();\n return false;\n }\n\n return true;\n });\n\n if (this.available.length !== 0) {\n this.timeoutId = setTimeout(function () {\n return _this3.gc();\n }, GC_INTERVAL);\n } else {\n this.timeoutId = 0;\n }\n};\n\nmodule.exports = Pool;\n\n},{}],14:[function(_dereq_,module,exports){\n// Add intermediate resizing steps when scaling down by a very large factor.\n//\n// For example, when resizing 10000x10000 down to 10x10, it'll resize it to\n// 300x300 first.\n//\n// It's needed because tiler has issues when the entire tile is scaled down\n// to a few pixels (1024px source tile with border size 3 should result in\n// at least 3+3+2 = 8px target tile, so max scale factor is 128 here).\n//\n// Also, adding intermediate steps can speed up processing if we use lower\n// quality algorithms for first stages.\n//\n'use strict'; // min size = 0 results in infinite loop,\n// min size = 1 can consume large amount of memory\n\nvar MIN_INNER_TILE_SIZE = 2;\n\nmodule.exports = function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize, destTileBorder) {\n var scaleX = toWidth / fromWidth;\n var scaleY = toHeight / fromHeight; // derived from createRegions equation:\n // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;\n\n var minScale = (2 * destTileBorder + MIN_INNER_TILE_SIZE + 1) / srcTileSize; // refuse to scale image multiple times by less than twice each time,\n // it could only happen because of invalid options\n\n if (minScale > 0.5) return [[toWidth, toHeight]];\n var stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale)); // no additional resizes are necessary,\n // stageCount can be zero or be negative when enlarging the image\n\n if (stageCount <= 1) return [[toWidth, toHeight]];\n var result = [];\n\n for (var i = 0; i < stageCount; i++) {\n var width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));\n var height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));\n result.push([width, height]);\n }\n\n return result;\n};\n\n},{}],15:[function(_dereq_,module,exports){\n// Split original image into multiple 1024x1024 chunks to reduce memory usage\n// (images have to be unpacked into typed arrays for resizing) and allow\n// parallel processing of multiple tiles at a time.\n//\n'use strict';\n/*\n * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil\n * functions which take into account floating point arithmetic errors.\n * Those errors can cause undesired increments/decrements of sizes and offsets:\n * Math.ceil(36 / (36 / 500)) = 501\n * pixelCeil(36 / (36 / 500)) = 500\n */\n\nvar PIXEL_EPSILON = 1e-5;\n\nfunction pixelFloor(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.floor(x);\n}\n\nfunction pixelCeil(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.ceil(x);\n}\n\nmodule.exports = function createRegions(options) {\n var scaleX = options.toWidth / options.width;\n var scaleY = options.toHeight / options.height;\n var innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;\n var innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder; // prevent infinite loop, this should never happen\n\n if (innerTileWidth < 1 || innerTileHeight < 1) {\n throw new Error('Internal error in pica: target tile width/height is too small.');\n }\n\n var x, y;\n var innerX, innerY, toTileWidth, toTileHeight;\n var tiles = [];\n var tile; // we go top-to-down instead of left-to-right to make image displayed from top to\n // doesn in the browser\n\n for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {\n for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {\n x = innerX - options.destTileBorder;\n\n if (x < 0) {\n x = 0;\n }\n\n toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;\n\n if (x + toTileWidth >= options.toWidth) {\n toTileWidth = options.toWidth - x;\n }\n\n y = innerY - options.destTileBorder;\n\n if (y < 0) {\n y = 0;\n }\n\n toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;\n\n if (y + toTileHeight >= options.toHeight) {\n toTileHeight = options.toHeight - y;\n }\n\n tile = {\n toX: x,\n toY: y,\n toWidth: toTileWidth,\n toHeight: toTileHeight,\n toInnerX: innerX,\n toInnerY: innerY,\n toInnerWidth: innerTileWidth,\n toInnerHeight: innerTileHeight,\n offsetX: x / scaleX - pixelFloor(x / scaleX),\n offsetY: y / scaleY - pixelFloor(y / scaleY),\n scaleX: scaleX,\n scaleY: scaleY,\n x: pixelFloor(x / scaleX),\n y: pixelFloor(y / scaleY),\n width: pixelCeil(toTileWidth / scaleX),\n height: pixelCeil(toTileHeight / scaleY)\n };\n tiles.push(tile);\n }\n }\n\n return tiles;\n};\n\n},{}],16:[function(_dereq_,module,exports){\n'use strict';\n\nfunction objClass(obj) {\n return Object.prototype.toString.call(obj);\n}\n\nmodule.exports.isCanvas = function isCanvas(element) {\n var cname = objClass(element);\n return cname === '[object HTMLCanvasElement]'\n /* browser */\n || cname === '[object OffscreenCanvas]' || cname === '[object Canvas]'\n /* node-canvas */\n ;\n};\n\nmodule.exports.isImage = function isImage(element) {\n return objClass(element) === '[object HTMLImageElement]';\n};\n\nmodule.exports.isImageBitmap = function isImageBitmap(element) {\n return objClass(element) === '[object ImageBitmap]';\n};\n\nmodule.exports.limiter = function limiter(concurrency) {\n var active = 0,\n queue = [];\n\n function roll() {\n if (active < concurrency && queue.length) {\n active++;\n queue.shift()();\n }\n }\n\n return function limit(fn) {\n return new Promise(function (resolve, reject) {\n queue.push(function () {\n fn().then(function (result) {\n resolve(result);\n active--;\n roll();\n }, function (err) {\n reject(err);\n active--;\n roll();\n });\n });\n roll();\n });\n };\n};\n\nmodule.exports.cib_quality_name = function cib_quality_name(num) {\n switch (num) {\n case 0:\n return 'pixelated';\n\n case 1:\n return 'low';\n\n case 2:\n return 'medium';\n }\n\n return 'high';\n};\n\nmodule.exports.cib_support = function cib_support(createCanvas) {\n return Promise.resolve().then(function () {\n if (typeof createImageBitmap === 'undefined') {\n return false;\n }\n\n var c = createCanvas(100, 100);\n return createImageBitmap(c, 0, 0, 100, 100, {\n resizeWidth: 10,\n resizeHeight: 10,\n resizeQuality: 'high'\n }).then(function (bitmap) {\n var status = bitmap.width === 10; // Branch below is filtered on upper level. We do not call resize\n // detection for basic ImageBitmap.\n //\n // https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap\n // old Crome 51 has ImageBitmap without .close(). Then this code\n // will throw and return 'false' as expected.\n //\n\n bitmap.close();\n c = null;\n return status;\n });\n })[\"catch\"](function () {\n return false;\n });\n};\n\nmodule.exports.worker_offscreen_canvas_support = function worker_offscreen_canvas_support() {\n return new Promise(function (resolve, reject) {\n if (typeof OffscreenCanvas === 'undefined') {\n // if OffscreenCanvas is present, we assume browser supports Worker and built-in Promise as well\n resolve(false);\n return;\n }\n\n function workerPayload(self) {\n if (typeof createImageBitmap === 'undefined') {\n self.postMessage(false);\n return;\n }\n\n Promise.resolve().then(function () {\n var canvas = new OffscreenCanvas(10, 10); // test that 2d context can be used in worker\n\n var ctx = canvas.getContext('2d');\n ctx.rect(0, 0, 1, 1); // test that cib can be used to return image bitmap from worker\n\n return createImageBitmap(canvas, 0, 0, 1, 1);\n }).then(function () {\n return self.postMessage(true);\n }, function () {\n return self.postMessage(false);\n });\n }\n\n var code = btoa(\"(\".concat(workerPayload.toString(), \")(self);\"));\n var w = new Worker(\"data:text/javascript;base64,\".concat(code));\n\n w.onmessage = function (ev) {\n return resolve(ev.data);\n };\n\n w.onerror = reject;\n }).then(function (result) {\n return result;\n }, function () {\n return false;\n });\n}; // Check if canvas.getContext('2d').getImageData can be used,\n// FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode\n\n\nmodule.exports.can_use_canvas = function can_use_canvas(createCanvas) {\n var usable = false;\n\n try {\n var canvas = createCanvas(2, 1);\n var ctx = canvas.getContext('2d');\n var d = ctx.createImageData(2, 1);\n d.data[0] = 12;\n d.data[1] = 23;\n d.data[2] = 34;\n d.data[3] = 255;\n d.data[4] = 45;\n d.data[5] = 56;\n d.data[6] = 67;\n d.data[7] = 255;\n ctx.putImageData(d, 0, 0);\n d = null;\n d = ctx.getImageData(0, 0, 2, 1);\n\n if (d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 && d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255) {\n usable = true;\n }\n } catch (err) {}\n\n return usable;\n}; // Check if createImageBitmap(img, sx, sy, sw, sh) signature works correctly\n// with JPEG images oriented with Exif;\n// https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n// TODO: remove after it's fixed in chrome for at least 2 releases\n\n\nmodule.exports.cib_can_use_region = function cib_can_use_region() {\n return new Promise(function (resolve) {\n if (typeof createImageBitmap === 'undefined') {\n resolve(false);\n return;\n }\n\n var image = new Image();\n image.src = 'data:image/jpeg;base64,' + '/9j/4QBiRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAYAAAEaAAUAAAABAAAASgEbAAUAA' + 'AABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAAAAABIAAAAAQAAAEgAAAAB/9' + 'sAQwAEAwMEAwMEBAMEBQQEBQYKBwYGBgYNCQoICg8NEBAPDQ8OERMYFBESFxIODxUcFRc' + 'ZGRsbGxAUHR8dGh8YGhsa/9sAQwEEBQUGBQYMBwcMGhEPERoaGhoaGhoaGhoaGhoaGhoa' + 'GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa/8IAEQgAAQACAwERAAIRAQMRA' + 'f/EABQAAQAAAAAAAAAAAAAAAAAAAAf/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAA' + 'IQAxAAAAF/P//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAA' + 'AAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIB' + 'AT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAA' + 'AAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQH//EABQRAQAAAAAAAAAAAAAAAA' + 'AAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQ' + 'QAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z';\n\n image.onload = function () {\n createImageBitmap(image, 0, 0, image.width, image.height).then(function (bitmap) {\n if (bitmap.width === image.width && bitmap.height === image.height) {\n resolve(true);\n } else {\n resolve(false);\n }\n }, function () {\n return resolve(false);\n });\n };\n\n image.onerror = function () {\n return resolve(false);\n };\n });\n};\n\n},{}],17:[function(_dereq_,module,exports){\n// Web Worker wrapper for image resize function\n'use strict';\n\nmodule.exports = function () {\n var MathLib = _dereq_('./mathlib');\n\n var mathLib;\n /* eslint-disable no-undef */\n\n onmessage = function onmessage(ev) {\n var tileOpts = ev.data.opts;\n var returnBitmap = false;\n\n if (!tileOpts.src && tileOpts.srcBitmap) {\n var canvas = new OffscreenCanvas(tileOpts.width, tileOpts.height);\n var ctx = canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n ctx.drawImage(tileOpts.srcBitmap, 0, 0);\n tileOpts.src = ctx.getImageData(0, 0, tileOpts.width, tileOpts.height).data;\n canvas.width = canvas.height = 0;\n canvas = null;\n tileOpts.srcBitmap.close();\n tileOpts.srcBitmap = null;\n returnBitmap = true;\n }\n\n if (!mathLib) mathLib = new MathLib(ev.data.features); // Use multimath's sync auto-init. Avoid Promise use in old browsers,\n // because polyfills are not propagated to webworker.\n\n var data = mathLib.resizeAndUnsharp(tileOpts);\n\n if (returnBitmap) {\n var toImageData = new ImageData(new Uint8ClampedArray(data), tileOpts.toWidth, tileOpts.toHeight);\n\n var _canvas = new OffscreenCanvas(tileOpts.toWidth, tileOpts.toHeight);\n\n var _ctx = _canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n\n _ctx.putImageData(toImageData, 0, 0);\n\n createImageBitmap(_canvas).then(function (bitmap) {\n postMessage({\n bitmap: bitmap\n }, [bitmap]);\n });\n } else {\n postMessage({\n data: data\n }, [data.buffer]);\n }\n };\n};\n\n},{\"./mathlib\":1}],18:[function(_dereq_,module,exports){\n// Calculate Gaussian blur of an image using IIR filter\n// The method is taken from Intel's white paper and code example attached to it:\n// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter\n// -implementation-using-intel-advanced-vector-extensions\n\nvar a0, a1, a2, a3, b1, b2, left_corner, right_corner;\n\nfunction gaussCoef(sigma) {\n if (sigma < 0.5) {\n sigma = 0.5;\n }\n\n var a = Math.exp(0.726 * 0.726) / sigma,\n g1 = Math.exp(-a),\n g2 = Math.exp(-2 * a),\n k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);\n\n a0 = k;\n a1 = k * (a - 1) * g1;\n a2 = k * (a + 1) * g1;\n a3 = -k * g2;\n b1 = 2 * g1;\n b2 = -g2;\n left_corner = (a0 + a1) / (1 - b1 - b2);\n right_corner = (a2 + a3) / (1 - b1 - b2);\n\n // Attempt to force type to FP32.\n return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);\n}\n\nfunction convolveMono16(src, out, line, coeff, width, height) {\n // takes src image and writes the blurred and transposed result into out\n\n var prev_src, curr_src, curr_out, prev_out, prev_prev_out;\n var src_index, out_index, line_index;\n var i, j;\n var coeff_a0, coeff_a1, coeff_b1, coeff_b2;\n\n for (i = 0; i < height; i++) {\n src_index = i * width;\n out_index = i;\n line_index = 0;\n\n // left to right\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[6];\n prev_out = prev_prev_out;\n\n coeff_a0 = coeff[0];\n coeff_a1 = coeff[1];\n coeff_b1 = coeff[4];\n coeff_b2 = coeff[5];\n\n for (j = 0; j < width; j++) {\n curr_src = src[src_index];\n\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n prev_src = curr_src;\n\n line[line_index] = prev_out;\n line_index++;\n src_index++;\n }\n\n src_index--;\n line_index--;\n out_index += height * (width - 1);\n\n // right to left\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[7];\n prev_out = prev_prev_out;\n curr_src = prev_src;\n\n coeff_a0 = coeff[2];\n coeff_a1 = coeff[3];\n\n for (j = width - 1; j >= 0; j--) {\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n\n prev_src = curr_src;\n curr_src = src[src_index];\n\n out[out_index] = line[line_index] + prev_out;\n\n src_index--;\n line_index--;\n out_index -= height;\n }\n }\n}\n\n\nfunction blurMono16(src, width, height, radius) {\n // Quick exit on zero radius\n if (!radius) { return; }\n\n var out = new Uint16Array(src.length),\n tmp_line = new Float32Array(Math.max(width, height));\n\n var coeff = gaussCoef(radius);\n\n convolveMono16(src, out, tmp_line, coeff, width, height, radius);\n convolveMono16(out, src, tmp_line, coeff, height, width, radius);\n}\n\nmodule.exports = blurMono16;\n\n},{}],19:[function(_dereq_,module,exports){\nif (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n\n},{}],20:[function(_dereq_,module,exports){\n'use strict';\n\n\nvar assign = _dereq_('object-assign');\nvar base64decode = _dereq_('./lib/base64decode');\nvar hasWebAssembly = _dereq_('./lib/wa_detect');\n\n\nvar DEFAULT_OPTIONS = {\n js: true,\n wasm: true\n};\n\n\nfunction MultiMath(options) {\n if (!(this instanceof MultiMath)) return new MultiMath(options);\n\n var opts = assign({}, DEFAULT_OPTIONS, options || {});\n\n this.options = opts;\n\n this.__cache = {};\n\n this.__init_promise = null;\n this.__modules = opts.modules || {};\n this.__memory = null;\n this.__wasm = {};\n\n this.__isLE = ((new Uint32Array((new Uint8Array([ 1, 0, 0, 0 ])).buffer))[0] === 1);\n\n if (!this.options.js && !this.options.wasm) {\n throw new Error('mathlib: at least \"js\" or \"wasm\" should be enabled');\n }\n}\n\n\nMultiMath.prototype.has_wasm = hasWebAssembly;\n\n\nMultiMath.prototype.use = function (module) {\n this.__modules[module.name] = module;\n\n // Pin the best possible implementation\n if (this.options.wasm && this.has_wasm() && module.wasm_fn) {\n this[module.name] = module.wasm_fn;\n } else {\n this[module.name] = module.fn;\n }\n\n return this;\n};\n\n\nMultiMath.prototype.init = function () {\n if (this.__init_promise) return this.__init_promise;\n\n if (!this.options.js && this.options.wasm && !this.has_wasm()) {\n return Promise.reject(new Error('mathlib: only \"wasm\" was enabled, but it\\'s not supported'));\n }\n\n var self = this;\n\n this.__init_promise = Promise.all(Object.keys(self.__modules).map(function (name) {\n var module = self.__modules[name];\n\n if (!self.options.wasm || !self.has_wasm() || !module.wasm_fn) return null;\n\n // If already compiled - exit\n if (self.__wasm[name]) return null;\n\n // Compile wasm source\n return WebAssembly.compile(self.__base64decode(module.wasm_src))\n .then(function (m) { self.__wasm[name] = m; });\n }))\n .then(function () { return self; });\n\n return this.__init_promise;\n};\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Methods below are for internal use from plugins\n\n\n// Simple decode base64 to typed array. Useful to load embedded webassembly\n// code. You probably don't need to call this method directly.\n//\nMultiMath.prototype.__base64decode = base64decode;\n\n\n// Increase current memory to include specified number of bytes. Do nothing if\n// size is already ok. You probably don't need to call this method directly,\n// because it will be invoked from `.__instance()`.\n//\nMultiMath.prototype.__reallocate = function mem_grow_to(bytes) {\n if (!this.__memory) {\n this.__memory = new WebAssembly.Memory({\n initial: Math.ceil(bytes / (64 * 1024))\n });\n return this.__memory;\n }\n\n var mem_size = this.__memory.buffer.byteLength;\n\n if (mem_size < bytes) {\n this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));\n }\n\n return this.__memory;\n};\n\n\n// Returns instantinated webassembly item by name, with specified memory size\n// and environment.\n// - use cache if available\n// - do sync module init, if async init was not called earlier\n// - allocate memory if not enougth\n// - can export functions to webassembly via \"env_extra\",\n// for example, { exp: Math.exp }\n//\nMultiMath.prototype.__instance = function instance(name, memsize, env_extra) {\n if (memsize) this.__reallocate(memsize);\n\n // If .init() was not called, do sync compile\n if (!this.__wasm[name]) {\n var module = this.__modules[name];\n this.__wasm[name] = new WebAssembly.Module(this.__base64decode(module.wasm_src));\n }\n\n if (!this.__cache[name]) {\n var env_base = {\n memoryBase: 0,\n memory: this.__memory,\n tableBase: 0,\n table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })\n };\n\n this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {\n env: assign(env_base, env_extra || {})\n });\n }\n\n return this.__cache[name];\n};\n\n\n// Helper to calculate memory aligh for pointers. Webassembly does not require\n// this, but you may wish to experiment. Default base = 8;\n//\nMultiMath.prototype.__align = function align(number, base) {\n base = base || 8;\n var reminder = number % base;\n return number + (reminder ? base - reminder : 0);\n};\n\n\nmodule.exports = MultiMath;\n\n},{\"./lib/base64decode\":21,\"./lib/wa_detect\":22,\"object-assign\":23}],21:[function(_dereq_,module,exports){\n// base64 decode str -> Uint8Array, to load WA modules\n//\n'use strict';\n\n\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n\nmodule.exports = function base64decode(str) {\n var input = str.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length;\n\n var out = new Uint8Array((max * 3) >> 2);\n\n // Collect by 6*4 bits (3 bytes)\n\n var bits = 0;\n var ptr = 0;\n\n for (var idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n }\n\n bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n var tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n } else if (tailbits === 18) {\n out[ptr++] = (bits >> 10) & 0xFF;\n out[ptr++] = (bits >> 2) & 0xFF;\n } else if (tailbits === 12) {\n out[ptr++] = (bits >> 4) & 0xFF;\n }\n\n return out;\n};\n\n},{}],22:[function(_dereq_,module,exports){\n// Detect WebAssembly support.\n// - Check global WebAssembly object\n// - Try to load simple module (can be disabled via CSP)\n//\n'use strict';\n\n\nvar wa;\n\n\nmodule.exports = function hasWebAssembly() {\n // use cache if called before;\n if (typeof wa !== 'undefined') return wa;\n\n wa = false;\n\n if (typeof WebAssembly === 'undefined') return wa;\n\n // If WebAssenbly is disabled, code can throw on compile\n try {\n // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js\n // Additional check that WA internals are correct\n\n /* eslint-disable comma-spacing, max-len */\n var bin = new Uint8Array([ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11 ]);\n var module = new WebAssembly.Module(bin);\n var instance = new WebAssembly.Instance(module, {});\n\n // test storing to and loading from a non-zero location via a parameter.\n // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations\n if (instance.exports.test(4) !== 0) wa = true;\n\n return wa;\n } catch (__) {}\n\n return wa;\n};\n\n},{}],23:[function(_dereq_,module,exports){\n/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\n},{}],24:[function(_dereq_,module,exports){\nvar bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n 'function(require,module,exports){' + fn + '(self); }',\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n 'function(require,module,exports){' +\n // try to call default if defined to also support babel esmodule exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);' +\n '}',\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n\n},{}],\"/index.js\":[function(_dereq_,module,exports){\n'use strict';\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar assign = _dereq_('object-assign');\n\nvar webworkify = _dereq_('webworkify');\n\nvar MathLib = _dereq_('./lib/mathlib');\n\nvar Pool = _dereq_('./lib/pool');\n\nvar utils = _dereq_('./lib/utils');\n\nvar worker = _dereq_('./lib/worker');\n\nvar createStages = _dereq_('./lib/stepper');\n\nvar createRegions = _dereq_('./lib/tiler'); // Deduplicate pools & limiters with the same configs\n// when user creates multiple pica instances.\n\n\nvar singletones = {};\nvar NEED_SAFARI_FIX = false;\n\ntry {\n if (typeof navigator !== 'undefined' && navigator.userAgent) {\n NEED_SAFARI_FIX = navigator.userAgent.indexOf('Safari') >= 0;\n }\n} catch (e) {}\n\nvar concurrency = 1;\n\nif (typeof navigator !== 'undefined') {\n concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);\n}\n\nvar DEFAULT_PICA_OPTS = {\n tile: 1024,\n concurrency: concurrency,\n features: ['js', 'wasm', 'ww'],\n idle: 2000,\n createCanvas: function createCanvas(width, height) {\n var tmpCanvas = document.createElement('canvas');\n tmpCanvas.width = width;\n tmpCanvas.height = height;\n return tmpCanvas;\n }\n};\nvar DEFAULT_RESIZE_OPTS = {\n quality: 3,\n alpha: false,\n unsharpAmount: 0,\n unsharpRadius: 0.0,\n unsharpThreshold: 0\n};\nvar CAN_NEW_IMAGE_DATA = false;\nvar CAN_CREATE_IMAGE_BITMAP = false;\nvar CAN_USE_CANVAS_GET_IMAGE_DATA = false;\nvar CAN_USE_OFFSCREEN_CANVAS = false;\nvar CAN_USE_CIB_REGION_FOR_IMAGE = false;\n\nfunction workerFabric() {\n return {\n value: webworkify(worker),\n destroy: function destroy() {\n this.value.terminate();\n\n if (typeof window !== 'undefined') {\n var url = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n if (url && url.revokeObjectURL && this.value.objectURL) {\n url.revokeObjectURL(this.value.objectURL);\n }\n }\n }\n };\n} ////////////////////////////////////////////////////////////////////////////////\n// API methods\n\n\nfunction Pica(options) {\n if (!(this instanceof Pica)) return new Pica(options);\n this.options = assign({}, DEFAULT_PICA_OPTS, options || {});\n var limiter_key = \"lk_\".concat(this.options.concurrency); // Share limiters to avoid multiple parallel workers when user creates\n // multiple pica instances.\n\n this.__limit = singletones[limiter_key] || utils.limiter(this.options.concurrency);\n if (!singletones[limiter_key]) singletones[limiter_key] = this.__limit; // List of supported features, according to options & browser/node.js\n\n this.features = {\n js: false,\n // pure JS implementation, can be disabled for testing\n wasm: false,\n // webassembly implementation for heavy functions\n cib: false,\n // resize via createImageBitmap (only FF at this moment)\n ww: false // webworkers\n\n };\n this.__workersPool = null; // Store requested features for webworkers\n\n this.__requested_features = [];\n this.__mathlib = null;\n}\n\nPica.prototype.init = function () {\n var _this = this;\n\n if (this.__initPromise) return this.__initPromise; // Test if we can create ImageData without canvas and memory copy\n\n if (typeof ImageData !== 'undefined' && typeof Uint8ClampedArray !== 'undefined') {\n try {\n /* eslint-disable no-new */\n new ImageData(new Uint8ClampedArray(400), 10, 10);\n CAN_NEW_IMAGE_DATA = true;\n } catch (__) {}\n } // ImageBitmap can be effective in 2 places:\n //\n // 1. Threaded jpeg unpack (basic)\n // 2. Built-in resize (blocked due problem in chrome, see issue #89)\n //\n // For basic use we also need ImageBitmap wo support .close() method,\n // see https://developer.mozilla.org/ru/docs/Web/API/ImageBitmap\n\n\n if (typeof ImageBitmap !== 'undefined') {\n if (ImageBitmap.prototype && ImageBitmap.prototype.close) {\n CAN_CREATE_IMAGE_BITMAP = true;\n } else {\n this.debug('ImageBitmap does not support .close(), disabled');\n }\n }\n\n var features = this.options.features.slice();\n\n if (features.indexOf('all') >= 0) {\n features = ['cib', 'wasm', 'js', 'ww'];\n }\n\n this.__requested_features = features;\n this.__mathlib = new MathLib(features); // Check WebWorker support if requested\n\n if (features.indexOf('ww') >= 0) {\n if (typeof window !== 'undefined' && 'Worker' in window) {\n // IE <= 11 don't allow to create webworkers from string. We should check it.\n // https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11\n try {\n var wkr = _dereq_('webworkify')(function () {});\n\n wkr.terminate();\n this.features.ww = true; // pool uniqueness depends on pool config + webworker config\n\n var wpool_key = \"wp_\".concat(JSON.stringify(this.options));\n\n if (singletones[wpool_key]) {\n this.__workersPool = singletones[wpool_key];\n } else {\n this.__workersPool = new Pool(workerFabric, this.options.idle);\n singletones[wpool_key] = this.__workersPool;\n }\n } catch (__) {}\n }\n }\n\n var initMath = this.__mathlib.init().then(function (mathlib) {\n // Copy detected features\n assign(_this.features, mathlib.features);\n });\n\n var checkCibResize;\n\n if (!CAN_CREATE_IMAGE_BITMAP) {\n checkCibResize = Promise.resolve(false);\n } else {\n checkCibResize = utils.cib_support(this.options.createCanvas).then(function (status) {\n if (_this.features.cib && features.indexOf('cib') < 0) {\n _this.debug('createImageBitmap() resize supported, but disabled by config');\n\n return;\n }\n\n if (features.indexOf('cib') >= 0) _this.features.cib = status;\n });\n }\n\n CAN_USE_CANVAS_GET_IMAGE_DATA = utils.can_use_canvas(this.options.createCanvas);\n var checkOffscreenCanvas;\n\n if (CAN_CREATE_IMAGE_BITMAP && CAN_NEW_IMAGE_DATA && features.indexOf('ww') !== -1) {\n checkOffscreenCanvas = utils.worker_offscreen_canvas_support();\n } else {\n checkOffscreenCanvas = Promise.resolve(false);\n }\n\n checkOffscreenCanvas = checkOffscreenCanvas.then(function (result) {\n CAN_USE_OFFSCREEN_CANVAS = result;\n }); // we use createImageBitmap to crop image data and pass it to workers,\n // so need to check whether function works correctly;\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n\n var checkCibRegion = utils.cib_can_use_region().then(function (result) {\n CAN_USE_CIB_REGION_FOR_IMAGE = result;\n }); // Init math lib. That's async because can load some\n\n this.__initPromise = Promise.all([initMath, checkCibResize, checkOffscreenCanvas, checkCibRegion]).then(function () {\n return _this;\n });\n return this.__initPromise;\n}; // Call resizer in webworker or locally, depending on config\n\n\nPica.prototype.__invokeResize = function (tileOpts, opts) {\n var _this2 = this;\n\n // Share cache between calls:\n //\n // - wasm instance\n // - wasm memory object\n //\n opts.__mathCache = opts.__mathCache || {};\n return Promise.resolve().then(function () {\n if (!_this2.features.ww) {\n // not possible to have ImageBitmap here if user disabled WW\n return {\n data: _this2.__mathlib.resizeAndUnsharp(tileOpts, opts.__mathCache)\n };\n }\n\n return new Promise(function (resolve, reject) {\n var w = _this2.__workersPool.acquire();\n\n if (opts.cancelToken) opts.cancelToken[\"catch\"](function (err) {\n return reject(err);\n });\n\n w.value.onmessage = function (ev) {\n w.release();\n if (ev.data.err) reject(ev.data.err);else resolve(ev.data);\n };\n\n var transfer = [];\n if (tileOpts.src) transfer.push(tileOpts.src.buffer);\n if (tileOpts.srcBitmap) transfer.push(tileOpts.srcBitmap);\n w.value.postMessage({\n opts: tileOpts,\n features: _this2.__requested_features,\n preload: {\n wasm_nodule: _this2.__mathlib.__\n }\n }, transfer);\n });\n });\n}; // this function can return promise if createImageBitmap is used\n\n\nPica.prototype.__extractTileData = function (tile, from, opts, stageEnv, extractTo) {\n if (this.features.ww && CAN_USE_OFFSCREEN_CANVAS && ( // createImageBitmap doesn't work for images (Image, ImageBitmap) with Exif orientation in Chrome,\n // can use canvas because canvas doesn't have orientation;\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n utils.isCanvas(from) || CAN_USE_CIB_REGION_FOR_IMAGE)) {\n this.debug('Create tile for OffscreenCanvas');\n return createImageBitmap(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height).then(function (bitmap) {\n extractTo.srcBitmap = bitmap;\n return extractTo;\n });\n } // Extract tile RGBA buffer, depending on input type\n\n\n if (utils.isCanvas(from)) {\n if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d', {\n alpha: Boolean(opts.alpha)\n }); // If input is Canvas - extract region data directly\n\n this.debug('Get tile pixel data');\n extractTo.src = stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data;\n return extractTo;\n } // If input is Image or decoded to ImageBitmap,\n // draw region to temporary canvas and extract data from it\n //\n // Note! Attempt to reuse this canvas causes significant slowdown in chrome\n //\n\n\n this.debug('Draw tile imageBitmap/image to temporary canvas');\n var tmpCanvas = this.options.createCanvas(tile.width, tile.height);\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.globalCompositeOperation = 'copy';\n tmpCtx.drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);\n this.debug('Get tile pixel data');\n extractTo.src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data; // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n return extractTo;\n};\n\nPica.prototype.__landTileData = function (tile, result, stageEnv) {\n var toImageData;\n this.debug('Convert raw rgba tile result to ImageData');\n\n if (result.bitmap) {\n stageEnv.toCtx.drawImage(result.bitmap, tile.toX, tile.toY);\n return null;\n }\n\n if (CAN_NEW_IMAGE_DATA) {\n // this branch is for modern browsers\n // If `new ImageData()` & Uint8ClampedArray suported\n toImageData = new ImageData(new Uint8ClampedArray(result.data), tile.toWidth, tile.toHeight);\n } else {\n // fallback for `node-canvas` and old browsers\n // (IE11 has ImageData but does not support `new ImageData()`)\n toImageData = stageEnv.toCtx.createImageData(tile.toWidth, tile.toHeight);\n\n if (toImageData.data.set) {\n toImageData.data.set(result.data);\n } else {\n // IE9 don't have `.set()`\n for (var i = toImageData.data.length - 1; i >= 0; i--) {\n toImageData.data[i] = result.data[i];\n }\n }\n }\n\n this.debug('Draw tile');\n\n if (NEED_SAFARI_FIX) {\n // Safari draws thin white stripes between tiles without this fix\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);\n } else {\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);\n }\n\n return null;\n};\n\nPica.prototype.__tileAndResize = function (from, to, opts) {\n var _this3 = this;\n\n var stageEnv = {\n srcCtx: null,\n srcImageBitmap: null,\n isImageBitmapReused: false,\n toCtx: null\n };\n\n var processTile = function processTile(tile) {\n return _this3.__limit(function () {\n if (opts.canceled) return opts.cancelToken;\n var tileOpts = {\n width: tile.width,\n height: tile.height,\n toWidth: tile.toWidth,\n toHeight: tile.toHeight,\n scaleX: tile.scaleX,\n scaleY: tile.scaleY,\n offsetX: tile.offsetX,\n offsetY: tile.offsetY,\n quality: opts.quality,\n alpha: opts.alpha,\n unsharpAmount: opts.unsharpAmount,\n unsharpRadius: opts.unsharpRadius,\n unsharpThreshold: opts.unsharpThreshold\n };\n\n _this3.debug('Invoke resize math');\n\n return Promise.resolve(tileOpts).then(function (tileOpts) {\n return _this3.__extractTileData(tile, from, opts, stageEnv, tileOpts);\n }).then(function (tileOpts) {\n _this3.debug('Invoke resize math');\n\n return _this3.__invokeResize(tileOpts, opts);\n }).then(function (result) {\n if (opts.canceled) return opts.cancelToken;\n stageEnv.srcImageData = null;\n return _this3.__landTileData(tile, result, stageEnv);\n });\n });\n }; // Need to normalize data source first. It can be canvas or image.\n // If image - try to decode in background if possible\n\n\n return Promise.resolve().then(function () {\n stageEnv.toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n if (utils.isCanvas(from)) return null;\n\n if (utils.isImageBitmap(from)) {\n stageEnv.srcImageBitmap = from;\n stageEnv.isImageBitmapReused = true;\n return null;\n }\n\n if (utils.isImage(from)) {\n // try do decode image in background for faster next operations;\n // if we're using offscreen canvas, cib is called per tile, so not needed here\n if (!CAN_CREATE_IMAGE_BITMAP) return null;\n\n _this3.debug('Decode image via createImageBitmap');\n\n return createImageBitmap(from).then(function (imageBitmap) {\n stageEnv.srcImageBitmap = imageBitmap;\n }) // Suppress error to use fallback, if method fails\n // https://github.com/nodeca/pica/issues/190\n\n /* eslint-disable no-unused-vars */\n [\"catch\"](function (e) {\n return null;\n });\n }\n\n throw new Error('Pica: \".from\" should be Image, Canvas or ImageBitmap');\n }).then(function () {\n if (opts.canceled) return opts.cancelToken;\n\n _this3.debug('Calculate tiles'); //\n // Here we are with \"normalized\" source,\n // follow to tiling\n //\n\n\n var regions = createRegions({\n width: opts.width,\n height: opts.height,\n srcTileSize: _this3.options.tile,\n toWidth: opts.toWidth,\n toHeight: opts.toHeight,\n destTileBorder: opts.__destTileBorder\n });\n var jobs = regions.map(function (tile) {\n return processTile(tile);\n });\n\n function cleanup(stageEnv) {\n if (stageEnv.srcImageBitmap) {\n if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close();\n stageEnv.srcImageBitmap = null;\n }\n }\n\n _this3.debug('Process tiles');\n\n return Promise.all(jobs).then(function () {\n _this3.debug('Finished!');\n\n cleanup(stageEnv);\n return to;\n }, function (err) {\n cleanup(stageEnv);\n throw err;\n });\n });\n};\n\nPica.prototype.__processStages = function (stages, from, to, opts) {\n var _this4 = this;\n\n if (opts.canceled) return opts.cancelToken;\n\n var _stages$shift = stages.shift(),\n _stages$shift2 = _slicedToArray(_stages$shift, 2),\n toWidth = _stages$shift2[0],\n toHeight = _stages$shift2[1];\n\n var isLastStage = stages.length === 0;\n opts = assign({}, opts, {\n toWidth: toWidth,\n toHeight: toHeight,\n // only use user-defined quality for the last stage,\n // use simpler (Hamming) filter for the first stages where\n // scale factor is large enough (more than 2-3)\n quality: isLastStage ? opts.quality : Math.min(1, opts.quality)\n });\n var tmpCanvas;\n\n if (!isLastStage) {\n // create temporary canvas\n tmpCanvas = this.options.createCanvas(toWidth, toHeight);\n }\n\n return this.__tileAndResize(from, isLastStage ? to : tmpCanvas, opts).then(function () {\n if (isLastStage) return to;\n opts.width = toWidth;\n opts.height = toHeight;\n return _this4.__processStages(stages, tmpCanvas, to, opts);\n }).then(function (res) {\n if (tmpCanvas) {\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0;\n }\n\n return res;\n });\n};\n\nPica.prototype.__resizeViaCreateImageBitmap = function (from, to, opts) {\n var _this5 = this;\n\n var toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n this.debug('Resize via createImageBitmap()');\n return createImageBitmap(from, {\n resizeWidth: opts.toWidth,\n resizeHeight: opts.toHeight,\n resizeQuality: utils.cib_quality_name(opts.quality)\n }).then(function (imageBitmap) {\n if (opts.canceled) return opts.cancelToken; // if no unsharp - draw directly to output canvas\n\n if (!opts.unsharpAmount) {\n toCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n }\n\n _this5.debug('Unsharp result');\n\n var tmpCanvas = _this5.options.createCanvas(opts.toWidth, opts.toHeight);\n\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);\n\n _this5.__mathlib.unsharp_mask(iData.data, opts.toWidth, opts.toHeight, opts.unsharpAmount, opts.unsharpRadius, opts.unsharpThreshold);\n\n toCtx.putImageData(iData, 0, 0); // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n iData = tmpCtx = tmpCanvas = toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n });\n};\n\nPica.prototype.resize = function (from, to, options) {\n var _this6 = this;\n\n this.debug('Start resize...');\n var opts = assign({}, DEFAULT_RESIZE_OPTS);\n\n if (!isNaN(options)) {\n opts = assign(opts, {\n quality: options\n });\n } else if (options) {\n opts = assign(opts, options);\n }\n\n opts.toWidth = to.width;\n opts.toHeight = to.height;\n opts.width = from.naturalWidth || from.width;\n opts.height = from.naturalHeight || from.height; // Prevent stepper from infinite loop\n\n if (to.width === 0 || to.height === 0) {\n return Promise.reject(new Error(\"Invalid output size: \".concat(to.width, \"x\").concat(to.height)));\n }\n\n if (opts.unsharpRadius > 2) opts.unsharpRadius = 2;\n opts.canceled = false;\n\n if (opts.cancelToken) {\n // Wrap cancelToken to avoid successive resolve & set flag\n opts.cancelToken = opts.cancelToken.then(function (data) {\n opts.canceled = true;\n throw data;\n }, function (err) {\n opts.canceled = true;\n throw err;\n });\n }\n\n var DEST_TILE_BORDER = 3; // Max possible filter window size\n\n opts.__destTileBorder = Math.ceil(Math.max(DEST_TILE_BORDER, 2.5 * opts.unsharpRadius | 0));\n return this.init().then(function () {\n if (opts.canceled) return opts.cancelToken; // if createImageBitmap supports resize, just do it and return\n\n if (_this6.features.cib) {\n return _this6.__resizeViaCreateImageBitmap(from, to, opts);\n }\n\n if (!CAN_USE_CANVAS_GET_IMAGE_DATA) {\n var err = new Error('Pica: cannot use getImageData on canvas, ' + \"make sure fingerprinting protection isn't enabled\");\n err.code = 'ERR_GET_IMAGE_DATA';\n throw err;\n } //\n // No easy way, let's resize manually via arrays\n //\n\n\n var stages = createStages(opts.width, opts.height, opts.toWidth, opts.toHeight, _this6.options.tile, opts.__destTileBorder);\n return _this6.__processStages(stages, from, to, opts);\n });\n}; // RGBA buffer resize\n//\n\n\nPica.prototype.resizeBuffer = function (options) {\n var _this7 = this;\n\n var opts = assign({}, DEFAULT_RESIZE_OPTS, options);\n return this.init().then(function () {\n return _this7.__mathlib.resizeAndUnsharp(opts);\n });\n};\n\nPica.prototype.toBlob = function (canvas, mimeType, quality) {\n mimeType = mimeType || 'image/png';\n return new Promise(function (resolve) {\n if (canvas.toBlob) {\n canvas.toBlob(function (blob) {\n return resolve(blob);\n }, mimeType, quality);\n return;\n }\n\n if (canvas.convertToBlob) {\n resolve(canvas.convertToBlob({\n type: mimeType,\n quality: quality\n }));\n return;\n } // Fallback for old browsers\n\n\n var asString = atob(canvas.toDataURL(mimeType, quality).split(',')[1]);\n var len = asString.length;\n var asBuffer = new Uint8Array(len);\n\n for (var i = 0; i < len; i++) {\n asBuffer[i] = asString.charCodeAt(i);\n }\n\n resolve(new Blob([asBuffer], {\n type: mimeType\n }));\n });\n};\n\nPica.prototype.debug = function () {};\n\nmodule.exports = Pica;\n\n},{\"./lib/mathlib\":1,\"./lib/pool\":13,\"./lib/stepper\":14,\"./lib/tiler\":15,\"./lib/utils\":16,\"./lib/worker\":17,\"object-assign\":23,\"webworkify\":24}]},{},[])(\"/index.js\")\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3BpY2EvZGlzdC9waWNhLmpzLmpzIiwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsYUFBYSxHQUFHLElBQXNELEVBQUUsbUJBQW1CLEtBQUssVUFBNk4sQ0FBQyxhQUFhLDBCQUEwQixtQkFBbUIsa0JBQWtCLGdCQUFnQixVQUFVLFVBQVUsTUFBTSxTQUFtQyxDQUFDLGdCQUFnQixPQUFDLE9BQU8sb0JBQW9CLDhDQUE4QyxrQ0FBa0MsWUFBWSxZQUFZLG1DQUFtQyxpQkFBaUIsZUFBZSxzQkFBc0Isb0JBQW9CLFVBQVUsU0FBbUMsS0FBSyxXQUFXLFlBQVksU0FBUyxTQUFTLEtBQUs7QUFDenpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSxtRUFBbUU7QUFDdEU7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7O0FBRXRCLGlCQUFpQixhQUFhO0FBQzlCLG1CQUFtQjs7QUFFbkIsb0JBQW9CLGVBQWU7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7O0FBRXpCLGFBQWEsZ0JBQWdCO0FBQzdCLDBDQUEwQztBQUMxQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxnREFBZ0QsUUFBUTtBQUN4RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0wsS0FBSztBQUNMOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxnREFBZ0Q7O0FBRWhEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEscUNBQXFDO0FBQ3JDOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRDs7QUFFbkQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBLGdEQUFnRDs7QUFFaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIOzs7QUFHQTtBQUNBOztBQUVBLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsTUFBTTs7O0FBR047QUFDQTtBQUNBOztBQUVBLG9CQUFvQixTQUFTO0FBQzdCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDRJQUE0SSxFQUFFLEdBQUc7QUFDcEosQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi8uLi9ub2RlX21vZHVsZXMvcGljYS9kaXN0L3BpY2EuanM/ZmY1OSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcblxucGljYVxuaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhXG5cbiovXG5cbihmdW5jdGlvbihmKXtpZih0eXBlb2YgZXhwb3J0cz09PVwib2JqZWN0XCImJnR5cGVvZiBtb2R1bGUhPT1cInVuZGVmaW5lZFwiKXttb2R1bGUuZXhwb3J0cz1mKCl9ZWxzZSBpZih0eXBlb2YgZGVmaW5lPT09XCJmdW5jdGlvblwiJiZkZWZpbmUuYW1kKXtkZWZpbmUoW10sZil9ZWxzZXt2YXIgZztpZih0eXBlb2Ygd2luZG93IT09XCJ1bmRlZmluZWRcIil7Zz13aW5kb3d9ZWxzZSBpZih0eXBlb2YgZ2xvYmFsIT09XCJ1bmRlZmluZWRcIil7Zz1nbG9iYWx9ZWxzZSBpZih0eXBlb2Ygc2VsZiE9PVwidW5kZWZpbmVkXCIpe2c9c2VsZn1lbHNle2c9dGhpc31nLnBpY2EgPSBmKCl9fSkoZnVuY3Rpb24oKXt2YXIgZGVmaW5lLG1vZHVsZSxleHBvcnRzO3JldHVybiAoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpKHsxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIENvbGxlY3Rpb24gb2YgbWF0aCBmdW5jdGlvbnNcbi8vXG4vLyAxLiBDb21iaW5lIGNvbXBvbmVudHMgdG9nZXRoZXJcbi8vIDIuIEhhcyBhc3luYyBpbml0IHRvIGxvYWQgd2FzbSBtb2R1bGVzXG4vL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW5oZXJpdHMgPSBfZGVyZXFfKCdpbmhlcml0cycpO1xuXG52YXIgTXVsdGltYXRoID0gX2RlcmVxXygnbXVsdGltYXRoJyk7XG5cbnZhciBtbV91bnNoYXJwX21hc2sgPSBfZGVyZXFfKCcuL21tX3Vuc2hhcnBfbWFzaycpO1xuXG52YXIgbW1fcmVzaXplID0gX2RlcmVxXygnLi9tbV9yZXNpemUnKTtcblxuZnVuY3Rpb24gTWF0aExpYihyZXF1ZXN0ZWRfZmVhdHVyZXMpIHtcbiAgdmFyIF9fcmVxdWVzdGVkX2ZlYXR1cmVzID0gcmVxdWVzdGVkX2ZlYXR1cmVzIHx8IFtdO1xuXG4gIHZhciBmZWF0dXJlcyA9IHtcbiAgICBqczogX19yZXF1ZXN0ZWRfZmVhdHVyZXMuaW5kZXhPZignanMnKSA+PSAwLFxuICAgIHdhc206IF9fcmVxdWVzdGVkX2ZlYXR1cmVzLmluZGV4T2YoJ3dhc20nKSA+PSAwXG4gIH07XG4gIE11bHRpbWF0aC5jYWxsKHRoaXMsIGZlYXR1cmVzKTtcbiAgdGhpcy5mZWF0dXJlcyA9IHtcbiAgICBqczogZmVhdHVyZXMuanMsXG4gICAgd2FzbTogZmVhdHVyZXMud2FzbSAmJiB0aGlzLmhhc193YXNtKClcbiAgfTtcbiAgdGhpcy51c2UobW1fdW5zaGFycF9tYXNrKTtcbiAgdGhpcy51c2UobW1fcmVzaXplKTtcbn1cblxuaW5oZXJpdHMoTWF0aExpYiwgTXVsdGltYXRoKTtcblxuTWF0aExpYi5wcm90b3R5cGUucmVzaXplQW5kVW5zaGFycCA9IGZ1bmN0aW9uIHJlc2l6ZUFuZFVuc2hhcnAob3B0aW9ucywgY2FjaGUpIHtcbiAgdmFyIHJlc3VsdCA9IHRoaXMucmVzaXplKG9wdGlvbnMsIGNhY2hlKTtcblxuICBpZiAob3B0aW9ucy51bnNoYXJwQW1vdW50KSB7XG4gICAgdGhpcy51bnNoYXJwX21hc2socmVzdWx0LCBvcHRpb25zLnRvV2lkdGgsIG9wdGlvbnMudG9IZWlnaHQsIG9wdGlvbnMudW5zaGFycEFtb3VudCwgb3B0aW9ucy51bnNoYXJwUmFkaXVzLCBvcHRpb25zLnVuc2hhcnBUaHJlc2hvbGQpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTWF0aExpYjtcblxufSx7XCIuL21tX3Jlc2l6ZVwiOjQsXCIuL21tX3Vuc2hhcnBfbWFza1wiOjksXCJpbmhlcml0c1wiOjE5LFwibXVsdGltYXRoXCI6MjB9XSwyOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFJlc2l6ZSBjb252b2x2ZXJzLCBwdXJlIEpTIGltcGxlbWVudGF0aW9uXG4vL1xuJ3VzZSBzdHJpY3QnOyAvLyBQcmVjaXNpb24gb2YgZml4ZWQgRlAgdmFsdWVzXG4vL3ZhciBGSVhFRF9GUkFDX0JJVFMgPSAxNDtcblxuZnVuY3Rpb24gY2xhbXBUbzgoaSkge1xuICByZXR1cm4gaSA8IDAgPyAwIDogaSA+IDI1NSA/IDI1NSA6IGk7XG59IC8vIENvbnZvbHZlIGltYWdlIGluIGhvcml6b250YWwgZGlyZWN0aW9ucyBhbmQgdHJhbnNwb3NlIG91dHB1dC4gSW4gdGhlb3J5LFxuLy8gdHJhbnNwb3NlIGFsbG93OlxuLy9cbi8vIC0gdXNlIHRoZSBzYW1lIGNvbnZvbHZlciBmb3IgYm90aCBwYXNzZXMgKHRoaXMgZmFpbHMgZHVlIGRpZmZlcmVudFxuLy8gICB0eXBlcyBvZiBpbnB1dCBhcnJheSBhbmQgdGVtcG9yYXJ5IGJ1ZmZlcilcbi8vIC0gbWFraW5nIHZlcnRpY2FsIHBhc3MgYnkgaG9yaXNvbmx0YWwgbGluZXMgaW5wcm92ZSBDUFUgY2FjaGUgdXNlLlxuLy9cbi8vIEJ1dCBpbiByZWFsIGxpZmUgdGhpcyBkb2Vzbid0IHdvcmsgOilcbi8vXG5cblxuZnVuY3Rpb24gY29udm9sdmVIb3Jpem9udGFsbHkoc3JjLCBkZXN0LCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVycykge1xuICB2YXIgciwgZywgYiwgYTtcbiAgdmFyIGZpbHRlclB0ciwgZmlsdGVyU2hpZnQsIGZpbHRlclNpemU7XG4gIHZhciBzcmNQdHIsIHNyY1ksIGRlc3RYLCBmaWx0ZXJWYWw7XG4gIHZhciBzcmNPZmZzZXQgPSAwLFxuICAgICAgZGVzdE9mZnNldCA9IDA7IC8vIEZvciBlYWNoIHJvd1xuXG4gIGZvciAoc3JjWSA9IDA7IHNyY1kgPCBzcmNIOyBzcmNZKyspIHtcbiAgICBmaWx0ZXJQdHIgPSAwOyAvLyBBcHBseSBwcmVjb21wdXRlZCBmaWx0ZXJzIHRvIGVhY2ggZGVzdGluYXRpb24gcm93IHBvaW50XG5cbiAgICBmb3IgKGRlc3RYID0gMDsgZGVzdFggPCBkZXN0VzsgZGVzdFgrKykge1xuICAgICAgLy8gR2V0IHRoZSBmaWx0ZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBjdXJyZW50IG91dHB1dCBwaXhlbC5cbiAgICAgIGZpbHRlclNoaWZ0ID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBmaWx0ZXJTaXplID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBzcmNQdHIgPSBzcmNPZmZzZXQgKyBmaWx0ZXJTaGlmdCAqIDQgfCAwO1xuICAgICAgciA9IGcgPSBiID0gYSA9IDA7IC8vIEFwcGx5IHRoZSBmaWx0ZXIgdG8gdGhlIHJvdyB0byBnZXQgdGhlIGRlc3RpbmF0aW9uIHBpeGVsIHIsIGcsIGIsIGFcblxuICAgICAgZm9yICg7IGZpbHRlclNpemUgPiAwOyBmaWx0ZXJTaXplLS0pIHtcbiAgICAgICAgZmlsdGVyVmFsID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107IC8vIFVzZSByZXZlcnNlIG9yZGVyIHRvIHdvcmthcm91bmQgZGVvcHRzIGluIG9sZCB2OCAobm9kZSB2LjEwKVxuICAgICAgICAvLyBCaWcgdGhhbmtzIHRvIEBtcmFsZXBoIChWeWFjaGVzbGF2IEVnb3JvdikgZm9yIHRoZSB0aXAuXG5cbiAgICAgICAgYSA9IGEgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgM10gfCAwO1xuICAgICAgICBiID0gYiArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAyXSB8IDA7XG4gICAgICAgIGcgPSBnICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDFdIHwgMDtcbiAgICAgICAgciA9IHIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyXSB8IDA7XG4gICAgICAgIHNyY1B0ciA9IHNyY1B0ciArIDQgfCAwO1xuICAgICAgfSAvLyBCcmluZyB0aGlzIHZhbHVlIGJhY2sgaW4gcmFuZ2UuIEFsbCBvZiB0aGUgZmlsdGVyIHNjYWxpbmcgZmFjdG9yc1xuICAgICAgLy8gYXJlIGluIGZpeGVkIHBvaW50IHdpdGggRklYRURfRlJBQ19CSVRTIGJpdHMgb2YgZnJhY3Rpb25hbCBwYXJ0LlxuICAgICAgLy9cbiAgICAgIC8vICghKSBBZGQgMS8yIG9mIHZhbHVlIGJlZm9yZSBjbGFtcGluZyB0byBnZXQgcHJvcGVyIHJvdW5kaW5nLiBJbiBvdGhlclxuICAgICAgLy8gY2FzZSBicmlnaHRuZXNzIGxvc3Mgd2lsbCBiZSBub3RpY2VhYmxlIGlmIHlvdSByZXNpemUgaW1hZ2Ugd2l0aCB3aGl0ZVxuICAgICAgLy8gYm9yZGVyIGFuZCBwbGFjZSBpdCBvbiB3aGl0ZSBiYWNrZ3JvdW5kLlxuICAgICAgLy9cblxuXG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAzXSA9IGNsYW1wVG84KGEgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAyXSA9IGNsYW1wVG84KGIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAxXSA9IGNsYW1wVG84KGcgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXRdID0gY2xhbXBUbzgociArICgxIDw8IDEzKSA+PiAxNFxuICAgICAgLypGSVhFRF9GUkFDX0JJVFMqL1xuICAgICAgKTtcbiAgICAgIGRlc3RPZmZzZXQgPSBkZXN0T2Zmc2V0ICsgc3JjSCAqIDQgfCAwO1xuICAgIH1cblxuICAgIGRlc3RPZmZzZXQgPSAoc3JjWSArIDEpICogNCB8IDA7XG4gICAgc3JjT2Zmc2V0ID0gKHNyY1kgKyAxKSAqIHNyY1cgKiA0IHwgMDtcbiAgfVxufSAvLyBUZWNobmljYWxseSwgY29udm9sdmVycyBhcmUgdGhlIHNhbWUuIEJ1dCBpbnB1dCBhcnJheSBhbmQgdGVtcG9yYXJ5XG4vLyBidWZmZXIgY2FuIGJlIG9mIGRpZmZlcmVudCB0eXBlIChlc3BlY2lhbGx5LCBpbiBvbGQgYnJvd3NlcnMpLiBTbyxcbi8vIGtlZXAgY29kZSBpbiBzZXBhcmF0ZSBmdW5jdGlvbnMgdG8gYXZvaWQgZGVvcHRpbWl6YXRpb25zICYgc3BlZWQgbG9zcy5cblxuXG5mdW5jdGlvbiBjb252b2x2ZVZlcnRpY2FsbHkoc3JjLCBkZXN0LCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVycykge1xuICB2YXIgciwgZywgYiwgYTtcbiAgdmFyIGZpbHRlclB0ciwgZmlsdGVyU2hpZnQsIGZpbHRlclNpemU7XG4gIHZhciBzcmNQdHIsIHNyY1ksIGRlc3RYLCBmaWx0ZXJWYWw7XG4gIHZhciBzcmNPZmZzZXQgPSAwLFxuICAgICAgZGVzdE9mZnNldCA9IDA7IC8vIEZvciBlYWNoIHJvd1xuXG4gIGZvciAoc3JjWSA9IDA7IHNyY1kgPCBzcmNIOyBzcmNZKyspIHtcbiAgICBmaWx0ZXJQdHIgPSAwOyAvLyBBcHBseSBwcmVjb21wdXRlZCBmaWx0ZXJzIHRvIGVhY2ggZGVzdGluYXRpb24gcm93IHBvaW50XG5cbiAgICBmb3IgKGRlc3RYID0gMDsgZGVzdFggPCBkZXN0VzsgZGVzdFgrKykge1xuICAgICAgLy8gR2V0IHRoZSBmaWx0ZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBjdXJyZW50IG91dHB1dCBwaXhlbC5cbiAgICAgIGZpbHRlclNoaWZ0ID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBmaWx0ZXJTaXplID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBzcmNQdHIgPSBzcmNPZmZzZXQgKyBmaWx0ZXJTaGlmdCAqIDQgfCAwO1xuICAgICAgciA9IGcgPSBiID0gYSA9IDA7IC8vIEFwcGx5IHRoZSBmaWx0ZXIgdG8gdGhlIHJvdyB0byBnZXQgdGhlIGRlc3RpbmF0aW9uIHBpeGVsIHIsIGcsIGIsIGFcblxuICAgICAgZm9yICg7IGZpbHRlclNpemUgPiAwOyBmaWx0ZXJTaXplLS0pIHtcbiAgICAgICAgZmlsdGVyVmFsID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107IC8vIFVzZSByZXZlcnNlIG9yZGVyIHRvIHdvcmthcm91bmQgZGVvcHRzIGluIG9sZCB2OCAobm9kZSB2LjEwKVxuICAgICAgICAvLyBCaWcgdGhhbmtzIHRvIEBtcmFsZXBoIChWeWFjaGVzbGF2IEVnb3JvdikgZm9yIHRoZSB0aXAuXG5cbiAgICAgICAgYSA9IGEgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgM10gfCAwO1xuICAgICAgICBiID0gYiArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAyXSB8IDA7XG4gICAgICAgIGcgPSBnICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDFdIHwgMDtcbiAgICAgICAgciA9IHIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyXSB8IDA7XG4gICAgICAgIHNyY1B0ciA9IHNyY1B0ciArIDQgfCAwO1xuICAgICAgfSAvLyBCcmluZyB0aGlzIHZhbHVlIGJhY2sgaW4gcmFuZ2UuIEFsbCBvZiB0aGUgZmlsdGVyIHNjYWxpbmcgZmFjdG9yc1xuICAgICAgLy8gYXJlIGluIGZpeGVkIHBvaW50IHdpdGggRklYRURfRlJBQ19CSVRTIGJpdHMgb2YgZnJhY3Rpb25hbCBwYXJ0LlxuICAgICAgLy9cbiAgICAgIC8vICghKSBBZGQgMS8yIG9mIHZhbHVlIGJlZm9yZSBjbGFtcGluZyB0byBnZXQgcHJvcGVyIHJvdW5kaW5nLiBJbiBvdGhlclxuICAgICAgLy8gY2FzZSBicmlnaHRuZXNzIGxvc3Mgd2lsbCBiZSBub3RpY2VhYmxlIGlmIHlvdSByZXNpemUgaW1hZ2Ugd2l0aCB3aGl0ZVxuICAgICAgLy8gYm9yZGVyIGFuZCBwbGFjZSBpdCBvbiB3aGl0ZSBiYWNrZ3JvdW5kLlxuICAgICAgLy9cblxuXG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAzXSA9IGNsYW1wVG84KGEgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAyXSA9IGNsYW1wVG84KGIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAxXSA9IGNsYW1wVG84KGcgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXRdID0gY2xhbXBUbzgociArICgxIDw8IDEzKSA+PiAxNFxuICAgICAgLypGSVhFRF9GUkFDX0JJVFMqL1xuICAgICAgKTtcbiAgICAgIGRlc3RPZmZzZXQgPSBkZXN0T2Zmc2V0ICsgc3JjSCAqIDQgfCAwO1xuICAgIH1cblxuICAgIGRlc3RPZmZzZXQgPSAoc3JjWSArIDEpICogNCB8IDA7XG4gICAgc3JjT2Zmc2V0ID0gKHNyY1kgKyAxKSAqIHNyY1cgKiA0IHwgMDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29udm9sdmVIb3Jpem9udGFsbHk6IGNvbnZvbHZlSG9yaXpvbnRhbGx5LFxuICBjb252b2x2ZVZlcnRpY2FsbHk6IGNvbnZvbHZlVmVydGljYWxseVxufTtcblxufSx7fV0sMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBUaGlzIGlzIGF1dG9nZW5lcmF0ZWQgZmlsZSBmcm9tIG1hdGgud2FzbSwgZG9uJ3QgZWRpdC5cbi8vXG4ndXNlIHN0cmljdCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbm1vZHVsZS5leHBvcnRzID0gJ0FHRnpiUUVBQUFBQURBWmtlV3hwYm1zQUFBQUFBQUVYQTJBQUFHQUdmMzkvZjM5L0FHQUhmMzkvZjM5L2Z3QUNEd0VEWlc1MkJtMWxiVzl5ZVFJQUFBTUVBd0FCQWdZR0FYOEFRUUFMQjFjRkVWOWZkMkZ6YlY5allXeHNYMk4wYjNKekFBQUlZMjl1ZG05c2RtVUFBUXBqYjI1MmIyeDJaVWhXQUFJTVgxOWtjMjlmYUdGdVpHeGxBd0FZWDE5M1lYTnRYMkZ3Y0d4NVgyUmhkR0ZmY21Wc2IyTnpBQUFLN0FNREF3QUJDOFlEQVE5L0FrQWdBMFVOQUNBRVJRMEFBMEFnRENFTlFRQWhFMEVBSVFjRFFDQUhRUUpxSVFZQ2Z5QUhRUUYwSUFWcUlnY3VBUUlpRkVVRVFFR0F3QUFoQ0VHQXdBQWhDVUdBd0FBaENrR0F3QUFoQ3lBR0RBRUxJQklnQnk0QkFHb2hDRUVBSVFzZ0ZDRUhRUUFoRGlBR0lRbEJBQ0VQUVFBaEVBTkFJQVVnQ1VFQmRHb3VBUUFpRVNBQUlBaEJBblJxS0FJQUlncEJHSFpzSUJCcUlSQWdDa0gvQVhFZ0VXd2dDMm9oQ3lBS1FSQjJRZjhCY1NBUmJDQVBhaUVQSUFwQkNIWkIvd0Z4SUJGc0lBNXFJUTRnQ0VFQmFpRUlJQWxCQVdvaENTQUhRUUZySWdjTkFBc2dDMEdBUUdzaENDQU9RWUJBYXlFSklBOUJnRUJySVFvZ0VFR0FRR3NoQ3lBR0lCUnFDeUVISUFFZ0RVRUNkR29nQ1VFT2RTSUdRZjhCSUFaQi93RklHeUlHUVFBZ0JrRUFTaHRCQ0hSQmdQNERjU0FLUVE1MUlnWkIvd0VnQmtIL0FVZ2JJZ1pCQUNBR1FRQktHMEVRZEVHQWdQd0hjU0FMUVE1MUlnWkIvd0VnQmtIL0FVZ2JJZ1pCQUNBR1FRQktHMEVZZEhKeUlBaEJEblVpQmtIL0FTQUdRZjhCU0JzaUJrRUFJQVpCQUVvYmNqWUNBQ0FESUExcUlRMGdFMEVCYWlJVElBUkhEUUFMSUF4QkFXb2lEQ0FDYkNFU0lBTWdERWNOQUFzTEN4NEFRUUFnQWlBRElBUWdCU0FBRUFFZ0FrRUFJQVFnQlNBR0lBRVFBUXM9JztcblxufSx7fV0sNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBuYW1lOiAncmVzaXplJyxcbiAgZm46IF9kZXJlcV8oJy4vcmVzaXplJyksXG4gIHdhc21fZm46IF9kZXJlcV8oJy4vcmVzaXplX3dhc20nKSxcbiAgd2FzbV9zcmM6IF9kZXJlcV8oJy4vY29udm9sdmVfd2FzbV9iYXNlNjQnKVxufTtcblxufSx7XCIuL2NvbnZvbHZlX3dhc21fYmFzZTY0XCI6MyxcIi4vcmVzaXplXCI6NSxcIi4vcmVzaXplX3dhc21cIjo4fV0sNTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBjcmVhdGVGaWx0ZXJzID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2dlbicpO1xuXG52YXIgY29udm9sdmVIb3Jpem9udGFsbHkgPSBfZGVyZXFfKCcuL2NvbnZvbHZlJykuY29udm9sdmVIb3Jpem9udGFsbHk7XG5cbnZhciBjb252b2x2ZVZlcnRpY2FsbHkgPSBfZGVyZXFfKCcuL2NvbnZvbHZlJykuY29udm9sdmVWZXJ0aWNhbGx5O1xuXG5mdW5jdGlvbiByZXNldEFscGhhKGRzdCwgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgcHRyID0gMyxcbiAgICAgIGxlbiA9IHdpZHRoICogaGVpZ2h0ICogNCB8IDA7XG5cbiAgd2hpbGUgKHB0ciA8IGxlbikge1xuICAgIGRzdFtwdHJdID0gMHhGRjtcbiAgICBwdHIgPSBwdHIgKyA0IHwgMDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlc2l6ZShvcHRpb25zKSB7XG4gIHZhciBzcmMgPSBvcHRpb25zLnNyYztcbiAgdmFyIHNyY1cgPSBvcHRpb25zLndpZHRoO1xuICB2YXIgc3JjSCA9IG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgZGVzdFcgPSBvcHRpb25zLnRvV2lkdGg7XG4gIHZhciBkZXN0SCA9IG9wdGlvbnMudG9IZWlnaHQ7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnNjYWxlWCB8fCBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy5zY2FsZVkgfHwgb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgb2Zmc2V0WCA9IG9wdGlvbnMub2Zmc2V0WCB8fCAwO1xuICB2YXIgb2Zmc2V0WSA9IG9wdGlvbnMub2Zmc2V0WSB8fCAwO1xuICB2YXIgZGVzdCA9IG9wdGlvbnMuZGVzdCB8fCBuZXcgVWludDhBcnJheShkZXN0VyAqIGRlc3RIICogNCk7XG4gIHZhciBxdWFsaXR5ID0gdHlwZW9mIG9wdGlvbnMucXVhbGl0eSA9PT0gJ3VuZGVmaW5lZCcgPyAzIDogb3B0aW9ucy5xdWFsaXR5O1xuICB2YXIgYWxwaGEgPSBvcHRpb25zLmFscGhhIHx8IGZhbHNlO1xuICB2YXIgZmlsdGVyc1ggPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY1csIGRlc3RXLCBzY2FsZVgsIG9mZnNldFgpLFxuICAgICAgZmlsdGVyc1kgPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY0gsIGRlc3RILCBzY2FsZVksIG9mZnNldFkpO1xuICB2YXIgdG1wID0gbmV3IFVpbnQ4QXJyYXkoZGVzdFcgKiBzcmNIICogNCk7IC8vIFRvIHVzZSBzaW5nbGUgZnVuY3Rpb24gd2UgbmVlZCBzcmMgJiB0bXAgb2YgdGhlIHNhbWUgdHlwZS5cbiAgLy8gQnV0IHNyYyBjYW4gYmUgQ2FudmFzUGl4ZWxBcnJheSwgYW5kIHRtcCAtIFVpbnQ4QXJyYXkuIFNvLCBrZWVwXG4gIC8vIHZlcnRpY2FsIGFuZCBob3Jpem9udGFsIHBhc3NlcyBzZXBhcmF0ZWx5IHRvIGF2b2lkIGRlb3B0aW1pemF0aW9uLlxuXG4gIGNvbnZvbHZlSG9yaXpvbnRhbGx5KHNyYywgdG1wLCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVyc1gpO1xuICBjb252b2x2ZVZlcnRpY2FsbHkodG1wLCBkZXN0LCBzcmNILCBkZXN0VywgZGVzdEgsIGZpbHRlcnNZKTsgLy8gVGhhdCdzIGZhc3RlciB0aGFuIGRvaW5nIGNoZWNrcyBpbiBjb252b2x2ZXIuXG4gIC8vICEhISBOb3RlLCBjYW52YXMgZGF0YSBpcyBub3QgcHJlbXVsdGlwbGVkLiBXZSBkb24ndCBuZWVkIG90aGVyXG4gIC8vIGFscGhhIGNvcnJlY3Rpb25zLlxuXG4gIGlmICghYWxwaGEpIHJlc2V0QWxwaGEoZGVzdCwgZGVzdFcsIGRlc3RIKTtcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG59LHtcIi4vY29udm9sdmVcIjoyLFwiLi9yZXNpemVfZmlsdGVyX2dlblwiOjZ9XSw2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIENhbGN1bGF0ZSBjb252b2x1dGlvbiBmaWx0ZXJzIGZvciBlYWNoIGRlc3RpbmF0aW9uIHBvaW50LFxuLy8gYW5kIHBhY2sgZGF0YSB0byBJbnQxNkFycmF5OlxuLy9cbi8vIFsgc2hpZnQsIGxlbmd0aCwgZGF0YS4uLiwgc2hpZnQyLCBsZW5ndGgyLCBkYXRhLi4uLCAuLi4gXVxuLy9cbi8vIC0gc2hpZnQgLSBvZmZzZXQgaW4gc3JjIGltYWdlXG4vLyAtIGxlbmd0aCAtIGZpbHRlciBsZW5ndGggKGluIHNyYyBwb2ludHMpXG4vLyAtIGRhdGEgLSBmaWx0ZXIgdmFsdWVzIHNlcXVlbmNlXG4vL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRklMVEVSX0lORk8gPSBfZGVyZXFfKCcuL3Jlc2l6ZV9maWx0ZXJfaW5mbycpOyAvLyBQcmVjaXNpb24gb2YgZml4ZWQgRlAgdmFsdWVzXG5cblxudmFyIEZJWEVEX0ZSQUNfQklUUyA9IDE0O1xuXG5mdW5jdGlvbiB0b0ZpeGVkUG9pbnQobnVtKSB7XG4gIHJldHVybiBNYXRoLnJvdW5kKG51bSAqICgoMSA8PCBGSVhFRF9GUkFDX0JJVFMpIC0gMSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlc2l6ZUZpbHRlckdlbihxdWFsaXR5LCBzcmNTaXplLCBkZXN0U2l6ZSwgc2NhbGUsIG9mZnNldCkge1xuICB2YXIgZmlsdGVyRnVuY3Rpb24gPSBGSUxURVJfSU5GT1txdWFsaXR5XS5maWx0ZXI7XG4gIHZhciBzY2FsZUludmVydGVkID0gMS4wIC8gc2NhbGU7XG4gIHZhciBzY2FsZUNsYW1wZWQgPSBNYXRoLm1pbigxLjAsIHNjYWxlKTsgLy8gRm9yIHVwc2NhbGVcbiAgLy8gRmlsdGVyIHdpbmRvdyAoYXZlcmFnaW5nIGludGVydmFsKSwgc2NhbGVkIHRvIHNyYyBpbWFnZVxuXG4gIHZhciBzcmNXaW5kb3cgPSBGSUxURVJfSU5GT1txdWFsaXR5XS53aW4gLyBzY2FsZUNsYW1wZWQ7XG4gIHZhciBkZXN0UGl4ZWwsIHNyY1BpeGVsLCBzcmNGaXJzdCwgc3JjTGFzdCwgZmlsdGVyRWxlbWVudFNpemUsIGZsb2F0RmlsdGVyLCBmeHBGaWx0ZXIsIHRvdGFsLCBweGwsIGlkeCwgZmxvYXRWYWwsIGZpbHRlclRvdGFsLCBmaWx0ZXJWYWw7XG4gIHZhciBsZWZ0Tm90RW1wdHksIHJpZ2h0Tm90RW1wdHksIGZpbHRlclNoaWZ0LCBmaWx0ZXJTaXplO1xuICB2YXIgbWF4RmlsdGVyRWxlbWVudFNpemUgPSBNYXRoLmZsb29yKChzcmNXaW5kb3cgKyAxKSAqIDIpO1xuICB2YXIgcGFja2VkRmlsdGVyID0gbmV3IEludDE2QXJyYXkoKG1heEZpbHRlckVsZW1lbnRTaXplICsgMikgKiBkZXN0U2l6ZSk7XG4gIHZhciBwYWNrZWRGaWx0ZXJQdHIgPSAwO1xuICB2YXIgc2xvd0NvcHkgPSAhcGFja2VkRmlsdGVyLnN1YmFycmF5IHx8ICFwYWNrZWRGaWx0ZXIuc2V0OyAvLyBGb3IgZWFjaCBkZXN0aW5hdGlvbiBwaXhlbCBjYWxjdWxhdGUgc291cmNlIHJhbmdlIGFuZCBidWlsdCBmaWx0ZXIgdmFsdWVzXG5cbiAgZm9yIChkZXN0UGl4ZWwgPSAwOyBkZXN0UGl4ZWwgPCBkZXN0U2l6ZTsgZGVzdFBpeGVsKyspIHtcbiAgICAvLyBTY2FsaW5nIHNob3VsZCBiZSBkb25lIHJlbGF0aXZlIHRvIGNlbnRyYWwgcGl4ZWwgcG9pbnRcbiAgICBzcmNQaXhlbCA9IChkZXN0UGl4ZWwgKyAwLjUpICogc2NhbGVJbnZlcnRlZCArIG9mZnNldDtcbiAgICBzcmNGaXJzdCA9IE1hdGgubWF4KDAsIE1hdGguZmxvb3Ioc3JjUGl4ZWwgLSBzcmNXaW5kb3cpKTtcbiAgICBzcmNMYXN0ID0gTWF0aC5taW4oc3JjU2l6ZSAtIDEsIE1hdGguY2VpbChzcmNQaXhlbCArIHNyY1dpbmRvdykpO1xuICAgIGZpbHRlckVsZW1lbnRTaXplID0gc3JjTGFzdCAtIHNyY0ZpcnN0ICsgMTtcbiAgICBmbG9hdEZpbHRlciA9IG5ldyBGbG9hdDMyQXJyYXkoZmlsdGVyRWxlbWVudFNpemUpO1xuICAgIGZ4cEZpbHRlciA9IG5ldyBJbnQxNkFycmF5KGZpbHRlckVsZW1lbnRTaXplKTtcbiAgICB0b3RhbCA9IDAuMDsgLy8gRmlsbCBmaWx0ZXIgdmFsdWVzIGZvciBjYWxjdWxhdGVkIHJhbmdlXG5cbiAgICBmb3IgKHB4bCA9IHNyY0ZpcnN0LCBpZHggPSAwOyBweGwgPD0gc3JjTGFzdDsgcHhsKyssIGlkeCsrKSB7XG4gICAgICBmbG9hdFZhbCA9IGZpbHRlckZ1bmN0aW9uKChweGwgKyAwLjUgLSBzcmNQaXhlbCkgKiBzY2FsZUNsYW1wZWQpO1xuICAgICAgdG90YWwgKz0gZmxvYXRWYWw7XG4gICAgICBmbG9hdEZpbHRlcltpZHhdID0gZmxvYXRWYWw7XG4gICAgfSAvLyBOb3JtYWxpemUgZmlsdGVyLCBjb252ZXJ0IHRvIGZpeGVkIHBvaW50IGFuZCBhY2N1bXVsYXRlIGNvbnZlcnNpb24gZXJyb3JcblxuXG4gICAgZmlsdGVyVG90YWwgPSAwO1xuXG4gICAgZm9yIChpZHggPSAwOyBpZHggPCBmbG9hdEZpbHRlci5sZW5ndGg7IGlkeCsrKSB7XG4gICAgICBmaWx0ZXJWYWwgPSBmbG9hdEZpbHRlcltpZHhdIC8gdG90YWw7XG4gICAgICBmaWx0ZXJUb3RhbCArPSBmaWx0ZXJWYWw7XG4gICAgICBmeHBGaWx0ZXJbaWR4XSA9IHRvRml4ZWRQb2ludChmaWx0ZXJWYWwpO1xuICAgIH0gLy8gQ29tcGVuc2F0ZSBub3JtYWxpemF0aW9uIGVycm9yLCB0byBtaW5pbWl6ZSBicmlnaHRuZXNzIGRyaWZ0XG5cblxuICAgIGZ4cEZpbHRlcltkZXN0U2l6ZSA+PiAxXSArPSB0b0ZpeGVkUG9pbnQoMS4wIC0gZmlsdGVyVG90YWwpOyAvL1xuICAgIC8vIE5vdyBwYWNrIGZpbHRlciB0byB1c2VhYmxlIGZvcm1cbiAgICAvL1xuICAgIC8vIDEuIFRyaW0gaGVhZGluZyBhbmQgdGFpbGluZyB6ZXJvIHZhbHVlcywgYW5kIGNvbXBlbnNhdGUgc2hpdGYvbGVuZ3RoXG4gICAgLy8gMi4gUHV0IGFsbCB0byBzaW5nbGUgYXJyYXkgaW4gdGhpcyBmb3JtYXQ6XG4gICAgLy9cbiAgICAvLyAgICBbIHBvcyBzaGlmdCwgZGF0YSBsZW5ndGgsIHZhbHVlMSwgdmFsdWUyLCB2YWx1ZTMsIC4uLiBdXG4gICAgLy9cblxuICAgIGxlZnROb3RFbXB0eSA9IDA7XG5cbiAgICB3aGlsZSAobGVmdE5vdEVtcHR5IDwgZnhwRmlsdGVyLmxlbmd0aCAmJiBmeHBGaWx0ZXJbbGVmdE5vdEVtcHR5XSA9PT0gMCkge1xuICAgICAgbGVmdE5vdEVtcHR5Kys7XG4gICAgfVxuXG4gICAgaWYgKGxlZnROb3RFbXB0eSA8IGZ4cEZpbHRlci5sZW5ndGgpIHtcbiAgICAgIHJpZ2h0Tm90RW1wdHkgPSBmeHBGaWx0ZXIubGVuZ3RoIC0gMTtcblxuICAgICAgd2hpbGUgKHJpZ2h0Tm90RW1wdHkgPiAwICYmIGZ4cEZpbHRlcltyaWdodE5vdEVtcHR5XSA9PT0gMCkge1xuICAgICAgICByaWdodE5vdEVtcHR5LS07XG4gICAgICB9XG5cbiAgICAgIGZpbHRlclNoaWZ0ID0gc3JjRmlyc3QgKyBsZWZ0Tm90RW1wdHk7XG4gICAgICBmaWx0ZXJTaXplID0gcmlnaHROb3RFbXB0eSAtIGxlZnROb3RFbXB0eSArIDE7XG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gZmlsdGVyU2hpZnQ7IC8vIHNoaWZ0XG5cbiAgICAgIHBhY2tlZEZpbHRlcltwYWNrZWRGaWx0ZXJQdHIrK10gPSBmaWx0ZXJTaXplOyAvLyBzaXplXG5cbiAgICAgIGlmICghc2xvd0NvcHkpIHtcbiAgICAgICAgcGFja2VkRmlsdGVyLnNldChmeHBGaWx0ZXIuc3ViYXJyYXkobGVmdE5vdEVtcHR5LCByaWdodE5vdEVtcHR5ICsgMSksIHBhY2tlZEZpbHRlclB0cik7XG4gICAgICAgIHBhY2tlZEZpbHRlclB0ciArPSBmaWx0ZXJTaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZmFsbGJhY2sgZm9yIG9sZCBJRSA8IDExLCB3aXRob3V0IHN1YmFycmF5L3NldCBtZXRob2RzXG4gICAgICAgIGZvciAoaWR4ID0gbGVmdE5vdEVtcHR5OyBpZHggPD0gcmlnaHROb3RFbXB0eTsgaWR4KyspIHtcbiAgICAgICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gZnhwRmlsdGVyW2lkeF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gemVybyBkYXRhLCB3cml0ZSBoZWFkZXIgb25seVxuICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IDA7IC8vIHNoaWZ0XG5cbiAgICAgIHBhY2tlZEZpbHRlcltwYWNrZWRGaWx0ZXJQdHIrK10gPSAwOyAvLyBzaXplXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhY2tlZEZpbHRlcjtcbn07XG5cbn0se1wiLi9yZXNpemVfZmlsdGVyX2luZm9cIjo3fV0sNzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBGaWx0ZXIgZGVmaW5pdGlvbnMgdG8gYnVpbGQgdGFibGVzIGZvclxuLy8gcmVzaXppbmcgY29udm9sdmVycy5cbi8vXG4vLyBQcmVzZXRzIGZvciBxdWFsaXR5IDAuLjMuIEZpbHRlciBmdW5jdGlvbnMgKyB3aW5kb3cgc2l6ZVxuLy9cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBbe1xuICAvLyBOZWFyZXN0IG5laWJvciAoQm94KVxuICB3aW46IDAuNSxcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoeCkge1xuICAgIHJldHVybiB4ID49IC0wLjUgJiYgeCA8IDAuNSA/IDEuMCA6IDAuMDtcbiAgfVxufSwge1xuICAvLyBIYW1taW5nXG4gIHdpbjogMS4wLFxuICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcih4KSB7XG4gICAgaWYgKHggPD0gLTEuMCB8fCB4ID49IDEuMCkge1xuICAgICAgcmV0dXJuIDAuMDtcbiAgICB9XG5cbiAgICBpZiAoeCA+IC0xLjE5MjA5MjkwRS0wNyAmJiB4IDwgMS4xOTIwOTI5MEUtMDcpIHtcbiAgICAgIHJldHVybiAxLjA7XG4gICAgfVxuXG4gICAgdmFyIHhwaSA9IHggKiBNYXRoLlBJO1xuICAgIHJldHVybiBNYXRoLnNpbih4cGkpIC8geHBpICogKDAuNTQgKyAwLjQ2ICogTWF0aC5jb3MoeHBpIC8gMS4wKSk7XG4gIH1cbn0sIHtcbiAgLy8gTGFuY3pvcywgd2luID0gMlxuICB3aW46IDIuMCxcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoeCkge1xuICAgIGlmICh4IDw9IC0yLjAgfHwgeCA+PSAyLjApIHtcbiAgICAgIHJldHVybiAwLjA7XG4gICAgfVxuXG4gICAgaWYgKHggPiAtMS4xOTIwOTI5MEUtMDcgJiYgeCA8IDEuMTkyMDkyOTBFLTA3KSB7XG4gICAgICByZXR1cm4gMS4wO1xuICAgIH1cblxuICAgIHZhciB4cGkgPSB4ICogTWF0aC5QSTtcbiAgICByZXR1cm4gTWF0aC5zaW4oeHBpKSAvIHhwaSAqIE1hdGguc2luKHhwaSAvIDIuMCkgLyAoeHBpIC8gMi4wKTtcbiAgfVxufSwge1xuICAvLyBMYW5jem9zLCB3aW4gPSAzXG4gIHdpbjogMy4wLFxuICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcih4KSB7XG4gICAgaWYgKHggPD0gLTMuMCB8fCB4ID49IDMuMCkge1xuICAgICAgcmV0dXJuIDAuMDtcbiAgICB9XG5cbiAgICBpZiAoeCA+IC0xLjE5MjA5MjkwRS0wNyAmJiB4IDwgMS4xOTIwOTI5MEUtMDcpIHtcbiAgICAgIHJldHVybiAxLjA7XG4gICAgfVxuXG4gICAgdmFyIHhwaSA9IHggKiBNYXRoLlBJO1xuICAgIHJldHVybiBNYXRoLnNpbih4cGkpIC8geHBpICogTWF0aC5zaW4oeHBpIC8gMy4wKSAvICh4cGkgLyAzLjApO1xuICB9XG59XTtcblxufSx7fV0sODpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBjcmVhdGVGaWx0ZXJzID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2dlbicpO1xuXG5mdW5jdGlvbiByZXNldEFscGhhKGRzdCwgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgcHRyID0gMyxcbiAgICAgIGxlbiA9IHdpZHRoICogaGVpZ2h0ICogNCB8IDA7XG5cbiAgd2hpbGUgKHB0ciA8IGxlbikge1xuICAgIGRzdFtwdHJdID0gMHhGRjtcbiAgICBwdHIgPSBwdHIgKyA0IHwgMDtcbiAgfVxufVxuXG5mdW5jdGlvbiBhc1VpbnQ4QXJyYXkoc3JjKSB7XG4gIHJldHVybiBuZXcgVWludDhBcnJheShzcmMuYnVmZmVyLCAwLCBzcmMuYnl0ZUxlbmd0aCk7XG59XG5cbnZhciBJU19MRSA9IHRydWU7IC8vIHNob3VsZCBub3QgY3Jhc2ggZXZlcnl0aGluZyBvbiBtb2R1bGUgbG9hZCBpbiBvbGQgYnJvd3NlcnNcblxudHJ5IHtcbiAgSVNfTEUgPSBuZXcgVWludDMyQXJyYXkobmV3IFVpbnQ4QXJyYXkoWzEsIDAsIDAsIDBdKS5idWZmZXIpWzBdID09PSAxO1xufSBjYXRjaCAoX18pIHt9XG5cbmZ1bmN0aW9uIGNvcHlJbnQxNmFzTEUoc3JjLCB0YXJnZXQsIHRhcmdldF9vZmZzZXQpIHtcbiAgaWYgKElTX0xFKSB7XG4gICAgdGFyZ2V0LnNldChhc1VpbnQ4QXJyYXkoc3JjKSwgdGFyZ2V0X29mZnNldCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZm9yICh2YXIgcHRyID0gdGFyZ2V0X29mZnNldCwgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGF0YSA9IHNyY1tpXTtcbiAgICB0YXJnZXRbcHRyKytdID0gZGF0YSAmIDB4RkY7XG4gICAgdGFyZ2V0W3B0cisrXSA9IGRhdGEgPj4gOCAmIDB4RkY7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXNpemVfd2FzbShvcHRpb25zKSB7XG4gIHZhciBzcmMgPSBvcHRpb25zLnNyYztcbiAgdmFyIHNyY1cgPSBvcHRpb25zLndpZHRoO1xuICB2YXIgc3JjSCA9IG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgZGVzdFcgPSBvcHRpb25zLnRvV2lkdGg7XG4gIHZhciBkZXN0SCA9IG9wdGlvbnMudG9IZWlnaHQ7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnNjYWxlWCB8fCBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy5zY2FsZVkgfHwgb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgb2Zmc2V0WCA9IG9wdGlvbnMub2Zmc2V0WCB8fCAwLjA7XG4gIHZhciBvZmZzZXRZID0gb3B0aW9ucy5vZmZzZXRZIHx8IDAuMDtcbiAgdmFyIGRlc3QgPSBvcHRpb25zLmRlc3QgfHwgbmV3IFVpbnQ4QXJyYXkoZGVzdFcgKiBkZXN0SCAqIDQpO1xuICB2YXIgcXVhbGl0eSA9IHR5cGVvZiBvcHRpb25zLnF1YWxpdHkgPT09ICd1bmRlZmluZWQnID8gMyA6IG9wdGlvbnMucXVhbGl0eTtcbiAgdmFyIGFscGhhID0gb3B0aW9ucy5hbHBoYSB8fCBmYWxzZTtcbiAgdmFyIGZpbHRlcnNYID0gY3JlYXRlRmlsdGVycyhxdWFsaXR5LCBzcmNXLCBkZXN0Vywgc2NhbGVYLCBvZmZzZXRYKSxcbiAgICAgIGZpbHRlcnNZID0gY3JlYXRlRmlsdGVycyhxdWFsaXR5LCBzcmNILCBkZXN0SCwgc2NhbGVZLCBvZmZzZXRZKTsgLy8gZGVzdGluYXRpb24gaXMgMCB0b28uXG5cbiAgdmFyIHNyY19vZmZzZXQgPSAwOyAvLyBidWZmZXIgYmV0d2VlbiBjb252b2x2ZSBwYXNzZXNcblxuICB2YXIgdG1wX29mZnNldCA9IHRoaXMuX19hbGlnbihzcmNfb2Zmc2V0ICsgTWF0aC5tYXgoc3JjLmJ5dGVMZW5ndGgsIGRlc3QuYnl0ZUxlbmd0aCkpO1xuXG4gIHZhciBmaWx0ZXJzWF9vZmZzZXQgPSB0aGlzLl9fYWxpZ24odG1wX29mZnNldCArIHNyY0ggKiBkZXN0VyAqIDQpO1xuXG4gIHZhciBmaWx0ZXJzWV9vZmZzZXQgPSB0aGlzLl9fYWxpZ24oZmlsdGVyc1hfb2Zmc2V0ICsgZmlsdGVyc1guYnl0ZUxlbmd0aCk7XG5cbiAgdmFyIGFsbG9jX2J5dGVzID0gZmlsdGVyc1lfb2Zmc2V0ICsgZmlsdGVyc1kuYnl0ZUxlbmd0aDtcblxuICB2YXIgaW5zdGFuY2UgPSB0aGlzLl9faW5zdGFuY2UoJ3Jlc2l6ZScsIGFsbG9jX2J5dGVzKTsgLy9cbiAgLy8gRmlsbCBtZW1vcnkgYmxvY2sgd2l0aCBkYXRhIHRvIHByb2Nlc3NcbiAgLy9cblxuXG4gIHZhciBtZW0gPSBuZXcgVWludDhBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlcik7XG4gIHZhciBtZW0zMiA9IG5ldyBVaW50MzJBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlcik7IC8vIDMyLWJpdCBjb3B5IGlzIG11Y2ggZmFzdGVyIGluIGNocm9tZVxuXG4gIHZhciBzcmMzMiA9IG5ldyBVaW50MzJBcnJheShzcmMuYnVmZmVyKTtcbiAgbWVtMzIuc2V0KHNyYzMyKTsgLy8gV2Ugc2hvdWxkIGd1YXJhbnRlZSBMRSBieXRlcyBvcmRlci4gRmlsdGVycyBhcmUgbm90IGJpZywgc29cbiAgLy8gc3BlZWQgZGlmZmVyZW5jZSBpcyBub3Qgc2lnbmlmaWNhbnQgdnMgZGlyZWN0IC5zZXQoKVxuXG4gIGNvcHlJbnQxNmFzTEUoZmlsdGVyc1gsIG1lbSwgZmlsdGVyc1hfb2Zmc2V0KTtcbiAgY29weUludDE2YXNMRShmaWx0ZXJzWSwgbWVtLCBmaWx0ZXJzWV9vZmZzZXQpOyAvL1xuICAvLyBOb3cgY2FsbCB3ZWJhc3NlbWJseSBtZXRob2RcbiAgLy8gZW1zZGsgZG9lcyBtZXRob2QgbmFtZXMgd2l0aCAnXydcblxuICB2YXIgZm4gPSBpbnN0YW5jZS5leHBvcnRzLmNvbnZvbHZlSFYgfHwgaW5zdGFuY2UuZXhwb3J0cy5fY29udm9sdmVIVjtcbiAgZm4oZmlsdGVyc1hfb2Zmc2V0LCBmaWx0ZXJzWV9vZmZzZXQsIHRtcF9vZmZzZXQsIHNyY1csIHNyY0gsIGRlc3RXLCBkZXN0SCk7IC8vXG4gIC8vIENvcHkgZGF0YSBiYWNrIHRvIHR5cGVkIGFycmF5XG4gIC8vXG4gIC8vIDMyLWJpdCBjb3B5IGlzIG11Y2ggZmFzdGVyIGluIGNocm9tZVxuXG4gIHZhciBkZXN0MzIgPSBuZXcgVWludDMyQXJyYXkoZGVzdC5idWZmZXIpO1xuICBkZXN0MzIuc2V0KG5ldyBVaW50MzJBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlciwgMCwgZGVzdEggKiBkZXN0VykpOyAvLyBUaGF0J3MgZmFzdGVyIHRoYW4gZG9pbmcgY2hlY2tzIGluIGNvbnZvbHZlci5cbiAgLy8gISEhIE5vdGUsIGNhbnZhcyBkYXRhIGlzIG5vdCBwcmVtdWx0aXBsZWQuIFdlIGRvbid0IG5lZWQgb3RoZXJcbiAgLy8gYWxwaGEgY29ycmVjdGlvbnMuXG5cbiAgaWYgKCFhbHBoYSkgcmVzZXRBbHBoYShkZXN0LCBkZXN0VywgZGVzdEgpO1xuICByZXR1cm4gZGVzdDtcbn07XG5cbn0se1wiLi9yZXNpemVfZmlsdGVyX2dlblwiOjZ9XSw5OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIG5hbWU6ICd1bnNoYXJwX21hc2snLFxuICBmbjogX2RlcmVxXygnLi91bnNoYXJwX21hc2snKSxcbiAgd2FzbV9mbjogX2RlcmVxXygnLi91bnNoYXJwX21hc2tfd2FzbScpLFxuICB3YXNtX3NyYzogX2RlcmVxXygnLi91bnNoYXJwX21hc2tfd2FzbV9iYXNlNjQnKVxufTtcblxufSx7XCIuL3Vuc2hhcnBfbWFza1wiOjEwLFwiLi91bnNoYXJwX21hc2tfd2FzbVwiOjExLFwiLi91bnNoYXJwX21hc2tfd2FzbV9iYXNlNjRcIjoxMn1dLDEwOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFVuc2hhcnAgbWFzayBmaWx0ZXJcbi8vXG4vLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMzMyMjgyMC8xMDMxODA0XG4vLyBVU00oTykgPSBPICsgKDIgKiAoQW1vdW50IC8gMTAwKSAqIChPIC0gR0IpKVxuLy8gR0IgLSBnYXVzc2lhbiBibHVyLlxuLy9cbi8vIEltYWdlIGlzIGNvbnZlcnRlZCBmcm9tIFJHQiB0byBIU1YsIHVuc2hhcnAgbWFzayBpcyBhcHBsaWVkIHRvIHRoZVxuLy8gYnJpZ2h0bmVzcyBjaGFubmVsIGFuZCB0aGVuIGltYWdlIGlzIGNvbnZlcnRlZCBiYWNrIHRvIFJHQi5cbi8vXG4ndXNlIHN0cmljdCc7XG5cbnZhciBnbHVyX21vbm8xNiA9IF9kZXJlcV8oJ2dsdXIvbW9ubzE2Jyk7XG5cbmZ1bmN0aW9uIGhzdl92MTYoaW1nLCB3aWR0aCwgaGVpZ2h0KSB7XG4gIHZhciBzaXplID0gd2lkdGggKiBoZWlnaHQ7XG4gIHZhciBvdXQgPSBuZXcgVWludDE2QXJyYXkoc2l6ZSk7XG4gIHZhciByLCBnLCBiLCBtYXg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICByID0gaW1nWzQgKiBpXTtcbiAgICBnID0gaW1nWzQgKiBpICsgMV07XG4gICAgYiA9IGltZ1s0ICogaSArIDJdO1xuICAgIG1heCA9IHIgPj0gZyAmJiByID49IGIgPyByIDogZyA+PSBiICYmIGcgPj0gciA/IGcgOiBiO1xuICAgIG91dFtpXSA9IG1heCA8PCA4O1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB1bnNoYXJwKGltZywgd2lkdGgsIGhlaWdodCwgYW1vdW50LCByYWRpdXMsIHRocmVzaG9sZCkge1xuICB2YXIgdjEsIHYyLCB2bXVsO1xuICB2YXIgZGlmZiwgaVRpbWVzNDtcblxuICBpZiAoYW1vdW50ID09PSAwIHx8IHJhZGl1cyA8IDAuNSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChyYWRpdXMgPiAyLjApIHtcbiAgICByYWRpdXMgPSAyLjA7XG4gIH1cblxuICB2YXIgYnJpZ2h0bmVzcyA9IGhzdl92MTYoaW1nLCB3aWR0aCwgaGVpZ2h0KTtcbiAgdmFyIGJsdXJlZCA9IG5ldyBVaW50MTZBcnJheShicmlnaHRuZXNzKTsgLy8gY29weSwgYmVjYXVzZSBibHVyIG1vZGlmeSBzcmNcblxuICBnbHVyX21vbm8xNihibHVyZWQsIHdpZHRoLCBoZWlnaHQsIHJhZGl1cyk7XG4gIHZhciBhbW91bnRGcCA9IGFtb3VudCAvIDEwMCAqIDB4MTAwMCArIDAuNSB8IDA7XG4gIHZhciB0aHJlc2hvbGRGcCA9IHRocmVzaG9sZCA8PCA4O1xuICB2YXIgc2l6ZSA9IHdpZHRoICogaGVpZ2h0O1xuICAvKiBlc2xpbnQtZGlzYWJsZSBpbmRlbnQgKi9cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7IGkrKykge1xuICAgIHYxID0gYnJpZ2h0bmVzc1tpXTtcbiAgICBkaWZmID0gdjEgLSBibHVyZWRbaV07XG5cbiAgICBpZiAoTWF0aC5hYnMoZGlmZikgPj0gdGhyZXNob2xkRnApIHtcbiAgICAgIC8vIGFkZCB1bnNoYXJwIG1hc2sgdG8gdGhlIGJyaWdodG5lc3MgY2hhbm5lbFxuICAgICAgdjIgPSB2MSArIChhbW91bnRGcCAqIGRpZmYgKyAweDgwMCA+PiAxMik7IC8vIEJvdGggdjEgYW5kIHYyIGFyZSB3aXRoaW4gWzAuMCAuLiAyNTUuMF0gKDAwMDAtRkYwMCkgcmFuZ2UsIG5ldmVyIGdvaW5nIGludG9cbiAgICAgIC8vIFsyNTUuMDAzIC4uIDI1NS45OTZdIChGRjAxLUZGRkYpLiBUaGlzIGFsbG93cyB0byByb3VuZCB0aGlzIHZhbHVlIGFzICh4Ky41KXwwXG4gICAgICAvLyBsYXRlciB3aXRob3V0IG92ZXJmbG93aW5nLlxuXG4gICAgICB2MiA9IHYyID4gMHhmZjAwID8gMHhmZjAwIDogdjI7XG4gICAgICB2MiA9IHYyIDwgMHgwMDAwID8gMHgwMDAwIDogdjI7IC8vIEF2b2lkIGRpdmlzaW9uIGJ5IDAuIFY9MCBtZWFucyByZ2IoMCwwLDApLCB1bnNoYXJwIHdpdGggdW5zaGFycEFtb3VudD4wIGNhbm5vdFxuICAgICAgLy8gY2hhbmdlIHRoaXMgdmFsdWUgKGJlY2F1c2UgZGlmZiBiZXR3ZWVuIGNvbG9ycyBnZXRzIGluZmxhdGVkKSwgc28gbm8gbmVlZCB0byB2ZXJpZnkgY29ycmVjdG5lc3MuXG5cbiAgICAgIHYxID0gdjEgIT09IDAgPyB2MSA6IDE7IC8vIE11bHRpcGx5aW5nIFYgaW4gSFNWIG1vZGVsIGJ5IGEgY29uc3RhbnQgaXMgZXF1aXZhbGVudCB0byBtdWx0aXBseWluZyBlYWNoIGNvbXBvbmVudFxuICAgICAgLy8gaW4gUkdCIGJ5IHRoZSBzYW1lIGNvbnN0YW50IChzYW1lIGZvciBIU0wpLCBzZWUgYWxzbzpcbiAgICAgIC8vIGh0dHBzOi8vYmVlc2J1enouYml6L2NvZGUvMTYtaHN2LWNvbG9yLXRyYW5zZm9ybXNcblxuICAgICAgdm11bCA9ICh2MiA8PCAxMikgLyB2MSB8IDA7IC8vIFJlc3VsdCB3aWxsIGJlIGluIFswLi4yNTVdIHJhbmdlIGJlY2F1c2U6XG4gICAgICAvLyAgLSBhbGwgbnVtYmVycyBhcmUgcG9zaXRpdmVcbiAgICAgIC8vICAtIHIsZyxiIDw9ICh2MS8yNTYpXG4gICAgICAvLyAgLSByLGcsYiwodjEvMjU2KSwodjIvMjU2KSA8PSAyNTVcbiAgICAgIC8vIFNvIGhpZ2hlc3QgdGhpcyBudW1iZXIgY2FuIGdldCBpcyBYKjI1NS9YKzAuNT0yNTUuNSB3aGljaCBpcyA8IDI1NiBhbmQgcm91bmRzIGRvd24uXG5cbiAgICAgIGlUaW1lczQgPSBpICogNDtcbiAgICAgIGltZ1tpVGltZXM0XSA9IGltZ1tpVGltZXM0XSAqIHZtdWwgKyAweDgwMCA+PiAxMjsgLy8gUlxuXG4gICAgICBpbWdbaVRpbWVzNCArIDFdID0gaW1nW2lUaW1lczQgKyAxXSAqIHZtdWwgKyAweDgwMCA+PiAxMjsgLy8gR1xuXG4gICAgICBpbWdbaVRpbWVzNCArIDJdID0gaW1nW2lUaW1lczQgKyAyXSAqIHZtdWwgKyAweDgwMCA+PiAxMjsgLy8gQlxuICAgIH1cbiAgfVxufTtcblxufSx7XCJnbHVyL21vbm8xNlwiOjE4fV0sMTE6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHVuc2hhcnAoaW1nLCB3aWR0aCwgaGVpZ2h0LCBhbW91bnQsIHJhZGl1cywgdGhyZXNob2xkKSB7XG4gIGlmIChhbW91bnQgPT09IDAgfHwgcmFkaXVzIDwgMC41KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHJhZGl1cyA+IDIuMCkge1xuICAgIHJhZGl1cyA9IDIuMDtcbiAgfVxuXG4gIHZhciBwaXhlbHMgPSB3aWR0aCAqIGhlaWdodDtcbiAgdmFyIGltZ19ieXRlc19jbnQgPSBwaXhlbHMgKiA0O1xuICB2YXIgaHN2X2J5dGVzX2NudCA9IHBpeGVscyAqIDI7XG4gIHZhciBibHVyX2J5dGVzX2NudCA9IHBpeGVscyAqIDI7XG4gIHZhciBibHVyX2xpbmVfYnl0ZV9jbnQgPSBNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KSAqIDQ7IC8vIGZsb2F0MzIgYXJyYXlcblxuICB2YXIgYmx1cl9jb2VmZnNfYnl0ZV9jbnQgPSA4ICogNDsgLy8gZmxvYXQzMiBhcnJheVxuXG4gIHZhciBpbWdfb2Zmc2V0ID0gMDtcbiAgdmFyIGhzdl9vZmZzZXQgPSBpbWdfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9vZmZzZXQgPSBoc3Zfb2Zmc2V0ICsgaHN2X2J5dGVzX2NudDtcbiAgdmFyIGJsdXJfdG1wX29mZnNldCA9IGJsdXJfb2Zmc2V0ICsgYmx1cl9ieXRlc19jbnQ7XG4gIHZhciBibHVyX2xpbmVfb2Zmc2V0ID0gYmx1cl90bXBfb2Zmc2V0ICsgYmx1cl9ieXRlc19jbnQ7XG4gIHZhciBibHVyX2NvZWZmc19vZmZzZXQgPSBibHVyX2xpbmVfb2Zmc2V0ICsgYmx1cl9saW5lX2J5dGVfY250O1xuXG4gIHZhciBpbnN0YW5jZSA9IHRoaXMuX19pbnN0YW5jZSgndW5zaGFycF9tYXNrJywgaW1nX2J5dGVzX2NudCArIGhzdl9ieXRlc19jbnQgKyBibHVyX2J5dGVzX2NudCAqIDIgKyBibHVyX2xpbmVfYnl0ZV9jbnQgKyBibHVyX2NvZWZmc19ieXRlX2NudCwge1xuICAgIGV4cDogTWF0aC5leHBcbiAgfSk7IC8vIDMyLWJpdCBjb3B5IGlzIG11Y2ggZmFzdGVyIGluIGNocm9tZVxuXG5cbiAgdmFyIGltZzMyID0gbmV3IFVpbnQzMkFycmF5KGltZy5idWZmZXIpO1xuICB2YXIgbWVtMzIgPSBuZXcgVWludDMyQXJyYXkodGhpcy5fX21lbW9yeS5idWZmZXIpO1xuICBtZW0zMi5zZXQoaW1nMzIpOyAvLyBIU0xcblxuICB2YXIgZm4gPSBpbnN0YW5jZS5leHBvcnRzLmhzdl92MTYgfHwgaW5zdGFuY2UuZXhwb3J0cy5faHN2X3YxNjtcbiAgZm4oaW1nX29mZnNldCwgaHN2X29mZnNldCwgd2lkdGgsIGhlaWdodCk7IC8vIEJMVVJcblxuICBmbiA9IGluc3RhbmNlLmV4cG9ydHMuYmx1ck1vbm8xNiB8fCBpbnN0YW5jZS5leHBvcnRzLl9ibHVyTW9ubzE2O1xuICBmbihoc3Zfb2Zmc2V0LCBibHVyX29mZnNldCwgYmx1cl90bXBfb2Zmc2V0LCBibHVyX2xpbmVfb2Zmc2V0LCBibHVyX2NvZWZmc19vZmZzZXQsIHdpZHRoLCBoZWlnaHQsIHJhZGl1cyk7IC8vIFVOU0hBUlBcblxuICBmbiA9IGluc3RhbmNlLmV4cG9ydHMudW5zaGFycCB8fCBpbnN0YW5jZS5leHBvcnRzLl91bnNoYXJwO1xuICBmbihpbWdfb2Zmc2V0LCBpbWdfb2Zmc2V0LCBoc3Zfb2Zmc2V0LCBibHVyX29mZnNldCwgd2lkdGgsIGhlaWdodCwgYW1vdW50LCB0aHJlc2hvbGQpOyAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuICBpbWczMi5zZXQobmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyLCAwLCBwaXhlbHMpKTtcbn07XG5cbn0se31dLDEyOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFRoaXMgaXMgYXV0b2dlbmVyYXRlZCBmaWxlIGZyb20gbWF0aC53YXNtLCBkb24ndCBlZGl0LlxuLy9cbid1c2Ugc3RyaWN0Jztcbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSAnQUdGemJRRUFBQUFBREFaa2VXeHBibXNBQUFBQUFBRTBCMkFBQUdBRWYzOS9md0JnQm45L2YzOS9md0JnQ0g5L2YzOS9mMzkvQUdBSWYzOS9mMzkvZjMwQVlBSjlmd0JnQVh3QmZBSVpBZ05sYm5ZRFpYaHdBQVlEWlc1MkJtMWxiVzl5ZVFJQUFBTUhCZ0FGQWdRQkF3WUdBWDhBUVFBTEI0b0JDQkZmWDNkaGMyMWZZMkZzYkY5amRHOXljd0FCRmw5ZlluVnBiR1JmWjJGMWMzTnBZVzVmWTI5bFpuTUFBZzVmWDJkaGRYTnpNVFpmYkdsdVpRQURDbUpzZFhKTmIyNXZNVFlBQkFkb2MzWmZkakUyQUFVSGRXNXphR0Z5Y0FBR0RGOWZaSE52WDJoaGJtUnNaUU1BR0Y5ZmQyRnpiVjloY0hCc2VWOWtZWFJoWDNKbGJHOWpjd0FCQ3NVTUJnTUFBUXZXQVFFSGZDQUJSTnVHdWtPQ0d2cy9JQUM3b3lJQ1JBQUFBQUFBQUFEQW9oQUFJZ1cyakRnQ0ZDQUJJQUthRUFBaUF5QURvQ0lHdGpnQ0VDQUJSQUFBQUFBQUFQQS9JQU9oSWdRZ0JLSWdBeUFDSUFLZ29rUUFBQUFBQUFEd1A2QWdCYUdqSWdTMk9BSUFJQUVnQlNBRW1xSWlCN1k0QWd3Z0FTQURJQUpFQUFBQUFBQUE4RCtnSUFTaW9pSUl0amdDQ0NBQklBTWdBa1FBQUFBQUFBRHd2NkFnQktLaUlnSzJPQUlFSUFFZ0J5QUlvQ0FGUkFBQUFBQUFBUEEvSUFhaG9DSURvN1k0QWh3Z0FTQUVJQUtnSUFPanRqZ0NHQXVHQlFNR2Z3bDhBbjBnQXlvQ0RDRVZJQU1xQWdnaEZpQURLZ0lVdXlFUklBTXFBaEM3SVJBQ1FDQUVRUUZySWdoQkFFZ2lDUVJBSUFJaEJ5QUFJUVlNQVFzZ0FpQUFMd0VBdUNJUElBTXFBaGk3b2lJTUlCR2lJZzBnRENBUW9pQVBJQU1xQWdTN0loT2lJaFFnQXlvQ0FMc2lFaUFQb3FDZ29DSU90amdDQUNBQ1FRUnFJUWNnQUVFQ2FpRUdJQWhGRFFBZ0NFRUJJQWhCQVVnYklncEJmM01oQ3dKL0lBUWdDbXRCQVhGRkJFQWdEaUVOSUFnTUFRc2dBaUFOSUE0Z0VLSWdGQ0FTSUFBdkFRSzRJZytpb0tDZ0lnMjJPQUlFSUFKQkNHb2hCeUFBUVFScUlRWWdEaUVNSUFSQkFtc0xJUUlnQzBFQUlBUnJSZzBBQTBBZ0J5QU1JQkdpSUEwZ0VLSWdEeUFUb2lBU0lBWXZBUUM0SWc2aW9LQ2dJZ3kyT0FJQUlBY2dEU0FSb2lBTUlCQ2lJQTRnRTZJZ0VpQUdMd0VDdUNJUG9xQ2dvQ0lOdGpnQ0JDQUhRUWhxSVFjZ0JrRUVhaUVHSUFKQkFrb2hBQ0FDUVFKcklRSWdBQTBBQ3dzQ1FDQUpEUUFnQVNBRklBaHNRUUYwYWlJQUFuOGdCa0VDYXk4QkFDSUN1Q0lOSUJXN0loS2lJQTBnRnJzaUU2S2dJQTBnQXlvQ0hMdWlJZ3dnRUtLZ0lBd2dFYUtnSWc4Z0IwRUVheUlIS2dJQXU2QWlEa1FBQUFBQUFBRHdRV01nRGtRQUFBQUFBQUFBQUdaeEJFQWdEcXNNQVF0QkFBczdBUUFnQ0VVTkFDQUdRUVJySVFaQkFDQUZhMEVCZENFQkEwQUNmeUFOSUJLaUlBSkIvLzhEY2JnaURTQVRvcUFnRHlJT0lCQ2lvQ0FNSUJHaW9DSVBJQWRCQkdzaUJ5b0NBTHVnSWd4RUFBQUFBQUFBOEVGaklBeEVBQUFBQUFBQUFBQm1jUVJBSUF5ckRBRUxRUUFMSVFNZ0JpOEJBQ0VDSUFBZ0FXb2lBQ0FET3dFQUlBWkJBbXNoQmlBSVFRRktJUU1nRGlFTUlBaEJBV3NoQ0NBRERRQUxDd3ZSQWdJQmZ3ZDhBa0FnQjBNQUFBQUFXdzBBSUFSRTI0YTZRNElhK3o4Z0IwTUFBQUEvbDd1aklnbEVBQUFBQUFBQUFNQ2lFQUFpRExhTU9BSVVJQVFnQ1pvUUFDSUtJQXFnSWcyMk9BSVFJQVJFQUFBQUFBQUE4RDhnQ3FFaUN5QUxvaUFLSUFrZ0NhQ2lSQUFBQUFBQUFQQS9vQ0FNb2FNaUM3WTRBZ0FnQkNBTUlBdWFvaUlPdGpnQ0RDQUVJQW9nQ1VRQUFBQUFBQUR3UDZBZ0M2S2lJZysyT0FJSUlBUWdDaUFKUkFBQUFBQUFBUEMvb0NBTG9xSWlDYlk0QWdRZ0JDQU9JQStnSUF4RUFBQUFBQUFBOEQ4Z0RhR2dJZ3FqdGpnQ0hDQUVJQXNnQ2FBZ0NxTzJPQUlZSUFZRVFBTkFJQUFnQlNBSWJFRUJkR29nQWlBSVFRRjBhaUFESUFRZ0JTQUdFQU1nQ0VFQmFpSUlJQVpIRFFBTEN5QUZSUTBBUVFBaENBTkFJQUlnQmlBSWJFRUJkR29nQVNBSVFRRjBhaUFESUFRZ0JpQUZFQU1nQ0VFQmFpSUlJQVZIRFFBTEN3dHhBUU4vSUFJZ0Eyd2lCUVJBQTBBZ0FTQUFLQUlBSWdSQkVIWkIvd0Z4SWdJZ0FpQUVRUWgyUWY4QmNTSURJQU1nQkVIL0FYRWlCRWtiSUFJZ0Ewc2JJZ1lnQmlBRUlBSWdCRXNiSUFNZ0JFc2JRUWgwT3dFQUlBRkJBbW9oQVNBQVFRUnFJUUFnQlVFQmF5SUZEUUFMQ3d1WkFnSURmd0Y4SUFRZ0JXd2hCQUovSUFhelF3QUFnRVdVUXdBQXlFS1Z1MFFBQUFBQUFBRGdQNkFpQzVsRUFBQUFBQUFBNEVGakJFQWdDNm9NQVF0QmdJQ0FnSGdMSVFVZ0JBUkFJQWRCQ0hRaENVRUFJUVlEUUNBSklBSWdCa0VCZENJSGFpOEJBQ0lCSUFNZ0Iyb3ZBUUJySWdjZ0IwRWZkU0lJYWlBSWMwMEVRQ0FBSUFaQkFuUWlDR29pQ2lBRklBZHNRWUFRYWtFTWRTQUJhaUlIUVlEK0F5QUhRWUQrQTBnYklnZEJBQ0FIUVFCS0cwRU1kQ0FCUVFFZ0FSdHVJZ0VnQ2kwQUFHeEJnQkJxUVF4Mk9nQUFJQUFnQ0VFQmNtb2lCeUFCSUFjdEFBQnNRWUFRYWtFTWRqb0FBQ0FBSUFoQkFuSnFJZ2NnQVNBSExRQUFiRUdBRUdwQkRIWTZBQUFMSUFaQkFXb2lCaUFFUncwQUN3c0wnO1xuXG59LHt9XSwxMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBHQ19JTlRFUlZBTCA9IDEwMDtcblxuZnVuY3Rpb24gUG9vbChjcmVhdGUsIGlkbGUpIHtcbiAgdGhpcy5jcmVhdGUgPSBjcmVhdGU7XG4gIHRoaXMuYXZhaWxhYmxlID0gW107XG4gIHRoaXMuYWNxdWlyZWQgPSB7fTtcbiAgdGhpcy5sYXN0SWQgPSAxO1xuICB0aGlzLnRpbWVvdXRJZCA9IDA7XG4gIHRoaXMuaWRsZSA9IGlkbGUgfHwgMjAwMDtcbn1cblxuUG9vbC5wcm90b3R5cGUuYWNxdWlyZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICB2YXIgcmVzb3VyY2U7XG5cbiAgaWYgKHRoaXMuYXZhaWxhYmxlLmxlbmd0aCAhPT0gMCkge1xuICAgIHJlc291cmNlID0gdGhpcy5hdmFpbGFibGUucG9wKCk7XG4gIH0gZWxzZSB7XG4gICAgcmVzb3VyY2UgPSB0aGlzLmNyZWF0ZSgpO1xuICAgIHJlc291cmNlLmlkID0gdGhpcy5sYXN0SWQrKztcblxuICAgIHJlc291cmNlLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gX3RoaXMucmVsZWFzZShyZXNvdXJjZSk7XG4gICAgfTtcbiAgfVxuXG4gIHRoaXMuYWNxdWlyZWRbcmVzb3VyY2UuaWRdID0gcmVzb3VyY2U7XG4gIHJldHVybiByZXNvdXJjZTtcbn07XG5cblBvb2wucHJvdG90eXBlLnJlbGVhc2UgPSBmdW5jdGlvbiAocmVzb3VyY2UpIHtcbiAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgZGVsZXRlIHRoaXMuYWNxdWlyZWRbcmVzb3VyY2UuaWRdO1xuICByZXNvdXJjZS5sYXN0VXNlZCA9IERhdGUubm93KCk7XG4gIHRoaXMuYXZhaWxhYmxlLnB1c2gocmVzb3VyY2UpO1xuXG4gIGlmICh0aGlzLnRpbWVvdXRJZCA9PT0gMCkge1xuICAgIHRoaXMudGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gX3RoaXMyLmdjKCk7XG4gICAgfSwgR0NfSU5URVJWQUwpO1xuICB9XG59O1xuXG5Qb29sLnByb3RvdHlwZS5nYyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgdmFyIG5vdyA9IERhdGUubm93KCk7XG4gIHRoaXMuYXZhaWxhYmxlID0gdGhpcy5hdmFpbGFibGUuZmlsdGVyKGZ1bmN0aW9uIChyZXNvdXJjZSkge1xuICAgIGlmIChub3cgLSByZXNvdXJjZS5sYXN0VXNlZCA+IF90aGlzMy5pZGxlKSB7XG4gICAgICByZXNvdXJjZS5kZXN0cm95KCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0pO1xuXG4gIGlmICh0aGlzLmF2YWlsYWJsZS5sZW5ndGggIT09IDApIHtcbiAgICB0aGlzLnRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzMy5nYygpO1xuICAgIH0sIEdDX0lOVEVSVkFMKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnRpbWVvdXRJZCA9IDA7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUG9vbDtcblxufSx7fV0sMTQ6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gQWRkIGludGVybWVkaWF0ZSByZXNpemluZyBzdGVwcyB3aGVuIHNjYWxpbmcgZG93biBieSBhIHZlcnkgbGFyZ2UgZmFjdG9yLlxuLy9cbi8vIEZvciBleGFtcGxlLCB3aGVuIHJlc2l6aW5nIDEwMDAweDEwMDAwIGRvd24gdG8gMTB4MTAsIGl0J2xsIHJlc2l6ZSBpdCB0b1xuLy8gMzAweDMwMCBmaXJzdC5cbi8vXG4vLyBJdCdzIG5lZWRlZCBiZWNhdXNlIHRpbGVyIGhhcyBpc3N1ZXMgd2hlbiB0aGUgZW50aXJlIHRpbGUgaXMgc2NhbGVkIGRvd25cbi8vIHRvIGEgZmV3IHBpeGVscyAoMTAyNHB4IHNvdXJjZSB0aWxlIHdpdGggYm9yZGVyIHNpemUgMyBzaG91bGQgcmVzdWx0IGluXG4vLyBhdCBsZWFzdCAzKzMrMiA9IDhweCB0YXJnZXQgdGlsZSwgc28gbWF4IHNjYWxlIGZhY3RvciBpcyAxMjggaGVyZSkuXG4vL1xuLy8gQWxzbywgYWRkaW5nIGludGVybWVkaWF0ZSBzdGVwcyBjYW4gc3BlZWQgdXAgcHJvY2Vzc2luZyBpZiB3ZSB1c2UgbG93ZXJcbi8vIHF1YWxpdHkgYWxnb3JpdGhtcyBmb3IgZmlyc3Qgc3RhZ2VzLlxuLy9cbid1c2Ugc3RyaWN0JzsgLy8gbWluIHNpemUgPSAwIHJlc3VsdHMgaW4gaW5maW5pdGUgbG9vcCxcbi8vIG1pbiBzaXplID0gMSBjYW4gY29uc3VtZSBsYXJnZSBhbW91bnQgb2YgbWVtb3J5XG5cbnZhciBNSU5fSU5ORVJfVElMRV9TSVpFID0gMjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVTdGFnZXMoZnJvbVdpZHRoLCBmcm9tSGVpZ2h0LCB0b1dpZHRoLCB0b0hlaWdodCwgc3JjVGlsZVNpemUsIGRlc3RUaWxlQm9yZGVyKSB7XG4gIHZhciBzY2FsZVggPSB0b1dpZHRoIC8gZnJvbVdpZHRoO1xuICB2YXIgc2NhbGVZID0gdG9IZWlnaHQgLyBmcm9tSGVpZ2h0OyAvLyBkZXJpdmVkIGZyb20gY3JlYXRlUmVnaW9ucyBlcXVhdGlvbjpcbiAgLy8gaW5uZXJUaWxlV2lkdGggPSBwaXhlbEZsb29yKHNyY1RpbGVTaXplICogc2NhbGVYKSAtIDIgKiBkZXN0VGlsZUJvcmRlcjtcblxuICB2YXIgbWluU2NhbGUgPSAoMiAqIGRlc3RUaWxlQm9yZGVyICsgTUlOX0lOTkVSX1RJTEVfU0laRSArIDEpIC8gc3JjVGlsZVNpemU7IC8vIHJlZnVzZSB0byBzY2FsZSBpbWFnZSBtdWx0aXBsZSB0aW1lcyBieSBsZXNzIHRoYW4gdHdpY2UgZWFjaCB0aW1lLFxuICAvLyBpdCBjb3VsZCBvbmx5IGhhcHBlbiBiZWNhdXNlIG9mIGludmFsaWQgb3B0aW9uc1xuXG4gIGlmIChtaW5TY2FsZSA+IDAuNSkgcmV0dXJuIFtbdG9XaWR0aCwgdG9IZWlnaHRdXTtcbiAgdmFyIHN0YWdlQ291bnQgPSBNYXRoLmNlaWwoTWF0aC5sb2coTWF0aC5taW4oc2NhbGVYLCBzY2FsZVkpKSAvIE1hdGgubG9nKG1pblNjYWxlKSk7IC8vIG5vIGFkZGl0aW9uYWwgcmVzaXplcyBhcmUgbmVjZXNzYXJ5LFxuICAvLyBzdGFnZUNvdW50IGNhbiBiZSB6ZXJvIG9yIGJlIG5lZ2F0aXZlIHdoZW4gZW5sYXJnaW5nIHRoZSBpbWFnZVxuXG4gIGlmIChzdGFnZUNvdW50IDw9IDEpIHJldHVybiBbW3RvV2lkdGgsIHRvSGVpZ2h0XV07XG4gIHZhciByZXN1bHQgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWdlQ291bnQ7IGkrKykge1xuICAgIHZhciB3aWR0aCA9IE1hdGgucm91bmQoTWF0aC5wb3coTWF0aC5wb3coZnJvbVdpZHRoLCBzdGFnZUNvdW50IC0gaSAtIDEpICogTWF0aC5wb3codG9XaWR0aCwgaSArIDEpLCAxIC8gc3RhZ2VDb3VudCkpO1xuICAgIHZhciBoZWlnaHQgPSBNYXRoLnJvdW5kKE1hdGgucG93KE1hdGgucG93KGZyb21IZWlnaHQsIHN0YWdlQ291bnQgLSBpIC0gMSkgKiBNYXRoLnBvdyh0b0hlaWdodCwgaSArIDEpLCAxIC8gc3RhZ2VDb3VudCkpO1xuICAgIHJlc3VsdC5wdXNoKFt3aWR0aCwgaGVpZ2h0XSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxufSx7fV0sMTU6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gU3BsaXQgb3JpZ2luYWwgaW1hZ2UgaW50byBtdWx0aXBsZSAxMDI0eDEwMjQgY2h1bmtzIHRvIHJlZHVjZSBtZW1vcnkgdXNhZ2Vcbi8vIChpbWFnZXMgaGF2ZSB0byBiZSB1bnBhY2tlZCBpbnRvIHR5cGVkIGFycmF5cyBmb3IgcmVzaXppbmcpIGFuZCBhbGxvd1xuLy8gcGFyYWxsZWwgcHJvY2Vzc2luZyBvZiBtdWx0aXBsZSB0aWxlcyBhdCBhIHRpbWUuXG4vL1xuJ3VzZSBzdHJpY3QnO1xuLypcbiAqIHBpeGVsRmxvb3IgYW5kIHBpeGVsQ2VpbCBhcmUgbW9kaWZpZWQgdmVyc2lvbnMgb2YgTWF0aC5mbG9vciBhbmQgTWF0aC5jZWlsXG4gKiBmdW5jdGlvbnMgd2hpY2ggdGFrZSBpbnRvIGFjY291bnQgZmxvYXRpbmcgcG9pbnQgYXJpdGhtZXRpYyBlcnJvcnMuXG4gKiBUaG9zZSBlcnJvcnMgY2FuIGNhdXNlIHVuZGVzaXJlZCBpbmNyZW1lbnRzL2RlY3JlbWVudHMgb2Ygc2l6ZXMgYW5kIG9mZnNldHM6XG4gKiBNYXRoLmNlaWwoMzYgLyAoMzYgLyA1MDApKSA9IDUwMVxuICogcGl4ZWxDZWlsKDM2IC8gKDM2IC8gNTAwKSkgPSA1MDBcbiAqL1xuXG52YXIgUElYRUxfRVBTSUxPTiA9IDFlLTU7XG5cbmZ1bmN0aW9uIHBpeGVsRmxvb3IoeCkge1xuICB2YXIgbmVhcmVzdCA9IE1hdGgucm91bmQoeCk7XG5cbiAgaWYgKE1hdGguYWJzKHggLSBuZWFyZXN0KSA8IFBJWEVMX0VQU0lMT04pIHtcbiAgICByZXR1cm4gbmVhcmVzdDtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmZsb29yKHgpO1xufVxuXG5mdW5jdGlvbiBwaXhlbENlaWwoeCkge1xuICB2YXIgbmVhcmVzdCA9IE1hdGgucm91bmQoeCk7XG5cbiAgaWYgKE1hdGguYWJzKHggLSBuZWFyZXN0KSA8IFBJWEVMX0VQU0lMT04pIHtcbiAgICByZXR1cm4gbmVhcmVzdDtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmNlaWwoeCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlUmVnaW9ucyhvcHRpb25zKSB7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgaW5uZXJUaWxlV2lkdGggPSBwaXhlbEZsb29yKG9wdGlvbnMuc3JjVGlsZVNpemUgKiBzY2FsZVgpIC0gMiAqIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG4gIHZhciBpbm5lclRpbGVIZWlnaHQgPSBwaXhlbEZsb29yKG9wdGlvbnMuc3JjVGlsZVNpemUgKiBzY2FsZVkpIC0gMiAqIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7IC8vIHByZXZlbnQgaW5maW5pdGUgbG9vcCwgdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuXG5cbiAgaWYgKGlubmVyVGlsZVdpZHRoIDwgMSB8fCBpbm5lclRpbGVIZWlnaHQgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBlcnJvciBpbiBwaWNhOiB0YXJnZXQgdGlsZSB3aWR0aC9oZWlnaHQgaXMgdG9vIHNtYWxsLicpO1xuICB9XG5cbiAgdmFyIHgsIHk7XG4gIHZhciBpbm5lclgsIGlubmVyWSwgdG9UaWxlV2lkdGgsIHRvVGlsZUhlaWdodDtcbiAgdmFyIHRpbGVzID0gW107XG4gIHZhciB0aWxlOyAvLyB3ZSBnbyB0b3AtdG8tZG93biBpbnN0ZWFkIG9mIGxlZnQtdG8tcmlnaHQgdG8gbWFrZSBpbWFnZSBkaXNwbGF5ZWQgZnJvbSB0b3AgdG9cbiAgLy8gZG9lc24gaW4gdGhlIGJyb3dzZXJcblxuICBmb3IgKGlubmVyWSA9IDA7IGlubmVyWSA8IG9wdGlvbnMudG9IZWlnaHQ7IGlubmVyWSArPSBpbm5lclRpbGVIZWlnaHQpIHtcbiAgICBmb3IgKGlubmVyWCA9IDA7IGlubmVyWCA8IG9wdGlvbnMudG9XaWR0aDsgaW5uZXJYICs9IGlubmVyVGlsZVdpZHRoKSB7XG4gICAgICB4ID0gaW5uZXJYIC0gb3B0aW9ucy5kZXN0VGlsZUJvcmRlcjtcblxuICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgIHggPSAwO1xuICAgICAgfVxuXG4gICAgICB0b1RpbGVXaWR0aCA9IGlubmVyWCArIGlubmVyVGlsZVdpZHRoICsgb3B0aW9ucy5kZXN0VGlsZUJvcmRlciAtIHg7XG5cbiAgICAgIGlmICh4ICsgdG9UaWxlV2lkdGggPj0gb3B0aW9ucy50b1dpZHRoKSB7XG4gICAgICAgIHRvVGlsZVdpZHRoID0gb3B0aW9ucy50b1dpZHRoIC0geDtcbiAgICAgIH1cblxuICAgICAgeSA9IGlubmVyWSAtIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG5cbiAgICAgIGlmICh5IDwgMCkge1xuICAgICAgICB5ID0gMDtcbiAgICAgIH1cblxuICAgICAgdG9UaWxlSGVpZ2h0ID0gaW5uZXJZICsgaW5uZXJUaWxlSGVpZ2h0ICsgb3B0aW9ucy5kZXN0VGlsZUJvcmRlciAtIHk7XG5cbiAgICAgIGlmICh5ICsgdG9UaWxlSGVpZ2h0ID49IG9wdGlvbnMudG9IZWlnaHQpIHtcbiAgICAgICAgdG9UaWxlSGVpZ2h0ID0gb3B0aW9ucy50b0hlaWdodCAtIHk7XG4gICAgICB9XG5cbiAgICAgIHRpbGUgPSB7XG4gICAgICAgIHRvWDogeCxcbiAgICAgICAgdG9ZOiB5LFxuICAgICAgICB0b1dpZHRoOiB0b1RpbGVXaWR0aCxcbiAgICAgICAgdG9IZWlnaHQ6IHRvVGlsZUhlaWdodCxcbiAgICAgICAgdG9Jbm5lclg6IGlubmVyWCxcbiAgICAgICAgdG9Jbm5lclk6IGlubmVyWSxcbiAgICAgICAgdG9Jbm5lcldpZHRoOiBpbm5lclRpbGVXaWR0aCxcbiAgICAgICAgdG9Jbm5lckhlaWdodDogaW5uZXJUaWxlSGVpZ2h0LFxuICAgICAgICBvZmZzZXRYOiB4IC8gc2NhbGVYIC0gcGl4ZWxGbG9vcih4IC8gc2NhbGVYKSxcbiAgICAgICAgb2Zmc2V0WTogeSAvIHNjYWxlWSAtIHBpeGVsRmxvb3IoeSAvIHNjYWxlWSksXG4gICAgICAgIHNjYWxlWDogc2NhbGVYLFxuICAgICAgICBzY2FsZVk6IHNjYWxlWSxcbiAgICAgICAgeDogcGl4ZWxGbG9vcih4IC8gc2NhbGVYKSxcbiAgICAgICAgeTogcGl4ZWxGbG9vcih5IC8gc2NhbGVZKSxcbiAgICAgICAgd2lkdGg6IHBpeGVsQ2VpbCh0b1RpbGVXaWR0aCAvIHNjYWxlWCksXG4gICAgICAgIGhlaWdodDogcGl4ZWxDZWlsKHRvVGlsZUhlaWdodCAvIHNjYWxlWSlcbiAgICAgIH07XG4gICAgICB0aWxlcy5wdXNoKHRpbGUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aWxlcztcbn07XG5cbn0se31dLDE2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gb2JqQ2xhc3Mob2JqKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuaXNDYW52YXMgPSBmdW5jdGlvbiBpc0NhbnZhcyhlbGVtZW50KSB7XG4gIHZhciBjbmFtZSA9IG9iakNsYXNzKGVsZW1lbnQpO1xuICByZXR1cm4gY25hbWUgPT09ICdbb2JqZWN0IEhUTUxDYW52YXNFbGVtZW50XSdcbiAgLyogYnJvd3NlciAqL1xuICB8fCBjbmFtZSA9PT0gJ1tvYmplY3QgT2Zmc2NyZWVuQ2FudmFzXScgfHwgY25hbWUgPT09ICdbb2JqZWN0IENhbnZhc10nXG4gIC8qIG5vZGUtY2FudmFzICovXG4gIDtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmlzSW1hZ2UgPSBmdW5jdGlvbiBpc0ltYWdlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIG9iakNsYXNzKGVsZW1lbnQpID09PSAnW29iamVjdCBIVE1MSW1hZ2VFbGVtZW50XSc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5pc0ltYWdlQml0bWFwID0gZnVuY3Rpb24gaXNJbWFnZUJpdG1hcChlbGVtZW50KSB7XG4gIHJldHVybiBvYmpDbGFzcyhlbGVtZW50KSA9PT0gJ1tvYmplY3QgSW1hZ2VCaXRtYXBdJztcbn07XG5cbm1vZHVsZS5leHBvcnRzLmxpbWl0ZXIgPSBmdW5jdGlvbiBsaW1pdGVyKGNvbmN1cnJlbmN5KSB7XG4gIHZhciBhY3RpdmUgPSAwLFxuICAgICAgcXVldWUgPSBbXTtcblxuICBmdW5jdGlvbiByb2xsKCkge1xuICAgIGlmIChhY3RpdmUgPCBjb25jdXJyZW5jeSAmJiBxdWV1ZS5sZW5ndGgpIHtcbiAgICAgIGFjdGl2ZSsrO1xuICAgICAgcXVldWUuc2hpZnQoKSgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiBsaW1pdChmbikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBxdWV1ZS5wdXNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm4oKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgYWN0aXZlLS07XG4gICAgICAgICAgcm9sbCgpO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgYWN0aXZlLS07XG4gICAgICAgICAgcm9sbCgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcm9sbCgpO1xuICAgIH0pO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMuY2liX3F1YWxpdHlfbmFtZSA9IGZ1bmN0aW9uIGNpYl9xdWFsaXR5X25hbWUobnVtKSB7XG4gIHN3aXRjaCAobnVtKSB7XG4gICAgY2FzZSAwOlxuICAgICAgcmV0dXJuICdwaXhlbGF0ZWQnO1xuXG4gICAgY2FzZSAxOlxuICAgICAgcmV0dXJuICdsb3cnO1xuXG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuICdtZWRpdW0nO1xuICB9XG5cbiAgcmV0dXJuICdoaWdoJztcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNpYl9zdXBwb3J0ID0gZnVuY3Rpb24gY2liX3N1cHBvcnQoY3JlYXRlQ2FudmFzKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodHlwZW9mIGNyZWF0ZUltYWdlQml0bWFwID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBjID0gY3JlYXRlQ2FudmFzKDEwMCwgMTAwKTtcbiAgICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoYywgMCwgMCwgMTAwLCAxMDAsIHtcbiAgICAgIHJlc2l6ZVdpZHRoOiAxMCxcbiAgICAgIHJlc2l6ZUhlaWdodDogMTAsXG4gICAgICByZXNpemVRdWFsaXR5OiAnaGlnaCdcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgIHZhciBzdGF0dXMgPSBiaXRtYXAud2lkdGggPT09IDEwOyAvLyBCcmFuY2ggYmVsb3cgaXMgZmlsdGVyZWQgb24gdXBwZXIgbGV2ZWwuIFdlIGRvIG5vdCBjYWxsIHJlc2l6ZVxuICAgICAgLy8gZGV0ZWN0aW9uIGZvciBiYXNpYyBJbWFnZUJpdG1hcC5cbiAgICAgIC8vXG4gICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSW1hZ2VCaXRtYXBcbiAgICAgIC8vIG9sZCBDcm9tZSA1MSBoYXMgSW1hZ2VCaXRtYXAgd2l0aG91dCAuY2xvc2UoKS4gVGhlbiB0aGlzIGNvZGVcbiAgICAgIC8vIHdpbGwgdGhyb3cgYW5kIHJldHVybiAnZmFsc2UnIGFzIGV4cGVjdGVkLlxuICAgICAgLy9cblxuICAgICAgYml0bWFwLmNsb3NlKCk7XG4gICAgICBjID0gbnVsbDtcbiAgICAgIHJldHVybiBzdGF0dXM7XG4gICAgfSk7XG4gIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy53b3JrZXJfb2Zmc2NyZWVuX2NhbnZhc19zdXBwb3J0ID0gZnVuY3Rpb24gd29ya2VyX29mZnNjcmVlbl9jYW52YXNfc3VwcG9ydCgpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBpZiAodHlwZW9mIE9mZnNjcmVlbkNhbnZhcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8vIGlmIE9mZnNjcmVlbkNhbnZhcyBpcyBwcmVzZW50LCB3ZSBhc3N1bWUgYnJvd3NlciBzdXBwb3J0cyBXb3JrZXIgYW5kIGJ1aWx0LWluIFByb21pc2UgYXMgd2VsbFxuICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd29ya2VyUGF5bG9hZChzZWxmKSB7XG4gICAgICBpZiAodHlwZW9mIGNyZWF0ZUltYWdlQml0bWFwID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBzZWxmLnBvc3RNZXNzYWdlKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNhbnZhcyA9IG5ldyBPZmZzY3JlZW5DYW52YXMoMTAsIDEwKTsgLy8gdGVzdCB0aGF0IDJkIGNvbnRleHQgY2FuIGJlIHVzZWQgaW4gd29ya2VyXG5cbiAgICAgICAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICBjdHgucmVjdCgwLCAwLCAxLCAxKTsgLy8gdGVzdCB0aGF0IGNpYiBjYW4gYmUgdXNlZCB0byByZXR1cm4gaW1hZ2UgYml0bWFwIGZyb20gd29ya2VyXG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGNhbnZhcywgMCwgMCwgMSwgMSk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYucG9zdE1lc3NhZ2UodHJ1ZSk7XG4gICAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzZWxmLnBvc3RNZXNzYWdlKGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBjb2RlID0gYnRvYShcIihcIi5jb25jYXQod29ya2VyUGF5bG9hZC50b1N0cmluZygpLCBcIikoc2VsZik7XCIpKTtcbiAgICB2YXIgdyA9IG5ldyBXb3JrZXIoXCJkYXRhOnRleHQvamF2YXNjcmlwdDtiYXNlNjQsXCIuY29uY2F0KGNvZGUpKTtcblxuICAgIHcub25tZXNzYWdlID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZShldi5kYXRhKTtcbiAgICB9O1xuXG4gICAgdy5vbmVycm9yID0gcmVqZWN0O1xuICB9KS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KTtcbn07IC8vIENoZWNrIGlmIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmdldEltYWdlRGF0YSBjYW4gYmUgdXNlZCxcbi8vIEZpcmVGb3ggcmFuZG9taXplcyB0aGUgb3V0cHV0IG9mIHRoYXQgZnVuY3Rpb24gaW4gYHByaXZhY3kucmVzaXN0RmluZ2VycHJpbnRpbmdgIG1vZGVcblxuXG5tb2R1bGUuZXhwb3J0cy5jYW5fdXNlX2NhbnZhcyA9IGZ1bmN0aW9uIGNhbl91c2VfY2FudmFzKGNyZWF0ZUNhbnZhcykge1xuICB2YXIgdXNhYmxlID0gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgY2FudmFzID0gY3JlYXRlQ2FudmFzKDIsIDEpO1xuICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICB2YXIgZCA9IGN0eC5jcmVhdGVJbWFnZURhdGEoMiwgMSk7XG4gICAgZC5kYXRhWzBdID0gMTI7XG4gICAgZC5kYXRhWzFdID0gMjM7XG4gICAgZC5kYXRhWzJdID0gMzQ7XG4gICAgZC5kYXRhWzNdID0gMjU1O1xuICAgIGQuZGF0YVs0XSA9IDQ1O1xuICAgIGQuZGF0YVs1XSA9IDU2O1xuICAgIGQuZGF0YVs2XSA9IDY3O1xuICAgIGQuZGF0YVs3XSA9IDI1NTtcbiAgICBjdHgucHV0SW1hZ2VEYXRhKGQsIDAsIDApO1xuICAgIGQgPSBudWxsO1xuICAgIGQgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIDIsIDEpO1xuXG4gICAgaWYgKGQuZGF0YVswXSA9PT0gMTIgJiYgZC5kYXRhWzFdID09PSAyMyAmJiBkLmRhdGFbMl0gPT09IDM0ICYmIGQuZGF0YVszXSA9PT0gMjU1ICYmIGQuZGF0YVs0XSA9PT0gNDUgJiYgZC5kYXRhWzVdID09PSA1NiAmJiBkLmRhdGFbNl0gPT09IDY3ICYmIGQuZGF0YVs3XSA9PT0gMjU1KSB7XG4gICAgICB1c2FibGUgPSB0cnVlO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7fVxuXG4gIHJldHVybiB1c2FibGU7XG59OyAvLyBDaGVjayBpZiBjcmVhdGVJbWFnZUJpdG1hcChpbWcsIHN4LCBzeSwgc3csIHNoKSBzaWduYXR1cmUgd29ya3MgY29ycmVjdGx5XG4vLyB3aXRoIEpQRUcgaW1hZ2VzIG9yaWVudGVkIHdpdGggRXhpZjtcbi8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTEyMjA2NzFcbi8vIFRPRE86IHJlbW92ZSBhZnRlciBpdCdzIGZpeGVkIGluIGNocm9tZSBmb3IgYXQgbGVhc3QgMiByZWxlYXNlc1xuXG5cbm1vZHVsZS5leHBvcnRzLmNpYl9jYW5fdXNlX3JlZ2lvbiA9IGZ1bmN0aW9uIGNpYl9jYW5fdXNlX3JlZ2lvbigpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgaWYgKHR5cGVvZiBjcmVhdGVJbWFnZUJpdG1hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuICAgIGltYWdlLnNyYyA9ICdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcgKyAnLzlqLzRRQmlSWGhwWmdBQVRVMEFLZ0FBQUFnQUJRRVNBQU1BQUFBQkFBWUFBQUVhQUFVQUFBQUJBQUFBU2dFYkFBVUFBJyArICdBQUJBQUFBVWdFb0FBTUFBQUFCQUFJQUFBSVRBQU1BQUFBQkFBRUFBQUFBQUFBQUFBQklBQUFBQVFBQUFFZ0FBQUFCLzknICsgJ3NBUXdBRUF3TUVBd01FQkFNRUJRUUVCUVlLQndZR0JnWU5DUW9JQ2c4TkVCQVBEUThPRVJNWUZCRVNGeElPRHhVY0ZSYycgKyAnWkdSc2JHeEFVSFI4ZEdoOFlHaHNhLzlzQVF3RUVCUVVHQlFZTUJ3Y01HaEVQRVJvYUdob2FHaG9hR2hvYUdob2FHaG9hJyArICdHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYS84SUFFUWdBQVFBQ0F3RVJBQUlSQVFNUkEnICsgJ2YvRUFCUUFBUUFBQUFBQUFBQUFBQUFBQUFBQUFBZi94QUFVQVFFQUFBQUFBQUFBQUFBQUFBQUFBQUFBLzlvQURBTUJBQScgKyAnSVFBeEFBQUFGL1AvL0VBQlFRQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRRUFBUVVDZi8vRUFCUVJBUUFBQUFBJyArICdBQUFBQUFBQUFBQUFBQUFELzJnQUlBUU1CQVQ4QmYvL0VBQlFSQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRSUInICsgJ0FUOEJmLy9FQUJRUUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUVBQmo4Q2YvL0VBQlFRQVFBQUFBQUFBQUFBQScgKyAnQUFBQUFBQUFBRC8yZ0FJQVFFQUFUOGhmLy9hQUF3REFRQUNBQU1BQUFBUUgvL0VBQlFSQVFBQUFBQUFBQUFBQUFBQUFBJyArICdBQUFBRC8yZ0FJQVFNQkFUOFFmLy9FQUJRUkFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUlCQVQ4UWYvL0VBQlEnICsgJ1FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFFQUFUOFFmLy9aJztcblxuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNyZWF0ZUltYWdlQml0bWFwKGltYWdlLCAwLCAwLCBpbWFnZS53aWR0aCwgaW1hZ2UuaGVpZ2h0KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgICAgaWYgKGJpdG1hcC53aWR0aCA9PT0gaW1hZ2Uud2lkdGggJiYgYml0bWFwLmhlaWdodCA9PT0gaW1hZ2UuaGVpZ2h0KSB7XG4gICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgaW1hZ2Uub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgICB9O1xuICB9KTtcbn07XG5cbn0se31dLDE3OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFdlYiBXb3JrZXIgd3JhcHBlciBmb3IgaW1hZ2UgcmVzaXplIGZ1bmN0aW9uXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgTWF0aExpYiA9IF9kZXJlcV8oJy4vbWF0aGxpYicpO1xuXG4gIHZhciBtYXRoTGliO1xuICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZiAqL1xuXG4gIG9ubWVzc2FnZSA9IGZ1bmN0aW9uIG9ubWVzc2FnZShldikge1xuICAgIHZhciB0aWxlT3B0cyA9IGV2LmRhdGEub3B0cztcbiAgICB2YXIgcmV0dXJuQml0bWFwID0gZmFsc2U7XG5cbiAgICBpZiAoIXRpbGVPcHRzLnNyYyAmJiB0aWxlT3B0cy5zcmNCaXRtYXApIHtcbiAgICAgIHZhciBjYW52YXMgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHRpbGVPcHRzLndpZHRoLCB0aWxlT3B0cy5oZWlnaHQpO1xuICAgICAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgICAgYWxwaGE6IEJvb2xlYW4odGlsZU9wdHMuYWxwaGEpXG4gICAgICB9KTtcbiAgICAgIGN0eC5kcmF3SW1hZ2UodGlsZU9wdHMuc3JjQml0bWFwLCAwLCAwKTtcbiAgICAgIHRpbGVPcHRzLnNyYyA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgdGlsZU9wdHMud2lkdGgsIHRpbGVPcHRzLmhlaWdodCkuZGF0YTtcbiAgICAgIGNhbnZhcy53aWR0aCA9IGNhbnZhcy5oZWlnaHQgPSAwO1xuICAgICAgY2FudmFzID0gbnVsbDtcbiAgICAgIHRpbGVPcHRzLnNyY0JpdG1hcC5jbG9zZSgpO1xuICAgICAgdGlsZU9wdHMuc3JjQml0bWFwID0gbnVsbDtcbiAgICAgIHJldHVybkJpdG1hcCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKCFtYXRoTGliKSBtYXRoTGliID0gbmV3IE1hdGhMaWIoZXYuZGF0YS5mZWF0dXJlcyk7IC8vIFVzZSBtdWx0aW1hdGgncyBzeW5jIGF1dG8taW5pdC4gQXZvaWQgUHJvbWlzZSB1c2UgaW4gb2xkIGJyb3dzZXJzLFxuICAgIC8vIGJlY2F1c2UgcG9seWZpbGxzIGFyZSBub3QgcHJvcGFnYXRlZCB0byB3ZWJ3b3JrZXIuXG5cbiAgICB2YXIgZGF0YSA9IG1hdGhMaWIucmVzaXplQW5kVW5zaGFycCh0aWxlT3B0cyk7XG5cbiAgICBpZiAocmV0dXJuQml0bWFwKSB7XG4gICAgICB2YXIgdG9JbWFnZURhdGEgPSBuZXcgSW1hZ2VEYXRhKG5ldyBVaW50OENsYW1wZWRBcnJheShkYXRhKSwgdGlsZU9wdHMudG9XaWR0aCwgdGlsZU9wdHMudG9IZWlnaHQpO1xuXG4gICAgICB2YXIgX2NhbnZhcyA9IG5ldyBPZmZzY3JlZW5DYW52YXModGlsZU9wdHMudG9XaWR0aCwgdGlsZU9wdHMudG9IZWlnaHQpO1xuXG4gICAgICB2YXIgX2N0eCA9IF9jYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICAgIGFscGhhOiBCb29sZWFuKHRpbGVPcHRzLmFscGhhKVxuICAgICAgfSk7XG5cbiAgICAgIF9jdHgucHV0SW1hZ2VEYXRhKHRvSW1hZ2VEYXRhLCAwLCAwKTtcblxuICAgICAgY3JlYXRlSW1hZ2VCaXRtYXAoX2NhbnZhcykudGhlbihmdW5jdGlvbiAoYml0bWFwKSB7XG4gICAgICAgIHBvc3RNZXNzYWdlKHtcbiAgICAgICAgICBiaXRtYXA6IGJpdG1hcFxuICAgICAgICB9LCBbYml0bWFwXSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcG9zdE1lc3NhZ2Uoe1xuICAgICAgICBkYXRhOiBkYXRhXG4gICAgICB9LCBbZGF0YS5idWZmZXJdKTtcbiAgICB9XG4gIH07XG59O1xuXG59LHtcIi4vbWF0aGxpYlwiOjF9XSwxODpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBDYWxjdWxhdGUgR2F1c3NpYW4gYmx1ciBvZiBhbiBpbWFnZSB1c2luZyBJSVIgZmlsdGVyXG4vLyBUaGUgbWV0aG9kIGlzIHRha2VuIGZyb20gSW50ZWwncyB3aGl0ZSBwYXBlciBhbmQgY29kZSBleGFtcGxlIGF0dGFjaGVkIHRvIGl0OlxuLy8gaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vZW4tdXMvYXJ0aWNsZXMvaWlyLWdhdXNzaWFuLWJsdXItZmlsdGVyXG4vLyAtaW1wbGVtZW50YXRpb24tdXNpbmctaW50ZWwtYWR2YW5jZWQtdmVjdG9yLWV4dGVuc2lvbnNcblxudmFyIGEwLCBhMSwgYTIsIGEzLCBiMSwgYjIsIGxlZnRfY29ybmVyLCByaWdodF9jb3JuZXI7XG5cbmZ1bmN0aW9uIGdhdXNzQ29lZihzaWdtYSkge1xuICBpZiAoc2lnbWEgPCAwLjUpIHtcbiAgICBzaWdtYSA9IDAuNTtcbiAgfVxuXG4gIHZhciBhID0gTWF0aC5leHAoMC43MjYgKiAwLjcyNikgLyBzaWdtYSxcbiAgICAgIGcxID0gTWF0aC5leHAoLWEpLFxuICAgICAgZzIgPSBNYXRoLmV4cCgtMiAqIGEpLFxuICAgICAgayA9ICgxIC0gZzEpICogKDEgLSBnMSkgLyAoMSArIDIgKiBhICogZzEgLSBnMik7XG5cbiAgYTAgPSBrO1xuICBhMSA9IGsgKiAoYSAtIDEpICogZzE7XG4gIGEyID0gayAqIChhICsgMSkgKiBnMTtcbiAgYTMgPSAtayAqIGcyO1xuICBiMSA9IDIgKiBnMTtcbiAgYjIgPSAtZzI7XG4gIGxlZnRfY29ybmVyID0gKGEwICsgYTEpIC8gKDEgLSBiMSAtIGIyKTtcbiAgcmlnaHRfY29ybmVyID0gKGEyICsgYTMpIC8gKDEgLSBiMSAtIGIyKTtcblxuICAvLyBBdHRlbXB0IHRvIGZvcmNlIHR5cGUgdG8gRlAzMi5cbiAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoWyBhMCwgYTEsIGEyLCBhMywgYjEsIGIyLCBsZWZ0X2Nvcm5lciwgcmlnaHRfY29ybmVyIF0pO1xufVxuXG5mdW5jdGlvbiBjb252b2x2ZU1vbm8xNihzcmMsIG91dCwgbGluZSwgY29lZmYsIHdpZHRoLCBoZWlnaHQpIHtcbiAgLy8gdGFrZXMgc3JjIGltYWdlIGFuZCB3cml0ZXMgdGhlIGJsdXJyZWQgYW5kIHRyYW5zcG9zZWQgcmVzdWx0IGludG8gb3V0XG5cbiAgdmFyIHByZXZfc3JjLCBjdXJyX3NyYywgY3Vycl9vdXQsIHByZXZfb3V0LCBwcmV2X3ByZXZfb3V0O1xuICB2YXIgc3JjX2luZGV4LCBvdXRfaW5kZXgsIGxpbmVfaW5kZXg7XG4gIHZhciBpLCBqO1xuICB2YXIgY29lZmZfYTAsIGNvZWZmX2ExLCBjb2VmZl9iMSwgY29lZmZfYjI7XG5cbiAgZm9yIChpID0gMDsgaSA8IGhlaWdodDsgaSsrKSB7XG4gICAgc3JjX2luZGV4ID0gaSAqIHdpZHRoO1xuICAgIG91dF9pbmRleCA9IGk7XG4gICAgbGluZV9pbmRleCA9IDA7XG5cbiAgICAvLyBsZWZ0IHRvIHJpZ2h0XG4gICAgcHJldl9zcmMgPSBzcmNbc3JjX2luZGV4XTtcbiAgICBwcmV2X3ByZXZfb3V0ID0gcHJldl9zcmMgKiBjb2VmZls2XTtcbiAgICBwcmV2X291dCA9IHByZXZfcHJldl9vdXQ7XG5cbiAgICBjb2VmZl9hMCA9IGNvZWZmWzBdO1xuICAgIGNvZWZmX2ExID0gY29lZmZbMV07XG4gICAgY29lZmZfYjEgPSBjb2VmZls0XTtcbiAgICBjb2VmZl9iMiA9IGNvZWZmWzVdO1xuXG4gICAgZm9yIChqID0gMDsgaiA8IHdpZHRoOyBqKyspIHtcbiAgICAgIGN1cnJfc3JjID0gc3JjW3NyY19pbmRleF07XG5cbiAgICAgIGN1cnJfb3V0ID0gY3Vycl9zcmMgKiBjb2VmZl9hMCArXG4gICAgICAgICAgICAgICAgIHByZXZfc3JjICogY29lZmZfYTEgK1xuICAgICAgICAgICAgICAgICBwcmV2X291dCAqIGNvZWZmX2IxICtcbiAgICAgICAgICAgICAgICAgcHJldl9wcmV2X291dCAqIGNvZWZmX2IyO1xuXG4gICAgICBwcmV2X3ByZXZfb3V0ID0gcHJldl9vdXQ7XG4gICAgICBwcmV2X291dCA9IGN1cnJfb3V0O1xuICAgICAgcHJldl9zcmMgPSBjdXJyX3NyYztcblxuICAgICAgbGluZVtsaW5lX2luZGV4XSA9IHByZXZfb3V0O1xuICAgICAgbGluZV9pbmRleCsrO1xuICAgICAgc3JjX2luZGV4Kys7XG4gICAgfVxuXG4gICAgc3JjX2luZGV4LS07XG4gICAgbGluZV9pbmRleC0tO1xuICAgIG91dF9pbmRleCArPSBoZWlnaHQgKiAod2lkdGggLSAxKTtcblxuICAgIC8vIHJpZ2h0IHRvIGxlZnRcbiAgICBwcmV2X3NyYyA9IHNyY1tzcmNfaW5kZXhdO1xuICAgIHByZXZfcHJldl9vdXQgPSBwcmV2X3NyYyAqIGNvZWZmWzddO1xuICAgIHByZXZfb3V0ID0gcHJldl9wcmV2X291dDtcbiAgICBjdXJyX3NyYyA9IHByZXZfc3JjO1xuXG4gICAgY29lZmZfYTAgPSBjb2VmZlsyXTtcbiAgICBjb2VmZl9hMSA9IGNvZWZmWzNdO1xuXG4gICAgZm9yIChqID0gd2lkdGggLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgY3Vycl9vdXQgPSBjdXJyX3NyYyAqIGNvZWZmX2EwICtcbiAgICAgICAgICAgICAgICAgcHJldl9zcmMgKiBjb2VmZl9hMSArXG4gICAgICAgICAgICAgICAgIHByZXZfb3V0ICogY29lZmZfYjEgK1xuICAgICAgICAgICAgICAgICBwcmV2X3ByZXZfb3V0ICogY29lZmZfYjI7XG5cbiAgICAgIHByZXZfcHJldl9vdXQgPSBwcmV2X291dDtcbiAgICAgIHByZXZfb3V0ID0gY3Vycl9vdXQ7XG5cbiAgICAgIHByZXZfc3JjID0gY3Vycl9zcmM7XG4gICAgICBjdXJyX3NyYyA9IHNyY1tzcmNfaW5kZXhdO1xuXG4gICAgICBvdXRbb3V0X2luZGV4XSA9IGxpbmVbbGluZV9pbmRleF0gKyBwcmV2X291dDtcblxuICAgICAgc3JjX2luZGV4LS07XG4gICAgICBsaW5lX2luZGV4LS07XG4gICAgICBvdXRfaW5kZXggLT0gaGVpZ2h0O1xuICAgIH1cbiAgfVxufVxuXG5cbmZ1bmN0aW9uIGJsdXJNb25vMTYoc3JjLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpIHtcbiAgLy8gUXVpY2sgZXhpdCBvbiB6ZXJvIHJhZGl1c1xuICBpZiAoIXJhZGl1cykgeyByZXR1cm47IH1cblxuICB2YXIgb3V0ICAgICAgPSBuZXcgVWludDE2QXJyYXkoc3JjLmxlbmd0aCksXG4gICAgICB0bXBfbGluZSA9IG5ldyBGbG9hdDMyQXJyYXkoTWF0aC5tYXgod2lkdGgsIGhlaWdodCkpO1xuXG4gIHZhciBjb2VmZiA9IGdhdXNzQ29lZihyYWRpdXMpO1xuXG4gIGNvbnZvbHZlTW9ubzE2KHNyYywgb3V0LCB0bXBfbGluZSwgY29lZmYsIHdpZHRoLCBoZWlnaHQsIHJhZGl1cyk7XG4gIGNvbnZvbHZlTW9ubzE2KG91dCwgc3JjLCB0bXBfbGluZSwgY29lZmYsIGhlaWdodCwgd2lkdGgsIHJhZGl1cyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmx1ck1vbm8xNjtcblxufSx7fV0sMTk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuXG59LHt9XSwyMDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cblxudmFyIGFzc2lnbiAgICAgICAgID0gX2RlcmVxXygnb2JqZWN0LWFzc2lnbicpO1xudmFyIGJhc2U2NGRlY29kZSAgID0gX2RlcmVxXygnLi9saWIvYmFzZTY0ZGVjb2RlJyk7XG52YXIgaGFzV2ViQXNzZW1ibHkgPSBfZGVyZXFfKCcuL2xpYi93YV9kZXRlY3QnKTtcblxuXG52YXIgREVGQVVMVF9PUFRJT05TID0ge1xuICBqczogdHJ1ZSxcbiAgd2FzbTogdHJ1ZVxufTtcblxuXG5mdW5jdGlvbiBNdWx0aU1hdGgob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTXVsdGlNYXRoKSkgcmV0dXJuIG5ldyBNdWx0aU1hdGgob3B0aW9ucyk7XG5cbiAgdmFyIG9wdHMgPSBhc3NpZ24oe30sIERFRkFVTFRfT1BUSU9OUywgb3B0aW9ucyB8fCB7fSk7XG5cbiAgdGhpcy5vcHRpb25zICAgICAgICAgPSBvcHRzO1xuXG4gIHRoaXMuX19jYWNoZSAgICAgICAgID0ge307XG5cbiAgdGhpcy5fX2luaXRfcHJvbWlzZSAgPSBudWxsO1xuICB0aGlzLl9fbW9kdWxlcyAgICAgICA9IG9wdHMubW9kdWxlcyB8fCB7fTtcbiAgdGhpcy5fX21lbW9yeSAgICAgICAgPSBudWxsO1xuICB0aGlzLl9fd2FzbSAgICAgICAgICA9IHt9O1xuXG4gIHRoaXMuX19pc0xFID0gKChuZXcgVWludDMyQXJyYXkoKG5ldyBVaW50OEFycmF5KFsgMSwgMCwgMCwgMCBdKSkuYnVmZmVyKSlbMF0gPT09IDEpO1xuXG4gIGlmICghdGhpcy5vcHRpb25zLmpzICYmICF0aGlzLm9wdGlvbnMud2FzbSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWF0aGxpYjogYXQgbGVhc3QgXCJqc1wiIG9yIFwid2FzbVwiIHNob3VsZCBiZSBlbmFibGVkJyk7XG4gIH1cbn1cblxuXG5NdWx0aU1hdGgucHJvdG90eXBlLmhhc193YXNtID0gaGFzV2ViQXNzZW1ibHk7XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiAobW9kdWxlKSB7XG4gIHRoaXMuX19tb2R1bGVzW21vZHVsZS5uYW1lXSA9IG1vZHVsZTtcblxuICAvLyBQaW4gdGhlIGJlc3QgcG9zc2libGUgaW1wbGVtZW50YXRpb25cbiAgaWYgKHRoaXMub3B0aW9ucy53YXNtICYmIHRoaXMuaGFzX3dhc20oKSAmJiBtb2R1bGUud2FzbV9mbikge1xuICAgIHRoaXNbbW9kdWxlLm5hbWVdID0gbW9kdWxlLndhc21fZm47XG4gIH0gZWxzZSB7XG4gICAgdGhpc1ttb2R1bGUubmFtZV0gPSBtb2R1bGUuZm47XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5fX2luaXRfcHJvbWlzZSkgcmV0dXJuIHRoaXMuX19pbml0X3Byb21pc2U7XG5cbiAgaWYgKCF0aGlzLm9wdGlvbnMuanMgJiYgdGhpcy5vcHRpb25zLndhc20gJiYgIXRoaXMuaGFzX3dhc20oKSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ21hdGhsaWI6IG9ubHkgXCJ3YXNtXCIgd2FzIGVuYWJsZWQsIGJ1dCBpdFxcJ3Mgbm90IHN1cHBvcnRlZCcpKTtcbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9faW5pdF9wcm9taXNlID0gUHJvbWlzZS5hbGwoT2JqZWN0LmtleXMoc2VsZi5fX21vZHVsZXMpLm1hcChmdW5jdGlvbiAobmFtZSkge1xuICAgIHZhciBtb2R1bGUgPSBzZWxmLl9fbW9kdWxlc1tuYW1lXTtcblxuICAgIGlmICghc2VsZi5vcHRpb25zLndhc20gfHwgIXNlbGYuaGFzX3dhc20oKSB8fCAhbW9kdWxlLndhc21fZm4pIHJldHVybiBudWxsO1xuXG4gICAgLy8gSWYgYWxyZWFkeSBjb21waWxlZCAtIGV4aXRcbiAgICBpZiAoc2VsZi5fX3dhc21bbmFtZV0pIHJldHVybiBudWxsO1xuXG4gICAgLy8gQ29tcGlsZSB3YXNtIHNvdXJjZVxuICAgIHJldHVybiBXZWJBc3NlbWJseS5jb21waWxlKHNlbGYuX19iYXNlNjRkZWNvZGUobW9kdWxlLndhc21fc3JjKSlcbiAgICAgIC50aGVuKGZ1bmN0aW9uIChtKSB7IHNlbGYuX193YXNtW25hbWVdID0gbTsgfSk7XG4gIH0pKVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGY7IH0pO1xuXG4gIHJldHVybiB0aGlzLl9faW5pdF9wcm9taXNlO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gTWV0aG9kcyBiZWxvdyBhcmUgZm9yIGludGVybmFsIHVzZSBmcm9tIHBsdWdpbnNcblxuXG4vLyBTaW1wbGUgZGVjb2RlIGJhc2U2NCB0byB0eXBlZCBhcnJheS4gVXNlZnVsIHRvIGxvYWQgZW1iZWRkZWQgd2ViYXNzZW1ibHlcbi8vIGNvZGUuIFlvdSBwcm9iYWJseSBkb24ndCBuZWVkIHRvIGNhbGwgdGhpcyBtZXRob2QgZGlyZWN0bHkuXG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2Jhc2U2NGRlY29kZSA9IGJhc2U2NGRlY29kZTtcblxuXG4vLyBJbmNyZWFzZSBjdXJyZW50IG1lbW9yeSB0byBpbmNsdWRlIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMuIERvIG5vdGhpbmcgaWZcbi8vIHNpemUgaXMgYWxyZWFkeSBvay4gWW91IHByb2JhYmx5IGRvbid0IG5lZWQgdG8gY2FsbCB0aGlzIG1ldGhvZCBkaXJlY3RseSxcbi8vIGJlY2F1c2UgaXQgd2lsbCBiZSBpbnZva2VkIGZyb20gYC5fX2luc3RhbmNlKClgLlxuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19yZWFsbG9jYXRlID0gZnVuY3Rpb24gbWVtX2dyb3dfdG8oYnl0ZXMpIHtcbiAgaWYgKCF0aGlzLl9fbWVtb3J5KSB7XG4gICAgdGhpcy5fX21lbW9yeSA9IG5ldyBXZWJBc3NlbWJseS5NZW1vcnkoe1xuICAgICAgaW5pdGlhbDogTWF0aC5jZWlsKGJ5dGVzIC8gKDY0ICogMTAyNCkpXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuX19tZW1vcnk7XG4gIH1cblxuICB2YXIgbWVtX3NpemUgPSB0aGlzLl9fbWVtb3J5LmJ1ZmZlci5ieXRlTGVuZ3RoO1xuXG4gIGlmIChtZW1fc2l6ZSA8IGJ5dGVzKSB7XG4gICAgdGhpcy5fX21lbW9yeS5ncm93KE1hdGguY2VpbCgoYnl0ZXMgLSBtZW1fc2l6ZSkgLyAoNjQgKiAxMDI0KSkpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX19tZW1vcnk7XG59O1xuXG5cbi8vIFJldHVybnMgaW5zdGFudGluYXRlZCB3ZWJhc3NlbWJseSBpdGVtIGJ5IG5hbWUsIHdpdGggc3BlY2lmaWVkIG1lbW9yeSBzaXplXG4vLyBhbmQgZW52aXJvbm1lbnQuXG4vLyAtIHVzZSBjYWNoZSBpZiBhdmFpbGFibGVcbi8vIC0gZG8gc3luYyBtb2R1bGUgaW5pdCwgaWYgYXN5bmMgaW5pdCB3YXMgbm90IGNhbGxlZCBlYXJsaWVyXG4vLyAtIGFsbG9jYXRlIG1lbW9yeSBpZiBub3QgZW5vdWd0aFxuLy8gLSBjYW4gZXhwb3J0IGZ1bmN0aW9ucyB0byB3ZWJhc3NlbWJseSB2aWEgXCJlbnZfZXh0cmFcIixcbi8vICAgZm9yIGV4YW1wbGUsIHsgZXhwOiBNYXRoLmV4cCB9XG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2luc3RhbmNlID0gZnVuY3Rpb24gaW5zdGFuY2UobmFtZSwgbWVtc2l6ZSwgZW52X2V4dHJhKSB7XG4gIGlmIChtZW1zaXplKSB0aGlzLl9fcmVhbGxvY2F0ZShtZW1zaXplKTtcblxuICAvLyBJZiAuaW5pdCgpIHdhcyBub3QgY2FsbGVkLCBkbyBzeW5jIGNvbXBpbGVcbiAgaWYgKCF0aGlzLl9fd2FzbVtuYW1lXSkge1xuICAgIHZhciBtb2R1bGUgPSB0aGlzLl9fbW9kdWxlc1tuYW1lXTtcbiAgICB0aGlzLl9fd2FzbVtuYW1lXSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUodGhpcy5fX2Jhc2U2NGRlY29kZShtb2R1bGUud2FzbV9zcmMpKTtcbiAgfVxuXG4gIGlmICghdGhpcy5fX2NhY2hlW25hbWVdKSB7XG4gICAgdmFyIGVudl9iYXNlID0ge1xuICAgICAgbWVtb3J5QmFzZTogMCxcbiAgICAgIG1lbW9yeTogdGhpcy5fX21lbW9yeSxcbiAgICAgIHRhYmxlQmFzZTogMCxcbiAgICAgIHRhYmxlOiBuZXcgV2ViQXNzZW1ibHkuVGFibGUoeyBpbml0aWFsOiAwLCBlbGVtZW50OiAnYW55ZnVuYycgfSlcbiAgICB9O1xuXG4gICAgdGhpcy5fX2NhY2hlW25hbWVdID0gbmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKHRoaXMuX193YXNtW25hbWVdLCB7XG4gICAgICBlbnY6IGFzc2lnbihlbnZfYmFzZSwgZW52X2V4dHJhIHx8IHt9KVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX19jYWNoZVtuYW1lXTtcbn07XG5cblxuLy8gSGVscGVyIHRvIGNhbGN1bGF0ZSBtZW1vcnkgYWxpZ2ggZm9yIHBvaW50ZXJzLiBXZWJhc3NlbWJseSBkb2VzIG5vdCByZXF1aXJlXG4vLyB0aGlzLCBidXQgeW91IG1heSB3aXNoIHRvIGV4cGVyaW1lbnQuIERlZmF1bHQgYmFzZSA9IDg7XG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2FsaWduID0gZnVuY3Rpb24gYWxpZ24obnVtYmVyLCBiYXNlKSB7XG4gIGJhc2UgPSBiYXNlIHx8IDg7XG4gIHZhciByZW1pbmRlciA9IG51bWJlciAlIGJhc2U7XG4gIHJldHVybiBudW1iZXIgKyAocmVtaW5kZXIgPyBiYXNlIC0gcmVtaW5kZXIgOiAwKTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNdWx0aU1hdGg7XG5cbn0se1wiLi9saWIvYmFzZTY0ZGVjb2RlXCI6MjEsXCIuL2xpYi93YV9kZXRlY3RcIjoyMixcIm9iamVjdC1hc3NpZ25cIjoyM31dLDIxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIGJhc2U2NCBkZWNvZGUgc3RyIC0+IFVpbnQ4QXJyYXksIHRvIGxvYWQgV0EgbW9kdWxlc1xuLy9cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgQkFTRTY0X01BUCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJhc2U2NGRlY29kZShzdHIpIHtcbiAgdmFyIGlucHV0ID0gc3RyLnJlcGxhY2UoL1tcXHJcXG49XS9nLCAnJyksIC8vIHJlbW92ZSBDUi9MRiAmIHBhZGRpbmcgdG8gc2ltcGxpZnkgc2NhblxuICAgICAgbWF4ICAgPSBpbnB1dC5sZW5ndGg7XG5cbiAgdmFyIG91dCA9IG5ldyBVaW50OEFycmF5KChtYXggKiAzKSA+PiAyKTtcblxuICAvLyBDb2xsZWN0IGJ5IDYqNCBiaXRzICgzIGJ5dGVzKVxuXG4gIHZhciBiaXRzID0gMDtcbiAgdmFyIHB0ciAgPSAwO1xuXG4gIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IG1heDsgaWR4KyspIHtcbiAgICBpZiAoKGlkeCAlIDQgPT09IDApICYmIGlkeCkge1xuICAgICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDE2KSAmIDB4RkY7XG4gICAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gOCkgJiAweEZGO1xuICAgICAgb3V0W3B0cisrXSA9IGJpdHMgJiAweEZGO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA2KSB8IEJBU0U2NF9NQVAuaW5kZXhPZihpbnB1dC5jaGFyQXQoaWR4KSk7XG4gIH1cblxuICAvLyBEdW1wIHRhaWxcblxuICB2YXIgdGFpbGJpdHMgPSAobWF4ICUgNCkgKiA2O1xuXG4gIGlmICh0YWlsYml0cyA9PT0gMCkge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxNikgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiA4KSAmIDB4RkY7XG4gICAgb3V0W3B0cisrXSA9IGJpdHMgJiAweEZGO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxOCkge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxMCkgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAyKSAmIDB4RkY7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDEyKSB7XG4gICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDQpICYgMHhGRjtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG59LHt9XSwyMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBEZXRlY3QgV2ViQXNzZW1ibHkgc3VwcG9ydC5cbi8vIC0gQ2hlY2sgZ2xvYmFsIFdlYkFzc2VtYmx5IG9iamVjdFxuLy8gLSBUcnkgdG8gbG9hZCBzaW1wbGUgbW9kdWxlIChjYW4gYmUgZGlzYWJsZWQgdmlhIENTUClcbi8vXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIHdhO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaGFzV2ViQXNzZW1ibHkoKSB7XG4gIC8vIHVzZSBjYWNoZSBpZiBjYWxsZWQgYmVmb3JlO1xuICBpZiAodHlwZW9mIHdhICE9PSAndW5kZWZpbmVkJykgcmV0dXJuIHdhO1xuXG4gIHdhID0gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBXZWJBc3NlbWJseSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiB3YTtcblxuICAvLyBJZiBXZWJBc3NlbmJseSBpcyBkaXNhYmxlZCwgY29kZSBjYW4gdGhyb3cgb24gY29tcGlsZVxuICB0cnkge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9icmlvbi9taW4td2FzbS1mYWlsL2Jsb2IvbWFzdGVyL21pbi13YXNtLWZhaWwuaW4uanNcbiAgICAvLyBBZGRpdGlvbmFsIGNoZWNrIHRoYXQgV0EgaW50ZXJuYWxzIGFyZSBjb3JyZWN0XG5cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjb21tYS1zcGFjaW5nLCBtYXgtbGVuICovXG4gICAgdmFyIGJpbiAgICAgID0gbmV3IFVpbnQ4QXJyYXkoWyAwLDk3LDExNSwxMDksMSwwLDAsMCwxLDYsMSw5NiwxLDEyNywxLDEyNywzLDIsMSwwLDUsMywxLDAsMSw3LDgsMSw0LDExNiwxMDEsMTE1LDExNiwwLDAsMTAsMTYsMSwxNCwwLDMyLDAsNjUsMSw1NCwyLDAsMzIsMCw0MCwyLDAsMTEgXSk7XG4gICAgdmFyIG1vZHVsZSAgID0gbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShiaW4pO1xuICAgIHZhciBpbnN0YW5jZSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZShtb2R1bGUsIHt9KTtcblxuICAgIC8vIHRlc3Qgc3RvcmluZyB0byBhbmQgbG9hZGluZyBmcm9tIGEgbm9uLXplcm8gbG9jYXRpb24gdmlhIGEgcGFyYW1ldGVyLlxuICAgIC8vIFNhZmFyaSBvbiBpT1MgMTEuMi41IHJldHVybnMgMCB1bmV4cGVjdGVkbHkgYXQgbm9uLXplcm8gbG9jYXRpb25zXG4gICAgaWYgKGluc3RhbmNlLmV4cG9ydHMudGVzdCg0KSAhPT0gMCkgd2EgPSB0cnVlO1xuXG4gICAgcmV0dXJuIHdhO1xuICB9IGNhdGNoIChfXykge31cblxuICByZXR1cm4gd2E7XG59O1xuXG59LHt9XSwyMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxub2JqZWN0LWFzc2lnblxuKGMpIFNpbmRyZSBTb3JodXNcbkBsaWNlbnNlIE1JVFxuKi9cblxuJ3VzZSBzdHJpY3QnO1xuLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbnZhciBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzO1xudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBwcm9wSXNFbnVtZXJhYmxlID0gT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuZnVuY3Rpb24gdG9PYmplY3QodmFsKSB7XG5cdGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3QuYXNzaWduIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCBudWxsIG9yIHVuZGVmaW5lZCcpO1xuXHR9XG5cblx0cmV0dXJuIE9iamVjdCh2YWwpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRVc2VOYXRpdmUoKSB7XG5cdHRyeSB7XG5cdFx0aWYgKCFPYmplY3QuYXNzaWduKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gRGV0ZWN0IGJ1Z2d5IHByb3BlcnR5IGVudW1lcmF0aW9uIG9yZGVyIGluIG9sZGVyIFY4IHZlcnNpb25zLlxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9NDExOFxuXHRcdHZhciB0ZXN0MSA9IG5ldyBTdHJpbmcoJ2FiYycpOyAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXctd3JhcHBlcnNcblx0XHR0ZXN0MVs1XSA9ICdkZSc7XG5cdFx0aWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRlc3QxKVswXSA9PT0gJzUnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MiA9IHt9O1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykge1xuXHRcdFx0dGVzdDJbJ18nICsgU3RyaW5nLmZyb21DaGFyQ29kZShpKV0gPSBpO1xuXHRcdH1cblx0XHR2YXIgb3JkZXIyID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDIpLm1hcChmdW5jdGlvbiAobikge1xuXHRcdFx0cmV0dXJuIHRlc3QyW25dO1xuXHRcdH0pO1xuXHRcdGlmIChvcmRlcjIuam9pbignJykgIT09ICcwMTIzNDU2Nzg5Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTMwNTZcblx0XHR2YXIgdGVzdDMgPSB7fTtcblx0XHQnYWJjZGVmZ2hpamtsbW5vcHFyc3QnLnNwbGl0KCcnKS5mb3JFYWNoKGZ1bmN0aW9uIChsZXR0ZXIpIHtcblx0XHRcdHRlc3QzW2xldHRlcl0gPSBsZXR0ZXI7XG5cdFx0fSk7XG5cdFx0aWYgKE9iamVjdC5rZXlzKE9iamVjdC5hc3NpZ24oe30sIHRlc3QzKSkuam9pbignJykgIT09XG5cdFx0XHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0Ly8gV2UgZG9uJ3QgZXhwZWN0IGFueSBvZiB0aGUgYWJvdmUgdG8gdGhyb3csIGJ1dCBiZXR0ZXIgdG8gYmUgc2FmZS5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaG91bGRVc2VOYXRpdmUoKSA/IE9iamVjdC5hc3NpZ24gOiBmdW5jdGlvbiAodGFyZ2V0LCBzb3VyY2UpIHtcblx0dmFyIGZyb207XG5cdHZhciB0byA9IHRvT2JqZWN0KHRhcmdldCk7XG5cdHZhciBzeW1ib2xzO1xuXG5cdGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG5cdFx0ZnJvbSA9IE9iamVjdChhcmd1bWVudHNbc10pO1xuXG5cdFx0Zm9yICh2YXIga2V5IGluIGZyb20pIHtcblx0XHRcdGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGZyb20sIGtleSkpIHtcblx0XHRcdFx0dG9ba2V5XSA9IGZyb21ba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG5cdFx0XHRzeW1ib2xzID0gZ2V0T3duUHJvcGVydHlTeW1ib2xzKGZyb20pO1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBzeW1ib2xzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGlmIChwcm9wSXNFbnVtZXJhYmxlLmNhbGwoZnJvbSwgc3ltYm9sc1tpXSkpIHtcblx0XHRcdFx0XHR0b1tzeW1ib2xzW2ldXSA9IGZyb21bc3ltYm9sc1tpXV07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gdG87XG59O1xuXG59LHt9XSwyNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG52YXIgYnVuZGxlRm4gPSBhcmd1bWVudHNbM107XG52YXIgc291cmNlcyA9IGFyZ3VtZW50c1s0XTtcbnZhciBjYWNoZSA9IGFyZ3VtZW50c1s1XTtcblxudmFyIHN0cmluZ2lmeSA9IEpTT04uc3RyaW5naWZ5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmbiwgb3B0aW9ucykge1xuICAgIHZhciB3a2V5O1xuICAgIHZhciBjYWNoZUtleXMgPSBPYmplY3Qua2V5cyhjYWNoZSk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNhY2hlS2V5cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGNhY2hlS2V5c1tpXTtcbiAgICAgICAgdmFyIGV4cCA9IGNhY2hlW2tleV0uZXhwb3J0cztcbiAgICAgICAgLy8gVXNpbmcgYmFiZWwgYXMgYSB0cmFuc3BpbGVyIHRvIHVzZSBlc21vZHVsZSwgdGhlIGV4cG9ydCB3aWxsIGFsd2F5c1xuICAgICAgICAvLyBiZSBhbiBvYmplY3Qgd2l0aCB0aGUgZGVmYXVsdCBleHBvcnQgYXMgYSBwcm9wZXJ0eSBvZiBpdC4gVG8gZW5zdXJlXG4gICAgICAgIC8vIHRoZSBleGlzdGluZyBhcGkgYW5kIGJhYmVsIGVzbW9kdWxlIGV4cG9ydHMgYXJlIGJvdGggc3VwcG9ydGVkIHdlXG4gICAgICAgIC8vIGNoZWNrIGZvciBib3RoXG4gICAgICAgIGlmIChleHAgPT09IGZuIHx8IGV4cCAmJiBleHAuZGVmYXVsdCA9PT0gZm4pIHtcbiAgICAgICAgICAgIHdrZXkgPSBrZXk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICghd2tleSkge1xuICAgICAgICB3a2V5ID0gTWF0aC5mbG9vcihNYXRoLnBvdygxNiwgOCkgKiBNYXRoLnJhbmRvbSgpKS50b1N0cmluZygxNik7XG4gICAgICAgIHZhciB3Y2FjaGUgPSB7fTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjYWNoZUtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gY2FjaGVLZXlzW2ldO1xuICAgICAgICAgICAgd2NhY2hlW2tleV0gPSBrZXk7XG4gICAgICAgIH1cbiAgICAgICAgc291cmNlc1t3a2V5XSA9IFtcbiAgICAgICAgICAgICdmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsnICsgZm4gKyAnKHNlbGYpOyB9JyxcbiAgICAgICAgICAgIHdjYWNoZVxuICAgICAgICBdO1xuICAgIH1cbiAgICB2YXIgc2tleSA9IE1hdGguZmxvb3IoTWF0aC5wb3coMTYsIDgpICogTWF0aC5yYW5kb20oKSkudG9TdHJpbmcoMTYpO1xuXG4gICAgdmFyIHNjYWNoZSA9IHt9OyBzY2FjaGVbd2tleV0gPSB3a2V5O1xuICAgIHNvdXJjZXNbc2tleV0gPSBbXG4gICAgICAgICdmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsnICtcbiAgICAgICAgICAgIC8vIHRyeSB0byBjYWxsIGRlZmF1bHQgaWYgZGVmaW5lZCB0byBhbHNvIHN1cHBvcnQgYmFiZWwgZXNtb2R1bGUgZXhwb3J0c1xuICAgICAgICAgICAgJ3ZhciBmID0gcmVxdWlyZSgnICsgc3RyaW5naWZ5KHdrZXkpICsgJyk7JyArXG4gICAgICAgICAgICAnKGYuZGVmYXVsdCA/IGYuZGVmYXVsdCA6IGYpKHNlbGYpOycgK1xuICAgICAgICAnfScsXG4gICAgICAgIHNjYWNoZVxuICAgIF07XG5cbiAgICB2YXIgd29ya2VyU291cmNlcyA9IHt9O1xuICAgIHJlc29sdmVTb3VyY2VzKHNrZXkpO1xuXG4gICAgZnVuY3Rpb24gcmVzb2x2ZVNvdXJjZXMoa2V5KSB7XG4gICAgICAgIHdvcmtlclNvdXJjZXNba2V5XSA9IHRydWU7XG5cbiAgICAgICAgZm9yICh2YXIgZGVwUGF0aCBpbiBzb3VyY2VzW2tleV1bMV0pIHtcbiAgICAgICAgICAgIHZhciBkZXBLZXkgPSBzb3VyY2VzW2tleV1bMV1bZGVwUGF0aF07XG4gICAgICAgICAgICBpZiAoIXdvcmtlclNvdXJjZXNbZGVwS2V5XSkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVTb3VyY2VzKGRlcEtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc3JjID0gJygnICsgYnVuZGxlRm4gKyAnKSh7J1xuICAgICAgICArIE9iamVjdC5rZXlzKHdvcmtlclNvdXJjZXMpLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gc3RyaW5naWZ5KGtleSkgKyAnOlsnXG4gICAgICAgICAgICAgICAgKyBzb3VyY2VzW2tleV1bMF1cbiAgICAgICAgICAgICAgICArICcsJyArIHN0cmluZ2lmeShzb3VyY2VzW2tleV1bMV0pICsgJ10nXG4gICAgICAgICAgICA7XG4gICAgICAgIH0pLmpvaW4oJywnKVxuICAgICAgICArICd9LHt9LFsnICsgc3RyaW5naWZ5KHNrZXkpICsgJ10pJ1xuICAgIDtcblxuICAgIHZhciBVUkwgPSB3aW5kb3cuVVJMIHx8IHdpbmRvdy53ZWJraXRVUkwgfHwgd2luZG93Lm1velVSTCB8fCB3aW5kb3cubXNVUkw7XG5cbiAgICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtzcmNdLCB7IHR5cGU6ICd0ZXh0L2phdmFzY3JpcHQnIH0pO1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYmFyZSkgeyByZXR1cm4gYmxvYjsgfVxuICAgIHZhciB3b3JrZXJVcmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgIHZhciB3b3JrZXIgPSBuZXcgV29ya2VyKHdvcmtlclVybCk7XG4gICAgd29ya2VyLm9iamVjdFVSTCA9IHdvcmtlclVybDtcbiAgICByZXR1cm4gd29ya2VyO1xufTtcblxufSx7fV0sXCIvaW5kZXguanNcIjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkgeyByZXR1cm4gX2FycmF5V2l0aEhvbGVzKGFycikgfHwgX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkgfHwgX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KGFyciwgaSkgfHwgX25vbkl0ZXJhYmxlUmVzdCgpOyB9XG5cbmZ1bmN0aW9uIF9ub25JdGVyYWJsZVJlc3QoKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gZGVzdHJ1Y3R1cmUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7IH1cblxuZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikgeyBpZiAoIW8pIHJldHVybjsgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTsgdmFyIG4gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobykuc2xpY2UoOCwgLTEpOyBpZiAobiA9PT0gXCJPYmplY3RcIiAmJiBvLmNvbnN0cnVjdG9yKSBuID0gby5jb25zdHJ1Y3Rvci5uYW1lOyBpZiAobiA9PT0gXCJNYXBcIiB8fCBuID09PSBcIlNldFwiKSByZXR1cm4gQXJyYXkuZnJvbShvKTsgaWYgKG4gPT09IFwiQXJndW1lbnRzXCIgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QobikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pOyB9XG5cbmZ1bmN0aW9uIF9hcnJheUxpa2VUb0FycmF5KGFyciwgbGVuKSB7IGlmIChsZW4gPT0gbnVsbCB8fCBsZW4gPiBhcnIubGVuZ3RoKSBsZW4gPSBhcnIubGVuZ3RoOyBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShsZW4pOyBpIDwgbGVuOyBpKyspIHsgYXJyMltpXSA9IGFycltpXTsgfSByZXR1cm4gYXJyMjsgfVxuXG5mdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB7IHZhciBfaSA9IGFyciA9PSBudWxsID8gbnVsbCA6IHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgYXJyW1N5bWJvbC5pdGVyYXRvcl0gfHwgYXJyW1wiQEBpdGVyYXRvclwiXTsgaWYgKF9pID09IG51bGwpIHJldHVybjsgdmFyIF9hcnIgPSBbXTsgdmFyIF9uID0gdHJ1ZTsgdmFyIF9kID0gZmFsc2U7IHZhciBfcywgX2U7IHRyeSB7IGZvciAoX2kgPSBfaS5jYWxsKGFycik7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHsgX2Fyci5wdXNoKF9zLnZhbHVlKTsgaWYgKGkgJiYgX2Fyci5sZW5ndGggPT09IGkpIGJyZWFrOyB9IH0gY2F0Y2ggKGVycikgeyBfZCA9IHRydWU7IF9lID0gZXJyOyB9IGZpbmFsbHkgeyB0cnkgeyBpZiAoIV9uICYmIF9pW1wicmV0dXJuXCJdICE9IG51bGwpIF9pW1wicmV0dXJuXCJdKCk7IH0gZmluYWxseSB7IGlmIChfZCkgdGhyb3cgX2U7IH0gfSByZXR1cm4gX2FycjsgfVxuXG5mdW5jdGlvbiBfYXJyYXlXaXRoSG9sZXMoYXJyKSB7IGlmIChBcnJheS5pc0FycmF5KGFycikpIHJldHVybiBhcnI7IH1cblxudmFyIGFzc2lnbiA9IF9kZXJlcV8oJ29iamVjdC1hc3NpZ24nKTtcblxudmFyIHdlYndvcmtpZnkgPSBfZGVyZXFfKCd3ZWJ3b3JraWZ5Jyk7XG5cbnZhciBNYXRoTGliID0gX2RlcmVxXygnLi9saWIvbWF0aGxpYicpO1xuXG52YXIgUG9vbCA9IF9kZXJlcV8oJy4vbGliL3Bvb2wnKTtcblxudmFyIHV0aWxzID0gX2RlcmVxXygnLi9saWIvdXRpbHMnKTtcblxudmFyIHdvcmtlciA9IF9kZXJlcV8oJy4vbGliL3dvcmtlcicpO1xuXG52YXIgY3JlYXRlU3RhZ2VzID0gX2RlcmVxXygnLi9saWIvc3RlcHBlcicpO1xuXG52YXIgY3JlYXRlUmVnaW9ucyA9IF9kZXJlcV8oJy4vbGliL3RpbGVyJyk7IC8vIERlZHVwbGljYXRlIHBvb2xzICYgbGltaXRlcnMgd2l0aCB0aGUgc2FtZSBjb25maWdzXG4vLyB3aGVuIHVzZXIgY3JlYXRlcyBtdWx0aXBsZSBwaWNhIGluc3RhbmNlcy5cblxuXG52YXIgc2luZ2xldG9uZXMgPSB7fTtcbnZhciBORUVEX1NBRkFSSV9GSVggPSBmYWxzZTtcblxudHJ5IHtcbiAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIG5hdmlnYXRvci51c2VyQWdlbnQpIHtcbiAgICBORUVEX1NBRkFSSV9GSVggPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ1NhZmFyaScpID49IDA7XG4gIH1cbn0gY2F0Y2ggKGUpIHt9XG5cbnZhciBjb25jdXJyZW5jeSA9IDE7XG5cbmlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJykge1xuICBjb25jdXJyZW5jeSA9IE1hdGgubWluKG5hdmlnYXRvci5oYXJkd2FyZUNvbmN1cnJlbmN5IHx8IDEsIDQpO1xufVxuXG52YXIgREVGQVVMVF9QSUNBX09QVFMgPSB7XG4gIHRpbGU6IDEwMjQsXG4gIGNvbmN1cnJlbmN5OiBjb25jdXJyZW5jeSxcbiAgZmVhdHVyZXM6IFsnanMnLCAnd2FzbScsICd3dyddLFxuICBpZGxlOiAyMDAwLFxuICBjcmVhdGVDYW52YXM6IGZ1bmN0aW9uIGNyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgdmFyIHRtcENhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIHRtcENhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIHRtcENhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgcmV0dXJuIHRtcENhbnZhcztcbiAgfVxufTtcbnZhciBERUZBVUxUX1JFU0laRV9PUFRTID0ge1xuICBxdWFsaXR5OiAzLFxuICBhbHBoYTogZmFsc2UsXG4gIHVuc2hhcnBBbW91bnQ6IDAsXG4gIHVuc2hhcnBSYWRpdXM6IDAuMCxcbiAgdW5zaGFycFRocmVzaG9sZDogMFxufTtcbnZhciBDQU5fTkVXX0lNQUdFX0RBVEEgPSBmYWxzZTtcbnZhciBDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCA9IGZhbHNlO1xudmFyIENBTl9VU0VfQ0FOVkFTX0dFVF9JTUFHRV9EQVRBID0gZmFsc2U7XG52YXIgQ0FOX1VTRV9PRkZTQ1JFRU5fQ0FOVkFTID0gZmFsc2U7XG52YXIgQ0FOX1VTRV9DSUJfUkVHSU9OX0ZPUl9JTUFHRSA9IGZhbHNlO1xuXG5mdW5jdGlvbiB3b3JrZXJGYWJyaWMoKSB7XG4gIHJldHVybiB7XG4gICAgdmFsdWU6IHdlYndvcmtpZnkod29ya2VyKSxcbiAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgICAgdGhpcy52YWx1ZS50ZXJtaW5hdGUoKTtcblxuICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHZhciB1cmwgPSB3aW5kb3cuVVJMIHx8IHdpbmRvdy53ZWJraXRVUkwgfHwgd2luZG93Lm1velVSTCB8fCB3aW5kb3cubXNVUkw7XG5cbiAgICAgICAgaWYgKHVybCAmJiB1cmwucmV2b2tlT2JqZWN0VVJMICYmIHRoaXMudmFsdWUub2JqZWN0VVJMKSB7XG4gICAgICAgICAgdXJsLnJldm9rZU9iamVjdFVSTCh0aGlzLnZhbHVlLm9iamVjdFVSTCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG59IC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBBUEkgbWV0aG9kc1xuXG5cbmZ1bmN0aW9uIFBpY2Eob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGljYSkpIHJldHVybiBuZXcgUGljYShvcHRpb25zKTtcbiAgdGhpcy5vcHRpb25zID0gYXNzaWduKHt9LCBERUZBVUxUX1BJQ0FfT1BUUywgb3B0aW9ucyB8fCB7fSk7XG4gIHZhciBsaW1pdGVyX2tleSA9IFwibGtfXCIuY29uY2F0KHRoaXMub3B0aW9ucy5jb25jdXJyZW5jeSk7IC8vIFNoYXJlIGxpbWl0ZXJzIHRvIGF2b2lkIG11bHRpcGxlIHBhcmFsbGVsIHdvcmtlcnMgd2hlbiB1c2VyIGNyZWF0ZXNcbiAgLy8gbXVsdGlwbGUgcGljYSBpbnN0YW5jZXMuXG5cbiAgdGhpcy5fX2xpbWl0ID0gc2luZ2xldG9uZXNbbGltaXRlcl9rZXldIHx8IHV0aWxzLmxpbWl0ZXIodGhpcy5vcHRpb25zLmNvbmN1cnJlbmN5KTtcbiAgaWYgKCFzaW5nbGV0b25lc1tsaW1pdGVyX2tleV0pIHNpbmdsZXRvbmVzW2xpbWl0ZXJfa2V5XSA9IHRoaXMuX19saW1pdDsgLy8gTGlzdCBvZiBzdXBwb3J0ZWQgZmVhdHVyZXMsIGFjY29yZGluZyB0byBvcHRpb25zICYgYnJvd3Nlci9ub2RlLmpzXG5cbiAgdGhpcy5mZWF0dXJlcyA9IHtcbiAgICBqczogZmFsc2UsXG4gICAgLy8gcHVyZSBKUyBpbXBsZW1lbnRhdGlvbiwgY2FuIGJlIGRpc2FibGVkIGZvciB0ZXN0aW5nXG4gICAgd2FzbTogZmFsc2UsXG4gICAgLy8gd2ViYXNzZW1ibHkgaW1wbGVtZW50YXRpb24gZm9yIGhlYXZ5IGZ1bmN0aW9uc1xuICAgIGNpYjogZmFsc2UsXG4gICAgLy8gcmVzaXplIHZpYSBjcmVhdGVJbWFnZUJpdG1hcCAob25seSBGRiBhdCB0aGlzIG1vbWVudClcbiAgICB3dzogZmFsc2UgLy8gd2Vid29ya2Vyc1xuXG4gIH07XG4gIHRoaXMuX193b3JrZXJzUG9vbCA9IG51bGw7IC8vIFN0b3JlIHJlcXVlc3RlZCBmZWF0dXJlcyBmb3Igd2Vid29ya2Vyc1xuXG4gIHRoaXMuX19yZXF1ZXN0ZWRfZmVhdHVyZXMgPSBbXTtcbiAgdGhpcy5fX21hdGhsaWIgPSBudWxsO1xufVxuXG5QaWNhLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIGlmICh0aGlzLl9faW5pdFByb21pc2UpIHJldHVybiB0aGlzLl9faW5pdFByb21pc2U7IC8vIFRlc3QgaWYgd2UgY2FuIGNyZWF0ZSBJbWFnZURhdGEgd2l0aG91dCBjYW52YXMgYW5kIG1lbW9yeSBjb3B5XG5cbiAgaWYgKHR5cGVvZiBJbWFnZURhdGEgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0cnkge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tbmV3ICovXG4gICAgICBuZXcgSW1hZ2VEYXRhKG5ldyBVaW50OENsYW1wZWRBcnJheSg0MDApLCAxMCwgMTApO1xuICAgICAgQ0FOX05FV19JTUFHRV9EQVRBID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChfXykge31cbiAgfSAvLyBJbWFnZUJpdG1hcCBjYW4gYmUgZWZmZWN0aXZlIGluIDIgcGxhY2VzOlxuICAvL1xuICAvLyAxLiBUaHJlYWRlZCBqcGVnIHVucGFjayAoYmFzaWMpXG4gIC8vIDIuIEJ1aWx0LWluIHJlc2l6ZSAoYmxvY2tlZCBkdWUgcHJvYmxlbSBpbiBjaHJvbWUsIHNlZSBpc3N1ZSAjODkpXG4gIC8vXG4gIC8vIEZvciBiYXNpYyB1c2Ugd2UgYWxzbyBuZWVkIEltYWdlQml0bWFwIHdvIHN1cHBvcnQgLmNsb3NlKCkgbWV0aG9kLFxuICAvLyBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvcnUvZG9jcy9XZWIvQVBJL0ltYWdlQml0bWFwXG5cblxuICBpZiAodHlwZW9mIEltYWdlQml0bWFwICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChJbWFnZUJpdG1hcC5wcm90b3R5cGUgJiYgSW1hZ2VCaXRtYXAucHJvdG90eXBlLmNsb3NlKSB7XG4gICAgICBDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGVidWcoJ0ltYWdlQml0bWFwIGRvZXMgbm90IHN1cHBvcnQgLmNsb3NlKCksIGRpc2FibGVkJyk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGZlYXR1cmVzID0gdGhpcy5vcHRpb25zLmZlYXR1cmVzLnNsaWNlKCk7XG5cbiAgaWYgKGZlYXR1cmVzLmluZGV4T2YoJ2FsbCcpID49IDApIHtcbiAgICBmZWF0dXJlcyA9IFsnY2liJywgJ3dhc20nLCAnanMnLCAnd3cnXTtcbiAgfVxuXG4gIHRoaXMuX19yZXF1ZXN0ZWRfZmVhdHVyZXMgPSBmZWF0dXJlcztcbiAgdGhpcy5fX21hdGhsaWIgPSBuZXcgTWF0aExpYihmZWF0dXJlcyk7IC8vIENoZWNrIFdlYldvcmtlciBzdXBwb3J0IGlmIHJlcXVlc3RlZFxuXG4gIGlmIChmZWF0dXJlcy5pbmRleE9mKCd3dycpID49IDApIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ1dvcmtlcicgaW4gd2luZG93KSB7XG4gICAgICAvLyBJRSA8PSAxMSBkb24ndCBhbGxvdyB0byBjcmVhdGUgd2Vid29ya2VycyBmcm9tIHN0cmluZy4gV2Ugc2hvdWxkIGNoZWNrIGl0LlxuICAgICAgLy8gaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vSUUvZmVlZGJhY2svZGV0YWlscy84MDE4MTAvd2ViLXdvcmtlcnMtZnJvbS1ibG9iLXVybHMtaW4taWUtMTAtYW5kLTExXG4gICAgICB0cnkge1xuICAgICAgICB2YXIgd2tyID0gX2RlcmVxXygnd2Vid29ya2lmeScpKGZ1bmN0aW9uICgpIHt9KTtcblxuICAgICAgICB3a3IudGVybWluYXRlKCk7XG4gICAgICAgIHRoaXMuZmVhdHVyZXMud3cgPSB0cnVlOyAvLyBwb29sIHVuaXF1ZW5lc3MgZGVwZW5kcyBvbiBwb29sIGNvbmZpZyArIHdlYndvcmtlciBjb25maWdcblxuICAgICAgICB2YXIgd3Bvb2xfa2V5ID0gXCJ3cF9cIi5jb25jYXQoSlNPTi5zdHJpbmdpZnkodGhpcy5vcHRpb25zKSk7XG5cbiAgICAgICAgaWYgKHNpbmdsZXRvbmVzW3dwb29sX2tleV0pIHtcbiAgICAgICAgICB0aGlzLl9fd29ya2Vyc1Bvb2wgPSBzaW5nbGV0b25lc1t3cG9vbF9rZXldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX193b3JrZXJzUG9vbCA9IG5ldyBQb29sKHdvcmtlckZhYnJpYywgdGhpcy5vcHRpb25zLmlkbGUpO1xuICAgICAgICAgIHNpbmdsZXRvbmVzW3dwb29sX2tleV0gPSB0aGlzLl9fd29ya2Vyc1Bvb2w7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKF9fKSB7fVxuICAgIH1cbiAgfVxuXG4gIHZhciBpbml0TWF0aCA9IHRoaXMuX19tYXRobGliLmluaXQoKS50aGVuKGZ1bmN0aW9uIChtYXRobGliKSB7XG4gICAgLy8gQ29weSBkZXRlY3RlZCBmZWF0dXJlc1xuICAgIGFzc2lnbihfdGhpcy5mZWF0dXJlcywgbWF0aGxpYi5mZWF0dXJlcyk7XG4gIH0pO1xuXG4gIHZhciBjaGVja0NpYlJlc2l6ZTtcblxuICBpZiAoIUNBTl9DUkVBVEVfSU1BR0VfQklUTUFQKSB7XG4gICAgY2hlY2tDaWJSZXNpemUgPSBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICB9IGVsc2Uge1xuICAgIGNoZWNrQ2liUmVzaXplID0gdXRpbHMuY2liX3N1cHBvcnQodGhpcy5vcHRpb25zLmNyZWF0ZUNhbnZhcykudGhlbihmdW5jdGlvbiAoc3RhdHVzKSB7XG4gICAgICBpZiAoX3RoaXMuZmVhdHVyZXMuY2liICYmIGZlYXR1cmVzLmluZGV4T2YoJ2NpYicpIDwgMCkge1xuICAgICAgICBfdGhpcy5kZWJ1ZygnY3JlYXRlSW1hZ2VCaXRtYXAoKSByZXNpemUgc3VwcG9ydGVkLCBidXQgZGlzYWJsZWQgYnkgY29uZmlnJyk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmVhdHVyZXMuaW5kZXhPZignY2liJykgPj0gMCkgX3RoaXMuZmVhdHVyZXMuY2liID0gc3RhdHVzO1xuICAgIH0pO1xuICB9XG5cbiAgQ0FOX1VTRV9DQU5WQVNfR0VUX0lNQUdFX0RBVEEgPSB1dGlscy5jYW5fdXNlX2NhbnZhcyh0aGlzLm9wdGlvbnMuY3JlYXRlQ2FudmFzKTtcbiAgdmFyIGNoZWNrT2Zmc2NyZWVuQ2FudmFzO1xuXG4gIGlmIChDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCAmJiBDQU5fTkVXX0lNQUdFX0RBVEEgJiYgZmVhdHVyZXMuaW5kZXhPZignd3cnKSAhPT0gLTEpIHtcbiAgICBjaGVja09mZnNjcmVlbkNhbnZhcyA9IHV0aWxzLndvcmtlcl9vZmZzY3JlZW5fY2FudmFzX3N1cHBvcnQoKTtcbiAgfSBlbHNlIHtcbiAgICBjaGVja09mZnNjcmVlbkNhbnZhcyA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH1cblxuICBjaGVja09mZnNjcmVlbkNhbnZhcyA9IGNoZWNrT2Zmc2NyZWVuQ2FudmFzLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgIENBTl9VU0VfT0ZGU0NSRUVOX0NBTlZBUyA9IHJlc3VsdDtcbiAgfSk7IC8vIHdlIHVzZSBjcmVhdGVJbWFnZUJpdG1hcCB0byBjcm9wIGltYWdlIGRhdGEgYW5kIHBhc3MgaXQgdG8gd29ya2VycyxcbiAgLy8gc28gbmVlZCB0byBjaGVjayB3aGV0aGVyIGZ1bmN0aW9uIHdvcmtzIGNvcnJlY3RseTtcbiAgLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9MTIyMDY3MVxuXG4gIHZhciBjaGVja0NpYlJlZ2lvbiA9IHV0aWxzLmNpYl9jYW5fdXNlX3JlZ2lvbigpLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgIENBTl9VU0VfQ0lCX1JFR0lPTl9GT1JfSU1BR0UgPSByZXN1bHQ7XG4gIH0pOyAvLyBJbml0IG1hdGggbGliLiBUaGF0J3MgYXN5bmMgYmVjYXVzZSBjYW4gbG9hZCBzb21lXG5cbiAgdGhpcy5fX2luaXRQcm9taXNlID0gUHJvbWlzZS5hbGwoW2luaXRNYXRoLCBjaGVja0NpYlJlc2l6ZSwgY2hlY2tPZmZzY3JlZW5DYW52YXMsIGNoZWNrQ2liUmVnaW9uXSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9KTtcbiAgcmV0dXJuIHRoaXMuX19pbml0UHJvbWlzZTtcbn07IC8vIENhbGwgcmVzaXplciBpbiB3ZWJ3b3JrZXIgb3IgbG9jYWxseSwgZGVwZW5kaW5nIG9uIGNvbmZpZ1xuXG5cblBpY2EucHJvdG90eXBlLl9faW52b2tlUmVzaXplID0gZnVuY3Rpb24gKHRpbGVPcHRzLCBvcHRzKSB7XG4gIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gIC8vIFNoYXJlIGNhY2hlIGJldHdlZW4gY2FsbHM6XG4gIC8vXG4gIC8vIC0gd2FzbSBpbnN0YW5jZVxuICAvLyAtIHdhc20gbWVtb3J5IG9iamVjdFxuICAvL1xuICBvcHRzLl9fbWF0aENhY2hlID0gb3B0cy5fX21hdGhDYWNoZSB8fCB7fTtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmICghX3RoaXMyLmZlYXR1cmVzLnd3KSB7XG4gICAgICAvLyBub3QgcG9zc2libGUgdG8gaGF2ZSBJbWFnZUJpdG1hcCBoZXJlIGlmIHVzZXIgZGlzYWJsZWQgV1dcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGE6IF90aGlzMi5fX21hdGhsaWIucmVzaXplQW5kVW5zaGFycCh0aWxlT3B0cywgb3B0cy5fX21hdGhDYWNoZSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciB3ID0gX3RoaXMyLl9fd29ya2Vyc1Bvb2wuYWNxdWlyZSgpO1xuXG4gICAgICBpZiAob3B0cy5jYW5jZWxUb2tlbikgb3B0cy5jYW5jZWxUb2tlbltcImNhdGNoXCJdKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgfSk7XG5cbiAgICAgIHcudmFsdWUub25tZXNzYWdlID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHcucmVsZWFzZSgpO1xuICAgICAgICBpZiAoZXYuZGF0YS5lcnIpIHJlamVjdChldi5kYXRhLmVycik7ZWxzZSByZXNvbHZlKGV2LmRhdGEpO1xuICAgICAgfTtcblxuICAgICAgdmFyIHRyYW5zZmVyID0gW107XG4gICAgICBpZiAodGlsZU9wdHMuc3JjKSB0cmFuc2Zlci5wdXNoKHRpbGVPcHRzLnNyYy5idWZmZXIpO1xuICAgICAgaWYgKHRpbGVPcHRzLnNyY0JpdG1hcCkgdHJhbnNmZXIucHVzaCh0aWxlT3B0cy5zcmNCaXRtYXApO1xuICAgICAgdy52YWx1ZS5wb3N0TWVzc2FnZSh7XG4gICAgICAgIG9wdHM6IHRpbGVPcHRzLFxuICAgICAgICBmZWF0dXJlczogX3RoaXMyLl9fcmVxdWVzdGVkX2ZlYXR1cmVzLFxuICAgICAgICBwcmVsb2FkOiB7XG4gICAgICAgICAgd2FzbV9ub2R1bGU6IF90aGlzMi5fX21hdGhsaWIuX19cbiAgICAgICAgfVxuICAgICAgfSwgdHJhbnNmZXIpO1xuICAgIH0pO1xuICB9KTtcbn07IC8vIHRoaXMgZnVuY3Rpb24gY2FuIHJldHVybiBwcm9taXNlIGlmIGNyZWF0ZUltYWdlQml0bWFwIGlzIHVzZWRcblxuXG5QaWNhLnByb3RvdHlwZS5fX2V4dHJhY3RUaWxlRGF0YSA9IGZ1bmN0aW9uICh0aWxlLCBmcm9tLCBvcHRzLCBzdGFnZUVudiwgZXh0cmFjdFRvKSB7XG4gIGlmICh0aGlzLmZlYXR1cmVzLnd3ICYmIENBTl9VU0VfT0ZGU0NSRUVOX0NBTlZBUyAmJiAoIC8vIGNyZWF0ZUltYWdlQml0bWFwIGRvZXNuJ3Qgd29yayBmb3IgaW1hZ2VzIChJbWFnZSwgSW1hZ2VCaXRtYXApIHdpdGggRXhpZiBvcmllbnRhdGlvbiBpbiBDaHJvbWUsXG4gIC8vIGNhbiB1c2UgY2FudmFzIGJlY2F1c2UgY2FudmFzIGRvZXNuJ3QgaGF2ZSBvcmllbnRhdGlvbjtcbiAgLy8gc2VlIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTEyMjA2NzFcbiAgdXRpbHMuaXNDYW52YXMoZnJvbSkgfHwgQ0FOX1VTRV9DSUJfUkVHSU9OX0ZPUl9JTUFHRSkpIHtcbiAgICB0aGlzLmRlYnVnKCdDcmVhdGUgdGlsZSBmb3IgT2Zmc2NyZWVuQ2FudmFzJyk7XG4gICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKHN0YWdlRW52LnNyY0ltYWdlQml0bWFwIHx8IGZyb20sIHRpbGUueCwgdGlsZS55LCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCkudGhlbihmdW5jdGlvbiAoYml0bWFwKSB7XG4gICAgICBleHRyYWN0VG8uc3JjQml0bWFwID0gYml0bWFwO1xuICAgICAgcmV0dXJuIGV4dHJhY3RUbztcbiAgICB9KTtcbiAgfSAvLyBFeHRyYWN0IHRpbGUgUkdCQSBidWZmZXIsIGRlcGVuZGluZyBvbiBpbnB1dCB0eXBlXG5cblxuICBpZiAodXRpbHMuaXNDYW52YXMoZnJvbSkpIHtcbiAgICBpZiAoIXN0YWdlRW52LnNyY0N0eCkgc3RhZ2VFbnYuc3JjQ3R4ID0gZnJvbS5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gICAgfSk7IC8vIElmIGlucHV0IGlzIENhbnZhcyAtIGV4dHJhY3QgcmVnaW9uIGRhdGEgZGlyZWN0bHlcblxuICAgIHRoaXMuZGVidWcoJ0dldCB0aWxlIHBpeGVsIGRhdGEnKTtcbiAgICBleHRyYWN0VG8uc3JjID0gc3RhZ2VFbnYuc3JjQ3R4LmdldEltYWdlRGF0YSh0aWxlLngsIHRpbGUueSwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpLmRhdGE7XG4gICAgcmV0dXJuIGV4dHJhY3RUbztcbiAgfSAvLyBJZiBpbnB1dCBpcyBJbWFnZSBvciBkZWNvZGVkIHRvIEltYWdlQml0bWFwLFxuICAvLyBkcmF3IHJlZ2lvbiB0byB0ZW1wb3JhcnkgY2FudmFzIGFuZCBleHRyYWN0IGRhdGEgZnJvbSBpdFxuICAvL1xuICAvLyBOb3RlISBBdHRlbXB0IHRvIHJldXNlIHRoaXMgY2FudmFzIGNhdXNlcyBzaWduaWZpY2FudCBzbG93ZG93biBpbiBjaHJvbWVcbiAgLy9cblxuXG4gIHRoaXMuZGVidWcoJ0RyYXcgdGlsZSBpbWFnZUJpdG1hcC9pbWFnZSB0byB0ZW1wb3JhcnkgY2FudmFzJyk7XG4gIHZhciB0bXBDYW52YXMgPSB0aGlzLm9wdGlvbnMuY3JlYXRlQ2FudmFzKHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KTtcbiAgdmFyIHRtcEN0eCA9IHRtcENhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICB9KTtcbiAgdG1wQ3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdjb3B5JztcbiAgdG1wQ3R4LmRyYXdJbWFnZShzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCB8fCBmcm9tLCB0aWxlLngsIHRpbGUueSwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQsIDAsIDAsIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KTtcbiAgdGhpcy5kZWJ1ZygnR2V0IHRpbGUgcGl4ZWwgZGF0YScpO1xuICBleHRyYWN0VG8uc3JjID0gdG1wQ3R4LmdldEltYWdlRGF0YSgwLCAwLCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCkuZGF0YTsgLy8gU2FmYXJpIDEyIHdvcmthcm91bmRcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcblxuICB0bXBDYW52YXMud2lkdGggPSB0bXBDYW52YXMuaGVpZ2h0ID0gMDtcbiAgcmV0dXJuIGV4dHJhY3RUbztcbn07XG5cblBpY2EucHJvdG90eXBlLl9fbGFuZFRpbGVEYXRhID0gZnVuY3Rpb24gKHRpbGUsIHJlc3VsdCwgc3RhZ2VFbnYpIHtcbiAgdmFyIHRvSW1hZ2VEYXRhO1xuICB0aGlzLmRlYnVnKCdDb252ZXJ0IHJhdyByZ2JhIHRpbGUgcmVzdWx0IHRvIEltYWdlRGF0YScpO1xuXG4gIGlmIChyZXN1bHQuYml0bWFwKSB7XG4gICAgc3RhZ2VFbnYudG9DdHguZHJhd0ltYWdlKHJlc3VsdC5iaXRtYXAsIHRpbGUudG9YLCB0aWxlLnRvWSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoQ0FOX05FV19JTUFHRV9EQVRBKSB7XG4gICAgLy8gdGhpcyBicmFuY2ggaXMgZm9yIG1vZGVybiBicm93c2Vyc1xuICAgIC8vIElmIGBuZXcgSW1hZ2VEYXRhKClgICYgVWludDhDbGFtcGVkQXJyYXkgc3Vwb3J0ZWRcbiAgICB0b0ltYWdlRGF0YSA9IG5ldyBJbWFnZURhdGEobmV3IFVpbnQ4Q2xhbXBlZEFycmF5KHJlc3VsdC5kYXRhKSwgdGlsZS50b1dpZHRoLCB0aWxlLnRvSGVpZ2h0KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBmYWxsYmFjayBmb3IgYG5vZGUtY2FudmFzYCBhbmQgb2xkIGJyb3dzZXJzXG4gICAgLy8gKElFMTEgaGFzIEltYWdlRGF0YSBidXQgZG9lcyBub3Qgc3VwcG9ydCBgbmV3IEltYWdlRGF0YSgpYClcbiAgICB0b0ltYWdlRGF0YSA9IHN0YWdlRW52LnRvQ3R4LmNyZWF0ZUltYWdlRGF0YSh0aWxlLnRvV2lkdGgsIHRpbGUudG9IZWlnaHQpO1xuXG4gICAgaWYgKHRvSW1hZ2VEYXRhLmRhdGEuc2V0KSB7XG4gICAgICB0b0ltYWdlRGF0YS5kYXRhLnNldChyZXN1bHQuZGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElFOSBkb24ndCBoYXZlIGAuc2V0KClgXG4gICAgICBmb3IgKHZhciBpID0gdG9JbWFnZURhdGEuZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICB0b0ltYWdlRGF0YS5kYXRhW2ldID0gcmVzdWx0LmRhdGFbaV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdGhpcy5kZWJ1ZygnRHJhdyB0aWxlJyk7XG5cbiAgaWYgKE5FRURfU0FGQVJJX0ZJWCkge1xuICAgIC8vIFNhZmFyaSBkcmF3cyB0aGluIHdoaXRlIHN0cmlwZXMgYmV0d2VlbiB0aWxlcyB3aXRob3V0IHRoaXMgZml4XG4gICAgc3RhZ2VFbnYudG9DdHgucHV0SW1hZ2VEYXRhKHRvSW1hZ2VEYXRhLCB0aWxlLnRvWCwgdGlsZS50b1ksIHRpbGUudG9Jbm5lclggLSB0aWxlLnRvWCwgdGlsZS50b0lubmVyWSAtIHRpbGUudG9ZLCB0aWxlLnRvSW5uZXJXaWR0aCArIDFlLTUsIHRpbGUudG9Jbm5lckhlaWdodCArIDFlLTUpO1xuICB9IGVsc2Uge1xuICAgIHN0YWdlRW52LnRvQ3R4LnB1dEltYWdlRGF0YSh0b0ltYWdlRGF0YSwgdGlsZS50b1gsIHRpbGUudG9ZLCB0aWxlLnRvSW5uZXJYIC0gdGlsZS50b1gsIHRpbGUudG9Jbm5lclkgLSB0aWxlLnRvWSwgdGlsZS50b0lubmVyV2lkdGgsIHRpbGUudG9Jbm5lckhlaWdodCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn07XG5cblBpY2EucHJvdG90eXBlLl9fdGlsZUFuZFJlc2l6ZSA9IGZ1bmN0aW9uIChmcm9tLCB0bywgb3B0cykge1xuICB2YXIgX3RoaXMzID0gdGhpcztcblxuICB2YXIgc3RhZ2VFbnYgPSB7XG4gICAgc3JjQ3R4OiBudWxsLFxuICAgIHNyY0ltYWdlQml0bWFwOiBudWxsLFxuICAgIGlzSW1hZ2VCaXRtYXBSZXVzZWQ6IGZhbHNlLFxuICAgIHRvQ3R4OiBudWxsXG4gIH07XG5cbiAgdmFyIHByb2Nlc3NUaWxlID0gZnVuY3Rpb24gcHJvY2Vzc1RpbGUodGlsZSkge1xuICAgIHJldHVybiBfdGhpczMuX19saW1pdChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47XG4gICAgICB2YXIgdGlsZU9wdHMgPSB7XG4gICAgICAgIHdpZHRoOiB0aWxlLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IHRpbGUuaGVpZ2h0LFxuICAgICAgICB0b1dpZHRoOiB0aWxlLnRvV2lkdGgsXG4gICAgICAgIHRvSGVpZ2h0OiB0aWxlLnRvSGVpZ2h0LFxuICAgICAgICBzY2FsZVg6IHRpbGUuc2NhbGVYLFxuICAgICAgICBzY2FsZVk6IHRpbGUuc2NhbGVZLFxuICAgICAgICBvZmZzZXRYOiB0aWxlLm9mZnNldFgsXG4gICAgICAgIG9mZnNldFk6IHRpbGUub2Zmc2V0WSxcbiAgICAgICAgcXVhbGl0eTogb3B0cy5xdWFsaXR5LFxuICAgICAgICBhbHBoYTogb3B0cy5hbHBoYSxcbiAgICAgICAgdW5zaGFycEFtb3VudDogb3B0cy51bnNoYXJwQW1vdW50LFxuICAgICAgICB1bnNoYXJwUmFkaXVzOiBvcHRzLnVuc2hhcnBSYWRpdXMsXG4gICAgICAgIHVuc2hhcnBUaHJlc2hvbGQ6IG9wdHMudW5zaGFycFRocmVzaG9sZFxuICAgICAgfTtcblxuICAgICAgX3RoaXMzLmRlYnVnKCdJbnZva2UgcmVzaXplIG1hdGgnKTtcblxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aWxlT3B0cykudGhlbihmdW5jdGlvbiAodGlsZU9wdHMpIHtcbiAgICAgICAgcmV0dXJuIF90aGlzMy5fX2V4dHJhY3RUaWxlRGF0YSh0aWxlLCBmcm9tLCBvcHRzLCBzdGFnZUVudiwgdGlsZU9wdHMpO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAodGlsZU9wdHMpIHtcbiAgICAgICAgX3RoaXMzLmRlYnVnKCdJbnZva2UgcmVzaXplIG1hdGgnKTtcblxuICAgICAgICByZXR1cm4gX3RoaXMzLl9faW52b2tlUmVzaXplKHRpbGVPcHRzLCBvcHRzKTtcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47XG4gICAgICAgIHN0YWdlRW52LnNyY0ltYWdlRGF0YSA9IG51bGw7XG4gICAgICAgIHJldHVybiBfdGhpczMuX19sYW5kVGlsZURhdGEodGlsZSwgcmVzdWx0LCBzdGFnZUVudik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTsgLy8gTmVlZCB0byBub3JtYWxpemUgZGF0YSBzb3VyY2UgZmlyc3QuIEl0IGNhbiBiZSBjYW52YXMgb3IgaW1hZ2UuXG4gIC8vIElmIGltYWdlIC0gdHJ5IHRvIGRlY29kZSBpbiBiYWNrZ3JvdW5kIGlmIHBvc3NpYmxlXG5cblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgc3RhZ2VFbnYudG9DdHggPSB0by5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gICAgfSk7XG4gICAgaWYgKHV0aWxzLmlzQ2FudmFzKGZyb20pKSByZXR1cm4gbnVsbDtcblxuICAgIGlmICh1dGlscy5pc0ltYWdlQml0bWFwKGZyb20pKSB7XG4gICAgICBzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCA9IGZyb207XG4gICAgICBzdGFnZUVudi5pc0ltYWdlQml0bWFwUmV1c2VkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmICh1dGlscy5pc0ltYWdlKGZyb20pKSB7XG4gICAgICAvLyB0cnkgZG8gZGVjb2RlIGltYWdlIGluIGJhY2tncm91bmQgZm9yIGZhc3RlciBuZXh0IG9wZXJhdGlvbnM7XG4gICAgICAvLyBpZiB3ZSdyZSB1c2luZyBvZmZzY3JlZW4gY2FudmFzLCBjaWIgaXMgY2FsbGVkIHBlciB0aWxlLCBzbyBub3QgbmVlZGVkIGhlcmVcbiAgICAgIGlmICghQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVApIHJldHVybiBudWxsO1xuXG4gICAgICBfdGhpczMuZGVidWcoJ0RlY29kZSBpbWFnZSB2aWEgY3JlYXRlSW1hZ2VCaXRtYXAnKTtcblxuICAgICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGZyb20pLnRoZW4oZnVuY3Rpb24gKGltYWdlQml0bWFwKSB7XG4gICAgICAgIHN0YWdlRW52LnNyY0ltYWdlQml0bWFwID0gaW1hZ2VCaXRtYXA7XG4gICAgICB9KSAvLyBTdXBwcmVzcyBlcnJvciB0byB1c2UgZmFsbGJhY2ssIGlmIG1ldGhvZCBmYWlsc1xuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTBcblxuICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbiAgICAgIFtcImNhdGNoXCJdKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdQaWNhOiBcIi5mcm9tXCIgc2hvdWxkIGJlIEltYWdlLCBDYW52YXMgb3IgSW1hZ2VCaXRtYXAnKTtcbiAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuO1xuXG4gICAgX3RoaXMzLmRlYnVnKCdDYWxjdWxhdGUgdGlsZXMnKTsgLy9cbiAgICAvLyBIZXJlIHdlIGFyZSB3aXRoIFwibm9ybWFsaXplZFwiIHNvdXJjZSxcbiAgICAvLyBmb2xsb3cgdG8gdGlsaW5nXG4gICAgLy9cblxuXG4gICAgdmFyIHJlZ2lvbnMgPSBjcmVhdGVSZWdpb25zKHtcbiAgICAgIHdpZHRoOiBvcHRzLndpZHRoLFxuICAgICAgaGVpZ2h0OiBvcHRzLmhlaWdodCxcbiAgICAgIHNyY1RpbGVTaXplOiBfdGhpczMub3B0aW9ucy50aWxlLFxuICAgICAgdG9XaWR0aDogb3B0cy50b1dpZHRoLFxuICAgICAgdG9IZWlnaHQ6IG9wdHMudG9IZWlnaHQsXG4gICAgICBkZXN0VGlsZUJvcmRlcjogb3B0cy5fX2Rlc3RUaWxlQm9yZGVyXG4gICAgfSk7XG4gICAgdmFyIGpvYnMgPSByZWdpb25zLm1hcChmdW5jdGlvbiAodGlsZSkge1xuICAgICAgcmV0dXJuIHByb2Nlc3NUaWxlKHRpbGUpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gY2xlYW51cChzdGFnZUVudikge1xuICAgICAgaWYgKHN0YWdlRW52LnNyY0ltYWdlQml0bWFwKSB7XG4gICAgICAgIGlmICghc3RhZ2VFbnYuaXNJbWFnZUJpdG1hcFJldXNlZCkgc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAuY2xvc2UoKTtcbiAgICAgICAgc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIF90aGlzMy5kZWJ1ZygnUHJvY2VzcyB0aWxlcycpO1xuXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGpvYnMpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgX3RoaXMzLmRlYnVnKCdGaW5pc2hlZCEnKTtcblxuICAgICAgY2xlYW51cChzdGFnZUVudik7XG4gICAgICByZXR1cm4gdG87XG4gICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgY2xlYW51cChzdGFnZUVudik7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUuX19wcm9jZXNzU3RhZ2VzID0gZnVuY3Rpb24gKHN0YWdlcywgZnJvbSwgdG8sIG9wdHMpIHtcbiAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuO1xuXG4gIHZhciBfc3RhZ2VzJHNoaWZ0ID0gc3RhZ2VzLnNoaWZ0KCksXG4gICAgICBfc3RhZ2VzJHNoaWZ0MiA9IF9zbGljZWRUb0FycmF5KF9zdGFnZXMkc2hpZnQsIDIpLFxuICAgICAgdG9XaWR0aCA9IF9zdGFnZXMkc2hpZnQyWzBdLFxuICAgICAgdG9IZWlnaHQgPSBfc3RhZ2VzJHNoaWZ0MlsxXTtcblxuICB2YXIgaXNMYXN0U3RhZ2UgPSBzdGFnZXMubGVuZ3RoID09PSAwO1xuICBvcHRzID0gYXNzaWduKHt9LCBvcHRzLCB7XG4gICAgdG9XaWR0aDogdG9XaWR0aCxcbiAgICB0b0hlaWdodDogdG9IZWlnaHQsXG4gICAgLy8gb25seSB1c2UgdXNlci1kZWZpbmVkIHF1YWxpdHkgZm9yIHRoZSBsYXN0IHN0YWdlLFxuICAgIC8vIHVzZSBzaW1wbGVyIChIYW1taW5nKSBmaWx0ZXIgZm9yIHRoZSBmaXJzdCBzdGFnZXMgd2hlcmVcbiAgICAvLyBzY2FsZSBmYWN0b3IgaXMgbGFyZ2UgZW5vdWdoIChtb3JlIHRoYW4gMi0zKVxuICAgIHF1YWxpdHk6IGlzTGFzdFN0YWdlID8gb3B0cy5xdWFsaXR5IDogTWF0aC5taW4oMSwgb3B0cy5xdWFsaXR5KVxuICB9KTtcbiAgdmFyIHRtcENhbnZhcztcblxuICBpZiAoIWlzTGFzdFN0YWdlKSB7XG4gICAgLy8gY3JlYXRlIHRlbXBvcmFyeSBjYW52YXNcbiAgICB0bXBDYW52YXMgPSB0aGlzLm9wdGlvbnMuY3JlYXRlQ2FudmFzKHRvV2lkdGgsIHRvSGVpZ2h0KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9fdGlsZUFuZFJlc2l6ZShmcm9tLCBpc0xhc3RTdGFnZSA/IHRvIDogdG1wQ2FudmFzLCBvcHRzKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoaXNMYXN0U3RhZ2UpIHJldHVybiB0bztcbiAgICBvcHRzLndpZHRoID0gdG9XaWR0aDtcbiAgICBvcHRzLmhlaWdodCA9IHRvSGVpZ2h0O1xuICAgIHJldHVybiBfdGhpczQuX19wcm9jZXNzU3RhZ2VzKHN0YWdlcywgdG1wQ2FudmFzLCB0bywgb3B0cyk7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgIGlmICh0bXBDYW52YXMpIHtcbiAgICAgIC8vIFNhZmFyaSAxMiB3b3JrYXJvdW5kXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL3BpY2EvaXNzdWVzLzE5OVxuICAgICAgdG1wQ2FudmFzLndpZHRoID0gdG1wQ2FudmFzLmhlaWdodCA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5fX3Jlc2l6ZVZpYUNyZWF0ZUltYWdlQml0bWFwID0gZnVuY3Rpb24gKGZyb20sIHRvLCBvcHRzKSB7XG4gIHZhciBfdGhpczUgPSB0aGlzO1xuXG4gIHZhciB0b0N0eCA9IHRvLmdldENvbnRleHQoJzJkJywge1xuICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gIH0pO1xuICB0aGlzLmRlYnVnKCdSZXNpemUgdmlhIGNyZWF0ZUltYWdlQml0bWFwKCknKTtcbiAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGZyb20sIHtcbiAgICByZXNpemVXaWR0aDogb3B0cy50b1dpZHRoLFxuICAgIHJlc2l6ZUhlaWdodDogb3B0cy50b0hlaWdodCxcbiAgICByZXNpemVRdWFsaXR5OiB1dGlscy5jaWJfcXVhbGl0eV9uYW1lKG9wdHMucXVhbGl0eSlcbiAgfSkudGhlbihmdW5jdGlvbiAoaW1hZ2VCaXRtYXApIHtcbiAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47IC8vIGlmIG5vIHVuc2hhcnAgLSBkcmF3IGRpcmVjdGx5IHRvIG91dHB1dCBjYW52YXNcblxuICAgIGlmICghb3B0cy51bnNoYXJwQW1vdW50KSB7XG4gICAgICB0b0N0eC5kcmF3SW1hZ2UoaW1hZ2VCaXRtYXAsIDAsIDApO1xuICAgICAgaW1hZ2VCaXRtYXAuY2xvc2UoKTtcbiAgICAgIHRvQ3R4ID0gbnVsbDtcblxuICAgICAgX3RoaXM1LmRlYnVnKCdGaW5pc2hlZCEnKTtcblxuICAgICAgcmV0dXJuIHRvO1xuICAgIH1cblxuICAgIF90aGlzNS5kZWJ1ZygnVW5zaGFycCByZXN1bHQnKTtcblxuICAgIHZhciB0bXBDYW52YXMgPSBfdGhpczUub3B0aW9ucy5jcmVhdGVDYW52YXMob3B0cy50b1dpZHRoLCBvcHRzLnRvSGVpZ2h0KTtcblxuICAgIHZhciB0bXBDdHggPSB0bXBDYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICAgIH0pO1xuICAgIHRtcEN0eC5kcmF3SW1hZ2UoaW1hZ2VCaXRtYXAsIDAsIDApO1xuICAgIGltYWdlQml0bWFwLmNsb3NlKCk7XG4gICAgdmFyIGlEYXRhID0gdG1wQ3R4LmdldEltYWdlRGF0YSgwLCAwLCBvcHRzLnRvV2lkdGgsIG9wdHMudG9IZWlnaHQpO1xuXG4gICAgX3RoaXM1Ll9fbWF0aGxpYi51bnNoYXJwX21hc2soaURhdGEuZGF0YSwgb3B0cy50b1dpZHRoLCBvcHRzLnRvSGVpZ2h0LCBvcHRzLnVuc2hhcnBBbW91bnQsIG9wdHMudW5zaGFycFJhZGl1cywgb3B0cy51bnNoYXJwVGhyZXNob2xkKTtcblxuICAgIHRvQ3R4LnB1dEltYWdlRGF0YShpRGF0YSwgMCwgMCk7IC8vIFNhZmFyaSAxMiB3b3JrYXJvdW5kXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcblxuICAgIHRtcENhbnZhcy53aWR0aCA9IHRtcENhbnZhcy5oZWlnaHQgPSAwO1xuICAgIGlEYXRhID0gdG1wQ3R4ID0gdG1wQ2FudmFzID0gdG9DdHggPSBudWxsO1xuXG4gICAgX3RoaXM1LmRlYnVnKCdGaW5pc2hlZCEnKTtcblxuICAgIHJldHVybiB0bztcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbiAoZnJvbSwgdG8sIG9wdGlvbnMpIHtcbiAgdmFyIF90aGlzNiA9IHRoaXM7XG5cbiAgdGhpcy5kZWJ1ZygnU3RhcnQgcmVzaXplLi4uJyk7XG4gIHZhciBvcHRzID0gYXNzaWduKHt9LCBERUZBVUxUX1JFU0laRV9PUFRTKTtcblxuICBpZiAoIWlzTmFOKG9wdGlvbnMpKSB7XG4gICAgb3B0cyA9IGFzc2lnbihvcHRzLCB7XG4gICAgICBxdWFsaXR5OiBvcHRpb25zXG4gICAgfSk7XG4gIH0gZWxzZSBpZiAob3B0aW9ucykge1xuICAgIG9wdHMgPSBhc3NpZ24ob3B0cywgb3B0aW9ucyk7XG4gIH1cblxuICBvcHRzLnRvV2lkdGggPSB0by53aWR0aDtcbiAgb3B0cy50b0hlaWdodCA9IHRvLmhlaWdodDtcbiAgb3B0cy53aWR0aCA9IGZyb20ubmF0dXJhbFdpZHRoIHx8IGZyb20ud2lkdGg7XG4gIG9wdHMuaGVpZ2h0ID0gZnJvbS5uYXR1cmFsSGVpZ2h0IHx8IGZyb20uaGVpZ2h0OyAvLyBQcmV2ZW50IHN0ZXBwZXIgZnJvbSBpbmZpbml0ZSBsb29wXG5cbiAgaWYgKHRvLndpZHRoID09PSAwIHx8IHRvLmhlaWdodCA9PT0gMCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIG91dHB1dCBzaXplOiBcIi5jb25jYXQodG8ud2lkdGgsIFwieFwiKS5jb25jYXQodG8uaGVpZ2h0KSkpO1xuICB9XG5cbiAgaWYgKG9wdHMudW5zaGFycFJhZGl1cyA+IDIpIG9wdHMudW5zaGFycFJhZGl1cyA9IDI7XG4gIG9wdHMuY2FuY2VsZWQgPSBmYWxzZTtcblxuICBpZiAob3B0cy5jYW5jZWxUb2tlbikge1xuICAgIC8vIFdyYXAgY2FuY2VsVG9rZW4gdG8gYXZvaWQgc3VjY2Vzc2l2ZSByZXNvbHZlICYgc2V0IGZsYWdcbiAgICBvcHRzLmNhbmNlbFRva2VuID0gb3B0cy5jYW5jZWxUb2tlbi50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICBvcHRzLmNhbmNlbGVkID0gdHJ1ZTtcbiAgICAgIHRocm93IGRhdGE7XG4gICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgb3B0cy5jYW5jZWxlZCA9IHRydWU7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSk7XG4gIH1cblxuICB2YXIgREVTVF9USUxFX0JPUkRFUiA9IDM7IC8vIE1heCBwb3NzaWJsZSBmaWx0ZXIgd2luZG93IHNpemVcblxuICBvcHRzLl9fZGVzdFRpbGVCb3JkZXIgPSBNYXRoLmNlaWwoTWF0aC5tYXgoREVTVF9USUxFX0JPUkRFUiwgMi41ICogb3B0cy51bnNoYXJwUmFkaXVzIHwgMCkpO1xuICByZXR1cm4gdGhpcy5pbml0KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuOyAvLyBpZiBjcmVhdGVJbWFnZUJpdG1hcCBzdXBwb3J0cyByZXNpemUsIGp1c3QgZG8gaXQgYW5kIHJldHVyblxuXG4gICAgaWYgKF90aGlzNi5mZWF0dXJlcy5jaWIpIHtcbiAgICAgIHJldHVybiBfdGhpczYuX19yZXNpemVWaWFDcmVhdGVJbWFnZUJpdG1hcChmcm9tLCB0bywgb3B0cyk7XG4gICAgfVxuXG4gICAgaWYgKCFDQU5fVVNFX0NBTlZBU19HRVRfSU1BR0VfREFUQSkge1xuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignUGljYTogY2Fubm90IHVzZSBnZXRJbWFnZURhdGEgb24gY2FudmFzLCAnICsgXCJtYWtlIHN1cmUgZmluZ2VycHJpbnRpbmcgcHJvdGVjdGlvbiBpc24ndCBlbmFibGVkXCIpO1xuICAgICAgZXJyLmNvZGUgPSAnRVJSX0dFVF9JTUFHRV9EQVRBJztcbiAgICAgIHRocm93IGVycjtcbiAgICB9IC8vXG4gICAgLy8gTm8gZWFzeSB3YXksIGxldCdzIHJlc2l6ZSBtYW51YWxseSB2aWEgYXJyYXlzXG4gICAgLy9cblxuXG4gICAgdmFyIHN0YWdlcyA9IGNyZWF0ZVN0YWdlcyhvcHRzLndpZHRoLCBvcHRzLmhlaWdodCwgb3B0cy50b1dpZHRoLCBvcHRzLnRvSGVpZ2h0LCBfdGhpczYub3B0aW9ucy50aWxlLCBvcHRzLl9fZGVzdFRpbGVCb3JkZXIpO1xuICAgIHJldHVybiBfdGhpczYuX19wcm9jZXNzU3RhZ2VzKHN0YWdlcywgZnJvbSwgdG8sIG9wdHMpO1xuICB9KTtcbn07IC8vIFJHQkEgYnVmZmVyIHJlc2l6ZVxuLy9cblxuXG5QaWNhLnByb3RvdHlwZS5yZXNpemVCdWZmZXIgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICB2YXIgX3RoaXM3ID0gdGhpcztcblxuICB2YXIgb3B0cyA9IGFzc2lnbih7fSwgREVGQVVMVF9SRVNJWkVfT1BUUywgb3B0aW9ucyk7XG4gIHJldHVybiB0aGlzLmluaXQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3RoaXM3Ll9fbWF0aGxpYi5yZXNpemVBbmRVbnNoYXJwKG9wdHMpO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLnRvQmxvYiA9IGZ1bmN0aW9uIChjYW52YXMsIG1pbWVUeXBlLCBxdWFsaXR5KSB7XG4gIG1pbWVUeXBlID0gbWltZVR5cGUgfHwgJ2ltYWdlL3BuZyc7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgIGlmIChjYW52YXMudG9CbG9iKSB7XG4gICAgICBjYW52YXMudG9CbG9iKGZ1bmN0aW9uIChibG9iKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKGJsb2IpO1xuICAgICAgfSwgbWltZVR5cGUsIHF1YWxpdHkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjYW52YXMuY29udmVydFRvQmxvYikge1xuICAgICAgcmVzb2x2ZShjYW52YXMuY29udmVydFRvQmxvYih7XG4gICAgICAgIHR5cGU6IG1pbWVUeXBlLFxuICAgICAgICBxdWFsaXR5OiBxdWFsaXR5XG4gICAgICB9KSk7XG4gICAgICByZXR1cm47XG4gICAgfSAvLyBGYWxsYmFjayBmb3Igb2xkIGJyb3dzZXJzXG5cblxuICAgIHZhciBhc1N0cmluZyA9IGF0b2IoY2FudmFzLnRvRGF0YVVSTChtaW1lVHlwZSwgcXVhbGl0eSkuc3BsaXQoJywnKVsxXSk7XG4gICAgdmFyIGxlbiA9IGFzU3RyaW5nLmxlbmd0aDtcbiAgICB2YXIgYXNCdWZmZXIgPSBuZXcgVWludDhBcnJheShsZW4pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgYXNCdWZmZXJbaV0gPSBhc1N0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgIH1cblxuICAgIHJlc29sdmUobmV3IEJsb2IoW2FzQnVmZmVyXSwge1xuICAgICAgdHlwZTogbWltZVR5cGVcbiAgICB9KSk7XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUuZGVidWcgPSBmdW5jdGlvbiAoKSB7fTtcblxubW9kdWxlLmV4cG9ydHMgPSBQaWNhO1xuXG59LHtcIi4vbGliL21hdGhsaWJcIjoxLFwiLi9saWIvcG9vbFwiOjEzLFwiLi9saWIvc3RlcHBlclwiOjE0LFwiLi9saWIvdGlsZXJcIjoxNSxcIi4vbGliL3V0aWxzXCI6MTYsXCIuL2xpYi93b3JrZXJcIjoxNyxcIm9iamVjdC1hc3NpZ25cIjoyMyxcIndlYndvcmtpZnlcIjoyNH1dfSx7fSxbXSkoXCIvaW5kZXguanNcIilcbn0pO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../../node_modules/pica/dist/pica.js\n");
17
+ eval("/*!\n\npica\nhttps://github.com/nodeca/pica\n\n*/\n\n(function(f){if(true){module.exports=f()}else { var g; }})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=undefined;if(!f&&c)return require(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=undefined,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){\n// Collection of math functions\n//\n// 1. Combine components together\n// 2. Has async init to load wasm modules\n//\n'use strict';\n\nvar inherits = _dereq_('inherits');\n\nvar Multimath = _dereq_('multimath');\n\nvar mm_unsharp_mask = _dereq_('./mm_unsharp_mask');\n\nvar mm_resize = _dereq_('./mm_resize');\n\nfunction MathLib(requested_features) {\n var __requested_features = requested_features || [];\n\n var features = {\n js: __requested_features.indexOf('js') >= 0,\n wasm: __requested_features.indexOf('wasm') >= 0\n };\n Multimath.call(this, features);\n this.features = {\n js: features.js,\n wasm: features.wasm && this.has_wasm()\n };\n this.use(mm_unsharp_mask);\n this.use(mm_resize);\n}\n\ninherits(MathLib, Multimath);\n\nMathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {\n var result = this.resize(options, cache);\n\n if (options.unsharpAmount) {\n this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);\n }\n\n return result;\n};\n\nmodule.exports = MathLib;\n\n},{\"./mm_resize\":4,\"./mm_unsharp_mask\":9,\"inherits\":19,\"multimath\":20}],2:[function(_dereq_,module,exports){\n// Resize convolvers, pure JS implementation\n//\n'use strict'; // Precision of fixed FP values\n//var FIXED_FRAC_BITS = 14;\n\nfunction clampTo8(i) {\n return i < 0 ? 0 : i > 255 ? 255 : i;\n} // Convolve image in horizontal directions and transpose output. In theory,\n// transpose allow:\n//\n// - use the same convolver for both passes (this fails due different\n// types of input array and temporary buffer)\n// - making vertical pass by horisonltal lines inprove CPU cache use.\n//\n// But in real life this doesn't work :)\n//\n\n\nfunction convolveHorizontally(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n} // Technically, convolvers are the same. But input array and temporary\n// buffer can be of different type (especially, in old browsers). So,\n// keep code in separate functions to avoid deoptimizations & speed loss.\n\n\nfunction convolveVertically(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n}\n\nmodule.exports = {\n convolveHorizontally: convolveHorizontally,\n convolveVertically: convolveVertically\n};\n\n},{}],3:[function(_dereq_,module,exports){\n// This is autogenerated file from math.wasm, don't edit.\n//\n'use strict';\n/* eslint-disable max-len */\n\nmodule.exports = 'AGFzbQEAAAAADAZkeWxpbmsAAAAAAAEXA2AAAGAGf39/f39/AGAHf39/f39/fwACDwEDZW52Bm1lbW9yeQIAAAMEAwABAgYGAX8AQQALB1cFEV9fd2FzbV9jYWxsX2N0b3JzAAAIY29udm9sdmUAAQpjb252b2x2ZUhWAAIMX19kc29faGFuZGxlAwAYX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzAAAK7AMDAwABC8YDAQ9/AkAgA0UNACAERQ0AA0AgDCENQQAhE0EAIQcDQCAHQQJqIQYCfyAHQQF0IAVqIgcuAQIiFEUEQEGAwAAhCEGAwAAhCUGAwAAhCkGAwAAhCyAGDAELIBIgBy4BAGohCEEAIQsgFCEHQQAhDiAGIQlBACEPQQAhEANAIAUgCUEBdGouAQAiESAAIAhBAnRqKAIAIgpBGHZsIBBqIRAgCkH/AXEgEWwgC2ohCyAKQRB2Qf8BcSARbCAPaiEPIApBCHZB/wFxIBFsIA5qIQ4gCEEBaiEIIAlBAWohCSAHQQFrIgcNAAsgC0GAQGshCCAOQYBAayEJIA9BgEBrIQogEEGAQGshCyAGIBRqCyEHIAEgDUECdGogCUEOdSIGQf8BIAZB/wFIGyIGQQAgBkEAShtBCHRBgP4DcSAKQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EQdEGAgPwHcSALQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EYdHJyIAhBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobcjYCACADIA1qIQ0gE0EBaiITIARHDQALIAxBAWoiDCACbCESIAMgDEcNAAsLCx4AQQAgAiADIAQgBSAAEAEgAkEAIAQgBSAGIAEQAQs=';\n\n},{}],4:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = {\n name: 'resize',\n fn: _dereq_('./resize'),\n wasm_fn: _dereq_('./resize_wasm'),\n wasm_src: _dereq_('./convolve_wasm_base64')\n};\n\n},{\"./convolve_wasm_base64\":3,\"./resize\":5,\"./resize_wasm\":8}],5:[function(_dereq_,module,exports){\n'use strict';\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nvar convolveHorizontally = _dereq_('./convolve').convolveHorizontally;\n\nvar convolveVertically = _dereq_('./convolve').convolveVertically;\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nmodule.exports = function resize(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0;\n var offsetY = options.offsetY || 0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY);\n var tmp = new Uint8Array(destW * srcH * 4); // To use single function we need src & tmp of the same type.\n // But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep\n // vertical and horizontal passes separately to avoid deoptimization.\n\n convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);\n convolveVertically(tmp, dest, srcH, destW, destH, filtersY); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./convolve\":2,\"./resize_filter_gen\":6}],6:[function(_dereq_,module,exports){\n// Calculate convolution filters for each destination point,\n// and pack data to Int16Array:\n//\n// [ shift, length, data..., shift2, length2, data..., ... ]\n//\n// - shift - offset in src image\n// - length - filter length (in src points)\n// - data - filter values sequence\n//\n'use strict';\n\nvar FILTER_INFO = _dereq_('./resize_filter_info'); // Precision of fixed FP values\n\n\nvar FIXED_FRAC_BITS = 14;\n\nfunction toFixedPoint(num) {\n return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));\n}\n\nmodule.exports = function resizeFilterGen(quality, srcSize, destSize, scale, offset) {\n var filterFunction = FILTER_INFO[quality].filter;\n var scaleInverted = 1.0 / scale;\n var scaleClamped = Math.min(1.0, scale); // For upscale\n // Filter window (averaging interval), scaled to src image\n\n var srcWindow = FILTER_INFO[quality].win / scaleClamped;\n var destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;\n var leftNotEmpty, rightNotEmpty, filterShift, filterSize;\n var maxFilterElementSize = Math.floor((srcWindow + 1) * 2);\n var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);\n var packedFilterPtr = 0;\n var slowCopy = !packedFilter.subarray || !packedFilter.set; // For each destination pixel calculate source range and built filter values\n\n for (destPixel = 0; destPixel < destSize; destPixel++) {\n // Scaling should be done relative to central pixel point\n srcPixel = (destPixel + 0.5) * scaleInverted + offset;\n srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));\n srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));\n filterElementSize = srcLast - srcFirst + 1;\n floatFilter = new Float32Array(filterElementSize);\n fxpFilter = new Int16Array(filterElementSize);\n total = 0.0; // Fill filter values for calculated range\n\n for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {\n floatVal = filterFunction((pxl + 0.5 - srcPixel) * scaleClamped);\n total += floatVal;\n floatFilter[idx] = floatVal;\n } // Normalize filter, convert to fixed point and accumulate conversion error\n\n\n filterTotal = 0;\n\n for (idx = 0; idx < floatFilter.length; idx++) {\n filterVal = floatFilter[idx] / total;\n filterTotal += filterVal;\n fxpFilter[idx] = toFixedPoint(filterVal);\n } // Compensate normalization error, to minimize brightness drift\n\n\n fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal); //\n // Now pack filter to useable form\n //\n // 1. Trim heading and tailing zero values, and compensate shitf/length\n // 2. Put all to single array in this format:\n //\n // [ pos shift, data length, value1, value2, value3, ... ]\n //\n\n leftNotEmpty = 0;\n\n while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {\n leftNotEmpty++;\n }\n\n if (leftNotEmpty < fxpFilter.length) {\n rightNotEmpty = fxpFilter.length - 1;\n\n while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {\n rightNotEmpty--;\n }\n\n filterShift = srcFirst + leftNotEmpty;\n filterSize = rightNotEmpty - leftNotEmpty + 1;\n packedFilter[packedFilterPtr++] = filterShift; // shift\n\n packedFilter[packedFilterPtr++] = filterSize; // size\n\n if (!slowCopy) {\n packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);\n packedFilterPtr += filterSize;\n } else {\n // fallback for old IE < 11, without subarray/set methods\n for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {\n packedFilter[packedFilterPtr++] = fxpFilter[idx];\n }\n }\n } else {\n // zero data, write header only\n packedFilter[packedFilterPtr++] = 0; // shift\n\n packedFilter[packedFilterPtr++] = 0; // size\n }\n }\n\n return packedFilter;\n};\n\n},{\"./resize_filter_info\":7}],7:[function(_dereq_,module,exports){\n// Filter definitions to build tables for\n// resizing convolvers.\n//\n// Presets for quality 0..3. Filter functions + window size\n//\n'use strict';\n\nmodule.exports = [{\n // Nearest neibor (Box)\n win: 0.5,\n filter: function filter(x) {\n return x >= -0.5 && x < 0.5 ? 1.0 : 0.0;\n }\n}, {\n // Hamming\n win: 1.0,\n filter: function filter(x) {\n if (x <= -1.0 || x >= 1.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * (0.54 + 0.46 * Math.cos(xpi / 1.0));\n }\n}, {\n // Lanczos, win = 2\n win: 2.0,\n filter: function filter(x) {\n if (x <= -2.0 || x >= 2.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 2.0) / (xpi / 2.0);\n }\n}, {\n // Lanczos, win = 3\n win: 3.0,\n filter: function filter(x) {\n if (x <= -3.0 || x >= 3.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 3.0) / (xpi / 3.0);\n }\n}];\n\n},{}],8:[function(_dereq_,module,exports){\n'use strict';\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nfunction asUint8Array(src) {\n return new Uint8Array(src.buffer, 0, src.byteLength);\n}\n\nvar IS_LE = true; // should not crash everything on module load in old browsers\n\ntry {\n IS_LE = new Uint32Array(new Uint8Array([1, 0, 0, 0]).buffer)[0] === 1;\n} catch (__) {}\n\nfunction copyInt16asLE(src, target, target_offset) {\n if (IS_LE) {\n target.set(asUint8Array(src), target_offset);\n return;\n }\n\n for (var ptr = target_offset, i = 0; i < src.length; i++) {\n var data = src[i];\n target[ptr++] = data & 0xFF;\n target[ptr++] = data >> 8 & 0xFF;\n }\n}\n\nmodule.exports = function resize_wasm(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0.0;\n var offsetY = options.offsetY || 0.0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY); // destination is 0 too.\n\n var src_offset = 0; // buffer between convolve passes\n\n var tmp_offset = this.__align(src_offset + Math.max(src.byteLength, dest.byteLength));\n\n var filtersX_offset = this.__align(tmp_offset + srcH * destW * 4);\n\n var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);\n\n var alloc_bytes = filtersY_offset + filtersY.byteLength;\n\n var instance = this.__instance('resize', alloc_bytes); //\n // Fill memory block with data to process\n //\n\n\n var mem = new Uint8Array(this.__memory.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer); // 32-bit copy is much faster in chrome\n\n var src32 = new Uint32Array(src.buffer);\n mem32.set(src32); // We should guarantee LE bytes order. Filters are not big, so\n // speed difference is not significant vs direct .set()\n\n copyInt16asLE(filtersX, mem, filtersX_offset);\n copyInt16asLE(filtersY, mem, filtersY_offset); //\n // Now call webassembly method\n // emsdk does method names with '_'\n\n var fn = instance.exports.convolveHV || instance.exports._convolveHV;\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH); //\n // Copy data back to typed array\n //\n // 32-bit copy is much faster in chrome\n\n var dest32 = new Uint32Array(dest.buffer);\n dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW)); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./resize_filter_gen\":6}],9:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = {\n name: 'unsharp_mask',\n fn: _dereq_('./unsharp_mask'),\n wasm_fn: _dereq_('./unsharp_mask_wasm'),\n wasm_src: _dereq_('./unsharp_mask_wasm_base64')\n};\n\n},{\"./unsharp_mask\":10,\"./unsharp_mask_wasm\":11,\"./unsharp_mask_wasm_base64\":12}],10:[function(_dereq_,module,exports){\n// Unsharp mask filter\n//\n// http://stackoverflow.com/a/23322820/1031804\n// USM(O) = O + (2 * (Amount / 100) * (O - GB))\n// GB - gaussian blur.\n//\n// Image is converted from RGB to HSV, unsharp mask is applied to the\n// brightness channel and then image is converted back to RGB.\n//\n'use strict';\n\nvar glur_mono16 = _dereq_('glur/mono16');\n\nfunction hsv_v16(img, width, height) {\n var size = width * height;\n var out = new Uint16Array(size);\n var r, g, b, max;\n\n for (var i = 0; i < size; i++) {\n r = img[4 * i];\n g = img[4 * i + 1];\n b = img[4 * i + 2];\n max = r >= g && r >= b ? r : g >= b && g >= r ? g : b;\n out[i] = max << 8;\n }\n\n return out;\n}\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n var v1, v2, vmul;\n var diff, iTimes4;\n\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var brightness = hsv_v16(img, width, height);\n var blured = new Uint16Array(brightness); // copy, because blur modify src\n\n glur_mono16(blured, width, height, radius);\n var amountFp = amount / 100 * 0x1000 + 0.5 | 0;\n var thresholdFp = threshold << 8;\n var size = width * height;\n /* eslint-disable indent */\n\n for (var i = 0; i < size; i++) {\n v1 = brightness[i];\n diff = v1 - blured[i];\n\n if (Math.abs(diff) >= thresholdFp) {\n // add unsharp mask to the brightness channel\n v2 = v1 + (amountFp * diff + 0x800 >> 12); // Both v1 and v2 are within [0.0 .. 255.0] (0000-FF00) range, never going into\n // [255.003 .. 255.996] (FF01-FFFF). This allows to round this value as (x+.5)|0\n // later without overflowing.\n\n v2 = v2 > 0xff00 ? 0xff00 : v2;\n v2 = v2 < 0x0000 ? 0x0000 : v2; // Avoid division by 0. V=0 means rgb(0,0,0), unsharp with unsharpAmount>0 cannot\n // change this value (because diff between colors gets inflated), so no need to verify correctness.\n\n v1 = v1 !== 0 ? v1 : 1; // Multiplying V in HSV model by a constant is equivalent to multiplying each component\n // in RGB by the same constant (same for HSL), see also:\n // https://beesbuzz.biz/code/16-hsv-color-transforms\n\n vmul = (v2 << 12) / v1 | 0; // Result will be in [0..255] range because:\n // - all numbers are positive\n // - r,g,b <= (v1/256)\n // - r,g,b,(v1/256),(v2/256) <= 255\n // So highest this number can get is X*255/X+0.5=255.5 which is < 256 and rounds down.\n\n iTimes4 = i * 4;\n img[iTimes4] = img[iTimes4] * vmul + 0x800 >> 12; // R\n\n img[iTimes4 + 1] = img[iTimes4 + 1] * vmul + 0x800 >> 12; // G\n\n img[iTimes4 + 2] = img[iTimes4 + 2] * vmul + 0x800 >> 12; // B\n }\n }\n};\n\n},{\"glur/mono16\":18}],11:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var pixels = width * height;\n var img_bytes_cnt = pixels * 4;\n var hsv_bytes_cnt = pixels * 2;\n var blur_bytes_cnt = pixels * 2;\n var blur_line_byte_cnt = Math.max(width, height) * 4; // float32 array\n\n var blur_coeffs_byte_cnt = 8 * 4; // float32 array\n\n var img_offset = 0;\n var hsv_offset = img_bytes_cnt;\n var blur_offset = hsv_offset + hsv_bytes_cnt;\n var blur_tmp_offset = blur_offset + blur_bytes_cnt;\n var blur_line_offset = blur_tmp_offset + blur_bytes_cnt;\n var blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;\n\n var instance = this.__instance('unsharp_mask', img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt, {\n exp: Math.exp\n }); // 32-bit copy is much faster in chrome\n\n\n var img32 = new Uint32Array(img.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer);\n mem32.set(img32); // HSL\n\n var fn = instance.exports.hsv_v16 || instance.exports._hsv_v16;\n fn(img_offset, hsv_offset, width, height); // BLUR\n\n fn = instance.exports.blurMono16 || instance.exports._blurMono16;\n fn(hsv_offset, blur_offset, blur_tmp_offset, blur_line_offset, blur_coeffs_offset, width, height, radius); // UNSHARP\n\n fn = instance.exports.unsharp || instance.exports._unsharp;\n fn(img_offset, img_offset, hsv_offset, blur_offset, width, height, amount, threshold); // 32-bit copy is much faster in chrome\n\n img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));\n};\n\n},{}],12:[function(_dereq_,module,exports){\n// This is autogenerated file from math.wasm, don't edit.\n//\n'use strict';\n/* eslint-disable max-len */\n\nmodule.exports = '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';\n\n},{}],13:[function(_dereq_,module,exports){\n'use strict';\n\nvar GC_INTERVAL = 100;\n\nfunction Pool(create, idle) {\n this.create = create;\n this.available = [];\n this.acquired = {};\n this.lastId = 1;\n this.timeoutId = 0;\n this.idle = idle || 2000;\n}\n\nPool.prototype.acquire = function () {\n var _this = this;\n\n var resource;\n\n if (this.available.length !== 0) {\n resource = this.available.pop();\n } else {\n resource = this.create();\n resource.id = this.lastId++;\n\n resource.release = function () {\n return _this.release(resource);\n };\n }\n\n this.acquired[resource.id] = resource;\n return resource;\n};\n\nPool.prototype.release = function (resource) {\n var _this2 = this;\n\n delete this.acquired[resource.id];\n resource.lastUsed = Date.now();\n this.available.push(resource);\n\n if (this.timeoutId === 0) {\n this.timeoutId = setTimeout(function () {\n return _this2.gc();\n }, GC_INTERVAL);\n }\n};\n\nPool.prototype.gc = function () {\n var _this3 = this;\n\n var now = Date.now();\n this.available = this.available.filter(function (resource) {\n if (now - resource.lastUsed > _this3.idle) {\n resource.destroy();\n return false;\n }\n\n return true;\n });\n\n if (this.available.length !== 0) {\n this.timeoutId = setTimeout(function () {\n return _this3.gc();\n }, GC_INTERVAL);\n } else {\n this.timeoutId = 0;\n }\n};\n\nmodule.exports = Pool;\n\n},{}],14:[function(_dereq_,module,exports){\n// Add intermediate resizing steps when scaling down by a very large factor.\n//\n// For example, when resizing 10000x10000 down to 10x10, it'll resize it to\n// 300x300 first.\n//\n// It's needed because tiler has issues when the entire tile is scaled down\n// to a few pixels (1024px source tile with border size 3 should result in\n// at least 3+3+2 = 8px target tile, so max scale factor is 128 here).\n//\n// Also, adding intermediate steps can speed up processing if we use lower\n// quality algorithms for first stages.\n//\n'use strict'; // min size = 0 results in infinite loop,\n// min size = 1 can consume large amount of memory\n\nvar MIN_INNER_TILE_SIZE = 2;\n\nmodule.exports = function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize, destTileBorder) {\n var scaleX = toWidth / fromWidth;\n var scaleY = toHeight / fromHeight; // derived from createRegions equation:\n // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;\n\n var minScale = (2 * destTileBorder + MIN_INNER_TILE_SIZE + 1) / srcTileSize; // refuse to scale image multiple times by less than twice each time,\n // it could only happen because of invalid options\n\n if (minScale > 0.5) return [[toWidth, toHeight]];\n var stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale)); // no additional resizes are necessary,\n // stageCount can be zero or be negative when enlarging the image\n\n if (stageCount <= 1) return [[toWidth, toHeight]];\n var result = [];\n\n for (var i = 0; i < stageCount; i++) {\n var width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));\n var height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));\n result.push([width, height]);\n }\n\n return result;\n};\n\n},{}],15:[function(_dereq_,module,exports){\n// Split original image into multiple 1024x1024 chunks to reduce memory usage\n// (images have to be unpacked into typed arrays for resizing) and allow\n// parallel processing of multiple tiles at a time.\n//\n'use strict';\n/*\n * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil\n * functions which take into account floating point arithmetic errors.\n * Those errors can cause undesired increments/decrements of sizes and offsets:\n * Math.ceil(36 / (36 / 500)) = 501\n * pixelCeil(36 / (36 / 500)) = 500\n */\n\nvar PIXEL_EPSILON = 1e-5;\n\nfunction pixelFloor(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.floor(x);\n}\n\nfunction pixelCeil(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.ceil(x);\n}\n\nmodule.exports = function createRegions(options) {\n var scaleX = options.toWidth / options.width;\n var scaleY = options.toHeight / options.height;\n var innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;\n var innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder; // prevent infinite loop, this should never happen\n\n if (innerTileWidth < 1 || innerTileHeight < 1) {\n throw new Error('Internal error in pica: target tile width/height is too small.');\n }\n\n var x, y;\n var innerX, innerY, toTileWidth, toTileHeight;\n var tiles = [];\n var tile; // we go top-to-down instead of left-to-right to make image displayed from top to\n // doesn in the browser\n\n for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {\n for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {\n x = innerX - options.destTileBorder;\n\n if (x < 0) {\n x = 0;\n }\n\n toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;\n\n if (x + toTileWidth >= options.toWidth) {\n toTileWidth = options.toWidth - x;\n }\n\n y = innerY - options.destTileBorder;\n\n if (y < 0) {\n y = 0;\n }\n\n toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;\n\n if (y + toTileHeight >= options.toHeight) {\n toTileHeight = options.toHeight - y;\n }\n\n tile = {\n toX: x,\n toY: y,\n toWidth: toTileWidth,\n toHeight: toTileHeight,\n toInnerX: innerX,\n toInnerY: innerY,\n toInnerWidth: innerTileWidth,\n toInnerHeight: innerTileHeight,\n offsetX: x / scaleX - pixelFloor(x / scaleX),\n offsetY: y / scaleY - pixelFloor(y / scaleY),\n scaleX: scaleX,\n scaleY: scaleY,\n x: pixelFloor(x / scaleX),\n y: pixelFloor(y / scaleY),\n width: pixelCeil(toTileWidth / scaleX),\n height: pixelCeil(toTileHeight / scaleY)\n };\n tiles.push(tile);\n }\n }\n\n return tiles;\n};\n\n},{}],16:[function(_dereq_,module,exports){\n'use strict';\n\nfunction objClass(obj) {\n return Object.prototype.toString.call(obj);\n}\n\nmodule.exports.isCanvas = function isCanvas(element) {\n var cname = objClass(element);\n return cname === '[object HTMLCanvasElement]'\n /* browser */\n || cname === '[object OffscreenCanvas]' || cname === '[object Canvas]'\n /* node-canvas */\n ;\n};\n\nmodule.exports.isImage = function isImage(element) {\n return objClass(element) === '[object HTMLImageElement]';\n};\n\nmodule.exports.isImageBitmap = function isImageBitmap(element) {\n return objClass(element) === '[object ImageBitmap]';\n};\n\nmodule.exports.limiter = function limiter(concurrency) {\n var active = 0,\n queue = [];\n\n function roll() {\n if (active < concurrency && queue.length) {\n active++;\n queue.shift()();\n }\n }\n\n return function limit(fn) {\n return new Promise(function (resolve, reject) {\n queue.push(function () {\n fn().then(function (result) {\n resolve(result);\n active--;\n roll();\n }, function (err) {\n reject(err);\n active--;\n roll();\n });\n });\n roll();\n });\n };\n};\n\nmodule.exports.cib_quality_name = function cib_quality_name(num) {\n switch (num) {\n case 0:\n return 'pixelated';\n\n case 1:\n return 'low';\n\n case 2:\n return 'medium';\n }\n\n return 'high';\n};\n\nmodule.exports.cib_support = function cib_support(createCanvas) {\n return Promise.resolve().then(function () {\n if (typeof createImageBitmap === 'undefined') {\n return false;\n }\n\n var c = createCanvas(100, 100);\n return createImageBitmap(c, 0, 0, 100, 100, {\n resizeWidth: 10,\n resizeHeight: 10,\n resizeQuality: 'high'\n }).then(function (bitmap) {\n var status = bitmap.width === 10; // Branch below is filtered on upper level. We do not call resize\n // detection for basic ImageBitmap.\n //\n // https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap\n // old Crome 51 has ImageBitmap without .close(). Then this code\n // will throw and return 'false' as expected.\n //\n\n bitmap.close();\n c = null;\n return status;\n });\n })[\"catch\"](function () {\n return false;\n });\n};\n\nmodule.exports.worker_offscreen_canvas_support = function worker_offscreen_canvas_support() {\n return new Promise(function (resolve, reject) {\n if (typeof OffscreenCanvas === 'undefined') {\n // if OffscreenCanvas is present, we assume browser supports Worker and built-in Promise as well\n resolve(false);\n return;\n }\n\n function workerPayload(self) {\n if (typeof createImageBitmap === 'undefined') {\n self.postMessage(false);\n return;\n }\n\n Promise.resolve().then(function () {\n var canvas = new OffscreenCanvas(10, 10); // test that 2d context can be used in worker\n\n var ctx = canvas.getContext('2d');\n ctx.rect(0, 0, 1, 1); // test that cib can be used to return image bitmap from worker\n\n return createImageBitmap(canvas, 0, 0, 1, 1);\n }).then(function () {\n return self.postMessage(true);\n }, function () {\n return self.postMessage(false);\n });\n }\n\n var code = btoa(\"(\".concat(workerPayload.toString(), \")(self);\"));\n var w = new Worker(\"data:text/javascript;base64,\".concat(code));\n\n w.onmessage = function (ev) {\n return resolve(ev.data);\n };\n\n w.onerror = reject;\n }).then(function (result) {\n return result;\n }, function () {\n return false;\n });\n}; // Check if canvas.getContext('2d').getImageData can be used,\n// FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode\n\n\nmodule.exports.can_use_canvas = function can_use_canvas(createCanvas) {\n var usable = false;\n\n try {\n var canvas = createCanvas(2, 1);\n var ctx = canvas.getContext('2d');\n var d = ctx.createImageData(2, 1);\n d.data[0] = 12;\n d.data[1] = 23;\n d.data[2] = 34;\n d.data[3] = 255;\n d.data[4] = 45;\n d.data[5] = 56;\n d.data[6] = 67;\n d.data[7] = 255;\n ctx.putImageData(d, 0, 0);\n d = null;\n d = ctx.getImageData(0, 0, 2, 1);\n\n if (d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 && d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255) {\n usable = true;\n }\n } catch (err) {}\n\n return usable;\n}; // Check if createImageBitmap(img, sx, sy, sw, sh) signature works correctly\n// with JPEG images oriented with Exif;\n// https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n// TODO: remove after it's fixed in chrome for at least 2 releases\n\n\nmodule.exports.cib_can_use_region = function cib_can_use_region() {\n return new Promise(function (resolve) {\n if (typeof createImageBitmap === 'undefined') {\n resolve(false);\n return;\n }\n\n var image = new Image();\n image.src = 'data:image/jpeg;base64,' + '/9j/4QBiRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAYAAAEaAAUAAAABAAAASgEbAAUAA' + 'AABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAAAAABIAAAAAQAAAEgAAAAB/9' + 'sAQwAEAwMEAwMEBAMEBQQEBQYKBwYGBgYNCQoICg8NEBAPDQ8OERMYFBESFxIODxUcFRc' + 'ZGRsbGxAUHR8dGh8YGhsa/9sAQwEEBQUGBQYMBwcMGhEPERoaGhoaGhoaGhoaGhoaGhoa' + 'GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa/8IAEQgAAQACAwERAAIRAQMRA' + 'f/EABQAAQAAAAAAAAAAAAAAAAAAAAf/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAA' + 'IQAxAAAAF/P//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAA' + 'AAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIB' + 'AT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAA' + 'AAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQH//EABQRAQAAAAAAAAAAAAAAAA' + 'AAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQ' + 'QAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z';\n\n image.onload = function () {\n createImageBitmap(image, 0, 0, image.width, image.height).then(function (bitmap) {\n if (bitmap.width === image.width && bitmap.height === image.height) {\n resolve(true);\n } else {\n resolve(false);\n }\n }, function () {\n return resolve(false);\n });\n };\n\n image.onerror = function () {\n return resolve(false);\n };\n });\n};\n\n},{}],17:[function(_dereq_,module,exports){\n// Web Worker wrapper for image resize function\n'use strict';\n\nmodule.exports = function () {\n var MathLib = _dereq_('./mathlib');\n\n var mathLib;\n /* eslint-disable no-undef */\n\n onmessage = function onmessage(ev) {\n var tileOpts = ev.data.opts;\n var returnBitmap = false;\n\n if (!tileOpts.src && tileOpts.srcBitmap) {\n var canvas = new OffscreenCanvas(tileOpts.width, tileOpts.height);\n var ctx = canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n ctx.drawImage(tileOpts.srcBitmap, 0, 0);\n tileOpts.src = ctx.getImageData(0, 0, tileOpts.width, tileOpts.height).data;\n canvas.width = canvas.height = 0;\n canvas = null;\n tileOpts.srcBitmap.close();\n tileOpts.srcBitmap = null; // Temporary force out data to typed array, because Chrome have artefacts\n // https://github.com/nodeca/pica/issues/223\n // returnBitmap = true;\n }\n\n if (!mathLib) mathLib = new MathLib(ev.data.features); // Use multimath's sync auto-init. Avoid Promise use in old browsers,\n // because polyfills are not propagated to webworker.\n\n var data = mathLib.resizeAndUnsharp(tileOpts);\n\n if (returnBitmap) {\n var toImageData = new ImageData(new Uint8ClampedArray(data), tileOpts.toWidth, tileOpts.toHeight);\n\n var _canvas = new OffscreenCanvas(tileOpts.toWidth, tileOpts.toHeight);\n\n var _ctx = _canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n\n _ctx.putImageData(toImageData, 0, 0);\n\n createImageBitmap(_canvas).then(function (bitmap) {\n postMessage({\n bitmap: bitmap\n }, [bitmap]);\n });\n } else {\n postMessage({\n data: data\n }, [data.buffer]);\n }\n };\n};\n\n},{\"./mathlib\":1}],18:[function(_dereq_,module,exports){\n// Calculate Gaussian blur of an image using IIR filter\n// The method is taken from Intel's white paper and code example attached to it:\n// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter\n// -implementation-using-intel-advanced-vector-extensions\n\nvar a0, a1, a2, a3, b1, b2, left_corner, right_corner;\n\nfunction gaussCoef(sigma) {\n if (sigma < 0.5) {\n sigma = 0.5;\n }\n\n var a = Math.exp(0.726 * 0.726) / sigma,\n g1 = Math.exp(-a),\n g2 = Math.exp(-2 * a),\n k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);\n\n a0 = k;\n a1 = k * (a - 1) * g1;\n a2 = k * (a + 1) * g1;\n a3 = -k * g2;\n b1 = 2 * g1;\n b2 = -g2;\n left_corner = (a0 + a1) / (1 - b1 - b2);\n right_corner = (a2 + a3) / (1 - b1 - b2);\n\n // Attempt to force type to FP32.\n return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);\n}\n\nfunction convolveMono16(src, out, line, coeff, width, height) {\n // takes src image and writes the blurred and transposed result into out\n\n var prev_src, curr_src, curr_out, prev_out, prev_prev_out;\n var src_index, out_index, line_index;\n var i, j;\n var coeff_a0, coeff_a1, coeff_b1, coeff_b2;\n\n for (i = 0; i < height; i++) {\n src_index = i * width;\n out_index = i;\n line_index = 0;\n\n // left to right\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[6];\n prev_out = prev_prev_out;\n\n coeff_a0 = coeff[0];\n coeff_a1 = coeff[1];\n coeff_b1 = coeff[4];\n coeff_b2 = coeff[5];\n\n for (j = 0; j < width; j++) {\n curr_src = src[src_index];\n\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n prev_src = curr_src;\n\n line[line_index] = prev_out;\n line_index++;\n src_index++;\n }\n\n src_index--;\n line_index--;\n out_index += height * (width - 1);\n\n // right to left\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[7];\n prev_out = prev_prev_out;\n curr_src = prev_src;\n\n coeff_a0 = coeff[2];\n coeff_a1 = coeff[3];\n\n for (j = width - 1; j >= 0; j--) {\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n\n prev_src = curr_src;\n curr_src = src[src_index];\n\n out[out_index] = line[line_index] + prev_out;\n\n src_index--;\n line_index--;\n out_index -= height;\n }\n }\n}\n\n\nfunction blurMono16(src, width, height, radius) {\n // Quick exit on zero radius\n if (!radius) { return; }\n\n var out = new Uint16Array(src.length),\n tmp_line = new Float32Array(Math.max(width, height));\n\n var coeff = gaussCoef(radius);\n\n convolveMono16(src, out, tmp_line, coeff, width, height, radius);\n convolveMono16(out, src, tmp_line, coeff, height, width, radius);\n}\n\nmodule.exports = blurMono16;\n\n},{}],19:[function(_dereq_,module,exports){\nif (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n\n},{}],20:[function(_dereq_,module,exports){\n'use strict';\n\n\nvar assign = _dereq_('object-assign');\nvar base64decode = _dereq_('./lib/base64decode');\nvar hasWebAssembly = _dereq_('./lib/wa_detect');\n\n\nvar DEFAULT_OPTIONS = {\n js: true,\n wasm: true\n};\n\n\nfunction MultiMath(options) {\n if (!(this instanceof MultiMath)) return new MultiMath(options);\n\n var opts = assign({}, DEFAULT_OPTIONS, options || {});\n\n this.options = opts;\n\n this.__cache = {};\n\n this.__init_promise = null;\n this.__modules = opts.modules || {};\n this.__memory = null;\n this.__wasm = {};\n\n this.__isLE = ((new Uint32Array((new Uint8Array([ 1, 0, 0, 0 ])).buffer))[0] === 1);\n\n if (!this.options.js && !this.options.wasm) {\n throw new Error('mathlib: at least \"js\" or \"wasm\" should be enabled');\n }\n}\n\n\nMultiMath.prototype.has_wasm = hasWebAssembly;\n\n\nMultiMath.prototype.use = function (module) {\n this.__modules[module.name] = module;\n\n // Pin the best possible implementation\n if (this.options.wasm && this.has_wasm() && module.wasm_fn) {\n this[module.name] = module.wasm_fn;\n } else {\n this[module.name] = module.fn;\n }\n\n return this;\n};\n\n\nMultiMath.prototype.init = function () {\n if (this.__init_promise) return this.__init_promise;\n\n if (!this.options.js && this.options.wasm && !this.has_wasm()) {\n return Promise.reject(new Error('mathlib: only \"wasm\" was enabled, but it\\'s not supported'));\n }\n\n var self = this;\n\n this.__init_promise = Promise.all(Object.keys(self.__modules).map(function (name) {\n var module = self.__modules[name];\n\n if (!self.options.wasm || !self.has_wasm() || !module.wasm_fn) return null;\n\n // If already compiled - exit\n if (self.__wasm[name]) return null;\n\n // Compile wasm source\n return WebAssembly.compile(self.__base64decode(module.wasm_src))\n .then(function (m) { self.__wasm[name] = m; });\n }))\n .then(function () { return self; });\n\n return this.__init_promise;\n};\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Methods below are for internal use from plugins\n\n\n// Simple decode base64 to typed array. Useful to load embedded webassembly\n// code. You probably don't need to call this method directly.\n//\nMultiMath.prototype.__base64decode = base64decode;\n\n\n// Increase current memory to include specified number of bytes. Do nothing if\n// size is already ok. You probably don't need to call this method directly,\n// because it will be invoked from `.__instance()`.\n//\nMultiMath.prototype.__reallocate = function mem_grow_to(bytes) {\n if (!this.__memory) {\n this.__memory = new WebAssembly.Memory({\n initial: Math.ceil(bytes / (64 * 1024))\n });\n return this.__memory;\n }\n\n var mem_size = this.__memory.buffer.byteLength;\n\n if (mem_size < bytes) {\n this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));\n }\n\n return this.__memory;\n};\n\n\n// Returns instantinated webassembly item by name, with specified memory size\n// and environment.\n// - use cache if available\n// - do sync module init, if async init was not called earlier\n// - allocate memory if not enougth\n// - can export functions to webassembly via \"env_extra\",\n// for example, { exp: Math.exp }\n//\nMultiMath.prototype.__instance = function instance(name, memsize, env_extra) {\n if (memsize) this.__reallocate(memsize);\n\n // If .init() was not called, do sync compile\n if (!this.__wasm[name]) {\n var module = this.__modules[name];\n this.__wasm[name] = new WebAssembly.Module(this.__base64decode(module.wasm_src));\n }\n\n if (!this.__cache[name]) {\n var env_base = {\n memoryBase: 0,\n memory: this.__memory,\n tableBase: 0,\n table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })\n };\n\n this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {\n env: assign(env_base, env_extra || {})\n });\n }\n\n return this.__cache[name];\n};\n\n\n// Helper to calculate memory aligh for pointers. Webassembly does not require\n// this, but you may wish to experiment. Default base = 8;\n//\nMultiMath.prototype.__align = function align(number, base) {\n base = base || 8;\n var reminder = number % base;\n return number + (reminder ? base - reminder : 0);\n};\n\n\nmodule.exports = MultiMath;\n\n},{\"./lib/base64decode\":21,\"./lib/wa_detect\":22,\"object-assign\":23}],21:[function(_dereq_,module,exports){\n// base64 decode str -> Uint8Array, to load WA modules\n//\n'use strict';\n\n\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n\nmodule.exports = function base64decode(str) {\n var input = str.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length;\n\n var out = new Uint8Array((max * 3) >> 2);\n\n // Collect by 6*4 bits (3 bytes)\n\n var bits = 0;\n var ptr = 0;\n\n for (var idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n }\n\n bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n var tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n } else if (tailbits === 18) {\n out[ptr++] = (bits >> 10) & 0xFF;\n out[ptr++] = (bits >> 2) & 0xFF;\n } else if (tailbits === 12) {\n out[ptr++] = (bits >> 4) & 0xFF;\n }\n\n return out;\n};\n\n},{}],22:[function(_dereq_,module,exports){\n// Detect WebAssembly support.\n// - Check global WebAssembly object\n// - Try to load simple module (can be disabled via CSP)\n//\n'use strict';\n\n\nvar wa;\n\n\nmodule.exports = function hasWebAssembly() {\n // use cache if called before;\n if (typeof wa !== 'undefined') return wa;\n\n wa = false;\n\n if (typeof WebAssembly === 'undefined') return wa;\n\n // If WebAssenbly is disabled, code can throw on compile\n try {\n // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js\n // Additional check that WA internals are correct\n\n /* eslint-disable comma-spacing, max-len */\n var bin = new Uint8Array([ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11 ]);\n var module = new WebAssembly.Module(bin);\n var instance = new WebAssembly.Instance(module, {});\n\n // test storing to and loading from a non-zero location via a parameter.\n // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations\n if (instance.exports.test(4) !== 0) wa = true;\n\n return wa;\n } catch (__) {}\n\n return wa;\n};\n\n},{}],23:[function(_dereq_,module,exports){\n/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\n},{}],24:[function(_dereq_,module,exports){\nvar bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n 'function(require,module,exports){' + fn + '(self); }',\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n 'function(require,module,exports){' +\n // try to call default if defined to also support babel esmodule exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);' +\n '}',\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n\n},{}],\"/index.js\":[function(_dereq_,module,exports){\n'use strict';\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar assign = _dereq_('object-assign');\n\nvar webworkify = _dereq_('webworkify');\n\nvar MathLib = _dereq_('./lib/mathlib');\n\nvar Pool = _dereq_('./lib/pool');\n\nvar utils = _dereq_('./lib/utils');\n\nvar worker = _dereq_('./lib/worker');\n\nvar createStages = _dereq_('./lib/stepper');\n\nvar createRegions = _dereq_('./lib/tiler'); // Deduplicate pools & limiters with the same configs\n// when user creates multiple pica instances.\n\n\nvar singletones = {};\nvar NEED_SAFARI_FIX = false;\n\ntry {\n if (typeof navigator !== 'undefined' && navigator.userAgent) {\n NEED_SAFARI_FIX = navigator.userAgent.indexOf('Safari') >= 0;\n }\n} catch (e) {}\n\nvar concurrency = 1;\n\nif (typeof navigator !== 'undefined') {\n concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);\n}\n\nvar DEFAULT_PICA_OPTS = {\n tile: 1024,\n concurrency: concurrency,\n features: ['js', 'wasm', 'ww'],\n idle: 2000,\n createCanvas: function createCanvas(width, height) {\n var tmpCanvas = document.createElement('canvas');\n tmpCanvas.width = width;\n tmpCanvas.height = height;\n return tmpCanvas;\n }\n};\nvar DEFAULT_RESIZE_OPTS = {\n quality: 3,\n alpha: false,\n unsharpAmount: 0,\n unsharpRadius: 0.0,\n unsharpThreshold: 0\n};\nvar CAN_NEW_IMAGE_DATA = false;\nvar CAN_CREATE_IMAGE_BITMAP = false;\nvar CAN_USE_CANVAS_GET_IMAGE_DATA = false;\nvar CAN_USE_OFFSCREEN_CANVAS = false;\nvar CAN_USE_CIB_REGION_FOR_IMAGE = false;\n\nfunction workerFabric() {\n return {\n value: webworkify(worker),\n destroy: function destroy() {\n this.value.terminate();\n\n if (typeof window !== 'undefined') {\n var url = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n if (url && url.revokeObjectURL && this.value.objectURL) {\n url.revokeObjectURL(this.value.objectURL);\n }\n }\n }\n };\n} ////////////////////////////////////////////////////////////////////////////////\n// API methods\n\n\nfunction Pica(options) {\n if (!(this instanceof Pica)) return new Pica(options);\n this.options = assign({}, DEFAULT_PICA_OPTS, options || {});\n var limiter_key = \"lk_\".concat(this.options.concurrency); // Share limiters to avoid multiple parallel workers when user creates\n // multiple pica instances.\n\n this.__limit = singletones[limiter_key] || utils.limiter(this.options.concurrency);\n if (!singletones[limiter_key]) singletones[limiter_key] = this.__limit; // List of supported features, according to options & browser/node.js\n\n this.features = {\n js: false,\n // pure JS implementation, can be disabled for testing\n wasm: false,\n // webassembly implementation for heavy functions\n cib: false,\n // resize via createImageBitmap (only FF at this moment)\n ww: false // webworkers\n\n };\n this.__workersPool = null; // Store requested features for webworkers\n\n this.__requested_features = [];\n this.__mathlib = null;\n}\n\nPica.prototype.init = function () {\n var _this = this;\n\n if (this.__initPromise) return this.__initPromise; // Test if we can create ImageData without canvas and memory copy\n\n if (typeof ImageData !== 'undefined' && typeof Uint8ClampedArray !== 'undefined') {\n try {\n /* eslint-disable no-new */\n new ImageData(new Uint8ClampedArray(400), 10, 10);\n CAN_NEW_IMAGE_DATA = true;\n } catch (__) {}\n } // ImageBitmap can be effective in 2 places:\n //\n // 1. Threaded jpeg unpack (basic)\n // 2. Built-in resize (blocked due problem in chrome, see issue #89)\n //\n // For basic use we also need ImageBitmap wo support .close() method,\n // see https://developer.mozilla.org/ru/docs/Web/API/ImageBitmap\n\n\n if (typeof ImageBitmap !== 'undefined') {\n if (ImageBitmap.prototype && ImageBitmap.prototype.close) {\n CAN_CREATE_IMAGE_BITMAP = true;\n } else {\n this.debug('ImageBitmap does not support .close(), disabled');\n }\n }\n\n var features = this.options.features.slice();\n\n if (features.indexOf('all') >= 0) {\n features = ['cib', 'wasm', 'js', 'ww'];\n }\n\n this.__requested_features = features;\n this.__mathlib = new MathLib(features); // Check WebWorker support if requested\n\n if (features.indexOf('ww') >= 0) {\n if (typeof window !== 'undefined' && 'Worker' in window) {\n // IE <= 11 don't allow to create webworkers from string. We should check it.\n // https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11\n try {\n var wkr = _dereq_('webworkify')(function () {});\n\n wkr.terminate();\n this.features.ww = true; // pool uniqueness depends on pool config + webworker config\n\n var wpool_key = \"wp_\".concat(JSON.stringify(this.options));\n\n if (singletones[wpool_key]) {\n this.__workersPool = singletones[wpool_key];\n } else {\n this.__workersPool = new Pool(workerFabric, this.options.idle);\n singletones[wpool_key] = this.__workersPool;\n }\n } catch (__) {}\n }\n }\n\n var initMath = this.__mathlib.init().then(function (mathlib) {\n // Copy detected features\n assign(_this.features, mathlib.features);\n });\n\n var checkCibResize;\n\n if (!CAN_CREATE_IMAGE_BITMAP) {\n checkCibResize = Promise.resolve(false);\n } else {\n checkCibResize = utils.cib_support(this.options.createCanvas).then(function (status) {\n if (_this.features.cib && features.indexOf('cib') < 0) {\n _this.debug('createImageBitmap() resize supported, but disabled by config');\n\n return;\n }\n\n if (features.indexOf('cib') >= 0) _this.features.cib = status;\n });\n }\n\n CAN_USE_CANVAS_GET_IMAGE_DATA = utils.can_use_canvas(this.options.createCanvas);\n var checkOffscreenCanvas;\n\n if (CAN_CREATE_IMAGE_BITMAP && CAN_NEW_IMAGE_DATA && features.indexOf('ww') !== -1) {\n checkOffscreenCanvas = utils.worker_offscreen_canvas_support();\n } else {\n checkOffscreenCanvas = Promise.resolve(false);\n }\n\n checkOffscreenCanvas = checkOffscreenCanvas.then(function (result) {\n CAN_USE_OFFSCREEN_CANVAS = result;\n }); // we use createImageBitmap to crop image data and pass it to workers,\n // so need to check whether function works correctly;\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n\n var checkCibRegion = utils.cib_can_use_region().then(function (result) {\n CAN_USE_CIB_REGION_FOR_IMAGE = result;\n }); // Init math lib. That's async because can load some\n\n this.__initPromise = Promise.all([initMath, checkCibResize, checkOffscreenCanvas, checkCibRegion]).then(function () {\n return _this;\n });\n return this.__initPromise;\n}; // Call resizer in webworker or locally, depending on config\n\n\nPica.prototype.__invokeResize = function (tileOpts, opts) {\n var _this2 = this;\n\n // Share cache between calls:\n //\n // - wasm instance\n // - wasm memory object\n //\n opts.__mathCache = opts.__mathCache || {};\n return Promise.resolve().then(function () {\n if (!_this2.features.ww) {\n // not possible to have ImageBitmap here if user disabled WW\n return {\n data: _this2.__mathlib.resizeAndUnsharp(tileOpts, opts.__mathCache)\n };\n }\n\n return new Promise(function (resolve, reject) {\n var w = _this2.__workersPool.acquire();\n\n if (opts.cancelToken) opts.cancelToken[\"catch\"](function (err) {\n return reject(err);\n });\n\n w.value.onmessage = function (ev) {\n w.release();\n if (ev.data.err) reject(ev.data.err);else resolve(ev.data);\n };\n\n var transfer = [];\n if (tileOpts.src) transfer.push(tileOpts.src.buffer);\n if (tileOpts.srcBitmap) transfer.push(tileOpts.srcBitmap);\n w.value.postMessage({\n opts: tileOpts,\n features: _this2.__requested_features,\n preload: {\n wasm_nodule: _this2.__mathlib.__\n }\n }, transfer);\n });\n });\n}; // this function can return promise if createImageBitmap is used\n\n\nPica.prototype.__extractTileData = function (tile, from, opts, stageEnv, extractTo) {\n if (this.features.ww && CAN_USE_OFFSCREEN_CANVAS && ( // createImageBitmap doesn't work for images (Image, ImageBitmap) with Exif orientation in Chrome,\n // can use canvas because canvas doesn't have orientation;\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n utils.isCanvas(from) || CAN_USE_CIB_REGION_FOR_IMAGE)) {\n this.debug('Create tile for OffscreenCanvas');\n return createImageBitmap(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height).then(function (bitmap) {\n extractTo.srcBitmap = bitmap;\n return extractTo;\n });\n } // Extract tile RGBA buffer, depending on input type\n\n\n if (utils.isCanvas(from)) {\n if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d', {\n alpha: Boolean(opts.alpha)\n }); // If input is Canvas - extract region data directly\n\n this.debug('Get tile pixel data');\n extractTo.src = stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data;\n return extractTo;\n } // If input is Image or decoded to ImageBitmap,\n // draw region to temporary canvas and extract data from it\n //\n // Note! Attempt to reuse this canvas causes significant slowdown in chrome\n //\n\n\n this.debug('Draw tile imageBitmap/image to temporary canvas');\n var tmpCanvas = this.options.createCanvas(tile.width, tile.height);\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.globalCompositeOperation = 'copy';\n tmpCtx.drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);\n this.debug('Get tile pixel data');\n extractTo.src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data; // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n return extractTo;\n};\n\nPica.prototype.__landTileData = function (tile, result, stageEnv) {\n var toImageData;\n this.debug('Convert raw rgba tile result to ImageData');\n\n if (result.bitmap) {\n stageEnv.toCtx.drawImage(result.bitmap, tile.toX, tile.toY);\n return null;\n }\n\n if (CAN_NEW_IMAGE_DATA) {\n // this branch is for modern browsers\n // If `new ImageData()` & Uint8ClampedArray suported\n toImageData = new ImageData(new Uint8ClampedArray(result.data), tile.toWidth, tile.toHeight);\n } else {\n // fallback for `node-canvas` and old browsers\n // (IE11 has ImageData but does not support `new ImageData()`)\n toImageData = stageEnv.toCtx.createImageData(tile.toWidth, tile.toHeight);\n\n if (toImageData.data.set) {\n toImageData.data.set(result.data);\n } else {\n // IE9 don't have `.set()`\n for (var i = toImageData.data.length - 1; i >= 0; i--) {\n toImageData.data[i] = result.data[i];\n }\n }\n }\n\n this.debug('Draw tile');\n\n if (NEED_SAFARI_FIX) {\n // Safari draws thin white stripes between tiles without this fix\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);\n } else {\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);\n }\n\n return null;\n};\n\nPica.prototype.__tileAndResize = function (from, to, opts) {\n var _this3 = this;\n\n var stageEnv = {\n srcCtx: null,\n srcImageBitmap: null,\n isImageBitmapReused: false,\n toCtx: null\n };\n\n var processTile = function processTile(tile) {\n return _this3.__limit(function () {\n if (opts.canceled) return opts.cancelToken;\n var tileOpts = {\n width: tile.width,\n height: tile.height,\n toWidth: tile.toWidth,\n toHeight: tile.toHeight,\n scaleX: tile.scaleX,\n scaleY: tile.scaleY,\n offsetX: tile.offsetX,\n offsetY: tile.offsetY,\n quality: opts.quality,\n alpha: opts.alpha,\n unsharpAmount: opts.unsharpAmount,\n unsharpRadius: opts.unsharpRadius,\n unsharpThreshold: opts.unsharpThreshold\n };\n\n _this3.debug('Invoke resize math');\n\n return Promise.resolve(tileOpts).then(function (tileOpts) {\n return _this3.__extractTileData(tile, from, opts, stageEnv, tileOpts);\n }).then(function (tileOpts) {\n _this3.debug('Invoke resize math');\n\n return _this3.__invokeResize(tileOpts, opts);\n }).then(function (result) {\n if (opts.canceled) return opts.cancelToken;\n stageEnv.srcImageData = null;\n return _this3.__landTileData(tile, result, stageEnv);\n });\n });\n }; // Need to normalize data source first. It can be canvas or image.\n // If image - try to decode in background if possible\n\n\n return Promise.resolve().then(function () {\n stageEnv.toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n if (utils.isCanvas(from)) return null;\n\n if (utils.isImageBitmap(from)) {\n stageEnv.srcImageBitmap = from;\n stageEnv.isImageBitmapReused = true;\n return null;\n }\n\n if (utils.isImage(from)) {\n // try do decode image in background for faster next operations;\n // if we're using offscreen canvas, cib is called per tile, so not needed here\n if (!CAN_CREATE_IMAGE_BITMAP) return null;\n\n _this3.debug('Decode image via createImageBitmap');\n\n return createImageBitmap(from).then(function (imageBitmap) {\n stageEnv.srcImageBitmap = imageBitmap;\n }) // Suppress error to use fallback, if method fails\n // https://github.com/nodeca/pica/issues/190\n\n /* eslint-disable no-unused-vars */\n [\"catch\"](function (e) {\n return null;\n });\n }\n\n throw new Error('Pica: \".from\" should be Image, Canvas or ImageBitmap');\n }).then(function () {\n if (opts.canceled) return opts.cancelToken;\n\n _this3.debug('Calculate tiles'); //\n // Here we are with \"normalized\" source,\n // follow to tiling\n //\n\n\n var regions = createRegions({\n width: opts.width,\n height: opts.height,\n srcTileSize: _this3.options.tile,\n toWidth: opts.toWidth,\n toHeight: opts.toHeight,\n destTileBorder: opts.__destTileBorder\n });\n var jobs = regions.map(function (tile) {\n return processTile(tile);\n });\n\n function cleanup(stageEnv) {\n if (stageEnv.srcImageBitmap) {\n if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close();\n stageEnv.srcImageBitmap = null;\n }\n }\n\n _this3.debug('Process tiles');\n\n return Promise.all(jobs).then(function () {\n _this3.debug('Finished!');\n\n cleanup(stageEnv);\n return to;\n }, function (err) {\n cleanup(stageEnv);\n throw err;\n });\n });\n};\n\nPica.prototype.__processStages = function (stages, from, to, opts) {\n var _this4 = this;\n\n if (opts.canceled) return opts.cancelToken;\n\n var _stages$shift = stages.shift(),\n _stages$shift2 = _slicedToArray(_stages$shift, 2),\n toWidth = _stages$shift2[0],\n toHeight = _stages$shift2[1];\n\n var isLastStage = stages.length === 0;\n opts = assign({}, opts, {\n toWidth: toWidth,\n toHeight: toHeight,\n // only use user-defined quality for the last stage,\n // use simpler (Hamming) filter for the first stages where\n // scale factor is large enough (more than 2-3)\n quality: isLastStage ? opts.quality : Math.min(1, opts.quality)\n });\n var tmpCanvas;\n\n if (!isLastStage) {\n // create temporary canvas\n tmpCanvas = this.options.createCanvas(toWidth, toHeight);\n }\n\n return this.__tileAndResize(from, isLastStage ? to : tmpCanvas, opts).then(function () {\n if (isLastStage) return to;\n opts.width = toWidth;\n opts.height = toHeight;\n return _this4.__processStages(stages, tmpCanvas, to, opts);\n }).then(function (res) {\n if (tmpCanvas) {\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0;\n }\n\n return res;\n });\n};\n\nPica.prototype.__resizeViaCreateImageBitmap = function (from, to, opts) {\n var _this5 = this;\n\n var toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n this.debug('Resize via createImageBitmap()');\n return createImageBitmap(from, {\n resizeWidth: opts.toWidth,\n resizeHeight: opts.toHeight,\n resizeQuality: utils.cib_quality_name(opts.quality)\n }).then(function (imageBitmap) {\n if (opts.canceled) return opts.cancelToken; // if no unsharp - draw directly to output canvas\n\n if (!opts.unsharpAmount) {\n toCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n }\n\n _this5.debug('Unsharp result');\n\n var tmpCanvas = _this5.options.createCanvas(opts.toWidth, opts.toHeight);\n\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);\n\n _this5.__mathlib.unsharp_mask(iData.data, opts.toWidth, opts.toHeight, opts.unsharpAmount, opts.unsharpRadius, opts.unsharpThreshold);\n\n toCtx.putImageData(iData, 0, 0); // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n iData = tmpCtx = tmpCanvas = toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n });\n};\n\nPica.prototype.resize = function (from, to, options) {\n var _this6 = this;\n\n this.debug('Start resize...');\n var opts = assign({}, DEFAULT_RESIZE_OPTS);\n\n if (!isNaN(options)) {\n opts = assign(opts, {\n quality: options\n });\n } else if (options) {\n opts = assign(opts, options);\n }\n\n opts.toWidth = to.width;\n opts.toHeight = to.height;\n opts.width = from.naturalWidth || from.width;\n opts.height = from.naturalHeight || from.height; // Prevent stepper from infinite loop\n\n if (to.width === 0 || to.height === 0) {\n return Promise.reject(new Error(\"Invalid output size: \".concat(to.width, \"x\").concat(to.height)));\n }\n\n if (opts.unsharpRadius > 2) opts.unsharpRadius = 2;\n opts.canceled = false;\n\n if (opts.cancelToken) {\n // Wrap cancelToken to avoid successive resolve & set flag\n opts.cancelToken = opts.cancelToken.then(function (data) {\n opts.canceled = true;\n throw data;\n }, function (err) {\n opts.canceled = true;\n throw err;\n });\n }\n\n var DEST_TILE_BORDER = 3; // Max possible filter window size\n\n opts.__destTileBorder = Math.ceil(Math.max(DEST_TILE_BORDER, 2.5 * opts.unsharpRadius | 0));\n return this.init().then(function () {\n if (opts.canceled) return opts.cancelToken; // if createImageBitmap supports resize, just do it and return\n\n if (_this6.features.cib) {\n return _this6.__resizeViaCreateImageBitmap(from, to, opts);\n }\n\n if (!CAN_USE_CANVAS_GET_IMAGE_DATA) {\n var err = new Error('Pica: cannot use getImageData on canvas, ' + \"make sure fingerprinting protection isn't enabled\");\n err.code = 'ERR_GET_IMAGE_DATA';\n throw err;\n } //\n // No easy way, let's resize manually via arrays\n //\n\n\n var stages = createStages(opts.width, opts.height, opts.toWidth, opts.toHeight, _this6.options.tile, opts.__destTileBorder);\n return _this6.__processStages(stages, from, to, opts);\n });\n}; // RGBA buffer resize\n//\n\n\nPica.prototype.resizeBuffer = function (options) {\n var _this7 = this;\n\n var opts = assign({}, DEFAULT_RESIZE_OPTS, options);\n return this.init().then(function () {\n return _this7.__mathlib.resizeAndUnsharp(opts);\n });\n};\n\nPica.prototype.toBlob = function (canvas, mimeType, quality) {\n mimeType = mimeType || 'image/png';\n return new Promise(function (resolve) {\n if (canvas.toBlob) {\n canvas.toBlob(function (blob) {\n return resolve(blob);\n }, mimeType, quality);\n return;\n }\n\n if (canvas.convertToBlob) {\n resolve(canvas.convertToBlob({\n type: mimeType,\n quality: quality\n }));\n return;\n } // Fallback for old browsers\n\n\n var asString = atob(canvas.toDataURL(mimeType, quality).split(',')[1]);\n var len = asString.length;\n var asBuffer = new Uint8Array(len);\n\n for (var i = 0; i < len; i++) {\n asBuffer[i] = asString.charCodeAt(i);\n }\n\n resolve(new Blob([asBuffer], {\n type: mimeType\n }));\n });\n};\n\nPica.prototype.debug = function () {};\n\nmodule.exports = Pica;\n\n},{\"./lib/mathlib\":1,\"./lib/pool\":13,\"./lib/stepper\":14,\"./lib/tiler\":15,\"./lib/utils\":16,\"./lib/worker\":17,\"object-assign\":23,\"webworkify\":24}]},{},[])(\"/index.js\")\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3BpY2EvZGlzdC9waWNhLmpzLmpzIiwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsYUFBYSxHQUFHLElBQXNELEVBQUUsbUJBQW1CLEtBQUssVUFBNk4sQ0FBQyxhQUFhLDBCQUEwQixtQkFBbUIsa0JBQWtCLGdCQUFnQixVQUFVLFVBQVUsTUFBTSxTQUFtQyxDQUFDLGdCQUFnQixPQUFDLE9BQU8sb0JBQW9CLDhDQUE4QyxrQ0FBa0MsWUFBWSxZQUFZLG1DQUFtQyxpQkFBaUIsZUFBZSxzQkFBc0Isb0JBQW9CLFVBQVUsU0FBbUMsS0FBSyxXQUFXLFlBQVksU0FBUyxTQUFTLEtBQUs7QUFDenpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSxtRUFBbUU7QUFDdEU7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7O0FBRXRCLGlCQUFpQixhQUFhO0FBQzlCLG1CQUFtQjs7QUFFbkIsb0JBQW9CLGVBQWU7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7O0FBRXpCLGFBQWEsZ0JBQWdCO0FBQzdCLDBDQUEwQztBQUMxQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUVBOztBQUVBLENBQUMsRUFBRSw0SUFBNEksRUFBRSxHQUFHO0FBQ3BKLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3BpY2EvZGlzdC9waWNhLmpzP2ZmNTkiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG5cbnBpY2Fcbmh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYVxuXG4qL1xuXG4oZnVuY3Rpb24oZil7aWYodHlwZW9mIGV4cG9ydHM9PT1cIm9iamVjdFwiJiZ0eXBlb2YgbW9kdWxlIT09XCJ1bmRlZmluZWRcIil7bW9kdWxlLmV4cG9ydHM9ZigpfWVsc2UgaWYodHlwZW9mIGRlZmluZT09PVwiZnVuY3Rpb25cIiYmZGVmaW5lLmFtZCl7ZGVmaW5lKFtdLGYpfWVsc2V7dmFyIGc7aWYodHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCIpe2c9d2luZG93fWVsc2UgaWYodHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCIpe2c9Z2xvYmFsfWVsc2UgaWYodHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiKXtnPXNlbGZ9ZWxzZXtnPXRoaXN9Zy5waWNhID0gZigpfX0pKGZ1bmN0aW9uKCl7dmFyIGRlZmluZSxtb2R1bGUsZXhwb3J0cztyZXR1cm4gKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSh7MTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBDb2xsZWN0aW9uIG9mIG1hdGggZnVuY3Rpb25zXG4vL1xuLy8gMS4gQ29tYmluZSBjb21wb25lbnRzIHRvZ2V0aGVyXG4vLyAyLiBIYXMgYXN5bmMgaW5pdCB0byBsb2FkIHdhc20gbW9kdWxlc1xuLy9cbid1c2Ugc3RyaWN0JztcblxudmFyIGluaGVyaXRzID0gX2RlcmVxXygnaW5oZXJpdHMnKTtcblxudmFyIE11bHRpbWF0aCA9IF9kZXJlcV8oJ211bHRpbWF0aCcpO1xuXG52YXIgbW1fdW5zaGFycF9tYXNrID0gX2RlcmVxXygnLi9tbV91bnNoYXJwX21hc2snKTtcblxudmFyIG1tX3Jlc2l6ZSA9IF9kZXJlcV8oJy4vbW1fcmVzaXplJyk7XG5cbmZ1bmN0aW9uIE1hdGhMaWIocmVxdWVzdGVkX2ZlYXR1cmVzKSB7XG4gIHZhciBfX3JlcXVlc3RlZF9mZWF0dXJlcyA9IHJlcXVlc3RlZF9mZWF0dXJlcyB8fCBbXTtcblxuICB2YXIgZmVhdHVyZXMgPSB7XG4gICAganM6IF9fcmVxdWVzdGVkX2ZlYXR1cmVzLmluZGV4T2YoJ2pzJykgPj0gMCxcbiAgICB3YXNtOiBfX3JlcXVlc3RlZF9mZWF0dXJlcy5pbmRleE9mKCd3YXNtJykgPj0gMFxuICB9O1xuICBNdWx0aW1hdGguY2FsbCh0aGlzLCBmZWF0dXJlcyk7XG4gIHRoaXMuZmVhdHVyZXMgPSB7XG4gICAganM6IGZlYXR1cmVzLmpzLFxuICAgIHdhc206IGZlYXR1cmVzLndhc20gJiYgdGhpcy5oYXNfd2FzbSgpXG4gIH07XG4gIHRoaXMudXNlKG1tX3Vuc2hhcnBfbWFzayk7XG4gIHRoaXMudXNlKG1tX3Jlc2l6ZSk7XG59XG5cbmluaGVyaXRzKE1hdGhMaWIsIE11bHRpbWF0aCk7XG5cbk1hdGhMaWIucHJvdG90eXBlLnJlc2l6ZUFuZFVuc2hhcnAgPSBmdW5jdGlvbiByZXNpemVBbmRVbnNoYXJwKG9wdGlvbnMsIGNhY2hlKSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLnJlc2l6ZShvcHRpb25zLCBjYWNoZSk7XG5cbiAgaWYgKG9wdGlvbnMudW5zaGFycEFtb3VudCkge1xuICAgIHRoaXMudW5zaGFycF9tYXNrKHJlc3VsdCwgb3B0aW9ucy50b1dpZHRoLCBvcHRpb25zLnRvSGVpZ2h0LCBvcHRpb25zLnVuc2hhcnBBbW91bnQsIG9wdGlvbnMudW5zaGFycFJhZGl1cywgb3B0aW9ucy51bnNoYXJwVGhyZXNob2xkKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGhMaWI7XG5cbn0se1wiLi9tbV9yZXNpemVcIjo0LFwiLi9tbV91bnNoYXJwX21hc2tcIjo5LFwiaW5oZXJpdHNcIjoxOSxcIm11bHRpbWF0aFwiOjIwfV0sMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBSZXNpemUgY29udm9sdmVycywgcHVyZSBKUyBpbXBsZW1lbnRhdGlvblxuLy9cbid1c2Ugc3RyaWN0JzsgLy8gUHJlY2lzaW9uIG9mIGZpeGVkIEZQIHZhbHVlc1xuLy92YXIgRklYRURfRlJBQ19CSVRTID0gMTQ7XG5cbmZ1bmN0aW9uIGNsYW1wVG84KGkpIHtcbiAgcmV0dXJuIGkgPCAwID8gMCA6IGkgPiAyNTUgPyAyNTUgOiBpO1xufSAvLyBDb252b2x2ZSBpbWFnZSBpbiBob3Jpem9udGFsIGRpcmVjdGlvbnMgYW5kIHRyYW5zcG9zZSBvdXRwdXQuIEluIHRoZW9yeSxcbi8vIHRyYW5zcG9zZSBhbGxvdzpcbi8vXG4vLyAtIHVzZSB0aGUgc2FtZSBjb252b2x2ZXIgZm9yIGJvdGggcGFzc2VzICh0aGlzIGZhaWxzIGR1ZSBkaWZmZXJlbnRcbi8vICAgdHlwZXMgb2YgaW5wdXQgYXJyYXkgYW5kIHRlbXBvcmFyeSBidWZmZXIpXG4vLyAtIG1ha2luZyB2ZXJ0aWNhbCBwYXNzIGJ5IGhvcmlzb25sdGFsIGxpbmVzIGlucHJvdmUgQ1BVIGNhY2hlIHVzZS5cbi8vXG4vLyBCdXQgaW4gcmVhbCBsaWZlIHRoaXMgZG9lc24ndCB3b3JrIDopXG4vL1xuXG5cbmZ1bmN0aW9uIGNvbnZvbHZlSG9yaXpvbnRhbGx5KHNyYywgZGVzdCwgc3JjVywgc3JjSCwgZGVzdFcsIGZpbHRlcnMpIHtcbiAgdmFyIHIsIGcsIGIsIGE7XG4gIHZhciBmaWx0ZXJQdHIsIGZpbHRlclNoaWZ0LCBmaWx0ZXJTaXplO1xuICB2YXIgc3JjUHRyLCBzcmNZLCBkZXN0WCwgZmlsdGVyVmFsO1xuICB2YXIgc3JjT2Zmc2V0ID0gMCxcbiAgICAgIGRlc3RPZmZzZXQgPSAwOyAvLyBGb3IgZWFjaCByb3dcblxuICBmb3IgKHNyY1kgPSAwOyBzcmNZIDwgc3JjSDsgc3JjWSsrKSB7XG4gICAgZmlsdGVyUHRyID0gMDsgLy8gQXBwbHkgcHJlY29tcHV0ZWQgZmlsdGVycyB0byBlYWNoIGRlc3RpbmF0aW9uIHJvdyBwb2ludFxuXG4gICAgZm9yIChkZXN0WCA9IDA7IGRlc3RYIDwgZGVzdFc7IGRlc3RYKyspIHtcbiAgICAgIC8vIEdldCB0aGUgZmlsdGVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgY3VycmVudCBvdXRwdXQgcGl4ZWwuXG4gICAgICBmaWx0ZXJTaGlmdCA9IGZpbHRlcnNbZmlsdGVyUHRyKytdO1xuICAgICAgZmlsdGVyU2l6ZSA9IGZpbHRlcnNbZmlsdGVyUHRyKytdO1xuICAgICAgc3JjUHRyID0gc3JjT2Zmc2V0ICsgZmlsdGVyU2hpZnQgKiA0IHwgMDtcbiAgICAgIHIgPSBnID0gYiA9IGEgPSAwOyAvLyBBcHBseSB0aGUgZmlsdGVyIHRvIHRoZSByb3cgdG8gZ2V0IHRoZSBkZXN0aW5hdGlvbiBwaXhlbCByLCBnLCBiLCBhXG5cbiAgICAgIGZvciAoOyBmaWx0ZXJTaXplID4gMDsgZmlsdGVyU2l6ZS0tKSB7XG4gICAgICAgIGZpbHRlclZhbCA9IGZpbHRlcnNbZmlsdGVyUHRyKytdOyAvLyBVc2UgcmV2ZXJzZSBvcmRlciB0byB3b3JrYXJvdW5kIGRlb3B0cyBpbiBvbGQgdjggKG5vZGUgdi4xMClcbiAgICAgICAgLy8gQmlnIHRoYW5rcyB0byBAbXJhbGVwaCAoVnlhY2hlc2xhdiBFZ29yb3YpIGZvciB0aGUgdGlwLlxuXG4gICAgICAgIGEgPSBhICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDNdIHwgMDtcbiAgICAgICAgYiA9IGIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgMl0gfCAwO1xuICAgICAgICBnID0gZyArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAxXSB8IDA7XG4gICAgICAgIHIgPSByICsgZmlsdGVyVmFsICogc3JjW3NyY1B0cl0gfCAwO1xuICAgICAgICBzcmNQdHIgPSBzcmNQdHIgKyA0IHwgMDtcbiAgICAgIH0gLy8gQnJpbmcgdGhpcyB2YWx1ZSBiYWNrIGluIHJhbmdlLiBBbGwgb2YgdGhlIGZpbHRlciBzY2FsaW5nIGZhY3RvcnNcbiAgICAgIC8vIGFyZSBpbiBmaXhlZCBwb2ludCB3aXRoIEZJWEVEX0ZSQUNfQklUUyBiaXRzIG9mIGZyYWN0aW9uYWwgcGFydC5cbiAgICAgIC8vXG4gICAgICAvLyAoISkgQWRkIDEvMiBvZiB2YWx1ZSBiZWZvcmUgY2xhbXBpbmcgdG8gZ2V0IHByb3BlciByb3VuZGluZy4gSW4gb3RoZXJcbiAgICAgIC8vIGNhc2UgYnJpZ2h0bmVzcyBsb3NzIHdpbGwgYmUgbm90aWNlYWJsZSBpZiB5b3UgcmVzaXplIGltYWdlIHdpdGggd2hpdGVcbiAgICAgIC8vIGJvcmRlciBhbmQgcGxhY2UgaXQgb24gd2hpdGUgYmFja2dyb3VuZC5cbiAgICAgIC8vXG5cblxuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgM10gPSBjbGFtcFRvOChhICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgMl0gPSBjbGFtcFRvOChiICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgMV0gPSBjbGFtcFRvOChnICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0XSA9IGNsYW1wVG84KHIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0T2Zmc2V0ID0gZGVzdE9mZnNldCArIHNyY0ggKiA0IHwgMDtcbiAgICB9XG5cbiAgICBkZXN0T2Zmc2V0ID0gKHNyY1kgKyAxKSAqIDQgfCAwO1xuICAgIHNyY09mZnNldCA9IChzcmNZICsgMSkgKiBzcmNXICogNCB8IDA7XG4gIH1cbn0gLy8gVGVjaG5pY2FsbHksIGNvbnZvbHZlcnMgYXJlIHRoZSBzYW1lLiBCdXQgaW5wdXQgYXJyYXkgYW5kIHRlbXBvcmFyeVxuLy8gYnVmZmVyIGNhbiBiZSBvZiBkaWZmZXJlbnQgdHlwZSAoZXNwZWNpYWxseSwgaW4gb2xkIGJyb3dzZXJzKS4gU28sXG4vLyBrZWVwIGNvZGUgaW4gc2VwYXJhdGUgZnVuY3Rpb25zIHRvIGF2b2lkIGRlb3B0aW1pemF0aW9ucyAmIHNwZWVkIGxvc3MuXG5cblxuZnVuY3Rpb24gY29udm9sdmVWZXJ0aWNhbGx5KHNyYywgZGVzdCwgc3JjVywgc3JjSCwgZGVzdFcsIGZpbHRlcnMpIHtcbiAgdmFyIHIsIGcsIGIsIGE7XG4gIHZhciBmaWx0ZXJQdHIsIGZpbHRlclNoaWZ0LCBmaWx0ZXJTaXplO1xuICB2YXIgc3JjUHRyLCBzcmNZLCBkZXN0WCwgZmlsdGVyVmFsO1xuICB2YXIgc3JjT2Zmc2V0ID0gMCxcbiAgICAgIGRlc3RPZmZzZXQgPSAwOyAvLyBGb3IgZWFjaCByb3dcblxuICBmb3IgKHNyY1kgPSAwOyBzcmNZIDwgc3JjSDsgc3JjWSsrKSB7XG4gICAgZmlsdGVyUHRyID0gMDsgLy8gQXBwbHkgcHJlY29tcHV0ZWQgZmlsdGVycyB0byBlYWNoIGRlc3RpbmF0aW9uIHJvdyBwb2ludFxuXG4gICAgZm9yIChkZXN0WCA9IDA7IGRlc3RYIDwgZGVzdFc7IGRlc3RYKyspIHtcbiAgICAgIC8vIEdldCB0aGUgZmlsdGVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgY3VycmVudCBvdXRwdXQgcGl4ZWwuXG4gICAgICBmaWx0ZXJTaGlmdCA9IGZpbHRlcnNbZmlsdGVyUHRyKytdO1xuICAgICAgZmlsdGVyU2l6ZSA9IGZpbHRlcnNbZmlsdGVyUHRyKytdO1xuICAgICAgc3JjUHRyID0gc3JjT2Zmc2V0ICsgZmlsdGVyU2hpZnQgKiA0IHwgMDtcbiAgICAgIHIgPSBnID0gYiA9IGEgPSAwOyAvLyBBcHBseSB0aGUgZmlsdGVyIHRvIHRoZSByb3cgdG8gZ2V0IHRoZSBkZXN0aW5hdGlvbiBwaXhlbCByLCBnLCBiLCBhXG5cbiAgICAgIGZvciAoOyBmaWx0ZXJTaXplID4gMDsgZmlsdGVyU2l6ZS0tKSB7XG4gICAgICAgIGZpbHRlclZhbCA9IGZpbHRlcnNbZmlsdGVyUHRyKytdOyAvLyBVc2UgcmV2ZXJzZSBvcmRlciB0byB3b3JrYXJvdW5kIGRlb3B0cyBpbiBvbGQgdjggKG5vZGUgdi4xMClcbiAgICAgICAgLy8gQmlnIHRoYW5rcyB0byBAbXJhbGVwaCAoVnlhY2hlc2xhdiBFZ29yb3YpIGZvciB0aGUgdGlwLlxuXG4gICAgICAgIGEgPSBhICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDNdIHwgMDtcbiAgICAgICAgYiA9IGIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgMl0gfCAwO1xuICAgICAgICBnID0gZyArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAxXSB8IDA7XG4gICAgICAgIHIgPSByICsgZmlsdGVyVmFsICogc3JjW3NyY1B0cl0gfCAwO1xuICAgICAgICBzcmNQdHIgPSBzcmNQdHIgKyA0IHwgMDtcbiAgICAgIH0gLy8gQnJpbmcgdGhpcyB2YWx1ZSBiYWNrIGluIHJhbmdlLiBBbGwgb2YgdGhlIGZpbHRlciBzY2FsaW5nIGZhY3RvcnNcbiAgICAgIC8vIGFyZSBpbiBmaXhlZCBwb2ludCB3aXRoIEZJWEVEX0ZSQUNfQklUUyBiaXRzIG9mIGZyYWN0aW9uYWwgcGFydC5cbiAgICAgIC8vXG4gICAgICAvLyAoISkgQWRkIDEvMiBvZiB2YWx1ZSBiZWZvcmUgY2xhbXBpbmcgdG8gZ2V0IHByb3BlciByb3VuZGluZy4gSW4gb3RoZXJcbiAgICAgIC8vIGNhc2UgYnJpZ2h0bmVzcyBsb3NzIHdpbGwgYmUgbm90aWNlYWJsZSBpZiB5b3UgcmVzaXplIGltYWdlIHdpdGggd2hpdGVcbiAgICAgIC8vIGJvcmRlciBhbmQgcGxhY2UgaXQgb24gd2hpdGUgYmFja2dyb3VuZC5cbiAgICAgIC8vXG5cblxuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgM10gPSBjbGFtcFRvOChhICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgMl0gPSBjbGFtcFRvOChiICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgMV0gPSBjbGFtcFRvOChnICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0XSA9IGNsYW1wVG84KHIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0T2Zmc2V0ID0gZGVzdE9mZnNldCArIHNyY0ggKiA0IHwgMDtcbiAgICB9XG5cbiAgICBkZXN0T2Zmc2V0ID0gKHNyY1kgKyAxKSAqIDQgfCAwO1xuICAgIHNyY09mZnNldCA9IChzcmNZICsgMSkgKiBzcmNXICogNCB8IDA7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNvbnZvbHZlSG9yaXpvbnRhbGx5OiBjb252b2x2ZUhvcml6b250YWxseSxcbiAgY29udm9sdmVWZXJ0aWNhbGx5OiBjb252b2x2ZVZlcnRpY2FsbHlcbn07XG5cbn0se31dLDM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gVGhpcyBpcyBhdXRvZ2VuZXJhdGVkIGZpbGUgZnJvbSBtYXRoLndhc20sIGRvbid0IGVkaXQuXG4vL1xuJ3VzZSBzdHJpY3QnO1xuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9ICdBR0Z6YlFFQUFBQUFEQVprZVd4cGJtc0FBQUFBQUFFWEEyQUFBR0FHZjM5L2YzOS9BR0FIZjM5L2YzOS9md0FDRHdFRFpXNTJCbTFsYlc5eWVRSUFBQU1FQXdBQkFnWUdBWDhBUVFBTEIxY0ZFVjlmZDJGemJWOWpZV3hzWDJOMGIzSnpBQUFJWTI5dWRtOXNkbVVBQVFwamIyNTJiMngyWlVoV0FBSU1YMTlrYzI5ZmFHRnVaR3hsQXdBWVgxOTNZWE50WDJGd2NHeDVYMlJoZEdGZmNtVnNiMk56QUFBSzdBTURBd0FCQzhZREFROS9Ba0FnQTBVTkFDQUVSUTBBQTBBZ0RDRU5RUUFoRTBFQUlRY0RRQ0FIUVFKcUlRWUNmeUFIUVFGMElBVnFJZ2N1QVFJaUZFVUVRRUdBd0FBaENFR0F3QUFoQ1VHQXdBQWhDa0dBd0FBaEN5QUdEQUVMSUJJZ0J5NEJBR29oQ0VFQUlRc2dGQ0VIUVFBaERpQUdJUWxCQUNFUFFRQWhFQU5BSUFVZ0NVRUJkR291QVFBaUVTQUFJQWhCQW5ScUtBSUFJZ3BCR0hac0lCQnFJUkFnQ2tIL0FYRWdFV3dnQzJvaEN5QUtRUkIyUWY4QmNTQVJiQ0FQYWlFUElBcEJDSFpCL3dGeElCRnNJQTVxSVE0Z0NFRUJhaUVJSUFsQkFXb2hDU0FIUVFGcklnY05BQXNnQzBHQVFHc2hDQ0FPUVlCQWF5RUpJQTlCZ0VCcklRb2dFRUdBUUdzaEN5QUdJQlJxQ3lFSElBRWdEVUVDZEdvZ0NVRU9kU0lHUWY4QklBWkIvd0ZJR3lJR1FRQWdCa0VBU2h0QkNIUkJnUDREY1NBS1FRNTFJZ1pCL3dFZ0JrSC9BVWdiSWdaQkFDQUdRUUJLRzBFUWRFR0FnUHdIY1NBTFFRNTFJZ1pCL3dFZ0JrSC9BVWdiSWdaQkFDQUdRUUJLRzBFWWRISnlJQWhCRG5VaUJrSC9BU0FHUWY4QlNCc2lCa0VBSUFaQkFFb2JjallDQUNBRElBMXFJUTBnRTBFQmFpSVRJQVJIRFFBTElBeEJBV29pRENBQ2JDRVNJQU1nREVjTkFBc0xDeDRBUVFBZ0FpQURJQVFnQlNBQUVBRWdBa0VBSUFRZ0JTQUdJQUVRQVFzPSc7XG5cbn0se31dLDQ6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbmFtZTogJ3Jlc2l6ZScsXG4gIGZuOiBfZGVyZXFfKCcuL3Jlc2l6ZScpLFxuICB3YXNtX2ZuOiBfZGVyZXFfKCcuL3Jlc2l6ZV93YXNtJyksXG4gIHdhc21fc3JjOiBfZGVyZXFfKCcuL2NvbnZvbHZlX3dhc21fYmFzZTY0Jylcbn07XG5cbn0se1wiLi9jb252b2x2ZV93YXNtX2Jhc2U2NFwiOjMsXCIuL3Jlc2l6ZVwiOjUsXCIuL3Jlc2l6ZV93YXNtXCI6OH1dLDU6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3JlYXRlRmlsdGVycyA9IF9kZXJlcV8oJy4vcmVzaXplX2ZpbHRlcl9nZW4nKTtcblxudmFyIGNvbnZvbHZlSG9yaXpvbnRhbGx5ID0gX2RlcmVxXygnLi9jb252b2x2ZScpLmNvbnZvbHZlSG9yaXpvbnRhbGx5O1xuXG52YXIgY29udm9sdmVWZXJ0aWNhbGx5ID0gX2RlcmVxXygnLi9jb252b2x2ZScpLmNvbnZvbHZlVmVydGljYWxseTtcblxuZnVuY3Rpb24gcmVzZXRBbHBoYShkc3QsIHdpZHRoLCBoZWlnaHQpIHtcbiAgdmFyIHB0ciA9IDMsXG4gICAgICBsZW4gPSB3aWR0aCAqIGhlaWdodCAqIDQgfCAwO1xuXG4gIHdoaWxlIChwdHIgPCBsZW4pIHtcbiAgICBkc3RbcHRyXSA9IDB4RkY7XG4gICAgcHRyID0gcHRyICsgNCB8IDA7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXNpemUob3B0aW9ucykge1xuICB2YXIgc3JjID0gb3B0aW9ucy5zcmM7XG4gIHZhciBzcmNXID0gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNyY0ggPSBvcHRpb25zLmhlaWdodDtcbiAgdmFyIGRlc3RXID0gb3B0aW9ucy50b1dpZHRoO1xuICB2YXIgZGVzdEggPSBvcHRpb25zLnRvSGVpZ2h0O1xuICB2YXIgc2NhbGVYID0gb3B0aW9ucy5zY2FsZVggfHwgb3B0aW9ucy50b1dpZHRoIC8gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNjYWxlWSA9IG9wdGlvbnMuc2NhbGVZIHx8IG9wdGlvbnMudG9IZWlnaHQgLyBvcHRpb25zLmhlaWdodDtcbiAgdmFyIG9mZnNldFggPSBvcHRpb25zLm9mZnNldFggfHwgMDtcbiAgdmFyIG9mZnNldFkgPSBvcHRpb25zLm9mZnNldFkgfHwgMDtcbiAgdmFyIGRlc3QgPSBvcHRpb25zLmRlc3QgfHwgbmV3IFVpbnQ4QXJyYXkoZGVzdFcgKiBkZXN0SCAqIDQpO1xuICB2YXIgcXVhbGl0eSA9IHR5cGVvZiBvcHRpb25zLnF1YWxpdHkgPT09ICd1bmRlZmluZWQnID8gMyA6IG9wdGlvbnMucXVhbGl0eTtcbiAgdmFyIGFscGhhID0gb3B0aW9ucy5hbHBoYSB8fCBmYWxzZTtcbiAgdmFyIGZpbHRlcnNYID0gY3JlYXRlRmlsdGVycyhxdWFsaXR5LCBzcmNXLCBkZXN0Vywgc2NhbGVYLCBvZmZzZXRYKSxcbiAgICAgIGZpbHRlcnNZID0gY3JlYXRlRmlsdGVycyhxdWFsaXR5LCBzcmNILCBkZXN0SCwgc2NhbGVZLCBvZmZzZXRZKTtcbiAgdmFyIHRtcCA9IG5ldyBVaW50OEFycmF5KGRlc3RXICogc3JjSCAqIDQpOyAvLyBUbyB1c2Ugc2luZ2xlIGZ1bmN0aW9uIHdlIG5lZWQgc3JjICYgdG1wIG9mIHRoZSBzYW1lIHR5cGUuXG4gIC8vIEJ1dCBzcmMgY2FuIGJlIENhbnZhc1BpeGVsQXJyYXksIGFuZCB0bXAgLSBVaW50OEFycmF5LiBTbywga2VlcFxuICAvLyB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCBwYXNzZXMgc2VwYXJhdGVseSB0byBhdm9pZCBkZW9wdGltaXphdGlvbi5cblxuICBjb252b2x2ZUhvcml6b250YWxseShzcmMsIHRtcCwgc3JjVywgc3JjSCwgZGVzdFcsIGZpbHRlcnNYKTtcbiAgY29udm9sdmVWZXJ0aWNhbGx5KHRtcCwgZGVzdCwgc3JjSCwgZGVzdFcsIGRlc3RILCBmaWx0ZXJzWSk7IC8vIFRoYXQncyBmYXN0ZXIgdGhhbiBkb2luZyBjaGVja3MgaW4gY29udm9sdmVyLlxuICAvLyAhISEgTm90ZSwgY2FudmFzIGRhdGEgaXMgbm90IHByZW11bHRpcGxlZC4gV2UgZG9uJ3QgbmVlZCBvdGhlclxuICAvLyBhbHBoYSBjb3JyZWN0aW9ucy5cblxuICBpZiAoIWFscGhhKSByZXNldEFscGhhKGRlc3QsIGRlc3RXLCBkZXN0SCk7XG4gIHJldHVybiBkZXN0O1xufTtcblxufSx7XCIuL2NvbnZvbHZlXCI6MixcIi4vcmVzaXplX2ZpbHRlcl9nZW5cIjo2fV0sNjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBDYWxjdWxhdGUgY29udm9sdXRpb24gZmlsdGVycyBmb3IgZWFjaCBkZXN0aW5hdGlvbiBwb2ludCxcbi8vIGFuZCBwYWNrIGRhdGEgdG8gSW50MTZBcnJheTpcbi8vXG4vLyBbIHNoaWZ0LCBsZW5ndGgsIGRhdGEuLi4sIHNoaWZ0MiwgbGVuZ3RoMiwgZGF0YS4uLiwgLi4uIF1cbi8vXG4vLyAtIHNoaWZ0IC0gb2Zmc2V0IGluIHNyYyBpbWFnZVxuLy8gLSBsZW5ndGggLSBmaWx0ZXIgbGVuZ3RoIChpbiBzcmMgcG9pbnRzKVxuLy8gLSBkYXRhIC0gZmlsdGVyIHZhbHVlcyBzZXF1ZW5jZVxuLy9cbid1c2Ugc3RyaWN0JztcblxudmFyIEZJTFRFUl9JTkZPID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2luZm8nKTsgLy8gUHJlY2lzaW9uIG9mIGZpeGVkIEZQIHZhbHVlc1xuXG5cbnZhciBGSVhFRF9GUkFDX0JJVFMgPSAxNDtcblxuZnVuY3Rpb24gdG9GaXhlZFBvaW50KG51bSkge1xuICByZXR1cm4gTWF0aC5yb3VuZChudW0gKiAoKDEgPDwgRklYRURfRlJBQ19CSVRTKSAtIDEpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXNpemVGaWx0ZXJHZW4ocXVhbGl0eSwgc3JjU2l6ZSwgZGVzdFNpemUsIHNjYWxlLCBvZmZzZXQpIHtcbiAgdmFyIGZpbHRlckZ1bmN0aW9uID0gRklMVEVSX0lORk9bcXVhbGl0eV0uZmlsdGVyO1xuICB2YXIgc2NhbGVJbnZlcnRlZCA9IDEuMCAvIHNjYWxlO1xuICB2YXIgc2NhbGVDbGFtcGVkID0gTWF0aC5taW4oMS4wLCBzY2FsZSk7IC8vIEZvciB1cHNjYWxlXG4gIC8vIEZpbHRlciB3aW5kb3cgKGF2ZXJhZ2luZyBpbnRlcnZhbCksIHNjYWxlZCB0byBzcmMgaW1hZ2VcblxuICB2YXIgc3JjV2luZG93ID0gRklMVEVSX0lORk9bcXVhbGl0eV0ud2luIC8gc2NhbGVDbGFtcGVkO1xuICB2YXIgZGVzdFBpeGVsLCBzcmNQaXhlbCwgc3JjRmlyc3QsIHNyY0xhc3QsIGZpbHRlckVsZW1lbnRTaXplLCBmbG9hdEZpbHRlciwgZnhwRmlsdGVyLCB0b3RhbCwgcHhsLCBpZHgsIGZsb2F0VmFsLCBmaWx0ZXJUb3RhbCwgZmlsdGVyVmFsO1xuICB2YXIgbGVmdE5vdEVtcHR5LCByaWdodE5vdEVtcHR5LCBmaWx0ZXJTaGlmdCwgZmlsdGVyU2l6ZTtcbiAgdmFyIG1heEZpbHRlckVsZW1lbnRTaXplID0gTWF0aC5mbG9vcigoc3JjV2luZG93ICsgMSkgKiAyKTtcbiAgdmFyIHBhY2tlZEZpbHRlciA9IG5ldyBJbnQxNkFycmF5KChtYXhGaWx0ZXJFbGVtZW50U2l6ZSArIDIpICogZGVzdFNpemUpO1xuICB2YXIgcGFja2VkRmlsdGVyUHRyID0gMDtcbiAgdmFyIHNsb3dDb3B5ID0gIXBhY2tlZEZpbHRlci5zdWJhcnJheSB8fCAhcGFja2VkRmlsdGVyLnNldDsgLy8gRm9yIGVhY2ggZGVzdGluYXRpb24gcGl4ZWwgY2FsY3VsYXRlIHNvdXJjZSByYW5nZSBhbmQgYnVpbHQgZmlsdGVyIHZhbHVlc1xuXG4gIGZvciAoZGVzdFBpeGVsID0gMDsgZGVzdFBpeGVsIDwgZGVzdFNpemU7IGRlc3RQaXhlbCsrKSB7XG4gICAgLy8gU2NhbGluZyBzaG91bGQgYmUgZG9uZSByZWxhdGl2ZSB0byBjZW50cmFsIHBpeGVsIHBvaW50XG4gICAgc3JjUGl4ZWwgPSAoZGVzdFBpeGVsICsgMC41KSAqIHNjYWxlSW52ZXJ0ZWQgKyBvZmZzZXQ7XG4gICAgc3JjRmlyc3QgPSBNYXRoLm1heCgwLCBNYXRoLmZsb29yKHNyY1BpeGVsIC0gc3JjV2luZG93KSk7XG4gICAgc3JjTGFzdCA9IE1hdGgubWluKHNyY1NpemUgLSAxLCBNYXRoLmNlaWwoc3JjUGl4ZWwgKyBzcmNXaW5kb3cpKTtcbiAgICBmaWx0ZXJFbGVtZW50U2l6ZSA9IHNyY0xhc3QgLSBzcmNGaXJzdCArIDE7XG4gICAgZmxvYXRGaWx0ZXIgPSBuZXcgRmxvYXQzMkFycmF5KGZpbHRlckVsZW1lbnRTaXplKTtcbiAgICBmeHBGaWx0ZXIgPSBuZXcgSW50MTZBcnJheShmaWx0ZXJFbGVtZW50U2l6ZSk7XG4gICAgdG90YWwgPSAwLjA7IC8vIEZpbGwgZmlsdGVyIHZhbHVlcyBmb3IgY2FsY3VsYXRlZCByYW5nZVxuXG4gICAgZm9yIChweGwgPSBzcmNGaXJzdCwgaWR4ID0gMDsgcHhsIDw9IHNyY0xhc3Q7IHB4bCsrLCBpZHgrKykge1xuICAgICAgZmxvYXRWYWwgPSBmaWx0ZXJGdW5jdGlvbigocHhsICsgMC41IC0gc3JjUGl4ZWwpICogc2NhbGVDbGFtcGVkKTtcbiAgICAgIHRvdGFsICs9IGZsb2F0VmFsO1xuICAgICAgZmxvYXRGaWx0ZXJbaWR4XSA9IGZsb2F0VmFsO1xuICAgIH0gLy8gTm9ybWFsaXplIGZpbHRlciwgY29udmVydCB0byBmaXhlZCBwb2ludCBhbmQgYWNjdW11bGF0ZSBjb252ZXJzaW9uIGVycm9yXG5cblxuICAgIGZpbHRlclRvdGFsID0gMDtcblxuICAgIGZvciAoaWR4ID0gMDsgaWR4IDwgZmxvYXRGaWx0ZXIubGVuZ3RoOyBpZHgrKykge1xuICAgICAgZmlsdGVyVmFsID0gZmxvYXRGaWx0ZXJbaWR4XSAvIHRvdGFsO1xuICAgICAgZmlsdGVyVG90YWwgKz0gZmlsdGVyVmFsO1xuICAgICAgZnhwRmlsdGVyW2lkeF0gPSB0b0ZpeGVkUG9pbnQoZmlsdGVyVmFsKTtcbiAgICB9IC8vIENvbXBlbnNhdGUgbm9ybWFsaXphdGlvbiBlcnJvciwgdG8gbWluaW1pemUgYnJpZ2h0bmVzcyBkcmlmdFxuXG5cbiAgICBmeHBGaWx0ZXJbZGVzdFNpemUgPj4gMV0gKz0gdG9GaXhlZFBvaW50KDEuMCAtIGZpbHRlclRvdGFsKTsgLy9cbiAgICAvLyBOb3cgcGFjayBmaWx0ZXIgdG8gdXNlYWJsZSBmb3JtXG4gICAgLy9cbiAgICAvLyAxLiBUcmltIGhlYWRpbmcgYW5kIHRhaWxpbmcgemVybyB2YWx1ZXMsIGFuZCBjb21wZW5zYXRlIHNoaXRmL2xlbmd0aFxuICAgIC8vIDIuIFB1dCBhbGwgdG8gc2luZ2xlIGFycmF5IGluIHRoaXMgZm9ybWF0OlxuICAgIC8vXG4gICAgLy8gICAgWyBwb3Mgc2hpZnQsIGRhdGEgbGVuZ3RoLCB2YWx1ZTEsIHZhbHVlMiwgdmFsdWUzLCAuLi4gXVxuICAgIC8vXG5cbiAgICBsZWZ0Tm90RW1wdHkgPSAwO1xuXG4gICAgd2hpbGUgKGxlZnROb3RFbXB0eSA8IGZ4cEZpbHRlci5sZW5ndGggJiYgZnhwRmlsdGVyW2xlZnROb3RFbXB0eV0gPT09IDApIHtcbiAgICAgIGxlZnROb3RFbXB0eSsrO1xuICAgIH1cblxuICAgIGlmIChsZWZ0Tm90RW1wdHkgPCBmeHBGaWx0ZXIubGVuZ3RoKSB7XG4gICAgICByaWdodE5vdEVtcHR5ID0gZnhwRmlsdGVyLmxlbmd0aCAtIDE7XG5cbiAgICAgIHdoaWxlIChyaWdodE5vdEVtcHR5ID4gMCAmJiBmeHBGaWx0ZXJbcmlnaHROb3RFbXB0eV0gPT09IDApIHtcbiAgICAgICAgcmlnaHROb3RFbXB0eS0tO1xuICAgICAgfVxuXG4gICAgICBmaWx0ZXJTaGlmdCA9IHNyY0ZpcnN0ICsgbGVmdE5vdEVtcHR5O1xuICAgICAgZmlsdGVyU2l6ZSA9IHJpZ2h0Tm90RW1wdHkgLSBsZWZ0Tm90RW1wdHkgKyAxO1xuICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IGZpbHRlclNoaWZ0OyAvLyBzaGlmdFxuXG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gZmlsdGVyU2l6ZTsgLy8gc2l6ZVxuXG4gICAgICBpZiAoIXNsb3dDb3B5KSB7XG4gICAgICAgIHBhY2tlZEZpbHRlci5zZXQoZnhwRmlsdGVyLnN1YmFycmF5KGxlZnROb3RFbXB0eSwgcmlnaHROb3RFbXB0eSArIDEpLCBwYWNrZWRGaWx0ZXJQdHIpO1xuICAgICAgICBwYWNrZWRGaWx0ZXJQdHIgKz0gZmlsdGVyU2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGZhbGxiYWNrIGZvciBvbGQgSUUgPCAxMSwgd2l0aG91dCBzdWJhcnJheS9zZXQgbWV0aG9kc1xuICAgICAgICBmb3IgKGlkeCA9IGxlZnROb3RFbXB0eTsgaWR4IDw9IHJpZ2h0Tm90RW1wdHk7IGlkeCsrKSB7XG4gICAgICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IGZ4cEZpbHRlcltpZHhdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHplcm8gZGF0YSwgd3JpdGUgaGVhZGVyIG9ubHlcbiAgICAgIHBhY2tlZEZpbHRlcltwYWNrZWRGaWx0ZXJQdHIrK10gPSAwOyAvLyBzaGlmdFxuXG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gMDsgLy8gc2l6ZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYWNrZWRGaWx0ZXI7XG59O1xuXG59LHtcIi4vcmVzaXplX2ZpbHRlcl9pbmZvXCI6N31dLDc6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gRmlsdGVyIGRlZmluaXRpb25zIHRvIGJ1aWxkIHRhYmxlcyBmb3Jcbi8vIHJlc2l6aW5nIGNvbnZvbHZlcnMuXG4vL1xuLy8gUHJlc2V0cyBmb3IgcXVhbGl0eSAwLi4zLiBGaWx0ZXIgZnVuY3Rpb25zICsgd2luZG93IHNpemVcbi8vXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gW3tcbiAgLy8gTmVhcmVzdCBuZWlib3IgKEJveClcbiAgd2luOiAwLjUsXG4gIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKHgpIHtcbiAgICByZXR1cm4geCA+PSAtMC41ICYmIHggPCAwLjUgPyAxLjAgOiAwLjA7XG4gIH1cbn0sIHtcbiAgLy8gSGFtbWluZ1xuICB3aW46IDEuMCxcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoeCkge1xuICAgIGlmICh4IDw9IC0xLjAgfHwgeCA+PSAxLjApIHtcbiAgICAgIHJldHVybiAwLjA7XG4gICAgfVxuXG4gICAgaWYgKHggPiAtMS4xOTIwOTI5MEUtMDcgJiYgeCA8IDEuMTkyMDkyOTBFLTA3KSB7XG4gICAgICByZXR1cm4gMS4wO1xuICAgIH1cblxuICAgIHZhciB4cGkgPSB4ICogTWF0aC5QSTtcbiAgICByZXR1cm4gTWF0aC5zaW4oeHBpKSAvIHhwaSAqICgwLjU0ICsgMC40NiAqIE1hdGguY29zKHhwaSAvIDEuMCkpO1xuICB9XG59LCB7XG4gIC8vIExhbmN6b3MsIHdpbiA9IDJcbiAgd2luOiAyLjAsXG4gIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKHgpIHtcbiAgICBpZiAoeCA8PSAtMi4wIHx8IHggPj0gMi4wKSB7XG4gICAgICByZXR1cm4gMC4wO1xuICAgIH1cblxuICAgIGlmICh4ID4gLTEuMTkyMDkyOTBFLTA3ICYmIHggPCAxLjE5MjA5MjkwRS0wNykge1xuICAgICAgcmV0dXJuIDEuMDtcbiAgICB9XG5cbiAgICB2YXIgeHBpID0geCAqIE1hdGguUEk7XG4gICAgcmV0dXJuIE1hdGguc2luKHhwaSkgLyB4cGkgKiBNYXRoLnNpbih4cGkgLyAyLjApIC8gKHhwaSAvIDIuMCk7XG4gIH1cbn0sIHtcbiAgLy8gTGFuY3pvcywgd2luID0gM1xuICB3aW46IDMuMCxcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoeCkge1xuICAgIGlmICh4IDw9IC0zLjAgfHwgeCA+PSAzLjApIHtcbiAgICAgIHJldHVybiAwLjA7XG4gICAgfVxuXG4gICAgaWYgKHggPiAtMS4xOTIwOTI5MEUtMDcgJiYgeCA8IDEuMTkyMDkyOTBFLTA3KSB7XG4gICAgICByZXR1cm4gMS4wO1xuICAgIH1cblxuICAgIHZhciB4cGkgPSB4ICogTWF0aC5QSTtcbiAgICByZXR1cm4gTWF0aC5zaW4oeHBpKSAvIHhwaSAqIE1hdGguc2luKHhwaSAvIDMuMCkgLyAoeHBpIC8gMy4wKTtcbiAgfVxufV07XG5cbn0se31dLDg6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3JlYXRlRmlsdGVycyA9IF9kZXJlcV8oJy4vcmVzaXplX2ZpbHRlcl9nZW4nKTtcblxuZnVuY3Rpb24gcmVzZXRBbHBoYShkc3QsIHdpZHRoLCBoZWlnaHQpIHtcbiAgdmFyIHB0ciA9IDMsXG4gICAgICBsZW4gPSB3aWR0aCAqIGhlaWdodCAqIDQgfCAwO1xuXG4gIHdoaWxlIChwdHIgPCBsZW4pIHtcbiAgICBkc3RbcHRyXSA9IDB4RkY7XG4gICAgcHRyID0gcHRyICsgNCB8IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXNVaW50OEFycmF5KHNyYykge1xuICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc3JjLmJ1ZmZlciwgMCwgc3JjLmJ5dGVMZW5ndGgpO1xufVxuXG52YXIgSVNfTEUgPSB0cnVlOyAvLyBzaG91bGQgbm90IGNyYXNoIGV2ZXJ5dGhpbmcgb24gbW9kdWxlIGxvYWQgaW4gb2xkIGJyb3dzZXJzXG5cbnRyeSB7XG4gIElTX0xFID0gbmV3IFVpbnQzMkFycmF5KG5ldyBVaW50OEFycmF5KFsxLCAwLCAwLCAwXSkuYnVmZmVyKVswXSA9PT0gMTtcbn0gY2F0Y2ggKF9fKSB7fVxuXG5mdW5jdGlvbiBjb3B5SW50MTZhc0xFKHNyYywgdGFyZ2V0LCB0YXJnZXRfb2Zmc2V0KSB7XG4gIGlmIChJU19MRSkge1xuICAgIHRhcmdldC5zZXQoYXNVaW50OEFycmF5KHNyYyksIHRhcmdldF9vZmZzZXQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAodmFyIHB0ciA9IHRhcmdldF9vZmZzZXQsIGkgPSAwOyBpIDwgc3JjLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGRhdGEgPSBzcmNbaV07XG4gICAgdGFyZ2V0W3B0cisrXSA9IGRhdGEgJiAweEZGO1xuICAgIHRhcmdldFtwdHIrK10gPSBkYXRhID4+IDggJiAweEZGO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcmVzaXplX3dhc20ob3B0aW9ucykge1xuICB2YXIgc3JjID0gb3B0aW9ucy5zcmM7XG4gIHZhciBzcmNXID0gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNyY0ggPSBvcHRpb25zLmhlaWdodDtcbiAgdmFyIGRlc3RXID0gb3B0aW9ucy50b1dpZHRoO1xuICB2YXIgZGVzdEggPSBvcHRpb25zLnRvSGVpZ2h0O1xuICB2YXIgc2NhbGVYID0gb3B0aW9ucy5zY2FsZVggfHwgb3B0aW9ucy50b1dpZHRoIC8gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNjYWxlWSA9IG9wdGlvbnMuc2NhbGVZIHx8IG9wdGlvbnMudG9IZWlnaHQgLyBvcHRpb25zLmhlaWdodDtcbiAgdmFyIG9mZnNldFggPSBvcHRpb25zLm9mZnNldFggfHwgMC4wO1xuICB2YXIgb2Zmc2V0WSA9IG9wdGlvbnMub2Zmc2V0WSB8fCAwLjA7XG4gIHZhciBkZXN0ID0gb3B0aW9ucy5kZXN0IHx8IG5ldyBVaW50OEFycmF5KGRlc3RXICogZGVzdEggKiA0KTtcbiAgdmFyIHF1YWxpdHkgPSB0eXBlb2Ygb3B0aW9ucy5xdWFsaXR5ID09PSAndW5kZWZpbmVkJyA/IDMgOiBvcHRpb25zLnF1YWxpdHk7XG4gIHZhciBhbHBoYSA9IG9wdGlvbnMuYWxwaGEgfHwgZmFsc2U7XG4gIHZhciBmaWx0ZXJzWCA9IGNyZWF0ZUZpbHRlcnMocXVhbGl0eSwgc3JjVywgZGVzdFcsIHNjYWxlWCwgb2Zmc2V0WCksXG4gICAgICBmaWx0ZXJzWSA9IGNyZWF0ZUZpbHRlcnMocXVhbGl0eSwgc3JjSCwgZGVzdEgsIHNjYWxlWSwgb2Zmc2V0WSk7IC8vIGRlc3RpbmF0aW9uIGlzIDAgdG9vLlxuXG4gIHZhciBzcmNfb2Zmc2V0ID0gMDsgLy8gYnVmZmVyIGJldHdlZW4gY29udm9sdmUgcGFzc2VzXG5cbiAgdmFyIHRtcF9vZmZzZXQgPSB0aGlzLl9fYWxpZ24oc3JjX29mZnNldCArIE1hdGgubWF4KHNyYy5ieXRlTGVuZ3RoLCBkZXN0LmJ5dGVMZW5ndGgpKTtcblxuICB2YXIgZmlsdGVyc1hfb2Zmc2V0ID0gdGhpcy5fX2FsaWduKHRtcF9vZmZzZXQgKyBzcmNIICogZGVzdFcgKiA0KTtcblxuICB2YXIgZmlsdGVyc1lfb2Zmc2V0ID0gdGhpcy5fX2FsaWduKGZpbHRlcnNYX29mZnNldCArIGZpbHRlcnNYLmJ5dGVMZW5ndGgpO1xuXG4gIHZhciBhbGxvY19ieXRlcyA9IGZpbHRlcnNZX29mZnNldCArIGZpbHRlcnNZLmJ5dGVMZW5ndGg7XG5cbiAgdmFyIGluc3RhbmNlID0gdGhpcy5fX2luc3RhbmNlKCdyZXNpemUnLCBhbGxvY19ieXRlcyk7IC8vXG4gIC8vIEZpbGwgbWVtb3J5IGJsb2NrIHdpdGggZGF0YSB0byBwcm9jZXNzXG4gIC8vXG5cblxuICB2YXIgbWVtID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5fX21lbW9yeS5idWZmZXIpO1xuICB2YXIgbWVtMzIgPSBuZXcgVWludDMyQXJyYXkodGhpcy5fX21lbW9yeS5idWZmZXIpOyAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuICB2YXIgc3JjMzIgPSBuZXcgVWludDMyQXJyYXkoc3JjLmJ1ZmZlcik7XG4gIG1lbTMyLnNldChzcmMzMik7IC8vIFdlIHNob3VsZCBndWFyYW50ZWUgTEUgYnl0ZXMgb3JkZXIuIEZpbHRlcnMgYXJlIG5vdCBiaWcsIHNvXG4gIC8vIHNwZWVkIGRpZmZlcmVuY2UgaXMgbm90IHNpZ25pZmljYW50IHZzIGRpcmVjdCAuc2V0KClcblxuICBjb3B5SW50MTZhc0xFKGZpbHRlcnNYLCBtZW0sIGZpbHRlcnNYX29mZnNldCk7XG4gIGNvcHlJbnQxNmFzTEUoZmlsdGVyc1ksIG1lbSwgZmlsdGVyc1lfb2Zmc2V0KTsgLy9cbiAgLy8gTm93IGNhbGwgd2ViYXNzZW1ibHkgbWV0aG9kXG4gIC8vIGVtc2RrIGRvZXMgbWV0aG9kIG5hbWVzIHdpdGggJ18nXG5cbiAgdmFyIGZuID0gaW5zdGFuY2UuZXhwb3J0cy5jb252b2x2ZUhWIHx8IGluc3RhbmNlLmV4cG9ydHMuX2NvbnZvbHZlSFY7XG4gIGZuKGZpbHRlcnNYX29mZnNldCwgZmlsdGVyc1lfb2Zmc2V0LCB0bXBfb2Zmc2V0LCBzcmNXLCBzcmNILCBkZXN0VywgZGVzdEgpOyAvL1xuICAvLyBDb3B5IGRhdGEgYmFjayB0byB0eXBlZCBhcnJheVxuICAvL1xuICAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuICB2YXIgZGVzdDMyID0gbmV3IFVpbnQzMkFycmF5KGRlc3QuYnVmZmVyKTtcbiAgZGVzdDMyLnNldChuZXcgVWludDMyQXJyYXkodGhpcy5fX21lbW9yeS5idWZmZXIsIDAsIGRlc3RIICogZGVzdFcpKTsgLy8gVGhhdCdzIGZhc3RlciB0aGFuIGRvaW5nIGNoZWNrcyBpbiBjb252b2x2ZXIuXG4gIC8vICEhISBOb3RlLCBjYW52YXMgZGF0YSBpcyBub3QgcHJlbXVsdGlwbGVkLiBXZSBkb24ndCBuZWVkIG90aGVyXG4gIC8vIGFscGhhIGNvcnJlY3Rpb25zLlxuXG4gIGlmICghYWxwaGEpIHJlc2V0QWxwaGEoZGVzdCwgZGVzdFcsIGRlc3RIKTtcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG59LHtcIi4vcmVzaXplX2ZpbHRlcl9nZW5cIjo2fV0sOTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBuYW1lOiAndW5zaGFycF9tYXNrJyxcbiAgZm46IF9kZXJlcV8oJy4vdW5zaGFycF9tYXNrJyksXG4gIHdhc21fZm46IF9kZXJlcV8oJy4vdW5zaGFycF9tYXNrX3dhc20nKSxcbiAgd2FzbV9zcmM6IF9kZXJlcV8oJy4vdW5zaGFycF9tYXNrX3dhc21fYmFzZTY0Jylcbn07XG5cbn0se1wiLi91bnNoYXJwX21hc2tcIjoxMCxcIi4vdW5zaGFycF9tYXNrX3dhc21cIjoxMSxcIi4vdW5zaGFycF9tYXNrX3dhc21fYmFzZTY0XCI6MTJ9XSwxMDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBVbnNoYXJwIG1hc2sgZmlsdGVyXG4vL1xuLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjMzMjI4MjAvMTAzMTgwNFxuLy8gVVNNKE8pID0gTyArICgyICogKEFtb3VudCAvIDEwMCkgKiAoTyAtIEdCKSlcbi8vIEdCIC0gZ2F1c3NpYW4gYmx1ci5cbi8vXG4vLyBJbWFnZSBpcyBjb252ZXJ0ZWQgZnJvbSBSR0IgdG8gSFNWLCB1bnNoYXJwIG1hc2sgaXMgYXBwbGllZCB0byB0aGVcbi8vIGJyaWdodG5lc3MgY2hhbm5lbCBhbmQgdGhlbiBpbWFnZSBpcyBjb252ZXJ0ZWQgYmFjayB0byBSR0IuXG4vL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgZ2x1cl9tb25vMTYgPSBfZGVyZXFfKCdnbHVyL21vbm8xNicpO1xuXG5mdW5jdGlvbiBoc3ZfdjE2KGltZywgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgc2l6ZSA9IHdpZHRoICogaGVpZ2h0O1xuICB2YXIgb3V0ID0gbmV3IFVpbnQxNkFycmF5KHNpemUpO1xuICB2YXIgciwgZywgYiwgbWF4O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgciA9IGltZ1s0ICogaV07XG4gICAgZyA9IGltZ1s0ICogaSArIDFdO1xuICAgIGIgPSBpbWdbNCAqIGkgKyAyXTtcbiAgICBtYXggPSByID49IGcgJiYgciA+PSBiID8gciA6IGcgPj0gYiAmJiBnID49IHIgPyBnIDogYjtcbiAgICBvdXRbaV0gPSBtYXggPDwgODtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gdW5zaGFycChpbWcsIHdpZHRoLCBoZWlnaHQsIGFtb3VudCwgcmFkaXVzLCB0aHJlc2hvbGQpIHtcbiAgdmFyIHYxLCB2Miwgdm11bDtcbiAgdmFyIGRpZmYsIGlUaW1lczQ7XG5cbiAgaWYgKGFtb3VudCA9PT0gMCB8fCByYWRpdXMgPCAwLjUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAocmFkaXVzID4gMi4wKSB7XG4gICAgcmFkaXVzID0gMi4wO1xuICB9XG5cbiAgdmFyIGJyaWdodG5lc3MgPSBoc3ZfdjE2KGltZywgd2lkdGgsIGhlaWdodCk7XG4gIHZhciBibHVyZWQgPSBuZXcgVWludDE2QXJyYXkoYnJpZ2h0bmVzcyk7IC8vIGNvcHksIGJlY2F1c2UgYmx1ciBtb2RpZnkgc3JjXG5cbiAgZ2x1cl9tb25vMTYoYmx1cmVkLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpO1xuICB2YXIgYW1vdW50RnAgPSBhbW91bnQgLyAxMDAgKiAweDEwMDAgKyAwLjUgfCAwO1xuICB2YXIgdGhyZXNob2xkRnAgPSB0aHJlc2hvbGQgPDwgODtcbiAgdmFyIHNpemUgPSB3aWR0aCAqIGhlaWdodDtcbiAgLyogZXNsaW50LWRpc2FibGUgaW5kZW50ICovXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICB2MSA9IGJyaWdodG5lc3NbaV07XG4gICAgZGlmZiA9IHYxIC0gYmx1cmVkW2ldO1xuXG4gICAgaWYgKE1hdGguYWJzKGRpZmYpID49IHRocmVzaG9sZEZwKSB7XG4gICAgICAvLyBhZGQgdW5zaGFycCBtYXNrIHRvIHRoZSBicmlnaHRuZXNzIGNoYW5uZWxcbiAgICAgIHYyID0gdjEgKyAoYW1vdW50RnAgKiBkaWZmICsgMHg4MDAgPj4gMTIpOyAvLyBCb3RoIHYxIGFuZCB2MiBhcmUgd2l0aGluIFswLjAgLi4gMjU1LjBdICgwMDAwLUZGMDApIHJhbmdlLCBuZXZlciBnb2luZyBpbnRvXG4gICAgICAvLyBbMjU1LjAwMyAuLiAyNTUuOTk2XSAoRkYwMS1GRkZGKS4gVGhpcyBhbGxvd3MgdG8gcm91bmQgdGhpcyB2YWx1ZSBhcyAoeCsuNSl8MFxuICAgICAgLy8gbGF0ZXIgd2l0aG91dCBvdmVyZmxvd2luZy5cblxuICAgICAgdjIgPSB2MiA+IDB4ZmYwMCA/IDB4ZmYwMCA6IHYyO1xuICAgICAgdjIgPSB2MiA8IDB4MDAwMCA/IDB4MDAwMCA6IHYyOyAvLyBBdm9pZCBkaXZpc2lvbiBieSAwLiBWPTAgbWVhbnMgcmdiKDAsMCwwKSwgdW5zaGFycCB3aXRoIHVuc2hhcnBBbW91bnQ+MCBjYW5ub3RcbiAgICAgIC8vIGNoYW5nZSB0aGlzIHZhbHVlIChiZWNhdXNlIGRpZmYgYmV0d2VlbiBjb2xvcnMgZ2V0cyBpbmZsYXRlZCksIHNvIG5vIG5lZWQgdG8gdmVyaWZ5IGNvcnJlY3RuZXNzLlxuXG4gICAgICB2MSA9IHYxICE9PSAwID8gdjEgOiAxOyAvLyBNdWx0aXBseWluZyBWIGluIEhTViBtb2RlbCBieSBhIGNvbnN0YW50IGlzIGVxdWl2YWxlbnQgdG8gbXVsdGlwbHlpbmcgZWFjaCBjb21wb25lbnRcbiAgICAgIC8vIGluIFJHQiBieSB0aGUgc2FtZSBjb25zdGFudCAoc2FtZSBmb3IgSFNMKSwgc2VlIGFsc286XG4gICAgICAvLyBodHRwczovL2JlZXNidXp6LmJpei9jb2RlLzE2LWhzdi1jb2xvci10cmFuc2Zvcm1zXG5cbiAgICAgIHZtdWwgPSAodjIgPDwgMTIpIC8gdjEgfCAwOyAvLyBSZXN1bHQgd2lsbCBiZSBpbiBbMC4uMjU1XSByYW5nZSBiZWNhdXNlOlxuICAgICAgLy8gIC0gYWxsIG51bWJlcnMgYXJlIHBvc2l0aXZlXG4gICAgICAvLyAgLSByLGcsYiA8PSAodjEvMjU2KVxuICAgICAgLy8gIC0gcixnLGIsKHYxLzI1NiksKHYyLzI1NikgPD0gMjU1XG4gICAgICAvLyBTbyBoaWdoZXN0IHRoaXMgbnVtYmVyIGNhbiBnZXQgaXMgWCoyNTUvWCswLjU9MjU1LjUgd2hpY2ggaXMgPCAyNTYgYW5kIHJvdW5kcyBkb3duLlxuXG4gICAgICBpVGltZXM0ID0gaSAqIDQ7XG4gICAgICBpbWdbaVRpbWVzNF0gPSBpbWdbaVRpbWVzNF0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIFJcblxuICAgICAgaW1nW2lUaW1lczQgKyAxXSA9IGltZ1tpVGltZXM0ICsgMV0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIEdcblxuICAgICAgaW1nW2lUaW1lczQgKyAyXSA9IGltZ1tpVGltZXM0ICsgMl0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIEJcbiAgICB9XG4gIH1cbn07XG5cbn0se1wiZ2x1ci9tb25vMTZcIjoxOH1dLDExOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB1bnNoYXJwKGltZywgd2lkdGgsIGhlaWdodCwgYW1vdW50LCByYWRpdXMsIHRocmVzaG9sZCkge1xuICBpZiAoYW1vdW50ID09PSAwIHx8IHJhZGl1cyA8IDAuNSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChyYWRpdXMgPiAyLjApIHtcbiAgICByYWRpdXMgPSAyLjA7XG4gIH1cblxuICB2YXIgcGl4ZWxzID0gd2lkdGggKiBoZWlnaHQ7XG4gIHZhciBpbWdfYnl0ZXNfY250ID0gcGl4ZWxzICogNDtcbiAgdmFyIGhzdl9ieXRlc19jbnQgPSBwaXhlbHMgKiAyO1xuICB2YXIgYmx1cl9ieXRlc19jbnQgPSBwaXhlbHMgKiAyO1xuICB2YXIgYmx1cl9saW5lX2J5dGVfY250ID0gTWF0aC5tYXgod2lkdGgsIGhlaWdodCkgKiA0OyAvLyBmbG9hdDMyIGFycmF5XG5cbiAgdmFyIGJsdXJfY29lZmZzX2J5dGVfY250ID0gOCAqIDQ7IC8vIGZsb2F0MzIgYXJyYXlcblxuICB2YXIgaW1nX29mZnNldCA9IDA7XG4gIHZhciBoc3Zfb2Zmc2V0ID0gaW1nX2J5dGVzX2NudDtcbiAgdmFyIGJsdXJfb2Zmc2V0ID0gaHN2X29mZnNldCArIGhzdl9ieXRlc19jbnQ7XG4gIHZhciBibHVyX3RtcF9vZmZzZXQgPSBibHVyX29mZnNldCArIGJsdXJfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9saW5lX29mZnNldCA9IGJsdXJfdG1wX29mZnNldCArIGJsdXJfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9jb2VmZnNfb2Zmc2V0ID0gYmx1cl9saW5lX29mZnNldCArIGJsdXJfbGluZV9ieXRlX2NudDtcblxuICB2YXIgaW5zdGFuY2UgPSB0aGlzLl9faW5zdGFuY2UoJ3Vuc2hhcnBfbWFzaycsIGltZ19ieXRlc19jbnQgKyBoc3ZfYnl0ZXNfY250ICsgYmx1cl9ieXRlc19jbnQgKiAyICsgYmx1cl9saW5lX2J5dGVfY250ICsgYmx1cl9jb2VmZnNfYnl0ZV9jbnQsIHtcbiAgICBleHA6IE1hdGguZXhwXG4gIH0pOyAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuXG4gIHZhciBpbWczMiA9IG5ldyBVaW50MzJBcnJheShpbWcuYnVmZmVyKTtcbiAgdmFyIG1lbTMyID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyKTtcbiAgbWVtMzIuc2V0KGltZzMyKTsgLy8gSFNMXG5cbiAgdmFyIGZuID0gaW5zdGFuY2UuZXhwb3J0cy5oc3ZfdjE2IHx8IGluc3RhbmNlLmV4cG9ydHMuX2hzdl92MTY7XG4gIGZuKGltZ19vZmZzZXQsIGhzdl9vZmZzZXQsIHdpZHRoLCBoZWlnaHQpOyAvLyBCTFVSXG5cbiAgZm4gPSBpbnN0YW5jZS5leHBvcnRzLmJsdXJNb25vMTYgfHwgaW5zdGFuY2UuZXhwb3J0cy5fYmx1ck1vbm8xNjtcbiAgZm4oaHN2X29mZnNldCwgYmx1cl9vZmZzZXQsIGJsdXJfdG1wX29mZnNldCwgYmx1cl9saW5lX29mZnNldCwgYmx1cl9jb2VmZnNfb2Zmc2V0LCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpOyAvLyBVTlNIQVJQXG5cbiAgZm4gPSBpbnN0YW5jZS5leHBvcnRzLnVuc2hhcnAgfHwgaW5zdGFuY2UuZXhwb3J0cy5fdW5zaGFycDtcbiAgZm4oaW1nX29mZnNldCwgaW1nX29mZnNldCwgaHN2X29mZnNldCwgYmx1cl9vZmZzZXQsIHdpZHRoLCBoZWlnaHQsIGFtb3VudCwgdGhyZXNob2xkKTsgLy8gMzItYml0IGNvcHkgaXMgbXVjaCBmYXN0ZXIgaW4gY2hyb21lXG5cbiAgaW1nMzIuc2V0KG5ldyBVaW50MzJBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlciwgMCwgcGl4ZWxzKSk7XG59O1xuXG59LHt9XSwxMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBUaGlzIGlzIGF1dG9nZW5lcmF0ZWQgZmlsZSBmcm9tIG1hdGgud2FzbSwgZG9uJ3QgZWRpdC5cbi8vXG4ndXNlIHN0cmljdCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbm1vZHVsZS5leHBvcnRzID0gJ0FHRnpiUUVBQUFBQURBWmtlV3hwYm1zQUFBQUFBQUUwQjJBQUFHQUVmMzkvZndCZ0JuOS9mMzkvZndCZ0NIOS9mMzkvZjM5L0FHQUlmMzkvZjM5L2YzMEFZQUo5ZndCZ0FYd0JmQUlaQWdObGJuWURaWGh3QUFZRFpXNTJCbTFsYlc5eWVRSUFBQU1IQmdBRkFnUUJBd1lHQVg4QVFRQUxCNG9CQ0JGZlgzZGhjMjFmWTJGc2JGOWpkRzl5Y3dBQkZsOWZZblZwYkdSZloyRjFjM05wWVc1ZlkyOWxabk1BQWc1ZlgyZGhkWE56TVRaZmJHbHVaUUFEQ21Kc2RYSk5iMjV2TVRZQUJBZG9jM1pmZGpFMkFBVUhkVzV6YUdGeWNBQUdERjlmWkhOdlgyaGhibVJzWlFNQUdGOWZkMkZ6YlY5aGNIQnNlVjlrWVhSaFgzSmxiRzlqY3dBQkNzVU1CZ01BQVF2V0FRRUhmQ0FCUk51R3VrT0NHdnMvSUFDN295SUNSQUFBQUFBQUFBREFvaEFBSWdXMmpEZ0NGQ0FCSUFLYUVBQWlBeUFEb0NJR3RqZ0NFQ0FCUkFBQUFBQUFBUEEvSUFPaElnUWdCS0lnQXlBQ0lBS2dva1FBQUFBQUFBRHdQNkFnQmFHaklnUzJPQUlBSUFFZ0JTQUVtcUlpQjdZNEFnd2dBU0FESUFKRUFBQUFBQUFBOEQrZ0lBU2lvaUlJdGpnQ0NDQUJJQU1nQWtRQUFBQUFBQUR3djZBZ0JLS2lJZ0syT0FJRUlBRWdCeUFJb0NBRlJBQUFBQUFBQVBBL0lBYWhvQ0lEbzdZNEFod2dBU0FFSUFLZ0lBT2p0amdDR0F1R0JRTUdmd2w4QW4wZ0F5b0NEQ0VWSUFNcUFnZ2hGaUFES2dJVXV5RVJJQU1xQWhDN0lSQUNRQ0FFUVFGcklnaEJBRWdpQ1FSQUlBSWhCeUFBSVFZTUFRc2dBaUFBTHdFQXVDSVBJQU1xQWhpN29pSU1JQkdpSWcwZ0RDQVFvaUFQSUFNcUFnUzdJaE9pSWhRZ0F5b0NBTHNpRWlBUG9xQ2dvQ0lPdGpnQ0FDQUNRUVJxSVFjZ0FFRUNhaUVHSUFoRkRRQWdDRUVCSUFoQkFVZ2JJZ3BCZjNNaEN3Si9JQVFnQ210QkFYRkZCRUFnRGlFTklBZ01BUXNnQWlBTklBNGdFS0lnRkNBU0lBQXZBUUs0SWcraW9LQ2dJZzIyT0FJRUlBSkJDR29oQnlBQVFRUnFJUVlnRGlFTUlBUkJBbXNMSVFJZ0MwRUFJQVJyUmcwQUEwQWdCeUFNSUJHaUlBMGdFS0lnRHlBVG9pQVNJQVl2QVFDNElnNmlvS0NnSWd5Mk9BSUFJQWNnRFNBUm9pQU1JQkNpSUE0Z0U2SWdFaUFHTHdFQ3VDSVBvcUNnb0NJTnRqZ0NCQ0FIUVFocUlRY2dCa0VFYWlFR0lBSkJBa29oQUNBQ1FRSnJJUUlnQUEwQUN3c0NRQ0FKRFFBZ0FTQUZJQWhzUVFGMGFpSUFBbjhnQmtFQ2F5OEJBQ0lDdUNJTklCVzdJaEtpSUEwZ0Zyc2lFNktnSUEwZ0F5b0NITHVpSWd3Z0VLS2dJQXdnRWFLZ0lnOGdCMEVFYXlJSEtnSUF1NkFpRGtRQUFBQUFBQUR3UVdNZ0RrUUFBQUFBQUFBQUFHWnhCRUFnRHFzTUFRdEJBQXM3QVFBZ0NFVU5BQ0FHUVFScklRWkJBQ0FGYTBFQmRDRUJBMEFDZnlBTklCS2lJQUpCLy84RGNiZ2lEU0FUb3FBZ0R5SU9JQkNpb0NBTUlCR2lvQ0lQSUFkQkJHc2lCeW9DQUx1Z0lneEVBQUFBQUFBQThFRmpJQXhFQUFBQUFBQUFBQUJtY1FSQUlBeXJEQUVMUVFBTElRTWdCaThCQUNFQ0lBQWdBV29pQUNBRE93RUFJQVpCQW1zaEJpQUlRUUZLSVFNZ0RpRU1JQWhCQVdzaENDQUREUUFMQ3d2UkFnSUJmd2Q4QWtBZ0IwTUFBQUFBV3cwQUlBUkUyNGE2UTRJYSt6OGdCME1BQUFBL2w3dWpJZ2xFQUFBQUFBQUFBTUNpRUFBaURMYU1PQUlVSUFRZ0Nab1FBQ0lLSUFxZ0lnMjJPQUlRSUFSRUFBQUFBQUFBOEQ4Z0NxRWlDeUFMb2lBS0lBa2dDYUNpUkFBQUFBQUFBUEEvb0NBTW9hTWlDN1k0QWdBZ0JDQU1JQXVhb2lJT3RqZ0NEQ0FFSUFvZ0NVUUFBQUFBQUFEd1A2QWdDNktpSWcrMk9BSUlJQVFnQ2lBSlJBQUFBQUFBQVBDL29DQUxvcUlpQ2JZNEFnUWdCQ0FPSUErZ0lBeEVBQUFBQUFBQThEOGdEYUdnSWdxanRqZ0NIQ0FFSUFzZ0NhQWdDcU8yT0FJWUlBWUVRQU5BSUFBZ0JTQUliRUVCZEdvZ0FpQUlRUUYwYWlBRElBUWdCU0FHRUFNZ0NFRUJhaUlJSUFaSERRQUxDeUFGUlEwQVFRQWhDQU5BSUFJZ0JpQUliRUVCZEdvZ0FTQUlRUUYwYWlBRElBUWdCaUFGRUFNZ0NFRUJhaUlJSUFWSERRQUxDd3R4QVFOL0lBSWdBMndpQlFSQUEwQWdBU0FBS0FJQUlnUkJFSFpCL3dGeElnSWdBaUFFUVFoMlFmOEJjU0lESUFNZ0JFSC9BWEVpQkVrYklBSWdBMHNiSWdZZ0JpQUVJQUlnQkVzYklBTWdCRXNiUVFoME93RUFJQUZCQW1vaEFTQUFRUVJxSVFBZ0JVRUJheUlGRFFBTEN3dVpBZ0lEZndGOElBUWdCV3doQkFKL0lBYXpRd0FBZ0VXVVF3QUF5RUtWdTBRQUFBQUFBQURnUDZBaUM1bEVBQUFBQUFBQTRFRmpCRUFnQzZvTUFRdEJnSUNBZ0hnTElRVWdCQVJBSUFkQkNIUWhDVUVBSVFZRFFDQUpJQUlnQmtFQmRDSUhhaThCQUNJQklBTWdCMm92QVFCcklnY2dCMEVmZFNJSWFpQUljMDBFUUNBQUlBWkJBblFpQ0dvaUNpQUZJQWRzUVlBUWFrRU1kU0FCYWlJSFFZRCtBeUFIUVlEK0EwZ2JJZ2RCQUNBSFFRQktHMEVNZENBQlFRRWdBUnR1SWdFZ0NpMEFBR3hCZ0JCcVFReDJPZ0FBSUFBZ0NFRUJjbW9pQnlBQklBY3RBQUJzUVlBUWFrRU1kam9BQUNBQUlBaEJBbkpxSWdjZ0FTQUhMUUFBYkVHQUVHcEJESFk2QUFBTElBWkJBV29pQmlBRVJ3MEFDd3NMJztcblxufSx7fV0sMTM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgR0NfSU5URVJWQUwgPSAxMDA7XG5cbmZ1bmN0aW9uIFBvb2woY3JlYXRlLCBpZGxlKSB7XG4gIHRoaXMuY3JlYXRlID0gY3JlYXRlO1xuICB0aGlzLmF2YWlsYWJsZSA9IFtdO1xuICB0aGlzLmFjcXVpcmVkID0ge307XG4gIHRoaXMubGFzdElkID0gMTtcbiAgdGhpcy50aW1lb3V0SWQgPSAwO1xuICB0aGlzLmlkbGUgPSBpZGxlIHx8IDIwMDA7XG59XG5cblBvb2wucHJvdG90eXBlLmFjcXVpcmUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdmFyIHJlc291cmNlO1xuXG4gIGlmICh0aGlzLmF2YWlsYWJsZS5sZW5ndGggIT09IDApIHtcbiAgICByZXNvdXJjZSA9IHRoaXMuYXZhaWxhYmxlLnBvcCgpO1xuICB9IGVsc2Uge1xuICAgIHJlc291cmNlID0gdGhpcy5jcmVhdGUoKTtcbiAgICByZXNvdXJjZS5pZCA9IHRoaXMubGFzdElkKys7XG5cbiAgICByZXNvdXJjZS5yZWxlYXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzLnJlbGVhc2UocmVzb3VyY2UpO1xuICAgIH07XG4gIH1cblxuICB0aGlzLmFjcXVpcmVkW3Jlc291cmNlLmlkXSA9IHJlc291cmNlO1xuICByZXR1cm4gcmVzb3VyY2U7XG59O1xuXG5Qb29sLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24gKHJlc291cmNlKSB7XG4gIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gIGRlbGV0ZSB0aGlzLmFjcXVpcmVkW3Jlc291cmNlLmlkXTtcbiAgcmVzb3VyY2UubGFzdFVzZWQgPSBEYXRlLm5vdygpO1xuICB0aGlzLmF2YWlsYWJsZS5wdXNoKHJlc291cmNlKTtcblxuICBpZiAodGhpcy50aW1lb3V0SWQgPT09IDApIHtcbiAgICB0aGlzLnRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzMi5nYygpO1xuICAgIH0sIEdDX0lOVEVSVkFMKTtcbiAgfVxufTtcblxuUG9vbC5wcm90b3R5cGUuZ2MgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICB0aGlzLmF2YWlsYWJsZSA9IHRoaXMuYXZhaWxhYmxlLmZpbHRlcihmdW5jdGlvbiAocmVzb3VyY2UpIHtcbiAgICBpZiAobm93IC0gcmVzb3VyY2UubGFzdFVzZWQgPiBfdGhpczMuaWRsZSkge1xuICAgICAgcmVzb3VyY2UuZGVzdHJveSgpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcblxuICBpZiAodGhpcy5hdmFpbGFibGUubGVuZ3RoICE9PSAwKSB7XG4gICAgdGhpcy50aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBfdGhpczMuZ2MoKTtcbiAgICB9LCBHQ19JTlRFUlZBTCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy50aW1lb3V0SWQgPSAwO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvb2w7XG5cbn0se31dLDE0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIEFkZCBpbnRlcm1lZGlhdGUgcmVzaXppbmcgc3RlcHMgd2hlbiBzY2FsaW5nIGRvd24gYnkgYSB2ZXJ5IGxhcmdlIGZhY3Rvci5cbi8vXG4vLyBGb3IgZXhhbXBsZSwgd2hlbiByZXNpemluZyAxMDAwMHgxMDAwMCBkb3duIHRvIDEweDEwLCBpdCdsbCByZXNpemUgaXQgdG9cbi8vIDMwMHgzMDAgZmlyc3QuXG4vL1xuLy8gSXQncyBuZWVkZWQgYmVjYXVzZSB0aWxlciBoYXMgaXNzdWVzIHdoZW4gdGhlIGVudGlyZSB0aWxlIGlzIHNjYWxlZCBkb3duXG4vLyB0byBhIGZldyBwaXhlbHMgKDEwMjRweCBzb3VyY2UgdGlsZSB3aXRoIGJvcmRlciBzaXplIDMgc2hvdWxkIHJlc3VsdCBpblxuLy8gYXQgbGVhc3QgMyszKzIgPSA4cHggdGFyZ2V0IHRpbGUsIHNvIG1heCBzY2FsZSBmYWN0b3IgaXMgMTI4IGhlcmUpLlxuLy9cbi8vIEFsc28sIGFkZGluZyBpbnRlcm1lZGlhdGUgc3RlcHMgY2FuIHNwZWVkIHVwIHByb2Nlc3NpbmcgaWYgd2UgdXNlIGxvd2VyXG4vLyBxdWFsaXR5IGFsZ29yaXRobXMgZm9yIGZpcnN0IHN0YWdlcy5cbi8vXG4ndXNlIHN0cmljdCc7IC8vIG1pbiBzaXplID0gMCByZXN1bHRzIGluIGluZmluaXRlIGxvb3AsXG4vLyBtaW4gc2l6ZSA9IDEgY2FuIGNvbnN1bWUgbGFyZ2UgYW1vdW50IG9mIG1lbW9yeVxuXG52YXIgTUlOX0lOTkVSX1RJTEVfU0laRSA9IDI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlU3RhZ2VzKGZyb21XaWR0aCwgZnJvbUhlaWdodCwgdG9XaWR0aCwgdG9IZWlnaHQsIHNyY1RpbGVTaXplLCBkZXN0VGlsZUJvcmRlcikge1xuICB2YXIgc2NhbGVYID0gdG9XaWR0aCAvIGZyb21XaWR0aDtcbiAgdmFyIHNjYWxlWSA9IHRvSGVpZ2h0IC8gZnJvbUhlaWdodDsgLy8gZGVyaXZlZCBmcm9tIGNyZWF0ZVJlZ2lvbnMgZXF1YXRpb246XG4gIC8vIGlubmVyVGlsZVdpZHRoID0gcGl4ZWxGbG9vcihzcmNUaWxlU2l6ZSAqIHNjYWxlWCkgLSAyICogZGVzdFRpbGVCb3JkZXI7XG5cbiAgdmFyIG1pblNjYWxlID0gKDIgKiBkZXN0VGlsZUJvcmRlciArIE1JTl9JTk5FUl9USUxFX1NJWkUgKyAxKSAvIHNyY1RpbGVTaXplOyAvLyByZWZ1c2UgdG8gc2NhbGUgaW1hZ2UgbXVsdGlwbGUgdGltZXMgYnkgbGVzcyB0aGFuIHR3aWNlIGVhY2ggdGltZSxcbiAgLy8gaXQgY291bGQgb25seSBoYXBwZW4gYmVjYXVzZSBvZiBpbnZhbGlkIG9wdGlvbnNcblxuICBpZiAobWluU2NhbGUgPiAwLjUpIHJldHVybiBbW3RvV2lkdGgsIHRvSGVpZ2h0XV07XG4gIHZhciBzdGFnZUNvdW50ID0gTWF0aC5jZWlsKE1hdGgubG9nKE1hdGgubWluKHNjYWxlWCwgc2NhbGVZKSkgLyBNYXRoLmxvZyhtaW5TY2FsZSkpOyAvLyBubyBhZGRpdGlvbmFsIHJlc2l6ZXMgYXJlIG5lY2Vzc2FyeSxcbiAgLy8gc3RhZ2VDb3VudCBjYW4gYmUgemVybyBvciBiZSBuZWdhdGl2ZSB3aGVuIGVubGFyZ2luZyB0aGUgaW1hZ2VcblxuICBpZiAoc3RhZ2VDb3VudCA8PSAxKSByZXR1cm4gW1t0b1dpZHRoLCB0b0hlaWdodF1dO1xuICB2YXIgcmVzdWx0ID0gW107XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGFnZUNvdW50OyBpKyspIHtcbiAgICB2YXIgd2lkdGggPSBNYXRoLnJvdW5kKE1hdGgucG93KE1hdGgucG93KGZyb21XaWR0aCwgc3RhZ2VDb3VudCAtIGkgLSAxKSAqIE1hdGgucG93KHRvV2lkdGgsIGkgKyAxKSwgMSAvIHN0YWdlQ291bnQpKTtcbiAgICB2YXIgaGVpZ2h0ID0gTWF0aC5yb3VuZChNYXRoLnBvdyhNYXRoLnBvdyhmcm9tSGVpZ2h0LCBzdGFnZUNvdW50IC0gaSAtIDEpICogTWF0aC5wb3codG9IZWlnaHQsIGkgKyAxKSwgMSAvIHN0YWdlQ291bnQpKTtcbiAgICByZXN1bHQucHVzaChbd2lkdGgsIGhlaWdodF0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbn0se31dLDE1OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFNwbGl0IG9yaWdpbmFsIGltYWdlIGludG8gbXVsdGlwbGUgMTAyNHgxMDI0IGNodW5rcyB0byByZWR1Y2UgbWVtb3J5IHVzYWdlXG4vLyAoaW1hZ2VzIGhhdmUgdG8gYmUgdW5wYWNrZWQgaW50byB0eXBlZCBhcnJheXMgZm9yIHJlc2l6aW5nKSBhbmQgYWxsb3dcbi8vIHBhcmFsbGVsIHByb2Nlc3Npbmcgb2YgbXVsdGlwbGUgdGlsZXMgYXQgYSB0aW1lLlxuLy9cbid1c2Ugc3RyaWN0Jztcbi8qXG4gKiBwaXhlbEZsb29yIGFuZCBwaXhlbENlaWwgYXJlIG1vZGlmaWVkIHZlcnNpb25zIG9mIE1hdGguZmxvb3IgYW5kIE1hdGguY2VpbFxuICogZnVuY3Rpb25zIHdoaWNoIHRha2UgaW50byBhY2NvdW50IGZsb2F0aW5nIHBvaW50IGFyaXRobWV0aWMgZXJyb3JzLlxuICogVGhvc2UgZXJyb3JzIGNhbiBjYXVzZSB1bmRlc2lyZWQgaW5jcmVtZW50cy9kZWNyZW1lbnRzIG9mIHNpemVzIGFuZCBvZmZzZXRzOlxuICogTWF0aC5jZWlsKDM2IC8gKDM2IC8gNTAwKSkgPSA1MDFcbiAqIHBpeGVsQ2VpbCgzNiAvICgzNiAvIDUwMCkpID0gNTAwXG4gKi9cblxudmFyIFBJWEVMX0VQU0lMT04gPSAxZS01O1xuXG5mdW5jdGlvbiBwaXhlbEZsb29yKHgpIHtcbiAgdmFyIG5lYXJlc3QgPSBNYXRoLnJvdW5kKHgpO1xuXG4gIGlmIChNYXRoLmFicyh4IC0gbmVhcmVzdCkgPCBQSVhFTF9FUFNJTE9OKSB7XG4gICAgcmV0dXJuIG5lYXJlc3Q7XG4gIH1cblxuICByZXR1cm4gTWF0aC5mbG9vcih4KTtcbn1cblxuZnVuY3Rpb24gcGl4ZWxDZWlsKHgpIHtcbiAgdmFyIG5lYXJlc3QgPSBNYXRoLnJvdW5kKHgpO1xuXG4gIGlmIChNYXRoLmFicyh4IC0gbmVhcmVzdCkgPCBQSVhFTF9FUFNJTE9OKSB7XG4gICAgcmV0dXJuIG5lYXJlc3Q7XG4gIH1cblxuICByZXR1cm4gTWF0aC5jZWlsKHgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZVJlZ2lvbnMob3B0aW9ucykge1xuICB2YXIgc2NhbGVYID0gb3B0aW9ucy50b1dpZHRoIC8gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNjYWxlWSA9IG9wdGlvbnMudG9IZWlnaHQgLyBvcHRpb25zLmhlaWdodDtcbiAgdmFyIGlubmVyVGlsZVdpZHRoID0gcGl4ZWxGbG9vcihvcHRpb25zLnNyY1RpbGVTaXplICogc2NhbGVYKSAtIDIgKiBvcHRpb25zLmRlc3RUaWxlQm9yZGVyO1xuICB2YXIgaW5uZXJUaWxlSGVpZ2h0ID0gcGl4ZWxGbG9vcihvcHRpb25zLnNyY1RpbGVTaXplICogc2NhbGVZKSAtIDIgKiBvcHRpb25zLmRlc3RUaWxlQm9yZGVyOyAvLyBwcmV2ZW50IGluZmluaXRlIGxvb3AsIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlblxuXG4gIGlmIChpbm5lclRpbGVXaWR0aCA8IDEgfHwgaW5uZXJUaWxlSGVpZ2h0IDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgZXJyb3IgaW4gcGljYTogdGFyZ2V0IHRpbGUgd2lkdGgvaGVpZ2h0IGlzIHRvbyBzbWFsbC4nKTtcbiAgfVxuXG4gIHZhciB4LCB5O1xuICB2YXIgaW5uZXJYLCBpbm5lclksIHRvVGlsZVdpZHRoLCB0b1RpbGVIZWlnaHQ7XG4gIHZhciB0aWxlcyA9IFtdO1xuICB2YXIgdGlsZTsgLy8gd2UgZ28gdG9wLXRvLWRvd24gaW5zdGVhZCBvZiBsZWZ0LXRvLXJpZ2h0IHRvIG1ha2UgaW1hZ2UgZGlzcGxheWVkIGZyb20gdG9wIHRvXG4gIC8vIGRvZXNuIGluIHRoZSBicm93c2VyXG5cbiAgZm9yIChpbm5lclkgPSAwOyBpbm5lclkgPCBvcHRpb25zLnRvSGVpZ2h0OyBpbm5lclkgKz0gaW5uZXJUaWxlSGVpZ2h0KSB7XG4gICAgZm9yIChpbm5lclggPSAwOyBpbm5lclggPCBvcHRpb25zLnRvV2lkdGg7IGlubmVyWCArPSBpbm5lclRpbGVXaWR0aCkge1xuICAgICAgeCA9IGlubmVyWCAtIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG5cbiAgICAgIGlmICh4IDwgMCkge1xuICAgICAgICB4ID0gMDtcbiAgICAgIH1cblxuICAgICAgdG9UaWxlV2lkdGggPSBpbm5lclggKyBpbm5lclRpbGVXaWR0aCArIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXIgLSB4O1xuXG4gICAgICBpZiAoeCArIHRvVGlsZVdpZHRoID49IG9wdGlvbnMudG9XaWR0aCkge1xuICAgICAgICB0b1RpbGVXaWR0aCA9IG9wdGlvbnMudG9XaWR0aCAtIHg7XG4gICAgICB9XG5cbiAgICAgIHkgPSBpbm5lclkgLSBvcHRpb25zLmRlc3RUaWxlQm9yZGVyO1xuXG4gICAgICBpZiAoeSA8IDApIHtcbiAgICAgICAgeSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHRvVGlsZUhlaWdodCA9IGlubmVyWSArIGlubmVyVGlsZUhlaWdodCArIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXIgLSB5O1xuXG4gICAgICBpZiAoeSArIHRvVGlsZUhlaWdodCA+PSBvcHRpb25zLnRvSGVpZ2h0KSB7XG4gICAgICAgIHRvVGlsZUhlaWdodCA9IG9wdGlvbnMudG9IZWlnaHQgLSB5O1xuICAgICAgfVxuXG4gICAgICB0aWxlID0ge1xuICAgICAgICB0b1g6IHgsXG4gICAgICAgIHRvWTogeSxcbiAgICAgICAgdG9XaWR0aDogdG9UaWxlV2lkdGgsXG4gICAgICAgIHRvSGVpZ2h0OiB0b1RpbGVIZWlnaHQsXG4gICAgICAgIHRvSW5uZXJYOiBpbm5lclgsXG4gICAgICAgIHRvSW5uZXJZOiBpbm5lclksXG4gICAgICAgIHRvSW5uZXJXaWR0aDogaW5uZXJUaWxlV2lkdGgsXG4gICAgICAgIHRvSW5uZXJIZWlnaHQ6IGlubmVyVGlsZUhlaWdodCxcbiAgICAgICAgb2Zmc2V0WDogeCAvIHNjYWxlWCAtIHBpeGVsRmxvb3IoeCAvIHNjYWxlWCksXG4gICAgICAgIG9mZnNldFk6IHkgLyBzY2FsZVkgLSBwaXhlbEZsb29yKHkgLyBzY2FsZVkpLFxuICAgICAgICBzY2FsZVg6IHNjYWxlWCxcbiAgICAgICAgc2NhbGVZOiBzY2FsZVksXG4gICAgICAgIHg6IHBpeGVsRmxvb3IoeCAvIHNjYWxlWCksXG4gICAgICAgIHk6IHBpeGVsRmxvb3IoeSAvIHNjYWxlWSksXG4gICAgICAgIHdpZHRoOiBwaXhlbENlaWwodG9UaWxlV2lkdGggLyBzY2FsZVgpLFxuICAgICAgICBoZWlnaHQ6IHBpeGVsQ2VpbCh0b1RpbGVIZWlnaHQgLyBzY2FsZVkpXG4gICAgICB9O1xuICAgICAgdGlsZXMucHVzaCh0aWxlKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGlsZXM7XG59O1xuXG59LHt9XSwxNjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIG9iakNsYXNzKG9iaikge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaik7XG59XG5cbm1vZHVsZS5leHBvcnRzLmlzQ2FudmFzID0gZnVuY3Rpb24gaXNDYW52YXMoZWxlbWVudCkge1xuICB2YXIgY25hbWUgPSBvYmpDbGFzcyhlbGVtZW50KTtcbiAgcmV0dXJuIGNuYW1lID09PSAnW29iamVjdCBIVE1MQ2FudmFzRWxlbWVudF0nXG4gIC8qIGJyb3dzZXIgKi9cbiAgfHwgY25hbWUgPT09ICdbb2JqZWN0IE9mZnNjcmVlbkNhbnZhc10nIHx8IGNuYW1lID09PSAnW29iamVjdCBDYW52YXNdJ1xuICAvKiBub2RlLWNhbnZhcyAqL1xuICA7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5pc0ltYWdlID0gZnVuY3Rpb24gaXNJbWFnZShlbGVtZW50KSB7XG4gIHJldHVybiBvYmpDbGFzcyhlbGVtZW50KSA9PT0gJ1tvYmplY3QgSFRNTEltYWdlRWxlbWVudF0nO1xufTtcblxubW9kdWxlLmV4cG9ydHMuaXNJbWFnZUJpdG1hcCA9IGZ1bmN0aW9uIGlzSW1hZ2VCaXRtYXAoZWxlbWVudCkge1xuICByZXR1cm4gb2JqQ2xhc3MoZWxlbWVudCkgPT09ICdbb2JqZWN0IEltYWdlQml0bWFwXSc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5saW1pdGVyID0gZnVuY3Rpb24gbGltaXRlcihjb25jdXJyZW5jeSkge1xuICB2YXIgYWN0aXZlID0gMCxcbiAgICAgIHF1ZXVlID0gW107XG5cbiAgZnVuY3Rpb24gcm9sbCgpIHtcbiAgICBpZiAoYWN0aXZlIDwgY29uY3VycmVuY3kgJiYgcXVldWUubGVuZ3RoKSB7XG4gICAgICBhY3RpdmUrKztcbiAgICAgIHF1ZXVlLnNoaWZ0KCkoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gbGltaXQoZm4pIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgcXVldWUucHVzaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZuKCkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgIGFjdGl2ZS0tO1xuICAgICAgICAgIHJvbGwoKTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgIGFjdGl2ZS0tO1xuICAgICAgICAgIHJvbGwoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHJvbGwoKTtcbiAgICB9KTtcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNpYl9xdWFsaXR5X25hbWUgPSBmdW5jdGlvbiBjaWJfcXVhbGl0eV9uYW1lKG51bSkge1xuICBzd2l0Y2ggKG51bSkge1xuICAgIGNhc2UgMDpcbiAgICAgIHJldHVybiAncGl4ZWxhdGVkJztcblxuICAgIGNhc2UgMTpcbiAgICAgIHJldHVybiAnbG93JztcblxuICAgIGNhc2UgMjpcbiAgICAgIHJldHVybiAnbWVkaXVtJztcbiAgfVxuXG4gIHJldHVybiAnaGlnaCc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5jaWJfc3VwcG9ydCA9IGZ1bmN0aW9uIGNpYl9zdXBwb3J0KGNyZWF0ZUNhbnZhcykge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiBjcmVhdGVJbWFnZUJpdG1hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgYyA9IGNyZWF0ZUNhbnZhcygxMDAsIDEwMCk7XG4gICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGMsIDAsIDAsIDEwMCwgMTAwLCB7XG4gICAgICByZXNpemVXaWR0aDogMTAsXG4gICAgICByZXNpemVIZWlnaHQ6IDEwLFxuICAgICAgcmVzaXplUXVhbGl0eTogJ2hpZ2gnXG4gICAgfSkudGhlbihmdW5jdGlvbiAoYml0bWFwKSB7XG4gICAgICB2YXIgc3RhdHVzID0gYml0bWFwLndpZHRoID09PSAxMDsgLy8gQnJhbmNoIGJlbG93IGlzIGZpbHRlcmVkIG9uIHVwcGVyIGxldmVsLiBXZSBkbyBub3QgY2FsbCByZXNpemVcbiAgICAgIC8vIGRldGVjdGlvbiBmb3IgYmFzaWMgSW1hZ2VCaXRtYXAuXG4gICAgICAvL1xuICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0ltYWdlQml0bWFwXG4gICAgICAvLyBvbGQgQ3JvbWUgNTEgaGFzIEltYWdlQml0bWFwIHdpdGhvdXQgLmNsb3NlKCkuIFRoZW4gdGhpcyBjb2RlXG4gICAgICAvLyB3aWxsIHRocm93IGFuZCByZXR1cm4gJ2ZhbHNlJyBhcyBleHBlY3RlZC5cbiAgICAgIC8vXG5cbiAgICAgIGJpdG1hcC5jbG9zZSgpO1xuICAgICAgYyA9IG51bGw7XG4gICAgICByZXR1cm4gc3RhdHVzO1xuICAgIH0pO1xuICB9KVtcImNhdGNoXCJdKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMud29ya2VyX29mZnNjcmVlbl9jYW52YXNfc3VwcG9ydCA9IGZ1bmN0aW9uIHdvcmtlcl9vZmZzY3JlZW5fY2FudmFzX3N1cHBvcnQoKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgaWYgKHR5cGVvZiBPZmZzY3JlZW5DYW52YXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAvLyBpZiBPZmZzY3JlZW5DYW52YXMgaXMgcHJlc2VudCwgd2UgYXNzdW1lIGJyb3dzZXIgc3VwcG9ydHMgV29ya2VyIGFuZCBidWlsdC1pbiBQcm9taXNlIGFzIHdlbGxcbiAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdvcmtlclBheWxvYWQoc2VsZikge1xuICAgICAgaWYgKHR5cGVvZiBjcmVhdGVJbWFnZUJpdG1hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VsZi5wb3N0TWVzc2FnZShmYWxzZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjYW52YXMgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKDEwLCAxMCk7IC8vIHRlc3QgdGhhdCAyZCBjb250ZXh0IGNhbiBiZSB1c2VkIGluIHdvcmtlclxuXG4gICAgICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgY3R4LnJlY3QoMCwgMCwgMSwgMSk7IC8vIHRlc3QgdGhhdCBjaWIgY2FuIGJlIHVzZWQgdG8gcmV0dXJuIGltYWdlIGJpdG1hcCBmcm9tIHdvcmtlclxuXG4gICAgICAgIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChjYW52YXMsIDAsIDAsIDEsIDEpO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzZWxmLnBvc3RNZXNzYWdlKHRydWUpO1xuICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gc2VsZi5wb3N0TWVzc2FnZShmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgY29kZSA9IGJ0b2EoXCIoXCIuY29uY2F0KHdvcmtlclBheWxvYWQudG9TdHJpbmcoKSwgXCIpKHNlbGYpO1wiKSk7XG4gICAgdmFyIHcgPSBuZXcgV29ya2VyKFwiZGF0YTp0ZXh0L2phdmFzY3JpcHQ7YmFzZTY0LFwiLmNvbmNhdChjb2RlKSk7XG5cbiAgICB3Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgcmV0dXJuIHJlc29sdmUoZXYuZGF0YSk7XG4gICAgfTtcblxuICAgIHcub25lcnJvciA9IHJlamVjdDtcbiAgfSkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSwgZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSk7XG59OyAvLyBDaGVjayBpZiBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKS5nZXRJbWFnZURhdGEgY2FuIGJlIHVzZWQsXG4vLyBGaXJlRm94IHJhbmRvbWl6ZXMgdGhlIG91dHB1dCBvZiB0aGF0IGZ1bmN0aW9uIGluIGBwcml2YWN5LnJlc2lzdEZpbmdlcnByaW50aW5nYCBtb2RlXG5cblxubW9kdWxlLmV4cG9ydHMuY2FuX3VzZV9jYW52YXMgPSBmdW5jdGlvbiBjYW5fdXNlX2NhbnZhcyhjcmVhdGVDYW52YXMpIHtcbiAgdmFyIHVzYWJsZSA9IGZhbHNlO1xuXG4gIHRyeSB7XG4gICAgdmFyIGNhbnZhcyA9IGNyZWF0ZUNhbnZhcygyLCAxKTtcbiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgdmFyIGQgPSBjdHguY3JlYXRlSW1hZ2VEYXRhKDIsIDEpO1xuICAgIGQuZGF0YVswXSA9IDEyO1xuICAgIGQuZGF0YVsxXSA9IDIzO1xuICAgIGQuZGF0YVsyXSA9IDM0O1xuICAgIGQuZGF0YVszXSA9IDI1NTtcbiAgICBkLmRhdGFbNF0gPSA0NTtcbiAgICBkLmRhdGFbNV0gPSA1NjtcbiAgICBkLmRhdGFbNl0gPSA2NztcbiAgICBkLmRhdGFbN10gPSAyNTU7XG4gICAgY3R4LnB1dEltYWdlRGF0YShkLCAwLCAwKTtcbiAgICBkID0gbnVsbDtcbiAgICBkID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCAyLCAxKTtcblxuICAgIGlmIChkLmRhdGFbMF0gPT09IDEyICYmIGQuZGF0YVsxXSA9PT0gMjMgJiYgZC5kYXRhWzJdID09PSAzNCAmJiBkLmRhdGFbM10gPT09IDI1NSAmJiBkLmRhdGFbNF0gPT09IDQ1ICYmIGQuZGF0YVs1XSA9PT0gNTYgJiYgZC5kYXRhWzZdID09PSA2NyAmJiBkLmRhdGFbN10gPT09IDI1NSkge1xuICAgICAgdXNhYmxlID0gdHJ1ZTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge31cblxuICByZXR1cm4gdXNhYmxlO1xufTsgLy8gQ2hlY2sgaWYgY3JlYXRlSW1hZ2VCaXRtYXAoaW1nLCBzeCwgc3ksIHN3LCBzaCkgc2lnbmF0dXJlIHdvcmtzIGNvcnJlY3RseVxuLy8gd2l0aCBKUEVHIGltYWdlcyBvcmllbnRlZCB3aXRoIEV4aWY7XG4vLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0xMjIwNjcxXG4vLyBUT0RPOiByZW1vdmUgYWZ0ZXIgaXQncyBmaXhlZCBpbiBjaHJvbWUgZm9yIGF0IGxlYXN0IDIgcmVsZWFzZXNcblxuXG5tb2R1bGUuZXhwb3J0cy5jaWJfY2FuX3VzZV9yZWdpb24gPSBmdW5jdGlvbiBjaWJfY2FuX3VzZV9yZWdpb24oKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgIGlmICh0eXBlb2YgY3JlYXRlSW1hZ2VCaXRtYXAgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICBpbWFnZS5zcmMgPSAnZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwnICsgJy85ai80UUJpUlhocFpnQUFUVTBBS2dBQUFBZ0FCUUVTQUFNQUFBQUJBQVlBQUFFYUFBVUFBQUFCQUFBQVNnRWJBQVVBQScgKyAnQUFCQUFBQVVnRW9BQU1BQUFBQkFBSUFBQUlUQUFNQUFBQUJBQUVBQUFBQUFBQUFBQUJJQUFBQUFRQUFBRWdBQUFBQi85JyArICdzQVF3QUVBd01FQXdNRUJBTUVCUVFFQlFZS0J3WUdCZ1lOQ1FvSUNnOE5FQkFQRFE4T0VSTVlGQkVTRnhJT0R4VWNGUmMnICsgJ1pHUnNiR3hBVUhSOGRHaDhZR2hzYS85c0FRd0VFQlFVR0JRWU1Cd2NNR2hFUEVSb2FHaG9hR2hvYUdob2FHaG9hR2hvYScgKyAnR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2EvOElBRVFnQUFRQUNBd0VSQUFJUkFRTVJBJyArICdmL0VBQlFBQVFBQUFBQUFBQUFBQUFBQUFBQUFBQWYveEFBVUFRRUFBQUFBQUFBQUFBQUFBQUFBQUFBQS85b0FEQU1CQUEnICsgJ0lRQXhBQUFBRi9QLy9FQUJRUUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUVBQVFVQ2YvL0VBQlFSQVFBQUFBQScgKyAnQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFNQkFUOEJmLy9FQUJRUkFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUlCJyArICdBVDhCZi8vRUFCUVFBUUFBQUFBQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFFQUJqOENmLy9FQUJRUUFRQUFBQUFBQUFBQUEnICsgJ0FBQUFBQUFBQUQvMmdBSUFRRUFBVDhoZi8vYUFBd0RBUUFDQUFNQUFBQVFILy9FQUJRUkFRQUFBQUFBQUFBQUFBQUFBQScgKyAnQUFBQUQvMmdBSUFRTUJBVDhRZi8vRUFCUVJBUUFBQUFBQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFJQkFUOFFmLy9FQUJRJyArICdRQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRRUFBVDhRZi8vWic7XG5cbiAgICBpbWFnZS5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBjcmVhdGVJbWFnZUJpdG1hcChpbWFnZSwgMCwgMCwgaW1hZ2Uud2lkdGgsIGltYWdlLmhlaWdodCkudGhlbihmdW5jdGlvbiAoYml0bWFwKSB7XG4gICAgICAgIGlmIChiaXRtYXAud2lkdGggPT09IGltYWdlLndpZHRoICYmIGJpdG1hcC5oZWlnaHQgPT09IGltYWdlLmhlaWdodCkge1xuICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoZmFsc2UpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZShmYWxzZSk7XG4gICAgfTtcbiAgfSk7XG59O1xuXG59LHt9XSwxNzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBXZWIgV29ya2VyIHdyYXBwZXIgZm9yIGltYWdlIHJlc2l6ZSBmdW5jdGlvblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIE1hdGhMaWIgPSBfZGVyZXFfKCcuL21hdGhsaWInKTtcblxuICB2YXIgbWF0aExpYjtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cblxuICBvbm1lc3NhZ2UgPSBmdW5jdGlvbiBvbm1lc3NhZ2UoZXYpIHtcbiAgICB2YXIgdGlsZU9wdHMgPSBldi5kYXRhLm9wdHM7XG4gICAgdmFyIHJldHVybkJpdG1hcCA9IGZhbHNlO1xuXG4gICAgaWYgKCF0aWxlT3B0cy5zcmMgJiYgdGlsZU9wdHMuc3JjQml0bWFwKSB7XG4gICAgICB2YXIgY2FudmFzID0gbmV3IE9mZnNjcmVlbkNhbnZhcyh0aWxlT3B0cy53aWR0aCwgdGlsZU9wdHMuaGVpZ2h0KTtcbiAgICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICAgIGFscGhhOiBCb29sZWFuKHRpbGVPcHRzLmFscGhhKVxuICAgICAgfSk7XG4gICAgICBjdHguZHJhd0ltYWdlKHRpbGVPcHRzLnNyY0JpdG1hcCwgMCwgMCk7XG4gICAgICB0aWxlT3B0cy5zcmMgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIHRpbGVPcHRzLndpZHRoLCB0aWxlT3B0cy5oZWlnaHQpLmRhdGE7XG4gICAgICBjYW52YXMud2lkdGggPSBjYW52YXMuaGVpZ2h0ID0gMDtcbiAgICAgIGNhbnZhcyA9IG51bGw7XG4gICAgICB0aWxlT3B0cy5zcmNCaXRtYXAuY2xvc2UoKTtcbiAgICAgIHRpbGVPcHRzLnNyY0JpdG1hcCA9IG51bGw7IC8vIFRlbXBvcmFyeSBmb3JjZSBvdXQgZGF0YSB0byB0eXBlZCBhcnJheSwgYmVjYXVzZSBDaHJvbWUgaGF2ZSBhcnRlZmFjdHNcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMjIzXG4gICAgICAvLyByZXR1cm5CaXRtYXAgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICghbWF0aExpYikgbWF0aExpYiA9IG5ldyBNYXRoTGliKGV2LmRhdGEuZmVhdHVyZXMpOyAvLyBVc2UgbXVsdGltYXRoJ3Mgc3luYyBhdXRvLWluaXQuIEF2b2lkIFByb21pc2UgdXNlIGluIG9sZCBicm93c2VycyxcbiAgICAvLyBiZWNhdXNlIHBvbHlmaWxscyBhcmUgbm90IHByb3BhZ2F0ZWQgdG8gd2Vid29ya2VyLlxuXG4gICAgdmFyIGRhdGEgPSBtYXRoTGliLnJlc2l6ZUFuZFVuc2hhcnAodGlsZU9wdHMpO1xuXG4gICAgaWYgKHJldHVybkJpdG1hcCkge1xuICAgICAgdmFyIHRvSW1hZ2VEYXRhID0gbmV3IEltYWdlRGF0YShuZXcgVWludDhDbGFtcGVkQXJyYXkoZGF0YSksIHRpbGVPcHRzLnRvV2lkdGgsIHRpbGVPcHRzLnRvSGVpZ2h0KTtcblxuICAgICAgdmFyIF9jYW52YXMgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHRpbGVPcHRzLnRvV2lkdGgsIHRpbGVPcHRzLnRvSGVpZ2h0KTtcblxuICAgICAgdmFyIF9jdHggPSBfY2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgICAgICBhbHBoYTogQm9vbGVhbih0aWxlT3B0cy5hbHBoYSlcbiAgICAgIH0pO1xuXG4gICAgICBfY3R4LnB1dEltYWdlRGF0YSh0b0ltYWdlRGF0YSwgMCwgMCk7XG5cbiAgICAgIGNyZWF0ZUltYWdlQml0bWFwKF9jYW52YXMpLnRoZW4oZnVuY3Rpb24gKGJpdG1hcCkge1xuICAgICAgICBwb3N0TWVzc2FnZSh7XG4gICAgICAgICAgYml0bWFwOiBiaXRtYXBcbiAgICAgICAgfSwgW2JpdG1hcF0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBvc3RNZXNzYWdlKHtcbiAgICAgICAgZGF0YTogZGF0YVxuICAgICAgfSwgW2RhdGEuYnVmZmVyXSk7XG4gICAgfVxuICB9O1xufTtcblxufSx7XCIuL21hdGhsaWJcIjoxfV0sMTg6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gQ2FsY3VsYXRlIEdhdXNzaWFuIGJsdXIgb2YgYW4gaW1hZ2UgdXNpbmcgSUlSIGZpbHRlclxuLy8gVGhlIG1ldGhvZCBpcyB0YWtlbiBmcm9tIEludGVsJ3Mgd2hpdGUgcGFwZXIgYW5kIGNvZGUgZXhhbXBsZSBhdHRhY2hlZCB0byBpdDpcbi8vIGh0dHBzOi8vc29mdHdhcmUuaW50ZWwuY29tL2VuLXVzL2FydGljbGVzL2lpci1nYXVzc2lhbi1ibHVyLWZpbHRlclxuLy8gLWltcGxlbWVudGF0aW9uLXVzaW5nLWludGVsLWFkdmFuY2VkLXZlY3Rvci1leHRlbnNpb25zXG5cbnZhciBhMCwgYTEsIGEyLCBhMywgYjEsIGIyLCBsZWZ0X2Nvcm5lciwgcmlnaHRfY29ybmVyO1xuXG5mdW5jdGlvbiBnYXVzc0NvZWYoc2lnbWEpIHtcbiAgaWYgKHNpZ21hIDwgMC41KSB7XG4gICAgc2lnbWEgPSAwLjU7XG4gIH1cblxuICB2YXIgYSA9IE1hdGguZXhwKDAuNzI2ICogMC43MjYpIC8gc2lnbWEsXG4gICAgICBnMSA9IE1hdGguZXhwKC1hKSxcbiAgICAgIGcyID0gTWF0aC5leHAoLTIgKiBhKSxcbiAgICAgIGsgPSAoMSAtIGcxKSAqICgxIC0gZzEpIC8gKDEgKyAyICogYSAqIGcxIC0gZzIpO1xuXG4gIGEwID0gaztcbiAgYTEgPSBrICogKGEgLSAxKSAqIGcxO1xuICBhMiA9IGsgKiAoYSArIDEpICogZzE7XG4gIGEzID0gLWsgKiBnMjtcbiAgYjEgPSAyICogZzE7XG4gIGIyID0gLWcyO1xuICBsZWZ0X2Nvcm5lciA9IChhMCArIGExKSAvICgxIC0gYjEgLSBiMik7XG4gIHJpZ2h0X2Nvcm5lciA9IChhMiArIGEzKSAvICgxIC0gYjEgLSBiMik7XG5cbiAgLy8gQXR0ZW1wdCB0byBmb3JjZSB0eXBlIHRvIEZQMzIuXG4gIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KFsgYTAsIGExLCBhMiwgYTMsIGIxLCBiMiwgbGVmdF9jb3JuZXIsIHJpZ2h0X2Nvcm5lciBdKTtcbn1cblxuZnVuY3Rpb24gY29udm9sdmVNb25vMTYoc3JjLCBvdXQsIGxpbmUsIGNvZWZmLCB3aWR0aCwgaGVpZ2h0KSB7XG4gIC8vIHRha2VzIHNyYyBpbWFnZSBhbmQgd3JpdGVzIHRoZSBibHVycmVkIGFuZCB0cmFuc3Bvc2VkIHJlc3VsdCBpbnRvIG91dFxuXG4gIHZhciBwcmV2X3NyYywgY3Vycl9zcmMsIGN1cnJfb3V0LCBwcmV2X291dCwgcHJldl9wcmV2X291dDtcbiAgdmFyIHNyY19pbmRleCwgb3V0X2luZGV4LCBsaW5lX2luZGV4O1xuICB2YXIgaSwgajtcbiAgdmFyIGNvZWZmX2EwLCBjb2VmZl9hMSwgY29lZmZfYjEsIGNvZWZmX2IyO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBoZWlnaHQ7IGkrKykge1xuICAgIHNyY19pbmRleCA9IGkgKiB3aWR0aDtcbiAgICBvdXRfaW5kZXggPSBpO1xuICAgIGxpbmVfaW5kZXggPSAwO1xuXG4gICAgLy8gbGVmdCB0byByaWdodFxuICAgIHByZXZfc3JjID0gc3JjW3NyY19pbmRleF07XG4gICAgcHJldl9wcmV2X291dCA9IHByZXZfc3JjICogY29lZmZbNl07XG4gICAgcHJldl9vdXQgPSBwcmV2X3ByZXZfb3V0O1xuXG4gICAgY29lZmZfYTAgPSBjb2VmZlswXTtcbiAgICBjb2VmZl9hMSA9IGNvZWZmWzFdO1xuICAgIGNvZWZmX2IxID0gY29lZmZbNF07XG4gICAgY29lZmZfYjIgPSBjb2VmZls1XTtcblxuICAgIGZvciAoaiA9IDA7IGogPCB3aWR0aDsgaisrKSB7XG4gICAgICBjdXJyX3NyYyA9IHNyY1tzcmNfaW5kZXhdO1xuXG4gICAgICBjdXJyX291dCA9IGN1cnJfc3JjICogY29lZmZfYTAgK1xuICAgICAgICAgICAgICAgICBwcmV2X3NyYyAqIGNvZWZmX2ExICtcbiAgICAgICAgICAgICAgICAgcHJldl9vdXQgKiBjb2VmZl9iMSArXG4gICAgICAgICAgICAgICAgIHByZXZfcHJldl9vdXQgKiBjb2VmZl9iMjtcblxuICAgICAgcHJldl9wcmV2X291dCA9IHByZXZfb3V0O1xuICAgICAgcHJldl9vdXQgPSBjdXJyX291dDtcbiAgICAgIHByZXZfc3JjID0gY3Vycl9zcmM7XG5cbiAgICAgIGxpbmVbbGluZV9pbmRleF0gPSBwcmV2X291dDtcbiAgICAgIGxpbmVfaW5kZXgrKztcbiAgICAgIHNyY19pbmRleCsrO1xuICAgIH1cblxuICAgIHNyY19pbmRleC0tO1xuICAgIGxpbmVfaW5kZXgtLTtcbiAgICBvdXRfaW5kZXggKz0gaGVpZ2h0ICogKHdpZHRoIC0gMSk7XG5cbiAgICAvLyByaWdodCB0byBsZWZ0XG4gICAgcHJldl9zcmMgPSBzcmNbc3JjX2luZGV4XTtcbiAgICBwcmV2X3ByZXZfb3V0ID0gcHJldl9zcmMgKiBjb2VmZls3XTtcbiAgICBwcmV2X291dCA9IHByZXZfcHJldl9vdXQ7XG4gICAgY3Vycl9zcmMgPSBwcmV2X3NyYztcblxuICAgIGNvZWZmX2EwID0gY29lZmZbMl07XG4gICAgY29lZmZfYTEgPSBjb2VmZlszXTtcblxuICAgIGZvciAoaiA9IHdpZHRoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgIGN1cnJfb3V0ID0gY3Vycl9zcmMgKiBjb2VmZl9hMCArXG4gICAgICAgICAgICAgICAgIHByZXZfc3JjICogY29lZmZfYTEgK1xuICAgICAgICAgICAgICAgICBwcmV2X291dCAqIGNvZWZmX2IxICtcbiAgICAgICAgICAgICAgICAgcHJldl9wcmV2X291dCAqIGNvZWZmX2IyO1xuXG4gICAgICBwcmV2X3ByZXZfb3V0ID0gcHJldl9vdXQ7XG4gICAgICBwcmV2X291dCA9IGN1cnJfb3V0O1xuXG4gICAgICBwcmV2X3NyYyA9IGN1cnJfc3JjO1xuICAgICAgY3Vycl9zcmMgPSBzcmNbc3JjX2luZGV4XTtcblxuICAgICAgb3V0W291dF9pbmRleF0gPSBsaW5lW2xpbmVfaW5kZXhdICsgcHJldl9vdXQ7XG5cbiAgICAgIHNyY19pbmRleC0tO1xuICAgICAgbGluZV9pbmRleC0tO1xuICAgICAgb3V0X2luZGV4IC09IGhlaWdodDtcbiAgICB9XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBibHVyTW9ubzE2KHNyYywgd2lkdGgsIGhlaWdodCwgcmFkaXVzKSB7XG4gIC8vIFF1aWNrIGV4aXQgb24gemVybyByYWRpdXNcbiAgaWYgKCFyYWRpdXMpIHsgcmV0dXJuOyB9XG5cbiAgdmFyIG91dCAgICAgID0gbmV3IFVpbnQxNkFycmF5KHNyYy5sZW5ndGgpLFxuICAgICAgdG1wX2xpbmUgPSBuZXcgRmxvYXQzMkFycmF5KE1hdGgubWF4KHdpZHRoLCBoZWlnaHQpKTtcblxuICB2YXIgY29lZmYgPSBnYXVzc0NvZWYocmFkaXVzKTtcblxuICBjb252b2x2ZU1vbm8xNihzcmMsIG91dCwgdG1wX2xpbmUsIGNvZWZmLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpO1xuICBjb252b2x2ZU1vbm8xNihvdXQsIHNyYywgdG1wX2xpbmUsIGNvZWZmLCBoZWlnaHQsIHdpZHRoLCByYWRpdXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJsdXJNb25vMTY7XG5cbn0se31dLDE5OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbmlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cblxufSx7fV0sMjA6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBhc3NpZ24gICAgICAgICA9IF9kZXJlcV8oJ29iamVjdC1hc3NpZ24nKTtcbnZhciBiYXNlNjRkZWNvZGUgICA9IF9kZXJlcV8oJy4vbGliL2Jhc2U2NGRlY29kZScpO1xudmFyIGhhc1dlYkFzc2VtYmx5ID0gX2RlcmVxXygnLi9saWIvd2FfZGV0ZWN0Jyk7XG5cblxudmFyIERFRkFVTFRfT1BUSU9OUyA9IHtcbiAganM6IHRydWUsXG4gIHdhc206IHRydWVcbn07XG5cblxuZnVuY3Rpb24gTXVsdGlNYXRoKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE11bHRpTWF0aCkpIHJldHVybiBuZXcgTXVsdGlNYXRoKG9wdGlvbnMpO1xuXG4gIHZhciBvcHRzID0gYXNzaWduKHt9LCBERUZBVUxUX09QVElPTlMsIG9wdGlvbnMgfHwge30pO1xuXG4gIHRoaXMub3B0aW9ucyAgICAgICAgID0gb3B0cztcblxuICB0aGlzLl9fY2FjaGUgICAgICAgICA9IHt9O1xuXG4gIHRoaXMuX19pbml0X3Byb21pc2UgID0gbnVsbDtcbiAgdGhpcy5fX21vZHVsZXMgICAgICAgPSBvcHRzLm1vZHVsZXMgfHwge307XG4gIHRoaXMuX19tZW1vcnkgICAgICAgID0gbnVsbDtcbiAgdGhpcy5fX3dhc20gICAgICAgICAgPSB7fTtcblxuICB0aGlzLl9faXNMRSA9ICgobmV3IFVpbnQzMkFycmF5KChuZXcgVWludDhBcnJheShbIDEsIDAsIDAsIDAgXSkpLmJ1ZmZlcikpWzBdID09PSAxKTtcblxuICBpZiAoIXRoaXMub3B0aW9ucy5qcyAmJiAhdGhpcy5vcHRpb25zLndhc20pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ21hdGhsaWI6IGF0IGxlYXN0IFwianNcIiBvciBcIndhc21cIiBzaG91bGQgYmUgZW5hYmxlZCcpO1xuICB9XG59XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS5oYXNfd2FzbSA9IGhhc1dlYkFzc2VtYmx5O1xuXG5cbk11bHRpTWF0aC5wcm90b3R5cGUudXNlID0gZnVuY3Rpb24gKG1vZHVsZSkge1xuICB0aGlzLl9fbW9kdWxlc1ttb2R1bGUubmFtZV0gPSBtb2R1bGU7XG5cbiAgLy8gUGluIHRoZSBiZXN0IHBvc3NpYmxlIGltcGxlbWVudGF0aW9uXG4gIGlmICh0aGlzLm9wdGlvbnMud2FzbSAmJiB0aGlzLmhhc193YXNtKCkgJiYgbW9kdWxlLndhc21fZm4pIHtcbiAgICB0aGlzW21vZHVsZS5uYW1lXSA9IG1vZHVsZS53YXNtX2ZuO1xuICB9IGVsc2Uge1xuICAgIHRoaXNbbW9kdWxlLm5hbWVdID0gbW9kdWxlLmZuO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5cbk11bHRpTWF0aC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX19pbml0X3Byb21pc2UpIHJldHVybiB0aGlzLl9faW5pdF9wcm9taXNlO1xuXG4gIGlmICghdGhpcy5vcHRpb25zLmpzICYmIHRoaXMub3B0aW9ucy53YXNtICYmICF0aGlzLmhhc193YXNtKCkpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdtYXRobGliOiBvbmx5IFwid2FzbVwiIHdhcyBlbmFibGVkLCBidXQgaXRcXCdzIG5vdCBzdXBwb3J0ZWQnKSk7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5fX2luaXRfcHJvbWlzZSA9IFByb21pc2UuYWxsKE9iamVjdC5rZXlzKHNlbGYuX19tb2R1bGVzKS5tYXAoZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB2YXIgbW9kdWxlID0gc2VsZi5fX21vZHVsZXNbbmFtZV07XG5cbiAgICBpZiAoIXNlbGYub3B0aW9ucy53YXNtIHx8ICFzZWxmLmhhc193YXNtKCkgfHwgIW1vZHVsZS53YXNtX2ZuKSByZXR1cm4gbnVsbDtcblxuICAgIC8vIElmIGFscmVhZHkgY29tcGlsZWQgLSBleGl0XG4gICAgaWYgKHNlbGYuX193YXNtW25hbWVdKSByZXR1cm4gbnVsbDtcblxuICAgIC8vIENvbXBpbGUgd2FzbSBzb3VyY2VcbiAgICByZXR1cm4gV2ViQXNzZW1ibHkuY29tcGlsZShzZWxmLl9fYmFzZTY0ZGVjb2RlKG1vZHVsZS53YXNtX3NyYykpXG4gICAgICAudGhlbihmdW5jdGlvbiAobSkgeyBzZWxmLl9fd2FzbVtuYW1lXSA9IG07IH0pO1xuICB9KSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBzZWxmOyB9KTtcblxuICByZXR1cm4gdGhpcy5fX2luaXRfcHJvbWlzZTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIE1ldGhvZHMgYmVsb3cgYXJlIGZvciBpbnRlcm5hbCB1c2UgZnJvbSBwbHVnaW5zXG5cblxuLy8gU2ltcGxlIGRlY29kZSBiYXNlNjQgdG8gdHlwZWQgYXJyYXkuIFVzZWZ1bCB0byBsb2FkIGVtYmVkZGVkIHdlYmFzc2VtYmx5XG4vLyBjb2RlLiBZb3UgcHJvYmFibHkgZG9uJ3QgbmVlZCB0byBjYWxsIHRoaXMgbWV0aG9kIGRpcmVjdGx5LlxuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19iYXNlNjRkZWNvZGUgPSBiYXNlNjRkZWNvZGU7XG5cblxuLy8gSW5jcmVhc2UgY3VycmVudCBtZW1vcnkgdG8gaW5jbHVkZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzLiBEbyBub3RoaW5nIGlmXG4vLyBzaXplIGlzIGFscmVhZHkgb2suIFlvdSBwcm9iYWJseSBkb24ndCBuZWVkIHRvIGNhbGwgdGhpcyBtZXRob2QgZGlyZWN0bHksXG4vLyBiZWNhdXNlIGl0IHdpbGwgYmUgaW52b2tlZCBmcm9tIGAuX19pbnN0YW5jZSgpYC5cbi8vXG5NdWx0aU1hdGgucHJvdG90eXBlLl9fcmVhbGxvY2F0ZSA9IGZ1bmN0aW9uIG1lbV9ncm93X3RvKGJ5dGVzKSB7XG4gIGlmICghdGhpcy5fX21lbW9yeSkge1xuICAgIHRoaXMuX19tZW1vcnkgPSBuZXcgV2ViQXNzZW1ibHkuTWVtb3J5KHtcbiAgICAgIGluaXRpYWw6IE1hdGguY2VpbChieXRlcyAvICg2NCAqIDEwMjQpKVxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLl9fbWVtb3J5O1xuICB9XG5cbiAgdmFyIG1lbV9zaXplID0gdGhpcy5fX21lbW9yeS5idWZmZXIuYnl0ZUxlbmd0aDtcblxuICBpZiAobWVtX3NpemUgPCBieXRlcykge1xuICAgIHRoaXMuX19tZW1vcnkuZ3JvdyhNYXRoLmNlaWwoKGJ5dGVzIC0gbWVtX3NpemUpIC8gKDY0ICogMTAyNCkpKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9fbWVtb3J5O1xufTtcblxuXG4vLyBSZXR1cm5zIGluc3RhbnRpbmF0ZWQgd2ViYXNzZW1ibHkgaXRlbSBieSBuYW1lLCB3aXRoIHNwZWNpZmllZCBtZW1vcnkgc2l6ZVxuLy8gYW5kIGVudmlyb25tZW50LlxuLy8gLSB1c2UgY2FjaGUgaWYgYXZhaWxhYmxlXG4vLyAtIGRvIHN5bmMgbW9kdWxlIGluaXQsIGlmIGFzeW5jIGluaXQgd2FzIG5vdCBjYWxsZWQgZWFybGllclxuLy8gLSBhbGxvY2F0ZSBtZW1vcnkgaWYgbm90IGVub3VndGhcbi8vIC0gY2FuIGV4cG9ydCBmdW5jdGlvbnMgdG8gd2ViYXNzZW1ibHkgdmlhIFwiZW52X2V4dHJhXCIsXG4vLyAgIGZvciBleGFtcGxlLCB7IGV4cDogTWF0aC5leHAgfVxuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19pbnN0YW5jZSA9IGZ1bmN0aW9uIGluc3RhbmNlKG5hbWUsIG1lbXNpemUsIGVudl9leHRyYSkge1xuICBpZiAobWVtc2l6ZSkgdGhpcy5fX3JlYWxsb2NhdGUobWVtc2l6ZSk7XG5cbiAgLy8gSWYgLmluaXQoKSB3YXMgbm90IGNhbGxlZCwgZG8gc3luYyBjb21waWxlXG4gIGlmICghdGhpcy5fX3dhc21bbmFtZV0pIHtcbiAgICB2YXIgbW9kdWxlID0gdGhpcy5fX21vZHVsZXNbbmFtZV07XG4gICAgdGhpcy5fX3dhc21bbmFtZV0gPSBuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKHRoaXMuX19iYXNlNjRkZWNvZGUobW9kdWxlLndhc21fc3JjKSk7XG4gIH1cblxuICBpZiAoIXRoaXMuX19jYWNoZVtuYW1lXSkge1xuICAgIHZhciBlbnZfYmFzZSA9IHtcbiAgICAgIG1lbW9yeUJhc2U6IDAsXG4gICAgICBtZW1vcnk6IHRoaXMuX19tZW1vcnksXG4gICAgICB0YWJsZUJhc2U6IDAsXG4gICAgICB0YWJsZTogbmV3IFdlYkFzc2VtYmx5LlRhYmxlKHsgaW5pdGlhbDogMCwgZWxlbWVudDogJ2FueWZ1bmMnIH0pXG4gICAgfTtcblxuICAgIHRoaXMuX19jYWNoZVtuYW1lXSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZSh0aGlzLl9fd2FzbVtuYW1lXSwge1xuICAgICAgZW52OiBhc3NpZ24oZW52X2Jhc2UsIGVudl9leHRyYSB8fCB7fSlcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9fY2FjaGVbbmFtZV07XG59O1xuXG5cbi8vIEhlbHBlciB0byBjYWxjdWxhdGUgbWVtb3J5IGFsaWdoIGZvciBwb2ludGVycy4gV2ViYXNzZW1ibHkgZG9lcyBub3QgcmVxdWlyZVxuLy8gdGhpcywgYnV0IHlvdSBtYXkgd2lzaCB0byBleHBlcmltZW50LiBEZWZhdWx0IGJhc2UgPSA4O1xuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19hbGlnbiA9IGZ1bmN0aW9uIGFsaWduKG51bWJlciwgYmFzZSkge1xuICBiYXNlID0gYmFzZSB8fCA4O1xuICB2YXIgcmVtaW5kZXIgPSBudW1iZXIgJSBiYXNlO1xuICByZXR1cm4gbnVtYmVyICsgKHJlbWluZGVyID8gYmFzZSAtIHJlbWluZGVyIDogMCk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTXVsdGlNYXRoO1xuXG59LHtcIi4vbGliL2Jhc2U2NGRlY29kZVwiOjIxLFwiLi9saWIvd2FfZGV0ZWN0XCI6MjIsXCJvYmplY3QtYXNzaWduXCI6MjN9XSwyMTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBiYXNlNjQgZGVjb2RlIHN0ciAtPiBVaW50OEFycmF5LCB0byBsb2FkIFdBIG1vZHVsZXNcbi8vXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIEJBU0U2NF9NQVAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiYXNlNjRkZWNvZGUoc3RyKSB7XG4gIHZhciBpbnB1dCA9IHN0ci5yZXBsYWNlKC9bXFxyXFxuPV0vZywgJycpLCAvLyByZW1vdmUgQ1IvTEYgJiBwYWRkaW5nIHRvIHNpbXBsaWZ5IHNjYW5cbiAgICAgIG1heCAgID0gaW5wdXQubGVuZ3RoO1xuXG4gIHZhciBvdXQgPSBuZXcgVWludDhBcnJheSgobWF4ICogMykgPj4gMik7XG5cbiAgLy8gQ29sbGVjdCBieSA2KjQgYml0cyAoMyBieXRlcylcblxuICB2YXIgYml0cyA9IDA7XG4gIHZhciBwdHIgID0gMDtcblxuICBmb3IgKHZhciBpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7XG4gICAgaWYgKChpZHggJSA0ID09PSAwKSAmJiBpZHgpIHtcbiAgICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxNikgJiAweEZGO1xuICAgICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDgpICYgMHhGRjtcbiAgICAgIG91dFtwdHIrK10gPSBiaXRzICYgMHhGRjtcbiAgICB9XG5cbiAgICBiaXRzID0gKGJpdHMgPDwgNikgfCBCQVNFNjRfTUFQLmluZGV4T2YoaW5wdXQuY2hhckF0KGlkeCkpO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdmFyIHRhaWxiaXRzID0gKG1heCAlIDQpICogNjtcblxuICBpZiAodGFpbGJpdHMgPT09IDApIHtcbiAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gMTYpICYgMHhGRjtcbiAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gOCkgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSBiaXRzICYgMHhGRjtcbiAgfSBlbHNlIGlmICh0YWlsYml0cyA9PT0gMTgpIHtcbiAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gMTApICYgMHhGRjtcbiAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gMikgJiAweEZGO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxMikge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiA0KSAmIDB4RkY7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufTtcblxufSx7fV0sMjI6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gRGV0ZWN0IFdlYkFzc2VtYmx5IHN1cHBvcnQuXG4vLyAtIENoZWNrIGdsb2JhbCBXZWJBc3NlbWJseSBvYmplY3Rcbi8vIC0gVHJ5IHRvIGxvYWQgc2ltcGxlIG1vZHVsZSAoY2FuIGJlIGRpc2FibGVkIHZpYSBDU1ApXG4vL1xuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB3YTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGhhc1dlYkFzc2VtYmx5KCkge1xuICAvLyB1c2UgY2FjaGUgaWYgY2FsbGVkIGJlZm9yZTtcbiAgaWYgKHR5cGVvZiB3YSAhPT0gJ3VuZGVmaW5lZCcpIHJldHVybiB3YTtcblxuICB3YSA9IGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgV2ViQXNzZW1ibHkgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gd2E7XG5cbiAgLy8gSWYgV2ViQXNzZW5ibHkgaXMgZGlzYWJsZWQsIGNvZGUgY2FuIHRocm93IG9uIGNvbXBpbGVcbiAgdHJ5IHtcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYnJpb24vbWluLXdhc20tZmFpbC9ibG9iL21hc3Rlci9taW4td2FzbS1mYWlsLmluLmpzXG4gICAgLy8gQWRkaXRpb25hbCBjaGVjayB0aGF0IFdBIGludGVybmFscyBhcmUgY29ycmVjdFxuXG4gICAgLyogZXNsaW50LWRpc2FibGUgY29tbWEtc3BhY2luZywgbWF4LWxlbiAqL1xuICAgIHZhciBiaW4gICAgICA9IG5ldyBVaW50OEFycmF5KFsgMCw5NywxMTUsMTA5LDEsMCwwLDAsMSw2LDEsOTYsMSwxMjcsMSwxMjcsMywyLDEsMCw1LDMsMSwwLDEsNyw4LDEsNCwxMTYsMTAxLDExNSwxMTYsMCwwLDEwLDE2LDEsMTQsMCwzMiwwLDY1LDEsNTQsMiwwLDMyLDAsNDAsMiwwLDExIF0pO1xuICAgIHZhciBtb2R1bGUgICA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUoYmluKTtcbiAgICB2YXIgaW5zdGFuY2UgPSBuZXcgV2ViQXNzZW1ibHkuSW5zdGFuY2UobW9kdWxlLCB7fSk7XG5cbiAgICAvLyB0ZXN0IHN0b3JpbmcgdG8gYW5kIGxvYWRpbmcgZnJvbSBhIG5vbi16ZXJvIGxvY2F0aW9uIHZpYSBhIHBhcmFtZXRlci5cbiAgICAvLyBTYWZhcmkgb24gaU9TIDExLjIuNSByZXR1cm5zIDAgdW5leHBlY3RlZGx5IGF0IG5vbi16ZXJvIGxvY2F0aW9uc1xuICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLnRlc3QoNCkgIT09IDApIHdhID0gdHJ1ZTtcblxuICAgIHJldHVybiB3YTtcbiAgfSBjYXRjaCAoX18pIHt9XG5cbiAgcmV0dXJuIHdhO1xufTtcblxufSx7fV0sMjM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLypcbm9iamVjdC1hc3NpZ25cbihjKSBTaW5kcmUgU29yaHVzXG5AbGljZW5zZSBNSVRcbiovXG5cbid1c2Ugc3RyaWN0Jztcbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG52YXIgZ2V0T3duUHJvcGVydHlTeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgcHJvcElzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbmZ1bmN0aW9uIHRvT2JqZWN0KHZhbCkge1xuXHRpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignT2JqZWN0LmFzc2lnbiBjYW5ub3QgYmUgY2FsbGVkIHdpdGggbnVsbCBvciB1bmRlZmluZWQnKTtcblx0fVxuXG5cdHJldHVybiBPYmplY3QodmFsKTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkVXNlTmF0aXZlKCkge1xuXHR0cnkge1xuXHRcdGlmICghT2JqZWN0LmFzc2lnbikge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIERldGVjdCBidWdneSBwcm9wZXJ0eSBlbnVtZXJhdGlvbiBvcmRlciBpbiBvbGRlciBWOCB2ZXJzaW9ucy5cblxuXHRcdC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTQxMThcblx0XHR2YXIgdGVzdDEgPSBuZXcgU3RyaW5nKCdhYmMnKTsgIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3LXdyYXBwZXJzXG5cdFx0dGVzdDFbNV0gPSAnZGUnO1xuXHRcdGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0ZXN0MSlbMF0gPT09ICc1Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTMwNTZcblx0XHR2YXIgdGVzdDIgPSB7fTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IDEwOyBpKyspIHtcblx0XHRcdHRlc3QyWydfJyArIFN0cmluZy5mcm9tQ2hhckNvZGUoaSldID0gaTtcblx0XHR9XG5cdFx0dmFyIG9yZGVyMiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRlc3QyKS5tYXAoZnVuY3Rpb24gKG4pIHtcblx0XHRcdHJldHVybiB0ZXN0MltuXTtcblx0XHR9KTtcblx0XHRpZiAob3JkZXIyLmpvaW4oJycpICE9PSAnMDEyMzQ1Njc4OScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMDU2XG5cdFx0dmFyIHRlc3QzID0ge307XG5cdFx0J2FiY2RlZmdoaWprbG1ub3BxcnN0Jy5zcGxpdCgnJykuZm9yRWFjaChmdW5jdGlvbiAobGV0dGVyKSB7XG5cdFx0XHR0ZXN0M1tsZXR0ZXJdID0gbGV0dGVyO1xuXHRcdH0pO1xuXHRcdGlmIChPYmplY3Qua2V5cyhPYmplY3QuYXNzaWduKHt9LCB0ZXN0MykpLmpvaW4oJycpICE9PVxuXHRcdFx0XHQnYWJjZGVmZ2hpamtsbW5vcHFyc3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGVycikge1xuXHRcdC8vIFdlIGRvbid0IGV4cGVjdCBhbnkgb2YgdGhlIGFib3ZlIHRvIHRocm93LCBidXQgYmV0dGVyIHRvIGJlIHNhZmUuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hvdWxkVXNlTmF0aXZlKCkgPyBPYmplY3QuYXNzaWduIDogZnVuY3Rpb24gKHRhcmdldCwgc291cmNlKSB7XG5cdHZhciBmcm9tO1xuXHR2YXIgdG8gPSB0b09iamVjdCh0YXJnZXQpO1xuXHR2YXIgc3ltYm9scztcblxuXHRmb3IgKHZhciBzID0gMTsgcyA8IGFyZ3VtZW50cy5sZW5ndGg7IHMrKykge1xuXHRcdGZyb20gPSBPYmplY3QoYXJndW1lbnRzW3NdKTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBmcm9tKSB7XG5cdFx0XHRpZiAoaGFzT3duUHJvcGVydHkuY2FsbChmcm9tLCBrZXkpKSB7XG5cdFx0XHRcdHRvW2tleV0gPSBmcm9tW2tleV07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGdldE93blByb3BlcnR5U3ltYm9scykge1xuXHRcdFx0c3ltYm9scyA9IGdldE93blByb3BlcnR5U3ltYm9scyhmcm9tKTtcblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgc3ltYm9scy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRpZiAocHJvcElzRW51bWVyYWJsZS5jYWxsKGZyb20sIHN5bWJvbHNbaV0pKSB7XG5cdFx0XHRcdFx0dG9bc3ltYm9sc1tpXV0gPSBmcm9tW3N5bWJvbHNbaV1dO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHRvO1xufTtcblxufSx7fV0sMjQ6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xudmFyIGJ1bmRsZUZuID0gYXJndW1lbnRzWzNdO1xudmFyIHNvdXJjZXMgPSBhcmd1bWVudHNbNF07XG52YXIgY2FjaGUgPSBhcmd1bWVudHNbNV07XG5cbnZhciBzdHJpbmdpZnkgPSBKU09OLnN0cmluZ2lmeTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZm4sIG9wdGlvbnMpIHtcbiAgICB2YXIgd2tleTtcbiAgICB2YXIgY2FjaGVLZXlzID0gT2JqZWN0LmtleXMoY2FjaGUpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjYWNoZUtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBjYWNoZUtleXNbaV07XG4gICAgICAgIHZhciBleHAgPSBjYWNoZVtrZXldLmV4cG9ydHM7XG4gICAgICAgIC8vIFVzaW5nIGJhYmVsIGFzIGEgdHJhbnNwaWxlciB0byB1c2UgZXNtb2R1bGUsIHRoZSBleHBvcnQgd2lsbCBhbHdheXNcbiAgICAgICAgLy8gYmUgYW4gb2JqZWN0IHdpdGggdGhlIGRlZmF1bHQgZXhwb3J0IGFzIGEgcHJvcGVydHkgb2YgaXQuIFRvIGVuc3VyZVxuICAgICAgICAvLyB0aGUgZXhpc3RpbmcgYXBpIGFuZCBiYWJlbCBlc21vZHVsZSBleHBvcnRzIGFyZSBib3RoIHN1cHBvcnRlZCB3ZVxuICAgICAgICAvLyBjaGVjayBmb3IgYm90aFxuICAgICAgICBpZiAoZXhwID09PSBmbiB8fCBleHAgJiYgZXhwLmRlZmF1bHQgPT09IGZuKSB7XG4gICAgICAgICAgICB3a2V5ID0ga2V5O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXdrZXkpIHtcbiAgICAgICAgd2tleSA9IE1hdGguZmxvb3IoTWF0aC5wb3coMTYsIDgpICogTWF0aC5yYW5kb20oKSkudG9TdHJpbmcoMTYpO1xuICAgICAgICB2YXIgd2NhY2hlID0ge307XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gY2FjaGVLZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGNhY2hlS2V5c1tpXTtcbiAgICAgICAgICAgIHdjYWNoZVtrZXldID0ga2V5O1xuICAgICAgICB9XG4gICAgICAgIHNvdXJjZXNbd2tleV0gPSBbXG4gICAgICAgICAgICAnZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7JyArIGZuICsgJyhzZWxmKTsgfScsXG4gICAgICAgICAgICB3Y2FjaGVcbiAgICAgICAgXTtcbiAgICB9XG4gICAgdmFyIHNrZXkgPSBNYXRoLmZsb29yKE1hdGgucG93KDE2LCA4KSAqIE1hdGgucmFuZG9tKCkpLnRvU3RyaW5nKDE2KTtcblxuICAgIHZhciBzY2FjaGUgPSB7fTsgc2NhY2hlW3drZXldID0gd2tleTtcbiAgICBzb3VyY2VzW3NrZXldID0gW1xuICAgICAgICAnZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7JyArXG4gICAgICAgICAgICAvLyB0cnkgdG8gY2FsbCBkZWZhdWx0IGlmIGRlZmluZWQgdG8gYWxzbyBzdXBwb3J0IGJhYmVsIGVzbW9kdWxlIGV4cG9ydHNcbiAgICAgICAgICAgICd2YXIgZiA9IHJlcXVpcmUoJyArIHN0cmluZ2lmeSh3a2V5KSArICcpOycgK1xuICAgICAgICAgICAgJyhmLmRlZmF1bHQgPyBmLmRlZmF1bHQgOiBmKShzZWxmKTsnICtcbiAgICAgICAgJ30nLFxuICAgICAgICBzY2FjaGVcbiAgICBdO1xuXG4gICAgdmFyIHdvcmtlclNvdXJjZXMgPSB7fTtcbiAgICByZXNvbHZlU291cmNlcyhza2V5KTtcblxuICAgIGZ1bmN0aW9uIHJlc29sdmVTb3VyY2VzKGtleSkge1xuICAgICAgICB3b3JrZXJTb3VyY2VzW2tleV0gPSB0cnVlO1xuXG4gICAgICAgIGZvciAodmFyIGRlcFBhdGggaW4gc291cmNlc1trZXldWzFdKSB7XG4gICAgICAgICAgICB2YXIgZGVwS2V5ID0gc291cmNlc1trZXldWzFdW2RlcFBhdGhdO1xuICAgICAgICAgICAgaWYgKCF3b3JrZXJTb3VyY2VzW2RlcEtleV0pIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlU291cmNlcyhkZXBLZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHNyYyA9ICcoJyArIGJ1bmRsZUZuICsgJykoeydcbiAgICAgICAgKyBPYmplY3Qua2V5cyh3b3JrZXJTb3VyY2VzKS5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgcmV0dXJuIHN0cmluZ2lmeShrZXkpICsgJzpbJ1xuICAgICAgICAgICAgICAgICsgc291cmNlc1trZXldWzBdXG4gICAgICAgICAgICAgICAgKyAnLCcgKyBzdHJpbmdpZnkoc291cmNlc1trZXldWzFdKSArICddJ1xuICAgICAgICAgICAgO1xuICAgICAgICB9KS5qb2luKCcsJylcbiAgICAgICAgKyAnfSx7fSxbJyArIHN0cmluZ2lmeShza2V5KSArICddKSdcbiAgICA7XG5cbiAgICB2YXIgVVJMID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMIHx8IHdpbmRvdy5tb3pVUkwgfHwgd2luZG93Lm1zVVJMO1xuXG4gICAgdmFyIGJsb2IgPSBuZXcgQmxvYihbc3JjXSwgeyB0eXBlOiAndGV4dC9qYXZhc2NyaXB0JyB9KTtcbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmJhcmUpIHsgcmV0dXJuIGJsb2I7IH1cbiAgICB2YXIgd29ya2VyVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICB2YXIgd29ya2VyID0gbmV3IFdvcmtlcih3b3JrZXJVcmwpO1xuICAgIHdvcmtlci5vYmplY3RVUkwgPSB3b3JrZXJVcmw7XG4gICAgcmV0dXJuIHdvcmtlcjtcbn07XG5cbn0se31dLFwiL2luZGV4LmpzXCI6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBfc2xpY2VkVG9BcnJheShhcnIsIGkpIHsgcmV0dXJuIF9hcnJheVdpdGhIb2xlcyhhcnIpIHx8IF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHx8IF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShhcnIsIGkpIHx8IF9ub25JdGVyYWJsZVJlc3QoKTsgfVxuXG5mdW5jdGlvbiBfbm9uSXRlcmFibGVSZXN0KCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpOyB9XG5cbmZ1bmN0aW9uIF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShvLCBtaW5MZW4pIHsgaWYgKCFvKSByZXR1cm47IGlmICh0eXBlb2YgbyA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7IHZhciBuID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pLnNsaWNlKDgsIC0xKTsgaWYgKG4gPT09IFwiT2JqZWN0XCIgJiYgby5jb25zdHJ1Y3RvcikgbiA9IG8uY29uc3RydWN0b3IubmFtZTsgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7IGlmIChuID09PSBcIkFyZ3VtZW50c1wiIHx8IC9eKD86VWl8SSludCg/Ojh8MTZ8MzIpKD86Q2xhbXBlZCk/QXJyYXkkLy50ZXN0KG4pKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTsgfVxuXG5mdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheShhcnIsIGxlbikgeyBpZiAobGVuID09IG51bGwgfHwgbGVuID4gYXJyLmxlbmd0aCkgbGVuID0gYXJyLmxlbmd0aDsgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBuZXcgQXJyYXkobGVuKTsgaSA8IGxlbjsgaSsrKSB7IGFycjJbaV0gPSBhcnJbaV07IH0gcmV0dXJuIGFycjI7IH1cblxuZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkgeyB2YXIgX2kgPSBhcnIgPT0gbnVsbCA/IG51bGwgOiB0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIGFycltTeW1ib2wuaXRlcmF0b3JdIHx8IGFycltcIkBAaXRlcmF0b3JcIl07IGlmIChfaSA9PSBudWxsKSByZXR1cm47IHZhciBfYXJyID0gW107IHZhciBfbiA9IHRydWU7IHZhciBfZCA9IGZhbHNlOyB2YXIgX3MsIF9lOyB0cnkgeyBmb3IgKF9pID0gX2kuY2FsbChhcnIpOyAhKF9uID0gKF9zID0gX2kubmV4dCgpKS5kb25lKTsgX24gPSB0cnVlKSB7IF9hcnIucHVzaChfcy52YWx1ZSk7IGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhazsgfSB9IGNhdGNoIChlcnIpIHsgX2QgPSB0cnVlOyBfZSA9IGVycjsgfSBmaW5hbGx5IHsgdHJ5IHsgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSAhPSBudWxsKSBfaVtcInJldHVyblwiXSgpOyB9IGZpbmFsbHkgeyBpZiAoX2QpIHRocm93IF9lOyB9IH0gcmV0dXJuIF9hcnI7IH1cblxuZnVuY3Rpb24gX2FycmF5V2l0aEhvbGVzKGFycikgeyBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gYXJyOyB9XG5cbnZhciBhc3NpZ24gPSBfZGVyZXFfKCdvYmplY3QtYXNzaWduJyk7XG5cbnZhciB3ZWJ3b3JraWZ5ID0gX2RlcmVxXygnd2Vid29ya2lmeScpO1xuXG52YXIgTWF0aExpYiA9IF9kZXJlcV8oJy4vbGliL21hdGhsaWInKTtcblxudmFyIFBvb2wgPSBfZGVyZXFfKCcuL2xpYi9wb29sJyk7XG5cbnZhciB1dGlscyA9IF9kZXJlcV8oJy4vbGliL3V0aWxzJyk7XG5cbnZhciB3b3JrZXIgPSBfZGVyZXFfKCcuL2xpYi93b3JrZXInKTtcblxudmFyIGNyZWF0ZVN0YWdlcyA9IF9kZXJlcV8oJy4vbGliL3N0ZXBwZXInKTtcblxudmFyIGNyZWF0ZVJlZ2lvbnMgPSBfZGVyZXFfKCcuL2xpYi90aWxlcicpOyAvLyBEZWR1cGxpY2F0ZSBwb29scyAmIGxpbWl0ZXJzIHdpdGggdGhlIHNhbWUgY29uZmlnc1xuLy8gd2hlbiB1c2VyIGNyZWF0ZXMgbXVsdGlwbGUgcGljYSBpbnN0YW5jZXMuXG5cblxudmFyIHNpbmdsZXRvbmVzID0ge307XG52YXIgTkVFRF9TQUZBUklfRklYID0gZmFsc2U7XG5cbnRyeSB7XG4gIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiBuYXZpZ2F0b3IudXNlckFnZW50KSB7XG4gICAgTkVFRF9TQUZBUklfRklYID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdTYWZhcmknKSA+PSAwO1xuICB9XG59IGNhdGNoIChlKSB7fVxuXG52YXIgY29uY3VycmVuY3kgPSAxO1xuXG5pZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgY29uY3VycmVuY3kgPSBNYXRoLm1pbihuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeSB8fCAxLCA0KTtcbn1cblxudmFyIERFRkFVTFRfUElDQV9PUFRTID0ge1xuICB0aWxlOiAxMDI0LFxuICBjb25jdXJyZW5jeTogY29uY3VycmVuY3ksXG4gIGZlYXR1cmVzOiBbJ2pzJywgJ3dhc20nLCAnd3cnXSxcbiAgaWRsZTogMjAwMCxcbiAgY3JlYXRlQ2FudmFzOiBmdW5jdGlvbiBjcmVhdGVDYW52YXMod2lkdGgsIGhlaWdodCkge1xuICAgIHZhciB0bXBDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICB0bXBDYW52YXMud2lkdGggPSB3aWR0aDtcbiAgICB0bXBDYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHJldHVybiB0bXBDYW52YXM7XG4gIH1cbn07XG52YXIgREVGQVVMVF9SRVNJWkVfT1BUUyA9IHtcbiAgcXVhbGl0eTogMyxcbiAgYWxwaGE6IGZhbHNlLFxuICB1bnNoYXJwQW1vdW50OiAwLFxuICB1bnNoYXJwUmFkaXVzOiAwLjAsXG4gIHVuc2hhcnBUaHJlc2hvbGQ6IDBcbn07XG52YXIgQ0FOX05FV19JTUFHRV9EQVRBID0gZmFsc2U7XG52YXIgQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVAgPSBmYWxzZTtcbnZhciBDQU5fVVNFX0NBTlZBU19HRVRfSU1BR0VfREFUQSA9IGZhbHNlO1xudmFyIENBTl9VU0VfT0ZGU0NSRUVOX0NBTlZBUyA9IGZhbHNlO1xudmFyIENBTl9VU0VfQ0lCX1JFR0lPTl9GT1JfSU1BR0UgPSBmYWxzZTtcblxuZnVuY3Rpb24gd29ya2VyRmFicmljKCkge1xuICByZXR1cm4ge1xuICAgIHZhbHVlOiB3ZWJ3b3JraWZ5KHdvcmtlciksXG4gICAgZGVzdHJveTogZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICAgIHRoaXMudmFsdWUudGVybWluYXRlKCk7XG5cbiAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB2YXIgdXJsID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMIHx8IHdpbmRvdy5tb3pVUkwgfHwgd2luZG93Lm1zVVJMO1xuXG4gICAgICAgIGlmICh1cmwgJiYgdXJsLnJldm9rZU9iamVjdFVSTCAmJiB0aGlzLnZhbHVlLm9iamVjdFVSTCkge1xuICAgICAgICAgIHVybC5yZXZva2VPYmplY3RVUkwodGhpcy52YWx1ZS5vYmplY3RVUkwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xufSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gQVBJIG1ldGhvZHNcblxuXG5mdW5jdGlvbiBQaWNhKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFBpY2EpKSByZXR1cm4gbmV3IFBpY2Eob3B0aW9ucyk7XG4gIHRoaXMub3B0aW9ucyA9IGFzc2lnbih7fSwgREVGQVVMVF9QSUNBX09QVFMsIG9wdGlvbnMgfHwge30pO1xuICB2YXIgbGltaXRlcl9rZXkgPSBcImxrX1wiLmNvbmNhdCh0aGlzLm9wdGlvbnMuY29uY3VycmVuY3kpOyAvLyBTaGFyZSBsaW1pdGVycyB0byBhdm9pZCBtdWx0aXBsZSBwYXJhbGxlbCB3b3JrZXJzIHdoZW4gdXNlciBjcmVhdGVzXG4gIC8vIG11bHRpcGxlIHBpY2EgaW5zdGFuY2VzLlxuXG4gIHRoaXMuX19saW1pdCA9IHNpbmdsZXRvbmVzW2xpbWl0ZXJfa2V5XSB8fCB1dGlscy5saW1pdGVyKHRoaXMub3B0aW9ucy5jb25jdXJyZW5jeSk7XG4gIGlmICghc2luZ2xldG9uZXNbbGltaXRlcl9rZXldKSBzaW5nbGV0b25lc1tsaW1pdGVyX2tleV0gPSB0aGlzLl9fbGltaXQ7IC8vIExpc3Qgb2Ygc3VwcG9ydGVkIGZlYXR1cmVzLCBhY2NvcmRpbmcgdG8gb3B0aW9ucyAmIGJyb3dzZXIvbm9kZS5qc1xuXG4gIHRoaXMuZmVhdHVyZXMgPSB7XG4gICAganM6IGZhbHNlLFxuICAgIC8vIHB1cmUgSlMgaW1wbGVtZW50YXRpb24sIGNhbiBiZSBkaXNhYmxlZCBmb3IgdGVzdGluZ1xuICAgIHdhc206IGZhbHNlLFxuICAgIC8vIHdlYmFzc2VtYmx5IGltcGxlbWVudGF0aW9uIGZvciBoZWF2eSBmdW5jdGlvbnNcbiAgICBjaWI6IGZhbHNlLFxuICAgIC8vIHJlc2l6ZSB2aWEgY3JlYXRlSW1hZ2VCaXRtYXAgKG9ubHkgRkYgYXQgdGhpcyBtb21lbnQpXG4gICAgd3c6IGZhbHNlIC8vIHdlYndvcmtlcnNcblxuICB9O1xuICB0aGlzLl9fd29ya2Vyc1Bvb2wgPSBudWxsOyAvLyBTdG9yZSByZXF1ZXN0ZWQgZmVhdHVyZXMgZm9yIHdlYndvcmtlcnNcblxuICB0aGlzLl9fcmVxdWVzdGVkX2ZlYXR1cmVzID0gW107XG4gIHRoaXMuX19tYXRobGliID0gbnVsbDtcbn1cblxuUGljYS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICBpZiAodGhpcy5fX2luaXRQcm9taXNlKSByZXR1cm4gdGhpcy5fX2luaXRQcm9taXNlOyAvLyBUZXN0IGlmIHdlIGNhbiBjcmVhdGUgSW1hZ2VEYXRhIHdpdGhvdXQgY2FudmFzIGFuZCBtZW1vcnkgY29weVxuXG4gIGlmICh0eXBlb2YgSW1hZ2VEYXRhICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgVWludDhDbGFtcGVkQXJyYXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLW5ldyAqL1xuICAgICAgbmV3IEltYWdlRGF0YShuZXcgVWludDhDbGFtcGVkQXJyYXkoNDAwKSwgMTAsIDEwKTtcbiAgICAgIENBTl9ORVdfSU1BR0VfREFUQSA9IHRydWU7XG4gICAgfSBjYXRjaCAoX18pIHt9XG4gIH0gLy8gSW1hZ2VCaXRtYXAgY2FuIGJlIGVmZmVjdGl2ZSBpbiAyIHBsYWNlczpcbiAgLy9cbiAgLy8gMS4gVGhyZWFkZWQganBlZyB1bnBhY2sgKGJhc2ljKVxuICAvLyAyLiBCdWlsdC1pbiByZXNpemUgKGJsb2NrZWQgZHVlIHByb2JsZW0gaW4gY2hyb21lLCBzZWUgaXNzdWUgIzg5KVxuICAvL1xuICAvLyBGb3IgYmFzaWMgdXNlIHdlIGFsc28gbmVlZCBJbWFnZUJpdG1hcCB3byBzdXBwb3J0IC5jbG9zZSgpIG1ldGhvZCxcbiAgLy8gc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL3J1L2RvY3MvV2ViL0FQSS9JbWFnZUJpdG1hcFxuXG5cbiAgaWYgKHR5cGVvZiBJbWFnZUJpdG1hcCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoSW1hZ2VCaXRtYXAucHJvdG90eXBlICYmIEltYWdlQml0bWFwLnByb3RvdHlwZS5jbG9zZSkge1xuICAgICAgQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVAgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlYnVnKCdJbWFnZUJpdG1hcCBkb2VzIG5vdCBzdXBwb3J0IC5jbG9zZSgpLCBkaXNhYmxlZCcpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBmZWF0dXJlcyA9IHRoaXMub3B0aW9ucy5mZWF0dXJlcy5zbGljZSgpO1xuXG4gIGlmIChmZWF0dXJlcy5pbmRleE9mKCdhbGwnKSA+PSAwKSB7XG4gICAgZmVhdHVyZXMgPSBbJ2NpYicsICd3YXNtJywgJ2pzJywgJ3d3J107XG4gIH1cblxuICB0aGlzLl9fcmVxdWVzdGVkX2ZlYXR1cmVzID0gZmVhdHVyZXM7XG4gIHRoaXMuX19tYXRobGliID0gbmV3IE1hdGhMaWIoZmVhdHVyZXMpOyAvLyBDaGVjayBXZWJXb3JrZXIgc3VwcG9ydCBpZiByZXF1ZXN0ZWRcblxuICBpZiAoZmVhdHVyZXMuaW5kZXhPZignd3cnKSA+PSAwKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmICdXb3JrZXInIGluIHdpbmRvdykge1xuICAgICAgLy8gSUUgPD0gMTEgZG9uJ3QgYWxsb3cgdG8gY3JlYXRlIHdlYndvcmtlcnMgZnJvbSBzdHJpbmcuIFdlIHNob3VsZCBjaGVjayBpdC5cbiAgICAgIC8vIGh0dHBzOi8vY29ubmVjdC5taWNyb3NvZnQuY29tL0lFL2ZlZWRiYWNrL2RldGFpbHMvODAxODEwL3dlYi13b3JrZXJzLWZyb20tYmxvYi11cmxzLWluLWllLTEwLWFuZC0xMVxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHdrciA9IF9kZXJlcV8oJ3dlYndvcmtpZnknKShmdW5jdGlvbiAoKSB7fSk7XG5cbiAgICAgICAgd2tyLnRlcm1pbmF0ZSgpO1xuICAgICAgICB0aGlzLmZlYXR1cmVzLnd3ID0gdHJ1ZTsgLy8gcG9vbCB1bmlxdWVuZXNzIGRlcGVuZHMgb24gcG9vbCBjb25maWcgKyB3ZWJ3b3JrZXIgY29uZmlnXG5cbiAgICAgICAgdmFyIHdwb29sX2tleSA9IFwid3BfXCIuY29uY2F0KEpTT04uc3RyaW5naWZ5KHRoaXMub3B0aW9ucykpO1xuXG4gICAgICAgIGlmIChzaW5nbGV0b25lc1t3cG9vbF9rZXldKSB7XG4gICAgICAgICAgdGhpcy5fX3dvcmtlcnNQb29sID0gc2luZ2xldG9uZXNbd3Bvb2xfa2V5XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9fd29ya2Vyc1Bvb2wgPSBuZXcgUG9vbCh3b3JrZXJGYWJyaWMsIHRoaXMub3B0aW9ucy5pZGxlKTtcbiAgICAgICAgICBzaW5nbGV0b25lc1t3cG9vbF9rZXldID0gdGhpcy5fX3dvcmtlcnNQb29sO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChfXykge31cbiAgICB9XG4gIH1cblxuICB2YXIgaW5pdE1hdGggPSB0aGlzLl9fbWF0aGxpYi5pbml0KCkudGhlbihmdW5jdGlvbiAobWF0aGxpYikge1xuICAgIC8vIENvcHkgZGV0ZWN0ZWQgZmVhdHVyZXNcbiAgICBhc3NpZ24oX3RoaXMuZmVhdHVyZXMsIG1hdGhsaWIuZmVhdHVyZXMpO1xuICB9KTtcblxuICB2YXIgY2hlY2tDaWJSZXNpemU7XG5cbiAgaWYgKCFDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCkge1xuICAgIGNoZWNrQ2liUmVzaXplID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgfSBlbHNlIHtcbiAgICBjaGVja0NpYlJlc2l6ZSA9IHV0aWxzLmNpYl9zdXBwb3J0KHRoaXMub3B0aW9ucy5jcmVhdGVDYW52YXMpLnRoZW4oZnVuY3Rpb24gKHN0YXR1cykge1xuICAgICAgaWYgKF90aGlzLmZlYXR1cmVzLmNpYiAmJiBmZWF0dXJlcy5pbmRleE9mKCdjaWInKSA8IDApIHtcbiAgICAgICAgX3RoaXMuZGVidWcoJ2NyZWF0ZUltYWdlQml0bWFwKCkgcmVzaXplIHN1cHBvcnRlZCwgYnV0IGRpc2FibGVkIGJ5IGNvbmZpZycpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGZlYXR1cmVzLmluZGV4T2YoJ2NpYicpID49IDApIF90aGlzLmZlYXR1cmVzLmNpYiA9IHN0YXR1cztcbiAgICB9KTtcbiAgfVxuXG4gIENBTl9VU0VfQ0FOVkFTX0dFVF9JTUFHRV9EQVRBID0gdXRpbHMuY2FuX3VzZV9jYW52YXModGhpcy5vcHRpb25zLmNyZWF0ZUNhbnZhcyk7XG4gIHZhciBjaGVja09mZnNjcmVlbkNhbnZhcztcblxuICBpZiAoQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVAgJiYgQ0FOX05FV19JTUFHRV9EQVRBICYmIGZlYXR1cmVzLmluZGV4T2YoJ3d3JykgIT09IC0xKSB7XG4gICAgY2hlY2tPZmZzY3JlZW5DYW52YXMgPSB1dGlscy53b3JrZXJfb2Zmc2NyZWVuX2NhbnZhc19zdXBwb3J0KCk7XG4gIH0gZWxzZSB7XG4gICAgY2hlY2tPZmZzY3JlZW5DYW52YXMgPSBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICB9XG5cbiAgY2hlY2tPZmZzY3JlZW5DYW52YXMgPSBjaGVja09mZnNjcmVlbkNhbnZhcy50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICBDQU5fVVNFX09GRlNDUkVFTl9DQU5WQVMgPSByZXN1bHQ7XG4gIH0pOyAvLyB3ZSB1c2UgY3JlYXRlSW1hZ2VCaXRtYXAgdG8gY3JvcCBpbWFnZSBkYXRhIGFuZCBwYXNzIGl0IHRvIHdvcmtlcnMsXG4gIC8vIHNvIG5lZWQgdG8gY2hlY2sgd2hldGhlciBmdW5jdGlvbiB3b3JrcyBjb3JyZWN0bHk7XG4gIC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTEyMjA2NzFcblxuICB2YXIgY2hlY2tDaWJSZWdpb24gPSB1dGlscy5jaWJfY2FuX3VzZV9yZWdpb24oKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICBDQU5fVVNFX0NJQl9SRUdJT05fRk9SX0lNQUdFID0gcmVzdWx0O1xuICB9KTsgLy8gSW5pdCBtYXRoIGxpYi4gVGhhdCdzIGFzeW5jIGJlY2F1c2UgY2FuIGxvYWQgc29tZVxuXG4gIHRoaXMuX19pbml0UHJvbWlzZSA9IFByb21pc2UuYWxsKFtpbml0TWF0aCwgY2hlY2tDaWJSZXNpemUsIGNoZWNrT2Zmc2NyZWVuQ2FudmFzLCBjaGVja0NpYlJlZ2lvbl0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdGhpcztcbiAgfSk7XG4gIHJldHVybiB0aGlzLl9faW5pdFByb21pc2U7XG59OyAvLyBDYWxsIHJlc2l6ZXIgaW4gd2Vid29ya2VyIG9yIGxvY2FsbHksIGRlcGVuZGluZyBvbiBjb25maWdcblxuXG5QaWNhLnByb3RvdHlwZS5fX2ludm9rZVJlc2l6ZSA9IGZ1bmN0aW9uICh0aWxlT3B0cywgb3B0cykge1xuICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAvLyBTaGFyZSBjYWNoZSBiZXR3ZWVuIGNhbGxzOlxuICAvL1xuICAvLyAtIHdhc20gaW5zdGFuY2VcbiAgLy8gLSB3YXNtIG1lbW9yeSBvYmplY3RcbiAgLy9cbiAgb3B0cy5fX21hdGhDYWNoZSA9IG9wdHMuX19tYXRoQ2FjaGUgfHwge307XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIV90aGlzMi5mZWF0dXJlcy53dykge1xuICAgICAgLy8gbm90IHBvc3NpYmxlIHRvIGhhdmUgSW1hZ2VCaXRtYXAgaGVyZSBpZiB1c2VyIGRpc2FibGVkIFdXXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXRhOiBfdGhpczIuX19tYXRobGliLnJlc2l6ZUFuZFVuc2hhcnAodGlsZU9wdHMsIG9wdHMuX19tYXRoQ2FjaGUpXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgdyA9IF90aGlzMi5fX3dvcmtlcnNQb29sLmFjcXVpcmUoKTtcblxuICAgICAgaWYgKG9wdHMuY2FuY2VsVG9rZW4pIG9wdHMuY2FuY2VsVG9rZW5bXCJjYXRjaFwiXShmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgIH0pO1xuXG4gICAgICB3LnZhbHVlLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB3LnJlbGVhc2UoKTtcbiAgICAgICAgaWYgKGV2LmRhdGEuZXJyKSByZWplY3QoZXYuZGF0YS5lcnIpO2Vsc2UgcmVzb2x2ZShldi5kYXRhKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciB0cmFuc2ZlciA9IFtdO1xuICAgICAgaWYgKHRpbGVPcHRzLnNyYykgdHJhbnNmZXIucHVzaCh0aWxlT3B0cy5zcmMuYnVmZmVyKTtcbiAgICAgIGlmICh0aWxlT3B0cy5zcmNCaXRtYXApIHRyYW5zZmVyLnB1c2godGlsZU9wdHMuc3JjQml0bWFwKTtcbiAgICAgIHcudmFsdWUucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBvcHRzOiB0aWxlT3B0cyxcbiAgICAgICAgZmVhdHVyZXM6IF90aGlzMi5fX3JlcXVlc3RlZF9mZWF0dXJlcyxcbiAgICAgICAgcHJlbG9hZDoge1xuICAgICAgICAgIHdhc21fbm9kdWxlOiBfdGhpczIuX19tYXRobGliLl9fXG4gICAgICAgIH1cbiAgICAgIH0sIHRyYW5zZmVyKTtcbiAgICB9KTtcbiAgfSk7XG59OyAvLyB0aGlzIGZ1bmN0aW9uIGNhbiByZXR1cm4gcHJvbWlzZSBpZiBjcmVhdGVJbWFnZUJpdG1hcCBpcyB1c2VkXG5cblxuUGljYS5wcm90b3R5cGUuX19leHRyYWN0VGlsZURhdGEgPSBmdW5jdGlvbiAodGlsZSwgZnJvbSwgb3B0cywgc3RhZ2VFbnYsIGV4dHJhY3RUbykge1xuICBpZiAodGhpcy5mZWF0dXJlcy53dyAmJiBDQU5fVVNFX09GRlNDUkVFTl9DQU5WQVMgJiYgKCAvLyBjcmVhdGVJbWFnZUJpdG1hcCBkb2Vzbid0IHdvcmsgZm9yIGltYWdlcyAoSW1hZ2UsIEltYWdlQml0bWFwKSB3aXRoIEV4aWYgb3JpZW50YXRpb24gaW4gQ2hyb21lLFxuICAvLyBjYW4gdXNlIGNhbnZhcyBiZWNhdXNlIGNhbnZhcyBkb2Vzbid0IGhhdmUgb3JpZW50YXRpb247XG4gIC8vIHNlZSBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0xMjIwNjcxXG4gIHV0aWxzLmlzQ2FudmFzKGZyb20pIHx8IENBTl9VU0VfQ0lCX1JFR0lPTl9GT1JfSU1BR0UpKSB7XG4gICAgdGhpcy5kZWJ1ZygnQ3JlYXRlIHRpbGUgZm9yIE9mZnNjcmVlbkNhbnZhcycpO1xuICAgIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCB8fCBmcm9tLCB0aWxlLngsIHRpbGUueSwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpLnRoZW4oZnVuY3Rpb24gKGJpdG1hcCkge1xuICAgICAgZXh0cmFjdFRvLnNyY0JpdG1hcCA9IGJpdG1hcDtcbiAgICAgIHJldHVybiBleHRyYWN0VG87XG4gICAgfSk7XG4gIH0gLy8gRXh0cmFjdCB0aWxlIFJHQkEgYnVmZmVyLCBkZXBlbmRpbmcgb24gaW5wdXQgdHlwZVxuXG5cbiAgaWYgKHV0aWxzLmlzQ2FudmFzKGZyb20pKSB7XG4gICAgaWYgKCFzdGFnZUVudi5zcmNDdHgpIHN0YWdlRW52LnNyY0N0eCA9IGZyb20uZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICAgIH0pOyAvLyBJZiBpbnB1dCBpcyBDYW52YXMgLSBleHRyYWN0IHJlZ2lvbiBkYXRhIGRpcmVjdGx5XG5cbiAgICB0aGlzLmRlYnVnKCdHZXQgdGlsZSBwaXhlbCBkYXRhJyk7XG4gICAgZXh0cmFjdFRvLnNyYyA9IHN0YWdlRW52LnNyY0N0eC5nZXRJbWFnZURhdGEodGlsZS54LCB0aWxlLnksIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KS5kYXRhO1xuICAgIHJldHVybiBleHRyYWN0VG87XG4gIH0gLy8gSWYgaW5wdXQgaXMgSW1hZ2Ugb3IgZGVjb2RlZCB0byBJbWFnZUJpdG1hcCxcbiAgLy8gZHJhdyByZWdpb24gdG8gdGVtcG9yYXJ5IGNhbnZhcyBhbmQgZXh0cmFjdCBkYXRhIGZyb20gaXRcbiAgLy9cbiAgLy8gTm90ZSEgQXR0ZW1wdCB0byByZXVzZSB0aGlzIGNhbnZhcyBjYXVzZXMgc2lnbmlmaWNhbnQgc2xvd2Rvd24gaW4gY2hyb21lXG4gIC8vXG5cblxuICB0aGlzLmRlYnVnKCdEcmF3IHRpbGUgaW1hZ2VCaXRtYXAvaW1hZ2UgdG8gdGVtcG9yYXJ5IGNhbnZhcycpO1xuICB2YXIgdG1wQ2FudmFzID0gdGhpcy5vcHRpb25zLmNyZWF0ZUNhbnZhcyh0aWxlLndpZHRoLCB0aWxlLmhlaWdodCk7XG4gIHZhciB0bXBDdHggPSB0bXBDYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgfSk7XG4gIHRtcEN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnY29weSc7XG4gIHRtcEN0eC5kcmF3SW1hZ2Uoc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgfHwgZnJvbSwgdGlsZS54LCB0aWxlLnksIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0LCAwLCAwLCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCk7XG4gIHRoaXMuZGVidWcoJ0dldCB0aWxlIHBpeGVsIGRhdGEnKTtcbiAgZXh0cmFjdFRvLnNyYyA9IHRtcEN0eC5nZXRJbWFnZURhdGEoMCwgMCwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpLmRhdGE7IC8vIFNhZmFyaSAxMiB3b3JrYXJvdW5kXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMTk5XG5cbiAgdG1wQ2FudmFzLndpZHRoID0gdG1wQ2FudmFzLmhlaWdodCA9IDA7XG4gIHJldHVybiBleHRyYWN0VG87XG59O1xuXG5QaWNhLnByb3RvdHlwZS5fX2xhbmRUaWxlRGF0YSA9IGZ1bmN0aW9uICh0aWxlLCByZXN1bHQsIHN0YWdlRW52KSB7XG4gIHZhciB0b0ltYWdlRGF0YTtcbiAgdGhpcy5kZWJ1ZygnQ29udmVydCByYXcgcmdiYSB0aWxlIHJlc3VsdCB0byBJbWFnZURhdGEnKTtcblxuICBpZiAocmVzdWx0LmJpdG1hcCkge1xuICAgIHN0YWdlRW52LnRvQ3R4LmRyYXdJbWFnZShyZXN1bHQuYml0bWFwLCB0aWxlLnRvWCwgdGlsZS50b1kpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKENBTl9ORVdfSU1BR0VfREFUQSkge1xuICAgIC8vIHRoaXMgYnJhbmNoIGlzIGZvciBtb2Rlcm4gYnJvd3NlcnNcbiAgICAvLyBJZiBgbmV3IEltYWdlRGF0YSgpYCAmIFVpbnQ4Q2xhbXBlZEFycmF5IHN1cG9ydGVkXG4gICAgdG9JbWFnZURhdGEgPSBuZXcgSW1hZ2VEYXRhKG5ldyBVaW50OENsYW1wZWRBcnJheShyZXN1bHQuZGF0YSksIHRpbGUudG9XaWR0aCwgdGlsZS50b0hlaWdodCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gZmFsbGJhY2sgZm9yIGBub2RlLWNhbnZhc2AgYW5kIG9sZCBicm93c2Vyc1xuICAgIC8vIChJRTExIGhhcyBJbWFnZURhdGEgYnV0IGRvZXMgbm90IHN1cHBvcnQgYG5ldyBJbWFnZURhdGEoKWApXG4gICAgdG9JbWFnZURhdGEgPSBzdGFnZUVudi50b0N0eC5jcmVhdGVJbWFnZURhdGEodGlsZS50b1dpZHRoLCB0aWxlLnRvSGVpZ2h0KTtcblxuICAgIGlmICh0b0ltYWdlRGF0YS5kYXRhLnNldCkge1xuICAgICAgdG9JbWFnZURhdGEuZGF0YS5zZXQocmVzdWx0LmRhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJRTkgZG9uJ3QgaGF2ZSBgLnNldCgpYFxuICAgICAgZm9yICh2YXIgaSA9IHRvSW1hZ2VEYXRhLmRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgdG9JbWFnZURhdGEuZGF0YVtpXSA9IHJlc3VsdC5kYXRhW2ldO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRoaXMuZGVidWcoJ0RyYXcgdGlsZScpO1xuXG4gIGlmIChORUVEX1NBRkFSSV9GSVgpIHtcbiAgICAvLyBTYWZhcmkgZHJhd3MgdGhpbiB3aGl0ZSBzdHJpcGVzIGJldHdlZW4gdGlsZXMgd2l0aG91dCB0aGlzIGZpeFxuICAgIHN0YWdlRW52LnRvQ3R4LnB1dEltYWdlRGF0YSh0b0ltYWdlRGF0YSwgdGlsZS50b1gsIHRpbGUudG9ZLCB0aWxlLnRvSW5uZXJYIC0gdGlsZS50b1gsIHRpbGUudG9Jbm5lclkgLSB0aWxlLnRvWSwgdGlsZS50b0lubmVyV2lkdGggKyAxZS01LCB0aWxlLnRvSW5uZXJIZWlnaHQgKyAxZS01KTtcbiAgfSBlbHNlIHtcbiAgICBzdGFnZUVudi50b0N0eC5wdXRJbWFnZURhdGEodG9JbWFnZURhdGEsIHRpbGUudG9YLCB0aWxlLnRvWSwgdGlsZS50b0lubmVyWCAtIHRpbGUudG9YLCB0aWxlLnRvSW5uZXJZIC0gdGlsZS50b1ksIHRpbGUudG9Jbm5lcldpZHRoLCB0aWxlLnRvSW5uZXJIZWlnaHQpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5fX3RpbGVBbmRSZXNpemUgPSBmdW5jdGlvbiAoZnJvbSwgdG8sIG9wdHMpIHtcbiAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgdmFyIHN0YWdlRW52ID0ge1xuICAgIHNyY0N0eDogbnVsbCxcbiAgICBzcmNJbWFnZUJpdG1hcDogbnVsbCxcbiAgICBpc0ltYWdlQml0bWFwUmV1c2VkOiBmYWxzZSxcbiAgICB0b0N0eDogbnVsbFxuICB9O1xuXG4gIHZhciBwcm9jZXNzVGlsZSA9IGZ1bmN0aW9uIHByb2Nlc3NUaWxlKHRpbGUpIHtcbiAgICByZXR1cm4gX3RoaXMzLl9fbGltaXQoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuO1xuICAgICAgdmFyIHRpbGVPcHRzID0ge1xuICAgICAgICB3aWR0aDogdGlsZS53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiB0aWxlLmhlaWdodCxcbiAgICAgICAgdG9XaWR0aDogdGlsZS50b1dpZHRoLFxuICAgICAgICB0b0hlaWdodDogdGlsZS50b0hlaWdodCxcbiAgICAgICAgc2NhbGVYOiB0aWxlLnNjYWxlWCxcbiAgICAgICAgc2NhbGVZOiB0aWxlLnNjYWxlWSxcbiAgICAgICAgb2Zmc2V0WDogdGlsZS5vZmZzZXRYLFxuICAgICAgICBvZmZzZXRZOiB0aWxlLm9mZnNldFksXG4gICAgICAgIHF1YWxpdHk6IG9wdHMucXVhbGl0eSxcbiAgICAgICAgYWxwaGE6IG9wdHMuYWxwaGEsXG4gICAgICAgIHVuc2hhcnBBbW91bnQ6IG9wdHMudW5zaGFycEFtb3VudCxcbiAgICAgICAgdW5zaGFycFJhZGl1czogb3B0cy51bnNoYXJwUmFkaXVzLFxuICAgICAgICB1bnNoYXJwVGhyZXNob2xkOiBvcHRzLnVuc2hhcnBUaHJlc2hvbGRcbiAgICAgIH07XG5cbiAgICAgIF90aGlzMy5kZWJ1ZygnSW52b2tlIHJlc2l6ZSBtYXRoJyk7XG5cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGlsZU9wdHMpLnRoZW4oZnVuY3Rpb24gKHRpbGVPcHRzKSB7XG4gICAgICAgIHJldHVybiBfdGhpczMuX19leHRyYWN0VGlsZURhdGEodGlsZSwgZnJvbSwgb3B0cywgc3RhZ2VFbnYsIHRpbGVPcHRzKTtcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHRpbGVPcHRzKSB7XG4gICAgICAgIF90aGlzMy5kZWJ1ZygnSW52b2tlIHJlc2l6ZSBtYXRoJyk7XG5cbiAgICAgICAgcmV0dXJuIF90aGlzMy5fX2ludm9rZVJlc2l6ZSh0aWxlT3B0cywgb3B0cyk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuO1xuICAgICAgICBzdGFnZUVudi5zcmNJbWFnZURhdGEgPSBudWxsO1xuICAgICAgICByZXR1cm4gX3RoaXMzLl9fbGFuZFRpbGVEYXRhKHRpbGUsIHJlc3VsdCwgc3RhZ2VFbnYpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07IC8vIE5lZWQgdG8gbm9ybWFsaXplIGRhdGEgc291cmNlIGZpcnN0LiBJdCBjYW4gYmUgY2FudmFzIG9yIGltYWdlLlxuICAvLyBJZiBpbWFnZSAtIHRyeSB0byBkZWNvZGUgaW4gYmFja2dyb3VuZCBpZiBwb3NzaWJsZVxuXG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHN0YWdlRW52LnRvQ3R4ID0gdG8uZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICAgIH0pO1xuICAgIGlmICh1dGlscy5pc0NhbnZhcyhmcm9tKSkgcmV0dXJuIG51bGw7XG5cbiAgICBpZiAodXRpbHMuaXNJbWFnZUJpdG1hcChmcm9tKSkge1xuICAgICAgc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgPSBmcm9tO1xuICAgICAgc3RhZ2VFbnYuaXNJbWFnZUJpdG1hcFJldXNlZCA9IHRydWU7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodXRpbHMuaXNJbWFnZShmcm9tKSkge1xuICAgICAgLy8gdHJ5IGRvIGRlY29kZSBpbWFnZSBpbiBiYWNrZ3JvdW5kIGZvciBmYXN0ZXIgbmV4dCBvcGVyYXRpb25zO1xuICAgICAgLy8gaWYgd2UncmUgdXNpbmcgb2Zmc2NyZWVuIGNhbnZhcywgY2liIGlzIGNhbGxlZCBwZXIgdGlsZSwgc28gbm90IG5lZWRlZCBoZXJlXG4gICAgICBpZiAoIUNBTl9DUkVBVEVfSU1BR0VfQklUTUFQKSByZXR1cm4gbnVsbDtcblxuICAgICAgX3RoaXMzLmRlYnVnKCdEZWNvZGUgaW1hZ2UgdmlhIGNyZWF0ZUltYWdlQml0bWFwJyk7XG5cbiAgICAgIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChmcm9tKS50aGVuKGZ1bmN0aW9uIChpbWFnZUJpdG1hcCkge1xuICAgICAgICBzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCA9IGltYWdlQml0bWFwO1xuICAgICAgfSkgLy8gU3VwcHJlc3MgZXJyb3IgdG8gdXNlIGZhbGxiYWNrLCBpZiBtZXRob2QgZmFpbHNcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMTkwXG5cbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4gICAgICBbXCJjYXRjaFwiXShmdW5jdGlvbiAoZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcignUGljYTogXCIuZnJvbVwiIHNob3VsZCBiZSBJbWFnZSwgQ2FudmFzIG9yIEltYWdlQml0bWFwJyk7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjtcblxuICAgIF90aGlzMy5kZWJ1ZygnQ2FsY3VsYXRlIHRpbGVzJyk7IC8vXG4gICAgLy8gSGVyZSB3ZSBhcmUgd2l0aCBcIm5vcm1hbGl6ZWRcIiBzb3VyY2UsXG4gICAgLy8gZm9sbG93IHRvIHRpbGluZ1xuICAgIC8vXG5cblxuICAgIHZhciByZWdpb25zID0gY3JlYXRlUmVnaW9ucyh7XG4gICAgICB3aWR0aDogb3B0cy53aWR0aCxcbiAgICAgIGhlaWdodDogb3B0cy5oZWlnaHQsXG4gICAgICBzcmNUaWxlU2l6ZTogX3RoaXMzLm9wdGlvbnMudGlsZSxcbiAgICAgIHRvV2lkdGg6IG9wdHMudG9XaWR0aCxcbiAgICAgIHRvSGVpZ2h0OiBvcHRzLnRvSGVpZ2h0LFxuICAgICAgZGVzdFRpbGVCb3JkZXI6IG9wdHMuX19kZXN0VGlsZUJvcmRlclxuICAgIH0pO1xuICAgIHZhciBqb2JzID0gcmVnaW9ucy5tYXAoZnVuY3Rpb24gKHRpbGUpIHtcbiAgICAgIHJldHVybiBwcm9jZXNzVGlsZSh0aWxlKTtcbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIGNsZWFudXAoc3RhZ2VFbnYpIHtcbiAgICAgIGlmIChzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCkge1xuICAgICAgICBpZiAoIXN0YWdlRW52LmlzSW1hZ2VCaXRtYXBSZXVzZWQpIHN0YWdlRW52LnNyY0ltYWdlQml0bWFwLmNsb3NlKCk7XG4gICAgICAgIHN0YWdlRW52LnNyY0ltYWdlQml0bWFwID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBfdGhpczMuZGVidWcoJ1Byb2Nlc3MgdGlsZXMnKTtcblxuICAgIHJldHVybiBQcm9taXNlLmFsbChqb2JzKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIF90aGlzMy5kZWJ1ZygnRmluaXNoZWQhJyk7XG5cbiAgICAgIGNsZWFudXAoc3RhZ2VFbnYpO1xuICAgICAgcmV0dXJuIHRvO1xuICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGNsZWFudXAoc3RhZ2VFbnYpO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0pO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLl9fcHJvY2Vzc1N0YWdlcyA9IGZ1bmN0aW9uIChzdGFnZXMsIGZyb20sIHRvLCBvcHRzKSB7XG4gIHZhciBfdGhpczQgPSB0aGlzO1xuXG4gIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjtcblxuICB2YXIgX3N0YWdlcyRzaGlmdCA9IHN0YWdlcy5zaGlmdCgpLFxuICAgICAgX3N0YWdlcyRzaGlmdDIgPSBfc2xpY2VkVG9BcnJheShfc3RhZ2VzJHNoaWZ0LCAyKSxcbiAgICAgIHRvV2lkdGggPSBfc3RhZ2VzJHNoaWZ0MlswXSxcbiAgICAgIHRvSGVpZ2h0ID0gX3N0YWdlcyRzaGlmdDJbMV07XG5cbiAgdmFyIGlzTGFzdFN0YWdlID0gc3RhZ2VzLmxlbmd0aCA9PT0gMDtcbiAgb3B0cyA9IGFzc2lnbih7fSwgb3B0cywge1xuICAgIHRvV2lkdGg6IHRvV2lkdGgsXG4gICAgdG9IZWlnaHQ6IHRvSGVpZ2h0LFxuICAgIC8vIG9ubHkgdXNlIHVzZXItZGVmaW5lZCBxdWFsaXR5IGZvciB0aGUgbGFzdCBzdGFnZSxcbiAgICAvLyB1c2Ugc2ltcGxlciAoSGFtbWluZykgZmlsdGVyIGZvciB0aGUgZmlyc3Qgc3RhZ2VzIHdoZXJlXG4gICAgLy8gc2NhbGUgZmFjdG9yIGlzIGxhcmdlIGVub3VnaCAobW9yZSB0aGFuIDItMylcbiAgICBxdWFsaXR5OiBpc0xhc3RTdGFnZSA/IG9wdHMucXVhbGl0eSA6IE1hdGgubWluKDEsIG9wdHMucXVhbGl0eSlcbiAgfSk7XG4gIHZhciB0bXBDYW52YXM7XG5cbiAgaWYgKCFpc0xhc3RTdGFnZSkge1xuICAgIC8vIGNyZWF0ZSB0ZW1wb3JhcnkgY2FudmFzXG4gICAgdG1wQ2FudmFzID0gdGhpcy5vcHRpb25zLmNyZWF0ZUNhbnZhcyh0b1dpZHRoLCB0b0hlaWdodCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fX3RpbGVBbmRSZXNpemUoZnJvbSwgaXNMYXN0U3RhZ2UgPyB0byA6IHRtcENhbnZhcywgb3B0cykudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGlzTGFzdFN0YWdlKSByZXR1cm4gdG87XG4gICAgb3B0cy53aWR0aCA9IHRvV2lkdGg7XG4gICAgb3B0cy5oZWlnaHQgPSB0b0hlaWdodDtcbiAgICByZXR1cm4gX3RoaXM0Ll9fcHJvY2Vzc1N0YWdlcyhzdGFnZXMsIHRtcENhbnZhcywgdG8sIG9wdHMpO1xuICB9KS50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICBpZiAodG1wQ2FudmFzKSB7XG4gICAgICAvLyBTYWZhcmkgMTIgd29ya2Fyb3VuZFxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcbiAgICAgIHRtcENhbnZhcy53aWR0aCA9IHRtcENhbnZhcy5oZWlnaHQgPSAwO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUuX19yZXNpemVWaWFDcmVhdGVJbWFnZUJpdG1hcCA9IGZ1bmN0aW9uIChmcm9tLCB0bywgb3B0cykge1xuICB2YXIgX3RoaXM1ID0gdGhpcztcblxuICB2YXIgdG9DdHggPSB0by5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICB9KTtcbiAgdGhpcy5kZWJ1ZygnUmVzaXplIHZpYSBjcmVhdGVJbWFnZUJpdG1hcCgpJyk7XG4gIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChmcm9tLCB7XG4gICAgcmVzaXplV2lkdGg6IG9wdHMudG9XaWR0aCxcbiAgICByZXNpemVIZWlnaHQ6IG9wdHMudG9IZWlnaHQsXG4gICAgcmVzaXplUXVhbGl0eTogdXRpbHMuY2liX3F1YWxpdHlfbmFtZShvcHRzLnF1YWxpdHkpXG4gIH0pLnRoZW4oZnVuY3Rpb24gKGltYWdlQml0bWFwKSB7XG4gICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuOyAvLyBpZiBubyB1bnNoYXJwIC0gZHJhdyBkaXJlY3RseSB0byBvdXRwdXQgY2FudmFzXG5cbiAgICBpZiAoIW9wdHMudW5zaGFycEFtb3VudCkge1xuICAgICAgdG9DdHguZHJhd0ltYWdlKGltYWdlQml0bWFwLCAwLCAwKTtcbiAgICAgIGltYWdlQml0bWFwLmNsb3NlKCk7XG4gICAgICB0b0N0eCA9IG51bGw7XG5cbiAgICAgIF90aGlzNS5kZWJ1ZygnRmluaXNoZWQhJyk7XG5cbiAgICAgIHJldHVybiB0bztcbiAgICB9XG5cbiAgICBfdGhpczUuZGVidWcoJ1Vuc2hhcnAgcmVzdWx0Jyk7XG5cbiAgICB2YXIgdG1wQ2FudmFzID0gX3RoaXM1Lm9wdGlvbnMuY3JlYXRlQ2FudmFzKG9wdHMudG9XaWR0aCwgb3B0cy50b0hlaWdodCk7XG5cbiAgICB2YXIgdG1wQ3R4ID0gdG1wQ2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgICB9KTtcbiAgICB0bXBDdHguZHJhd0ltYWdlKGltYWdlQml0bWFwLCAwLCAwKTtcbiAgICBpbWFnZUJpdG1hcC5jbG9zZSgpO1xuICAgIHZhciBpRGF0YSA9IHRtcEN0eC5nZXRJbWFnZURhdGEoMCwgMCwgb3B0cy50b1dpZHRoLCBvcHRzLnRvSGVpZ2h0KTtcblxuICAgIF90aGlzNS5fX21hdGhsaWIudW5zaGFycF9tYXNrKGlEYXRhLmRhdGEsIG9wdHMudG9XaWR0aCwgb3B0cy50b0hlaWdodCwgb3B0cy51bnNoYXJwQW1vdW50LCBvcHRzLnVuc2hhcnBSYWRpdXMsIG9wdHMudW5zaGFycFRocmVzaG9sZCk7XG5cbiAgICB0b0N0eC5wdXRJbWFnZURhdGEoaURhdGEsIDAsIDApOyAvLyBTYWZhcmkgMTIgd29ya2Fyb3VuZFxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMTk5XG5cbiAgICB0bXBDYW52YXMud2lkdGggPSB0bXBDYW52YXMuaGVpZ2h0ID0gMDtcbiAgICBpRGF0YSA9IHRtcEN0eCA9IHRtcENhbnZhcyA9IHRvQ3R4ID0gbnVsbDtcblxuICAgIF90aGlzNS5kZWJ1ZygnRmluaXNoZWQhJyk7XG5cbiAgICByZXR1cm4gdG87XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24gKGZyb20sIHRvLCBvcHRpb25zKSB7XG4gIHZhciBfdGhpczYgPSB0aGlzO1xuXG4gIHRoaXMuZGVidWcoJ1N0YXJ0IHJlc2l6ZS4uLicpO1xuICB2YXIgb3B0cyA9IGFzc2lnbih7fSwgREVGQVVMVF9SRVNJWkVfT1BUUyk7XG5cbiAgaWYgKCFpc05hTihvcHRpb25zKSkge1xuICAgIG9wdHMgPSBhc3NpZ24ob3B0cywge1xuICAgICAgcXVhbGl0eTogb3B0aW9uc1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKG9wdGlvbnMpIHtcbiAgICBvcHRzID0gYXNzaWduKG9wdHMsIG9wdGlvbnMpO1xuICB9XG5cbiAgb3B0cy50b1dpZHRoID0gdG8ud2lkdGg7XG4gIG9wdHMudG9IZWlnaHQgPSB0by5oZWlnaHQ7XG4gIG9wdHMud2lkdGggPSBmcm9tLm5hdHVyYWxXaWR0aCB8fCBmcm9tLndpZHRoO1xuICBvcHRzLmhlaWdodCA9IGZyb20ubmF0dXJhbEhlaWdodCB8fCBmcm9tLmhlaWdodDsgLy8gUHJldmVudCBzdGVwcGVyIGZyb20gaW5maW5pdGUgbG9vcFxuXG4gIGlmICh0by53aWR0aCA9PT0gMCB8fCB0by5oZWlnaHQgPT09IDApIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCBvdXRwdXQgc2l6ZTogXCIuY29uY2F0KHRvLndpZHRoLCBcInhcIikuY29uY2F0KHRvLmhlaWdodCkpKTtcbiAgfVxuXG4gIGlmIChvcHRzLnVuc2hhcnBSYWRpdXMgPiAyKSBvcHRzLnVuc2hhcnBSYWRpdXMgPSAyO1xuICBvcHRzLmNhbmNlbGVkID0gZmFsc2U7XG5cbiAgaWYgKG9wdHMuY2FuY2VsVG9rZW4pIHtcbiAgICAvLyBXcmFwIGNhbmNlbFRva2VuIHRvIGF2b2lkIHN1Y2Nlc3NpdmUgcmVzb2x2ZSAmIHNldCBmbGFnXG4gICAgb3B0cy5jYW5jZWxUb2tlbiA9IG9wdHMuY2FuY2VsVG9rZW4udGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgb3B0cy5jYW5jZWxlZCA9IHRydWU7XG4gICAgICB0aHJvdyBkYXRhO1xuICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIG9wdHMuY2FuY2VsZWQgPSB0cnVlO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0pO1xuICB9XG5cbiAgdmFyIERFU1RfVElMRV9CT1JERVIgPSAzOyAvLyBNYXggcG9zc2libGUgZmlsdGVyIHdpbmRvdyBzaXplXG5cbiAgb3B0cy5fX2Rlc3RUaWxlQm9yZGVyID0gTWF0aC5jZWlsKE1hdGgubWF4KERFU1RfVElMRV9CT1JERVIsIDIuNSAqIG9wdHMudW5zaGFycFJhZGl1cyB8IDApKTtcbiAgcmV0dXJuIHRoaXMuaW5pdCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjsgLy8gaWYgY3JlYXRlSW1hZ2VCaXRtYXAgc3VwcG9ydHMgcmVzaXplLCBqdXN0IGRvIGl0IGFuZCByZXR1cm5cblxuICAgIGlmIChfdGhpczYuZmVhdHVyZXMuY2liKSB7XG4gICAgICByZXR1cm4gX3RoaXM2Ll9fcmVzaXplVmlhQ3JlYXRlSW1hZ2VCaXRtYXAoZnJvbSwgdG8sIG9wdHMpO1xuICAgIH1cblxuICAgIGlmICghQ0FOX1VTRV9DQU5WQVNfR0VUX0lNQUdFX0RBVEEpIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1BpY2E6IGNhbm5vdCB1c2UgZ2V0SW1hZ2VEYXRhIG9uIGNhbnZhcywgJyArIFwibWFrZSBzdXJlIGZpbmdlcnByaW50aW5nIHByb3RlY3Rpb24gaXNuJ3QgZW5hYmxlZFwiKTtcbiAgICAgIGVyci5jb2RlID0gJ0VSUl9HRVRfSU1BR0VfREFUQSc7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSAvL1xuICAgIC8vIE5vIGVhc3kgd2F5LCBsZXQncyByZXNpemUgbWFudWFsbHkgdmlhIGFycmF5c1xuICAgIC8vXG5cblxuICAgIHZhciBzdGFnZXMgPSBjcmVhdGVTdGFnZXMob3B0cy53aWR0aCwgb3B0cy5oZWlnaHQsIG9wdHMudG9XaWR0aCwgb3B0cy50b0hlaWdodCwgX3RoaXM2Lm9wdGlvbnMudGlsZSwgb3B0cy5fX2Rlc3RUaWxlQm9yZGVyKTtcbiAgICByZXR1cm4gX3RoaXM2Ll9fcHJvY2Vzc1N0YWdlcyhzdGFnZXMsIGZyb20sIHRvLCBvcHRzKTtcbiAgfSk7XG59OyAvLyBSR0JBIGJ1ZmZlciByZXNpemVcbi8vXG5cblxuUGljYS5wcm90b3R5cGUucmVzaXplQnVmZmVyID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgdmFyIF90aGlzNyA9IHRoaXM7XG5cbiAgdmFyIG9wdHMgPSBhc3NpZ24oe30sIERFRkFVTFRfUkVTSVpFX09QVFMsIG9wdGlvbnMpO1xuICByZXR1cm4gdGhpcy5pbml0KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF90aGlzNy5fX21hdGhsaWIucmVzaXplQW5kVW5zaGFycChvcHRzKTtcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS50b0Jsb2IgPSBmdW5jdGlvbiAoY2FudmFzLCBtaW1lVHlwZSwgcXVhbGl0eSkge1xuICBtaW1lVHlwZSA9IG1pbWVUeXBlIHx8ICdpbWFnZS9wbmcnO1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICBpZiAoY2FudmFzLnRvQmxvYikge1xuICAgICAgY2FudmFzLnRvQmxvYihmdW5jdGlvbiAoYmxvYikge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShibG9iKTtcbiAgICAgIH0sIG1pbWVUeXBlLCBxdWFsaXR5KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY2FudmFzLmNvbnZlcnRUb0Jsb2IpIHtcbiAgICAgIHJlc29sdmUoY2FudmFzLmNvbnZlcnRUb0Jsb2Ioe1xuICAgICAgICB0eXBlOiBtaW1lVHlwZSxcbiAgICAgICAgcXVhbGl0eTogcXVhbGl0eVxuICAgICAgfSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gRmFsbGJhY2sgZm9yIG9sZCBicm93c2Vyc1xuXG5cbiAgICB2YXIgYXNTdHJpbmcgPSBhdG9iKGNhbnZhcy50b0RhdGFVUkwobWltZVR5cGUsIHF1YWxpdHkpLnNwbGl0KCcsJylbMV0pO1xuICAgIHZhciBsZW4gPSBhc1N0cmluZy5sZW5ndGg7XG4gICAgdmFyIGFzQnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkobGVuKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGFzQnVmZmVyW2ldID0gYXNTdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICB9XG5cbiAgICByZXNvbHZlKG5ldyBCbG9iKFthc0J1ZmZlcl0sIHtcbiAgICAgIHR5cGU6IG1pbWVUeXBlXG4gICAgfSkpO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLmRlYnVnID0gZnVuY3Rpb24gKCkge307XG5cbm1vZHVsZS5leHBvcnRzID0gUGljYTtcblxufSx7XCIuL2xpYi9tYXRobGliXCI6MSxcIi4vbGliL3Bvb2xcIjoxMyxcIi4vbGliL3N0ZXBwZXJcIjoxNCxcIi4vbGliL3RpbGVyXCI6MTUsXCIuL2xpYi91dGlsc1wiOjE2LFwiLi9saWIvd29ya2VyXCI6MTcsXCJvYmplY3QtYXNzaWduXCI6MjMsXCJ3ZWJ3b3JraWZ5XCI6MjR9XX0se30sW10pKFwiL2luZGV4LmpzXCIpXG59KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../../node_modules/pica/dist/pica.js\n");
18
18
 
19
19
  /***/ }),
20
20