@cartanova/qgrid-cli 2.10.10 → 2.11.1

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 (302) hide show
  1. package/bundle/dist/_virtual/_rolldown/runtime.js +1 -10
  2. package/bundle/dist/application/monit/log-buffer.js +12 -6
  3. package/bundle/dist/application/monit/monit.frame.js +11 -3
  4. package/bundle/dist/application/monit/monit.types.js +1 -1
  5. package/bundle/dist/application/qgrid/conv-routing.js +9 -6
  6. package/bundle/dist/application/qgrid/expired-token-reminder.js +2 -2
  7. package/bundle/dist/application/qgrid/oauth.js +31 -4
  8. package/bundle/dist/application/qgrid/qgrid-image-generation.js +1 -1
  9. package/bundle/dist/application/qgrid/qgrid-response-format.js +21 -19
  10. package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +40 -33
  11. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +128 -93
  12. package/bundle/dist/application/qgrid/qgrid.frame.js +930 -49
  13. package/bundle/dist/application/qgrid/qgrid.types.js +212 -5
  14. package/bundle/dist/application/qgrid/schema-prompt.js +75 -48
  15. package/bundle/dist/application/qgrid/slack-user-map.js +1 -1
  16. package/bundle/dist/application/qgrid/token-death.js +1 -1
  17. package/bundle/dist/application/qgrid/token-subscriber.js +83 -30
  18. package/bundle/dist/application/qgrid/token-trigger-setup.js +1 -1
  19. package/bundle/dist/application/qgrid/token-window-keepalive.js +8 -6
  20. package/bundle/dist/application/qgrid/tool-emulation-schema.js +13 -13
  21. package/bundle/dist/application/qgrid/tool-emulation.js +19 -15
  22. package/bundle/dist/application/request-log/json-schema-type-text.js +29 -12
  23. package/bundle/dist/application/request-log/request-log.model.js +83 -70
  24. package/bundle/dist/application/request-log/request-log.types.js +1 -1
  25. package/bundle/dist/application/request-log/zod-code-format.js +1 -1
  26. package/bundle/dist/application/request-log-step/request-log-step.model.js +1 -1
  27. package/bundle/dist/application/request-log-step/request-log-step.types.js +1 -1
  28. package/bundle/dist/application/setting/setting.constant.js +1 -1
  29. package/bundle/dist/application/setting/setting.model.js +2 -2
  30. package/bundle/dist/application/setting/setting.store.js +2 -2
  31. package/bundle/dist/application/setting/setting.types.js +1 -1
  32. package/bundle/dist/application/sonamu.generated.js +32 -16
  33. package/bundle/dist/application/sonamu.generated.sso.js +1 -1
  34. package/bundle/dist/application/token/token.model.js +26 -9
  35. package/bundle/dist/application/token/token.types.js +20 -3
  36. package/bundle/dist/i18n/en.js +15 -1
  37. package/bundle/dist/i18n/ko.js +15 -1
  38. package/bundle/dist/i18n/sd.generated.js +1 -1
  39. package/bundle/dist/migrations/20260807133553_manual__backfill_request_log_cost.js +8 -6
  40. package/bundle/dist/server-bootstrap.js +4 -2
  41. package/bundle/dist/server-error-handler.js +1 -1
  42. package/bundle/dist/sonamu.config.js +37 -8
  43. package/bundle/dist/startup-migrations.js +17 -7
  44. package/bundle/dist/testing/global.js +1 -1
  45. package/bundle/dist/testing/schema-bench.js +0 -0
  46. package/bundle/dist/testing/test-database-name.js +1 -1
  47. package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +1 -1
  48. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +11 -5
  49. package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +4 -4
  50. package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +1 -1
  51. package/bundle/dist/utils/providers/anthropic/claude-session.js +20 -19
  52. package/bundle/dist/utils/providers/anthropic/fence-strip.js +1 -1
  53. package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +49 -23
  54. package/bundle/dist/utils/providers/common/credentials.js +5 -1
  55. package/bundle/dist/utils/providers/common/effort.js +3 -3
  56. package/bundle/dist/utils/providers/common/model-cost.js +69 -14
  57. package/bundle/dist/utils/providers/common/provider-types.js +29 -1
  58. package/bundle/dist/utils/providers/common/schema-validation.js +78 -40
  59. package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -1
  60. package/bundle/dist/utils/providers/common/strictifier.js +62 -43
  61. package/bundle/dist/utils/providers/common/thinking.js +3 -2
  62. package/bundle/dist/utils/providers/common/ttft.js +1 -1
  63. package/bundle/dist/utils/providers/grok/grok-backend-protocol.js +427 -0
  64. package/bundle/dist/utils/providers/grok/grok-constants.js +55 -0
  65. package/bundle/dist/utils/providers/grok/grok-direct-client.js +196 -0
  66. package/bundle/dist/utils/providers/grok/grok-dispatcher.js +1313 -0
  67. package/bundle/dist/utils/providers/grok/grok-headers.js +118 -0
  68. package/bundle/dist/utils/providers/grok/grok-media-client.js +420 -0
  69. package/bundle/dist/utils/providers/grok/grok-models.js +114 -0
  70. package/bundle/dist/utils/providers/grok/grok-oauth.js +455 -0
  71. package/bundle/dist/utils/providers/grok/grok-quota.js +119 -0
  72. package/bundle/dist/utils/providers/grok/grok-refresh.js +192 -0
  73. package/bundle/dist/utils/providers/grok/grok-types.js +186 -0
  74. package/bundle/dist/utils/providers/grok/grok-voice-client.js +199 -0
  75. package/bundle/dist/utils/providers/grok/index.js +11 -0
  76. package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +111 -83
  77. package/bundle/dist/utils/providers/openai/openai-callback-relay.js +3 -2
  78. package/bundle/dist/utils/providers/openai/openai-constants.js +1 -1
  79. package/bundle/dist/utils/providers/openai/openai-direct-client.js +23 -7
  80. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +143 -106
  81. package/bundle/dist/utils/providers/openai/openai-image-generation.js +48 -33
  82. package/bundle/dist/utils/providers/openai/openai-oauth.js +28 -13
  83. package/bundle/dist/utils/providers/openai/openai-quota.js +38 -27
  84. package/bundle/dist/utils/providers/openai/openai-refresh.js +17 -9
  85. package/bundle/dist/utils/providers/openai/openai-sse.js +1 -1
  86. package/bundle/dist/utils/providers/openai/openai-transport-config.js +1 -1
  87. package/bundle/dist/utils/quiet-hours.js +1 -1
  88. package/bundle/dist/utils/slack-notify.js +14 -8
  89. package/bundle/dist/utils/subset-loaders.js +4 -5
  90. package/bundle/src/application/monit/log-buffer.ts +23 -9
  91. package/bundle/src/application/monit/monit.frame.ts +22 -5
  92. package/bundle/src/application/monit/monit.types.ts +6 -0
  93. package/bundle/src/application/qgrid/conv-routing.test.ts +76 -4
  94. package/bundle/src/application/qgrid/conv-routing.ts +35 -9
  95. package/bundle/src/application/qgrid/expired-token-reminder.ts +9 -1
  96. package/bundle/src/application/qgrid/oauth.ts +51 -15
  97. package/bundle/src/application/qgrid/qgrid-image-generation.ts +9 -0
  98. package/bundle/src/application/qgrid/qgrid-response-format.ts +50 -25
  99. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +19 -0
  100. package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +84 -40
  101. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +97 -0
  102. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +274 -126
  103. package/bundle/src/application/qgrid/qgrid.frame.test.ts +1013 -3
  104. package/bundle/src/application/qgrid/qgrid.frame.ts +1415 -60
  105. package/bundle/src/application/qgrid/qgrid.types.ts +335 -0
  106. package/bundle/src/application/qgrid/schema-prompt.ts +105 -41
  107. package/bundle/src/application/qgrid/slack-user-map.ts +5 -0
  108. package/bundle/src/application/qgrid/token-death.ts +4 -0
  109. package/bundle/src/application/qgrid/token-subscriber.test.ts +21 -19
  110. package/bundle/src/application/qgrid/token-subscriber.ts +186 -53
  111. package/bundle/src/application/qgrid/token-trigger-setup.ts +2 -0
  112. package/bundle/src/application/qgrid/token-window-keepalive.ts +49 -6
  113. package/bundle/src/application/qgrid/tool-emulation-schema.ts +33 -29
  114. package/bundle/src/application/qgrid/tool-emulation.ts +52 -27
  115. package/bundle/src/application/request-log/json-schema-type-text.test.ts +5 -5
  116. package/bundle/src/application/request-log/json-schema-type-text.ts +81 -26
  117. package/bundle/src/application/request-log/request-log.model.test.ts +111 -4
  118. package/bundle/src/application/request-log/request-log.model.ts +277 -146
  119. package/bundle/src/application/request-log/request-log.types.ts +6 -0
  120. package/bundle/src/application/request-log/zod-code-format.ts +11 -0
  121. package/bundle/src/application/request-log-step/request-log-step.model.ts +1 -0
  122. package/bundle/src/application/request-log-step/request-log-step.types.ts +2 -0
  123. package/bundle/src/application/setting/setting.constant.ts +9 -0
  124. package/bundle/src/application/setting/setting.model.ts +12 -2
  125. package/bundle/src/application/setting/setting.store.ts +5 -1
  126. package/bundle/src/application/setting/setting.types.ts +8 -0
  127. package/bundle/src/application/sonamu.generated.http +133 -0
  128. package/bundle/src/application/sonamu.generated.sso.ts +2 -0
  129. package/bundle/src/application/sonamu.generated.ts +15 -0
  130. package/bundle/src/application/token/token.identity.test.ts +20 -0
  131. package/bundle/src/application/token/token.model.ts +66 -7
  132. package/bundle/src/application/token/token.types.ts +24 -1
  133. package/bundle/src/i18n/en.ts +19 -0
  134. package/bundle/src/i18n/ko.ts +21 -0
  135. package/bundle/src/i18n/sd.generated.ts +23 -2
  136. package/bundle/src/migrations/20260807133553_manual__backfill_request_log_cost.ts +16 -8
  137. package/bundle/src/server-bootstrap.ts +4 -2
  138. package/bundle/src/server-error-handler.ts +1 -0
  139. package/bundle/src/sonamu.config.ts +69 -7
  140. package/bundle/src/startup-migrations.ts +27 -9
  141. package/bundle/src/testing/global.ts +20 -0
  142. package/bundle/src/testing/schema-bench.ts +105 -30
  143. package/bundle/src/testing/test-database-name.ts +2 -0
  144. package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +8 -0
  145. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +41 -6
  146. package/bundle/src/utils/providers/anthropic/anthropic-quota.ts +7 -3
  147. package/bundle/src/utils/providers/anthropic/anthropic-thinking.ts +6 -0
  148. package/bundle/src/utils/providers/anthropic/claude-session.ts +58 -24
  149. package/bundle/src/utils/providers/anthropic/fence-strip.ts +11 -0
  150. package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +110 -45
  151. package/bundle/src/utils/providers/common/credentials.ts +8 -0
  152. package/bundle/src/utils/providers/common/effort.ts +9 -2
  153. package/bundle/src/utils/providers/common/model-cost.test.ts +48 -1
  154. package/bundle/src/utils/providers/common/model-cost.ts +259 -158
  155. package/bundle/src/utils/providers/common/provider-dispatcher.ts +98 -2
  156. package/bundle/src/utils/providers/common/provider-types.ts +46 -3
  157. package/bundle/src/utils/providers/common/schema-validation.test.ts +5 -1
  158. package/bundle/src/utils/providers/common/schema-validation.ts +124 -56
  159. package/bundle/src/utils/providers/common/smooth-weighted-round-robin.ts +4 -0
  160. package/bundle/src/utils/providers/common/strictifier.ts +185 -59
  161. package/bundle/src/utils/providers/common/thinking.ts +2 -2
  162. package/bundle/src/utils/providers/common/ttft.ts +4 -2
  163. package/bundle/src/utils/providers/grok/__fixtures__/golden-responses-1.0.60.json +164 -0
  164. package/bundle/src/utils/providers/grok/grok-backend-protocol.test.ts +325 -0
  165. package/bundle/src/utils/providers/grok/grok-backend-protocol.ts +721 -0
  166. package/bundle/src/utils/providers/grok/grok-constants.ts +105 -0
  167. package/bundle/src/utils/providers/grok/grok-direct-client.test.ts +179 -0
  168. package/bundle/src/utils/providers/grok/grok-direct-client.ts +313 -0
  169. package/bundle/src/utils/providers/grok/grok-dispatcher.test.ts +1395 -0
  170. package/bundle/src/utils/providers/grok/grok-dispatcher.ts +2105 -0
  171. package/bundle/src/utils/providers/grok/grok-headers.test.ts +149 -0
  172. package/bundle/src/utils/providers/grok/grok-headers.ts +199 -0
  173. package/bundle/src/utils/providers/grok/grok-media-client.test.ts +446 -0
  174. package/bundle/src/utils/providers/grok/grok-media-client.ts +703 -0
  175. package/bundle/src/utils/providers/grok/grok-models.test.ts +96 -0
  176. package/bundle/src/utils/providers/grok/grok-models.ts +161 -0
  177. package/bundle/src/utils/providers/grok/grok-oauth.test.ts +406 -0
  178. package/bundle/src/utils/providers/grok/grok-oauth.ts +771 -0
  179. package/bundle/src/utils/providers/grok/grok-quota.test.ts +142 -0
  180. package/bundle/src/utils/providers/grok/grok-quota.ts +198 -0
  181. package/bundle/src/utils/providers/grok/grok-refresh.test.ts +239 -0
  182. package/bundle/src/utils/providers/grok/grok-refresh.ts +325 -0
  183. package/bundle/src/utils/providers/grok/grok-types.test.ts +252 -0
  184. package/bundle/src/utils/providers/grok/grok-types.ts +374 -0
  185. package/bundle/src/utils/providers/grok/grok-voice-client.test.ts +321 -0
  186. package/bundle/src/utils/providers/grok/grok-voice-client.ts +284 -0
  187. package/bundle/src/utils/providers/grok/index.ts +20 -0
  188. package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +221 -137
  189. package/bundle/src/utils/providers/openai/openai-callback-relay.ts +12 -1
  190. package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
  191. package/bundle/src/utils/providers/openai/openai-direct-client.ts +111 -21
  192. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +322 -169
  193. package/bundle/src/utils/providers/openai/openai-image-generation.ts +116 -36
  194. package/bundle/src/utils/providers/openai/openai-oauth.ts +48 -20
  195. package/bundle/src/utils/providers/openai/openai-quota.ts +77 -46
  196. package/bundle/src/utils/providers/openai/openai-refresh.ts +42 -18
  197. package/bundle/src/utils/providers/openai/openai-sse.ts +27 -3
  198. package/bundle/src/utils/providers/openai/openai-transport-config.ts +2 -0
  199. package/bundle/src/utils/quiet-hours.ts +12 -1
  200. package/bundle/src/utils/slack-notify.ts +44 -13
  201. package/bundle/src/utils/subset-loaders.ts +7 -7
  202. package/bundle/web-dist/client/assets/clsx-5XM_pHvN.js +1 -0
  203. package/bundle/web-dist/client/assets/index-Be2qCZmI.css +1 -0
  204. package/bundle/web-dist/client/assets/index-C96h3feE.js +32 -0
  205. package/bundle/web-dist/client/assets/logs-DBM6U0QD.js +1 -0
  206. package/bundle/web-dist/client/assets/monit-BBjXa7vB.js +1 -0
  207. package/bundle/web-dist/client/assets/routes-Crz_PQzi.js +5 -0
  208. package/bundle/web-dist/client/assets/{services.generated-NP-ValHd.js → services.generated-B5lc3aIC.js} +5 -5
  209. package/bundle/web-dist/client/assets/settings-Cdwm3OBB.js +1 -0
  210. package/bundle/web-dist/client/assets/show-DBUhALT1.js +2 -0
  211. package/bundle/web-dist/client/assets/tokens-CVQAVJTo.js +1 -0
  212. package/bundle/web-dist/client/assets/total-cost-MnfKU8IN.js +1 -0
  213. package/bundle/web-dist/client/assets/use-oauth-login-flow-BfxYI4Oh.js +1 -0
  214. package/bundle/web-dist/client/assets/use-update-token-mutation-qKBC2sn7.js +1 -0
  215. package/bundle/web-dist/client/assets/{vendor-tanstack-DJRQAbrY.js → vendor-tanstack-DRPs09ai.js} +1 -1
  216. package/bundle/web-dist/client/index.html +5 -5
  217. package/bundle/web-dist/server/assets/clsx-D_N5PN_2.js +16 -0
  218. package/bundle/web-dist/server/assets/{lazyRouteComponent-CgBdabgd.js → lazyRouteComponent-AKiHfZWp.js} +129 -2
  219. package/bundle/web-dist/server/assets/{logs-BMyR98rU.js → logs-B7QmGJq3.js} +18 -14
  220. package/bundle/web-dist/server/assets/{monit-ZPt66W5M.js → monit-DFt7x3bh.js} +13 -12
  221. package/bundle/web-dist/server/assets/{plus-BZ9I0VgC.js → plus-DaYQRpBt.js} +1 -1
  222. package/bundle/web-dist/server/assets/{react-dom-Ds75e4Jl.js → react-dom-Cv23mm1K.js} +2 -129
  223. package/bundle/web-dist/server/assets/{refresh-cw-CztCFis-.js → refresh-cw-BpXNsAy-.js} +1 -1
  224. package/bundle/web-dist/server/assets/{request-model-DjGldb-h.js → request-model-eHE6YbaF.js} +1 -1
  225. package/bundle/web-dist/server/assets/{routes-Ct-k7nBA.js → routes-_Y-PJfgO.js} +110 -39
  226. package/bundle/web-dist/server/assets/{services.generated-BA4AcAf5.js → services.generated-CMJ8AHbO.js} +582 -172
  227. package/bundle/web-dist/server/assets/{settings-CBUZ47Xx.js → settings-JwJKxn2e.js} +14 -14
  228. package/bundle/web-dist/server/assets/{show-LSFIzvO2.js → show-BEv6z1v_.js} +90 -60
  229. package/bundle/web-dist/server/assets/{tokens-DxrBW512.js → tokens-CNT4mI-f.js} +162 -50
  230. package/bundle/web-dist/server/assets/total-cost-fTE9Xy82.js +18 -0
  231. package/bundle/web-dist/server/assets/use-oauth-login-flow-jkAkT3X6.js +2345 -0
  232. package/bundle/web-dist/server/assets/{use-update-token-mutation-pkArIzCP.js → use-update-token-mutation-Sm6kh02m.js} +1 -1
  233. package/bundle/web-dist/server/entry-server.generated.js +1644 -21655
  234. package/dist/cli.js +9 -9
  235. package/package.json +4 -11
  236. package/postinstall.mjs +12 -0
  237. package/skills/qgrid/SKILL.md +1 -0
  238. package/skills/qgrid/references/cli-env-and-server-boot.md +4 -1
  239. package/skills/qgrid/references/decision-rationale.md +23 -0
  240. package/skills/qgrid/references/grok-runtime.md +89 -0
  241. package/skills/qgrid/references/provider-runtime-differences.md +30 -29
  242. package/skills/qgrid/references/repo-map.md +10 -0
  243. package/skills/qgrid/references/token-auth-quota-lifecycle.md +56 -3
  244. package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -406
  245. package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +0 -1507
  246. package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  247. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2756
  248. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +0 -8
  249. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +0 -8
  250. package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +0 -922
  251. package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +0 -386
  252. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -121
  253. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +0 -51
  254. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +0 -1317
  255. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +0 -561
  256. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +0 -40
  257. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +0 -272
  258. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +0 -27
  259. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +0 -77
  260. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +0 -381
  261. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +0 -51
  262. package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2986
  263. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  264. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  265. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  266. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  267. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  268. package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1126
  269. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  270. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  271. package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -517
  272. package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -101
  273. package/bundle/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.11.2_@emnapi_runtime@1.11.2_@types_node@25.0.7_esbuild@0.27.4_5b35fc1fb85d2af4d105e0d74f940f50/node_modules/vite/dist/node/module-runner.js +0 -1265
  274. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -9
  275. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
  276. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
  277. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
  278. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +0 -46
  279. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -119
  280. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +0 -3044
  281. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -59
  282. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/index.js +0 -28
  283. package/bundle/dist/testing/setup-mocks.js +0 -16
  284. package/bundle/src/testing/setup-mocks.ts +0 -44
  285. package/bundle/web-dist/client/assets/index-Bw2s88Ot.css +0 -1
  286. package/bundle/web-dist/client/assets/index-DZwzUfI-.js +0 -106
  287. package/bundle/web-dist/client/assets/logs-Cog79DU5.js +0 -1
  288. package/bundle/web-dist/client/assets/monit-2auznBys.js +0 -1
  289. package/bundle/web-dist/client/assets/routes-B0lTeLK-.js +0 -5
  290. package/bundle/web-dist/client/assets/settings-D8ZxZGSJ.js +0 -1
  291. package/bundle/web-dist/client/assets/show-CFSERlnM.js +0 -2
  292. package/bundle/web-dist/client/assets/tokens-CZXUyI7O.js +0 -1
  293. package/bundle/web-dist/client/assets/use-oauth-login-flow-hboOs3wG.js +0 -1
  294. package/bundle/web-dist/client/assets/use-update-token-mutation-BQHS0byG.js +0 -1
  295. package/bundle/web-dist/server/assets/use-oauth-login-flow-Gn8flMK5.js +0 -178
  296. package/dist/cli.d.ts +0 -10
  297. /package/bundle/web-dist/client/assets/{cost-DH2jZbrw.js → cost-DB3HbU7T.js} +0 -0
  298. /package/bundle/web-dist/client/assets/{plus-B62CuqT8.js → plus-BsQdY7PS.js} +0 -0
  299. /package/bundle/web-dist/client/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  300. /package/bundle/web-dist/client/assets/{refresh-cw-NNcU0Cmq.js → refresh-cw-D9IUmT23.js} +0 -0
  301. /package/bundle/web-dist/client/assets/{request-model-CojtinqK.js → request-model-Bpp_rkK8.js} +0 -0
  302. /package/bundle/web-dist/server/assets/{cost-eEHeTRT5.js → cost-BC9yzyA9.js} +0 -0
@@ -1,3044 +0,0 @@
1
- import { assertTypes, createDefer, createSimpleStackTrace } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js";
2
- import { processError } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js";
3
- import { delay, getSafeTimers } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js";
4
- import { parseSingleStack } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js";
5
- import { n as normalize } from "../../../../../pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js";
6
- import "../../../../../pathe@2.0.3/node_modules/pathe/dist/index.js";
7
- import { G as getNames, J as getTestName, K as getTests, Q as matchesTags, g as createTaskCollector, i as getCurrentSuite, j as getCurrentTest, k as getFn, l as getHooks, w as updateTask, y as createChainable } from "../../../../../@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js";
8
- import "../../../../../@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js";
9
- import "../../../../../@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js";
10
- import { g as getWorkerState, i as isChildProcess, r as resetModules, w as waitForImportsToResolve } from "./utils.BX5Fg8C4.js";
11
- import { a as getBenchOptions, g as getBenchFn } from "./benchmark.CX_oY03V.js";
12
- import { clearAllMocks, fn, isMockFunction, resetAllMocks, restoreAllMocks, spyOn } from "../../../../../@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js";
13
- import { Assertion, assert as assert$1, expect, should as should$1, use, util as utils_exports } from "../../../../../chai@6.2.2/node_modules/chai/index.js";
14
- import { ASYMMETRIC_MATCHERS_OBJECT, ChaiStyleAssertions, GLOBAL_EXPECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, addCustomEqualityTesters, createAssertionMessage, customMatchers, equals, getState, iterableEquality, recordAsyncExpect, setState, subsetEquality, wrapAssertion } from "../../../../../@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js";
15
- import "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js";
16
- import { c as commonjsGlobal } from "./_commonjsHelpers.D26ty3Ew.js";
17
- import { R as RealDate, b as resetDate, m as mockDate, r as rpc } from "./rpc.MzXet3jl.js";
18
- import { SnapshotClient, addSerializer, stripSnapshotIndentation } from "../../../../../@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js";
19
- //#region ../../node_modules/.pnpm/vitest@4.1.10_@opentelemetry+api@1.9.0_@types+node@25.0.7_@vitest+coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js
20
- var fakeTimersSrc = {};
21
- var global;
22
- var hasRequiredGlobal;
23
- function requireGlobal() {
24
- if (hasRequiredGlobal) return global;
25
- hasRequiredGlobal = 1;
26
- /**
27
- * A reference to the global object
28
- * @type {object} globalObject
29
- */
30
- var globalObject;
31
- /* istanbul ignore else */
32
- if (typeof commonjsGlobal !== "undefined") globalObject = commonjsGlobal;
33
- else if (typeof window !== "undefined") globalObject = window;
34
- else globalObject = self;
35
- global = globalObject;
36
- return global;
37
- }
38
- var throwsOnProto_1;
39
- var hasRequiredThrowsOnProto;
40
- function requireThrowsOnProto() {
41
- if (hasRequiredThrowsOnProto) return throwsOnProto_1;
42
- hasRequiredThrowsOnProto = 1;
43
- /**
44
- * Is true when the environment causes an error to be thrown for accessing the
45
- * __proto__ property.
46
- * This is necessary in order to support `node --disable-proto=throw`.
47
- *
48
- * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
49
- * @type {boolean}
50
- */
51
- let throwsOnProto;
52
- try {
53
- ({}).__proto__;
54
- throwsOnProto = false;
55
- } catch (_) {
56
- /* istanbul ignore next */
57
- throwsOnProto = true;
58
- }
59
- throwsOnProto_1 = throwsOnProto;
60
- return throwsOnProto_1;
61
- }
62
- var copyPrototypeMethods;
63
- var hasRequiredCopyPrototypeMethods;
64
- function requireCopyPrototypeMethods() {
65
- if (hasRequiredCopyPrototypeMethods) return copyPrototypeMethods;
66
- hasRequiredCopyPrototypeMethods = 1;
67
- var call = Function.call;
68
- var throwsOnProto = requireThrowsOnProto();
69
- var disallowedProperties = [
70
- "size",
71
- "caller",
72
- "callee",
73
- "arguments"
74
- ];
75
- /* istanbul ignore next */
76
- if (throwsOnProto) disallowedProperties.push("__proto__");
77
- copyPrototypeMethods = function copyPrototypeMethods(prototype) {
78
- return Object.getOwnPropertyNames(prototype).reduce(function(result, name) {
79
- if (disallowedProperties.includes(name)) return result;
80
- if (typeof prototype[name] !== "function") return result;
81
- result[name] = call.bind(prototype[name]);
82
- return result;
83
- }, Object.create(null));
84
- };
85
- return copyPrototypeMethods;
86
- }
87
- var array;
88
- var hasRequiredArray;
89
- function requireArray() {
90
- if (hasRequiredArray) return array;
91
- hasRequiredArray = 1;
92
- array = requireCopyPrototypeMethods()(Array.prototype);
93
- return array;
94
- }
95
- var calledInOrder_1;
96
- var hasRequiredCalledInOrder;
97
- function requireCalledInOrder() {
98
- if (hasRequiredCalledInOrder) return calledInOrder_1;
99
- hasRequiredCalledInOrder = 1;
100
- var every = requireArray().every;
101
- /**
102
- * @private
103
- */
104
- function hasCallsLeft(callMap, spy) {
105
- if (callMap[spy.id] === void 0) callMap[spy.id] = 0;
106
- return callMap[spy.id] < spy.callCount;
107
- }
108
- /**
109
- * @private
110
- */
111
- function checkAdjacentCalls(callMap, spy, index, spies) {
112
- var calledBeforeNext = true;
113
- if (index !== spies.length - 1) calledBeforeNext = spy.calledBefore(spies[index + 1]);
114
- if (hasCallsLeft(callMap, spy) && calledBeforeNext) {
115
- callMap[spy.id] += 1;
116
- return true;
117
- }
118
- return false;
119
- }
120
- /**
121
- * A Sinon proxy object (fake, spy, stub)
122
- * @typedef {object} SinonProxy
123
- * @property {Function} calledBefore - A method that determines if this proxy was called before another one
124
- * @property {string} id - Some id
125
- * @property {number} callCount - Number of times this proxy has been called
126
- */
127
- /**
128
- * Returns true when the spies have been called in the order they were supplied in
129
- * @param {SinonProxy[] | SinonProxy} spies An array of proxies, or several proxies as arguments
130
- * @returns {boolean} true when spies are called in order, false otherwise
131
- */
132
- function calledInOrder(spies) {
133
- return every(arguments.length > 1 ? arguments : spies, checkAdjacentCalls.bind(null, {}));
134
- }
135
- calledInOrder_1 = calledInOrder;
136
- return calledInOrder_1;
137
- }
138
- var className_1;
139
- var hasRequiredClassName;
140
- function requireClassName() {
141
- if (hasRequiredClassName) return className_1;
142
- hasRequiredClassName = 1;
143
- /**
144
- * Returns a display name for a value from a constructor
145
- * @param {object} value A value to examine
146
- * @returns {(string|null)} A string or null
147
- */
148
- function className(value) {
149
- return value.constructor && value.constructor.name || null;
150
- }
151
- className_1 = className;
152
- return className_1;
153
- }
154
- var deprecated = {};
155
- var hasRequiredDeprecated;
156
- function requireDeprecated() {
157
- if (hasRequiredDeprecated) return deprecated;
158
- hasRequiredDeprecated = 1;
159
- (function(exports$1) {
160
- /**
161
- * Returns a function that will invoke the supplied function and print a
162
- * deprecation warning to the console each time it is called.
163
- * @param {Function} func
164
- * @param {string} msg
165
- * @returns {Function}
166
- */
167
- exports$1.wrap = function(func, msg) {
168
- var wrapped = function() {
169
- exports$1.printWarning(msg);
170
- return func.apply(this, arguments);
171
- };
172
- if (func.prototype) wrapped.prototype = func.prototype;
173
- return wrapped;
174
- };
175
- /**
176
- * Returns a string which can be supplied to `wrap()` to notify the user that a
177
- * particular part of the sinon API has been deprecated.
178
- * @param {string} packageName
179
- * @param {string} funcName
180
- * @returns {string}
181
- */
182
- exports$1.defaultMsg = function(packageName, funcName) {
183
- return `${packageName}.${funcName} is deprecated and will be removed from the public API in a future version of ${packageName}.`;
184
- };
185
- /**
186
- * Prints a warning on the console, when it exists
187
- * @param {string} msg
188
- * @returns {undefined}
189
- */
190
- exports$1.printWarning = function(msg) {
191
- /* istanbul ignore next */
192
- if (typeof process === "object" && process.emitWarning) process.emitWarning(msg);
193
- else if (console.info) console.info(msg);
194
- else console.log(msg);
195
- };
196
- })(deprecated);
197
- return deprecated;
198
- }
199
- var every;
200
- var hasRequiredEvery;
201
- function requireEvery() {
202
- if (hasRequiredEvery) return every;
203
- hasRequiredEvery = 1;
204
- /**
205
- * Returns true when fn returns true for all members of obj.
206
- * This is an every implementation that works for all iterables
207
- * @param {object} obj
208
- * @param {Function} fn
209
- * @returns {boolean}
210
- */
211
- every = function every(obj, fn) {
212
- var pass = true;
213
- try {
214
- obj.forEach(function() {
215
- if (!fn.apply(this, arguments)) throw new Error();
216
- });
217
- } catch (e) {
218
- pass = false;
219
- }
220
- return pass;
221
- };
222
- return every;
223
- }
224
- var functionName;
225
- var hasRequiredFunctionName;
226
- function requireFunctionName() {
227
- if (hasRequiredFunctionName) return functionName;
228
- hasRequiredFunctionName = 1;
229
- /**
230
- * Returns a display name for a function
231
- * @param {Function} func
232
- * @returns {string}
233
- */
234
- functionName = function functionName(func) {
235
- if (!func) return "";
236
- try {
237
- return func.displayName || func.name || (String(func).match(/function ([^\s(]+)/) || [])[1];
238
- } catch (e) {
239
- return "";
240
- }
241
- };
242
- return functionName;
243
- }
244
- var orderByFirstCall_1;
245
- var hasRequiredOrderByFirstCall;
246
- function requireOrderByFirstCall() {
247
- if (hasRequiredOrderByFirstCall) return orderByFirstCall_1;
248
- hasRequiredOrderByFirstCall = 1;
249
- var sort = requireArray().sort;
250
- var slice = requireArray().slice;
251
- /**
252
- * @private
253
- */
254
- function comparator(a, b) {
255
- var aCall = a.getCall(0);
256
- var bCall = b.getCall(0);
257
- return (aCall && aCall.callId || -1) < (bCall && bCall.callId || -1) ? -1 : 1;
258
- }
259
- /**
260
- * A Sinon proxy object (fake, spy, stub)
261
- * @typedef {object} SinonProxy
262
- * @property {Function} getCall - A method that can return the first call
263
- */
264
- /**
265
- * Sorts an array of SinonProxy instances (fake, spy, stub) by their first call
266
- * @param {SinonProxy[] | SinonProxy} spies
267
- * @returns {SinonProxy[]}
268
- */
269
- function orderByFirstCall(spies) {
270
- return sort(slice(spies), comparator);
271
- }
272
- orderByFirstCall_1 = orderByFirstCall;
273
- return orderByFirstCall_1;
274
- }
275
- var _function;
276
- var hasRequired_function;
277
- function require_function() {
278
- if (hasRequired_function) return _function;
279
- hasRequired_function = 1;
280
- _function = requireCopyPrototypeMethods()(Function.prototype);
281
- return _function;
282
- }
283
- var map;
284
- var hasRequiredMap;
285
- function requireMap() {
286
- if (hasRequiredMap) return map;
287
- hasRequiredMap = 1;
288
- map = requireCopyPrototypeMethods()(Map.prototype);
289
- return map;
290
- }
291
- var object;
292
- var hasRequiredObject;
293
- function requireObject() {
294
- if (hasRequiredObject) return object;
295
- hasRequiredObject = 1;
296
- object = requireCopyPrototypeMethods()(Object.prototype);
297
- return object;
298
- }
299
- var set;
300
- var hasRequiredSet;
301
- function requireSet() {
302
- if (hasRequiredSet) return set;
303
- hasRequiredSet = 1;
304
- set = requireCopyPrototypeMethods()(Set.prototype);
305
- return set;
306
- }
307
- var string;
308
- var hasRequiredString;
309
- function requireString() {
310
- if (hasRequiredString) return string;
311
- hasRequiredString = 1;
312
- string = requireCopyPrototypeMethods()(String.prototype);
313
- return string;
314
- }
315
- var prototypes;
316
- var hasRequiredPrototypes;
317
- function requirePrototypes() {
318
- if (hasRequiredPrototypes) return prototypes;
319
- hasRequiredPrototypes = 1;
320
- prototypes = {
321
- array: requireArray(),
322
- function: require_function(),
323
- map: requireMap(),
324
- object: requireObject(),
325
- set: requireSet(),
326
- string: requireString()
327
- };
328
- return prototypes;
329
- }
330
- var typeDetect$1 = { exports: {} };
331
- var typeDetect = typeDetect$1.exports;
332
- var hasRequiredTypeDetect;
333
- function requireTypeDetect() {
334
- if (hasRequiredTypeDetect) return typeDetect$1.exports;
335
- hasRequiredTypeDetect = 1;
336
- (function(module, exports$1) {
337
- (function(global, factory) {
338
- module.exports = factory();
339
- })(typeDetect, (function() {
340
- var promiseExists = typeof Promise === "function";
341
- var globalObject = typeof self === "object" ? self : commonjsGlobal;
342
- var symbolExists = typeof Symbol !== "undefined";
343
- var mapExists = typeof Map !== "undefined";
344
- var setExists = typeof Set !== "undefined";
345
- var weakMapExists = typeof WeakMap !== "undefined";
346
- var weakSetExists = typeof WeakSet !== "undefined";
347
- var dataViewExists = typeof DataView !== "undefined";
348
- var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== "undefined";
349
- var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== "undefined";
350
- var setEntriesExists = setExists && typeof Set.prototype.entries === "function";
351
- var mapEntriesExists = mapExists && typeof Map.prototype.entries === "function";
352
- var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Set()).entries());
353
- var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Map()).entries());
354
- var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === "function";
355
- var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
356
- var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === "function";
357
- var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(""[Symbol.iterator]());
358
- var toStringLeftSliceLength = 8;
359
- var toStringRightSliceLength = -1;
360
- /**
361
- * ### typeOf (obj)
362
- *
363
- * Uses `Object.prototype.toString` to determine the type of an object,
364
- * normalising behaviour across engine versions & well optimised.
365
- *
366
- * @param {Mixed} object
367
- * @return {String} object type
368
- * @api public
369
- */
370
- function typeDetect(obj) {
371
- var typeofObj = typeof obj;
372
- if (typeofObj !== "object") return typeofObj;
373
- if (obj === null) return "null";
374
- if (obj === globalObject) return "global";
375
- if (Array.isArray(obj) && (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))) return "Array";
376
- if (typeof window === "object" && window !== null) {
377
- if (typeof window.location === "object" && obj === window.location) return "Location";
378
- if (typeof window.document === "object" && obj === window.document) return "Document";
379
- if (typeof window.navigator === "object") {
380
- if (typeof window.navigator.mimeTypes === "object" && obj === window.navigator.mimeTypes) return "MimeTypeArray";
381
- if (typeof window.navigator.plugins === "object" && obj === window.navigator.plugins) return "PluginArray";
382
- }
383
- if ((typeof window.HTMLElement === "function" || typeof window.HTMLElement === "object") && obj instanceof window.HTMLElement) {
384
- if (obj.tagName === "BLOCKQUOTE") return "HTMLQuoteElement";
385
- if (obj.tagName === "TD") return "HTMLTableDataCellElement";
386
- if (obj.tagName === "TH") return "HTMLTableHeaderCellElement";
387
- }
388
- }
389
- var stringTag = symbolToStringTagExists && obj[Symbol.toStringTag];
390
- if (typeof stringTag === "string") return stringTag;
391
- var objPrototype = Object.getPrototypeOf(obj);
392
- if (objPrototype === RegExp.prototype) return "RegExp";
393
- if (objPrototype === Date.prototype) return "Date";
394
- if (promiseExists && objPrototype === Promise.prototype) return "Promise";
395
- if (setExists && objPrototype === Set.prototype) return "Set";
396
- if (mapExists && objPrototype === Map.prototype) return "Map";
397
- if (weakSetExists && objPrototype === WeakSet.prototype) return "WeakSet";
398
- if (weakMapExists && objPrototype === WeakMap.prototype) return "WeakMap";
399
- if (dataViewExists && objPrototype === DataView.prototype) return "DataView";
400
- if (mapExists && objPrototype === mapIteratorPrototype) return "Map Iterator";
401
- if (setExists && objPrototype === setIteratorPrototype) return "Set Iterator";
402
- if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) return "Array Iterator";
403
- if (stringIteratorExists && objPrototype === stringIteratorPrototype) return "String Iterator";
404
- if (objPrototype === null) return "Object";
405
- return Object.prototype.toString.call(obj).slice(toStringLeftSliceLength, toStringRightSliceLength);
406
- }
407
- return typeDetect;
408
- }));
409
- })(typeDetect$1);
410
- return typeDetect$1.exports;
411
- }
412
- var typeOf;
413
- var hasRequiredTypeOf;
414
- function requireTypeOf() {
415
- if (hasRequiredTypeOf) return typeOf;
416
- hasRequiredTypeOf = 1;
417
- var type = requireTypeDetect();
418
- /**
419
- * Returns the lower-case result of running type from type-detect on the value
420
- * @param {*} value
421
- * @returns {string}
422
- */
423
- typeOf = function typeOf(value) {
424
- return type(value).toLowerCase();
425
- };
426
- return typeOf;
427
- }
428
- var valueToString_1;
429
- var hasRequiredValueToString;
430
- function requireValueToString() {
431
- if (hasRequiredValueToString) return valueToString_1;
432
- hasRequiredValueToString = 1;
433
- /**
434
- * Returns a string representation of the value
435
- * @param {*} value
436
- * @returns {string}
437
- */
438
- function valueToString(value) {
439
- if (value && value.toString) return value.toString();
440
- return String(value);
441
- }
442
- valueToString_1 = valueToString;
443
- return valueToString_1;
444
- }
445
- var lib;
446
- var hasRequiredLib;
447
- function requireLib() {
448
- if (hasRequiredLib) return lib;
449
- hasRequiredLib = 1;
450
- lib = {
451
- global: requireGlobal(),
452
- calledInOrder: requireCalledInOrder(),
453
- className: requireClassName(),
454
- deprecated: requireDeprecated(),
455
- every: requireEvery(),
456
- functionName: requireFunctionName(),
457
- orderByFirstCall: requireOrderByFirstCall(),
458
- prototypes: requirePrototypes(),
459
- typeOf: requireTypeOf(),
460
- valueToString: requireValueToString()
461
- };
462
- return lib;
463
- }
464
- var hasRequiredFakeTimersSrc;
465
- function requireFakeTimersSrc() {
466
- if (hasRequiredFakeTimersSrc) return fakeTimersSrc;
467
- hasRequiredFakeTimersSrc = 1;
468
- const globalObject = requireLib().global;
469
- let timersModule, timersPromisesModule;
470
- if (typeof __vitest_required__ !== "undefined") {
471
- try {
472
- timersModule = __vitest_required__.timers;
473
- } catch (e) {}
474
- try {
475
- timersPromisesModule = __vitest_required__.timersPromises;
476
- } catch (e) {}
477
- }
478
- /**
479
- * @typedef {"nextAsync" | "manual" | "interval"} TickMode
480
- */
481
- /**
482
- * @typedef {object} NextAsyncTickMode
483
- * @property {"nextAsync"} mode
484
- */
485
- /**
486
- * @typedef {object} ManualTickMode
487
- * @property {"manual"} mode
488
- */
489
- /**
490
- * @typedef {object} IntervalTickMode
491
- * @property {"interval"} mode
492
- * @property {number} [delta]
493
- */
494
- /**
495
- * @typedef {IntervalTickMode | NextAsyncTickMode | ManualTickMode} TimerTickMode
496
- */
497
- /**
498
- * @typedef {object} IdleDeadline
499
- * @property {boolean} didTimeout - whether or not the callback was called before reaching the optional timeout
500
- * @property {function():number} timeRemaining - a floating-point value providing an estimate of the number of milliseconds remaining in the current idle period
501
- */
502
- /**
503
- * Queues a function to be called during a browser's idle periods
504
- * @callback RequestIdleCallback
505
- * @param {function(IdleDeadline)} callback
506
- * @param {{timeout: number}} options - an options object
507
- * @returns {number} the id
508
- */
509
- /**
510
- * @callback NextTick
511
- * @param {VoidVarArgsFunc} callback - the callback to run
512
- * @param {...*} args - optional arguments to call the callback with
513
- * @returns {void}
514
- */
515
- /**
516
- * @callback SetImmediate
517
- * @param {VoidVarArgsFunc} callback - the callback to run
518
- * @param {...*} args - optional arguments to call the callback with
519
- * @returns {NodeImmediate}
520
- */
521
- /**
522
- * @callback VoidVarArgsFunc
523
- * @param {...*} callback - the callback to run
524
- * @returns {void}
525
- */
526
- /**
527
- * @typedef RequestAnimationFrame
528
- * @property {function(number):void} requestAnimationFrame
529
- * @returns {number} - the id
530
- */
531
- /**
532
- * @typedef Performance
533
- * @property {function(): number} now
534
- */
535
- /**
536
- * @typedef {object} Clock
537
- * @property {number} now - the current time
538
- * @property {Date} Date - the Date constructor
539
- * @property {number} loopLimit - the maximum number of timers before assuming an infinite loop
540
- * @property {RequestIdleCallback} requestIdleCallback
541
- * @property {function(number):void} cancelIdleCallback
542
- * @property {setTimeout} setTimeout
543
- * @property {clearTimeout} clearTimeout
544
- * @property {NextTick} nextTick
545
- * @property {queueMicrotask} queueMicrotask
546
- * @property {setInterval} setInterval
547
- * @property {clearInterval} clearInterval
548
- * @property {SetImmediate} setImmediate
549
- * @property {function(NodeImmediate):void} clearImmediate
550
- * @property {function():number} countTimers
551
- * @property {RequestAnimationFrame} requestAnimationFrame
552
- * @property {function(number):void} cancelAnimationFrame
553
- * @property {function():void} runMicrotasks
554
- * @property {function(string | number): number} tick
555
- * @property {function(string | number): Promise<number>} tickAsync
556
- * @property {function(): number} next
557
- * @property {function(): Promise<number>} nextAsync
558
- * @property {function(): number} runAll
559
- * @property {function(): number} runToFrame
560
- * @property {function(): Promise<number>} runAllAsync
561
- * @property {function(): number} runToLast
562
- * @property {function(): Promise<number>} runToLastAsync
563
- * @property {function(): void} reset
564
- * @property {function(number | Date): void} setSystemTime
565
- * @property {function(number): void} jump
566
- * @property {Performance} performance
567
- * @property {function(number[]): number[]} hrtime - process.hrtime (legacy)
568
- * @property {function(): void} uninstall Uninstall the clock.
569
- * @property {Function[]} methods - the methods that are faked
570
- * @property {boolean} [shouldClearNativeTimers] inherited from config
571
- * @property {{methodName:string, original:any}[] | undefined} timersModuleMethods
572
- * @property {{methodName:string, original:any}[] | undefined} timersPromisesModuleMethods
573
- * @property {Map<function(): void, AbortSignal>} abortListenerMap
574
- * @property {function(TimerTickMode): void} setTickMode
575
- */
576
- /**
577
- * Configuration object for the `install` method.
578
- * @typedef {object} Config
579
- * @property {number|Date} [now] a number (in milliseconds) or a Date object (default epoch)
580
- * @property {string[]} [toFake] names of the methods that should be faked.
581
- * @property {number} [loopLimit] the maximum number of timers that will be run when calling runAll()
582
- * @property {boolean} [shouldAdvanceTime] tells FakeTimers to increment mocked time automatically (default false)
583
- * @property {number} [advanceTimeDelta] increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
584
- * @property {boolean} [shouldClearNativeTimers] forwards clear timer calls to native functions if they are not fakes (default: false)
585
- * @property {boolean} [ignoreMissingTimers] default is false, meaning asking to fake timers that are not present will throw an error
586
- */
587
- /**
588
- * The internal structure to describe a scheduled fake timer
589
- * @typedef {object} Timer
590
- * @property {Function} func
591
- * @property {*[]} args
592
- * @property {number} delay
593
- * @property {number} callAt
594
- * @property {number} createdAt
595
- * @property {boolean} immediate
596
- * @property {number} id
597
- * @property {Error} [error]
598
- */
599
- /**
600
- * A Node timer
601
- * @typedef {object} NodeImmediate
602
- * @property {function(): boolean} hasRef
603
- * @property {function(): NodeImmediate} ref
604
- * @property {function(): NodeImmediate} unref
605
- */
606
- /**
607
- * Mocks available features in the specified global namespace.
608
- * @param {*} _global Namespace to mock (e.g. `window`)
609
- * @returns {FakeTimers}
610
- */
611
- function withGlobal(_global) {
612
- const maxTimeout = Math.pow(2, 31) - 1;
613
- const idCounterStart = 0xe8d4a51000;
614
- const NOOP = function() {};
615
- const NOOP_ARRAY = function() {
616
- return [];
617
- };
618
- const isPresent = {};
619
- let timeoutResult, addTimerReturnsObject = false;
620
- if (_global.setTimeout) {
621
- isPresent.setTimeout = true;
622
- timeoutResult = _global.setTimeout(NOOP, 0);
623
- addTimerReturnsObject = typeof timeoutResult === "object";
624
- }
625
- isPresent.clearTimeout = Boolean(_global.clearTimeout);
626
- isPresent.setInterval = Boolean(_global.setInterval);
627
- isPresent.clearInterval = Boolean(_global.clearInterval);
628
- isPresent.hrtime = _global.process && typeof _global.process.hrtime === "function";
629
- isPresent.hrtimeBigint = isPresent.hrtime && typeof _global.process.hrtime.bigint === "function";
630
- isPresent.nextTick = _global.process && typeof _global.process.nextTick === "function";
631
- const utilPromisify = _global.process && _global.__vitest_required__ && _global.__vitest_required__.util.promisify;
632
- isPresent.performance = _global.performance && typeof _global.performance.now === "function";
633
- const hasPerformancePrototype = _global.Performance && (typeof _global.Performance).match(/^(function|object)$/);
634
- const hasPerformanceConstructorPrototype = _global.performance && _global.performance.constructor && _global.performance.constructor.prototype;
635
- isPresent.queueMicrotask = _global.hasOwnProperty("queueMicrotask");
636
- isPresent.requestAnimationFrame = _global.requestAnimationFrame && typeof _global.requestAnimationFrame === "function";
637
- isPresent.cancelAnimationFrame = _global.cancelAnimationFrame && typeof _global.cancelAnimationFrame === "function";
638
- isPresent.requestIdleCallback = _global.requestIdleCallback && typeof _global.requestIdleCallback === "function";
639
- isPresent.cancelIdleCallbackPresent = _global.cancelIdleCallback && typeof _global.cancelIdleCallback === "function";
640
- isPresent.setImmediate = _global.setImmediate && typeof _global.setImmediate === "function";
641
- isPresent.clearImmediate = _global.clearImmediate && typeof _global.clearImmediate === "function";
642
- isPresent.Intl = _global.Intl && typeof _global.Intl === "object";
643
- if (_global.clearTimeout) _global.clearTimeout(timeoutResult);
644
- const NativeDate = _global.Date;
645
- const NativeIntl = isPresent.Intl ? Object.defineProperties(Object.create(null), Object.getOwnPropertyDescriptors(_global.Intl)) : void 0;
646
- let uniqueTimerId = idCounterStart;
647
- if (NativeDate === void 0) throw new Error("The global scope doesn't have a `Date` object (see https://github.com/sinonjs/sinon/issues/1852#issuecomment-419622780)");
648
- isPresent.Date = true;
649
- /**
650
- * The PerformanceEntry object encapsulates a single performance metric
651
- * that is part of the browser's performance timeline.
652
- *
653
- * This is an object returned by the `mark` and `measure` methods on the Performance prototype
654
- */
655
- class FakePerformanceEntry {
656
- constructor(name, entryType, startTime, duration) {
657
- this.name = name;
658
- this.entryType = entryType;
659
- this.startTime = startTime;
660
- this.duration = duration;
661
- }
662
- toJSON() {
663
- return JSON.stringify({ ...this });
664
- }
665
- }
666
- /**
667
- * @param {number} num
668
- * @returns {boolean}
669
- */
670
- function isNumberFinite(num) {
671
- if (Number.isFinite) return Number.isFinite(num);
672
- return isFinite(num);
673
- }
674
- let isNearInfiniteLimit = false;
675
- /**
676
- * @param {Clock} clock
677
- * @param {number} i
678
- */
679
- function checkIsNearInfiniteLimit(clock, i) {
680
- if (clock.loopLimit && i === clock.loopLimit - 1) isNearInfiniteLimit = true;
681
- }
682
- /**
683
- *
684
- */
685
- function resetIsNearInfiniteLimit() {
686
- isNearInfiniteLimit = false;
687
- }
688
- /**
689
- * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
690
- * number of milliseconds. This is used to support human-readable strings passed
691
- * to clock.tick()
692
- * @param {string} str
693
- * @returns {number}
694
- */
695
- function parseTime(str) {
696
- if (!str) return 0;
697
- const strings = str.split(":");
698
- const l = strings.length;
699
- let i = l;
700
- let ms = 0;
701
- let parsed;
702
- if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits");
703
- while (i--) {
704
- parsed = parseInt(strings[i], 10);
705
- if (parsed >= 60) throw new Error(`Invalid time ${str}`);
706
- ms += parsed * Math.pow(60, l - i - 1);
707
- }
708
- return ms * 1e3;
709
- }
710
- /**
711
- * Get the decimal part of the millisecond value as nanoseconds
712
- * @param {number} msFloat the number of milliseconds
713
- * @returns {number} an integer number of nanoseconds in the range [0,1e6)
714
- *
715
- * Example: nanoRemainer(123.456789) -> 456789
716
- */
717
- function nanoRemainder(msFloat) {
718
- const modulo = 1e6;
719
- const remainder = msFloat * 1e6 % modulo;
720
- const positiveRemainder = remainder < 0 ? remainder + modulo : remainder;
721
- return Math.floor(positiveRemainder);
722
- }
723
- /**
724
- * Used to grok the `now` parameter to createClock.
725
- * @param {Date|number} epoch the system time
726
- * @returns {number}
727
- */
728
- function getEpoch(epoch) {
729
- if (!epoch) return 0;
730
- if (typeof epoch.getTime === "function") return epoch.getTime();
731
- if (typeof epoch === "number") return epoch;
732
- throw new TypeError("now should be milliseconds since UNIX epoch");
733
- }
734
- /**
735
- * @param {number} from
736
- * @param {number} to
737
- * @param {Timer} timer
738
- * @returns {boolean}
739
- */
740
- function inRange(from, to, timer) {
741
- return timer && timer.callAt >= from && timer.callAt <= to;
742
- }
743
- /**
744
- * @param {Clock} clock
745
- * @param {Timer} job
746
- */
747
- function getInfiniteLoopError(clock, job) {
748
- const infiniteLoopError = /* @__PURE__ */ new Error(`Aborting after running ${clock.loopLimit} timers, assuming an infinite loop!`);
749
- if (!job.error) return infiniteLoopError;
750
- const computedTargetPattern = /target\.*[<|(|[].*?[>|\]|)]\s*/;
751
- let clockMethodPattern = new RegExp(String(Object.keys(clock).join("|")));
752
- if (addTimerReturnsObject) clockMethodPattern = new RegExp(`\\s+at (Object\\.)?(?:${Object.keys(clock).join("|")})\\s+`);
753
- let matchedLineIndex = -1;
754
- job.error.stack.split("\n").some(function(line, i) {
755
- /* istanbul ignore if */
756
- if (line.match(computedTargetPattern)) {
757
- matchedLineIndex = i;
758
- return true;
759
- }
760
- if (line.match(clockMethodPattern)) {
761
- matchedLineIndex = i;
762
- return false;
763
- }
764
- return matchedLineIndex >= 0;
765
- });
766
- const stack = `${infiniteLoopError}\n${job.type || "Microtask"} - ${job.func.name || "anonymous"}\n${job.error.stack.split("\n").slice(matchedLineIndex + 1).join("\n")}`;
767
- try {
768
- Object.defineProperty(infiniteLoopError, "stack", { value: stack });
769
- } catch (e) {}
770
- return infiniteLoopError;
771
- }
772
- function createDate() {
773
- class ClockDate extends NativeDate {
774
- /**
775
- * @param {number} year
776
- * @param {number} month
777
- * @param {number} date
778
- * @param {number} hour
779
- * @param {number} minute
780
- * @param {number} second
781
- * @param {number} ms
782
- * @returns void
783
- */
784
- constructor(year, month, date, hour, minute, second, ms) {
785
- if (arguments.length === 0) super(ClockDate.clock.now);
786
- else super(...arguments);
787
- Object.defineProperty(this, "constructor", {
788
- value: NativeDate,
789
- enumerable: false
790
- });
791
- }
792
- static [Symbol.hasInstance](instance) {
793
- return instance instanceof NativeDate;
794
- }
795
- }
796
- ClockDate.isFake = true;
797
- if (NativeDate.now) ClockDate.now = function now() {
798
- return ClockDate.clock.now;
799
- };
800
- if (NativeDate.toSource) ClockDate.toSource = function toSource() {
801
- return NativeDate.toSource();
802
- };
803
- ClockDate.toString = function toString() {
804
- return NativeDate.toString();
805
- };
806
- return new Proxy(ClockDate, { apply() {
807
- if (this instanceof ClockDate) throw new TypeError("A Proxy should only capture `new` calls with the `construct` handler. This is not supposed to be possible, so check the logic.");
808
- return new NativeDate(ClockDate.clock.now).toString();
809
- } });
810
- }
811
- /**
812
- * Mirror Intl by default on our fake implementation
813
- *
814
- * Most of the properties are the original native ones,
815
- * but we need to take control of those that have a
816
- * dependency on the current clock.
817
- * @returns {object} the partly fake Intl implementation
818
- */
819
- function createIntl() {
820
- const ClockIntl = {};
821
- Object.getOwnPropertyNames(NativeIntl).forEach((property) => ClockIntl[property] = NativeIntl[property]);
822
- ClockIntl.DateTimeFormat = function(...args) {
823
- const realFormatter = new NativeIntl.DateTimeFormat(...args);
824
- const formatter = {};
825
- [
826
- "formatRange",
827
- "formatRangeToParts",
828
- "resolvedOptions"
829
- ].forEach((method) => {
830
- formatter[method] = realFormatter[method].bind(realFormatter);
831
- });
832
- ["format", "formatToParts"].forEach((method) => {
833
- formatter[method] = function(date) {
834
- return realFormatter[method](date || ClockIntl.clock.now);
835
- };
836
- });
837
- return formatter;
838
- };
839
- ClockIntl.DateTimeFormat.prototype = Object.create(NativeIntl.DateTimeFormat.prototype);
840
- ClockIntl.DateTimeFormat.supportedLocalesOf = NativeIntl.DateTimeFormat.supportedLocalesOf;
841
- return ClockIntl;
842
- }
843
- function enqueueJob(clock, job) {
844
- if (!clock.jobs) clock.jobs = [];
845
- clock.jobs.push(job);
846
- }
847
- function runJobs(clock) {
848
- if (!clock.jobs) return;
849
- for (let i = 0; i < clock.jobs.length; i++) {
850
- const job = clock.jobs[i];
851
- job.func.apply(null, job.args);
852
- checkIsNearInfiniteLimit(clock, i);
853
- if (clock.loopLimit && i > clock.loopLimit) throw getInfiniteLoopError(clock, job);
854
- }
855
- resetIsNearInfiniteLimit();
856
- clock.jobs = [];
857
- }
858
- /**
859
- * @param {Clock} clock
860
- * @param {Timer} timer
861
- * @returns {number} id of the created timer
862
- */
863
- function addTimer(clock, timer) {
864
- if (timer.func === void 0) throw new Error("Callback must be provided to timer calls");
865
- if (addTimerReturnsObject) {
866
- if (typeof timer.func !== "function") throw new TypeError(`[ERR_INVALID_CALLBACK]: Callback must be a function. Received ${timer.func} of type ${typeof timer.func}`);
867
- }
868
- if (isNearInfiniteLimit) timer.error = /* @__PURE__ */ new Error();
869
- timer.type = timer.immediate ? "Immediate" : "Timeout";
870
- if (timer.hasOwnProperty("delay")) {
871
- if (typeof timer.delay !== "number") timer.delay = parseInt(timer.delay, 10);
872
- if (!isNumberFinite(timer.delay)) timer.delay = 0;
873
- timer.delay = timer.delay > maxTimeout ? 1 : timer.delay;
874
- timer.delay = Math.max(0, timer.delay);
875
- }
876
- if (timer.hasOwnProperty("interval")) {
877
- timer.type = "Interval";
878
- timer.interval = timer.interval > maxTimeout ? 1 : timer.interval;
879
- }
880
- if (timer.hasOwnProperty("animation")) {
881
- timer.type = "AnimationFrame";
882
- timer.animation = true;
883
- }
884
- if (timer.hasOwnProperty("idleCallback")) {
885
- timer.type = "IdleCallback";
886
- timer.idleCallback = true;
887
- }
888
- if (!clock.timers) clock.timers = {};
889
- timer.id = uniqueTimerId++;
890
- timer.createdAt = clock.now;
891
- timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
892
- clock.timers[timer.id] = timer;
893
- if (addTimerReturnsObject) {
894
- const res = {
895
- refed: true,
896
- ref: function() {
897
- this.refed = true;
898
- return res;
899
- },
900
- unref: function() {
901
- this.refed = false;
902
- return res;
903
- },
904
- hasRef: function() {
905
- return this.refed;
906
- },
907
- refresh: function() {
908
- timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
909
- clock.timers[timer.id] = timer;
910
- return res;
911
- },
912
- [Symbol.toPrimitive]: function() {
913
- return timer.id;
914
- }
915
- };
916
- return res;
917
- }
918
- return timer.id;
919
- }
920
- /**
921
- * Timer comparitor
922
- * @param {Timer} a
923
- * @param {Timer} b
924
- * @returns {number}
925
- */
926
- function compareTimers(a, b) {
927
- if (a.callAt < b.callAt) return -1;
928
- if (a.callAt > b.callAt) return 1;
929
- if (a.immediate && !b.immediate) return -1;
930
- if (!a.immediate && b.immediate) return 1;
931
- if (a.createdAt < b.createdAt) return -1;
932
- if (a.createdAt > b.createdAt) return 1;
933
- if (a.id < b.id) return -1;
934
- if (a.id > b.id) return 1;
935
- }
936
- /**
937
- * @param {Clock} clock
938
- * @param {number} from
939
- * @param {number} to
940
- * @returns {Timer}
941
- */
942
- function firstTimerInRange(clock, from, to) {
943
- const timers = clock.timers;
944
- let timer = null;
945
- let id, isInRange;
946
- for (id in timers) if (timers.hasOwnProperty(id)) {
947
- isInRange = inRange(from, to, timers[id]);
948
- if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) timer = timers[id];
949
- }
950
- return timer;
951
- }
952
- /**
953
- * @param {Clock} clock
954
- * @returns {Timer}
955
- */
956
- function firstTimer(clock) {
957
- const timers = clock.timers;
958
- let timer = null;
959
- let id;
960
- for (id in timers) if (timers.hasOwnProperty(id)) {
961
- if (!timer || compareTimers(timer, timers[id]) === 1) timer = timers[id];
962
- }
963
- return timer;
964
- }
965
- /**
966
- * @param {Clock} clock
967
- * @returns {Timer}
968
- */
969
- function lastTimer(clock) {
970
- const timers = clock.timers;
971
- let timer = null;
972
- let id;
973
- for (id in timers) if (timers.hasOwnProperty(id)) {
974
- if (!timer || compareTimers(timer, timers[id]) === -1) timer = timers[id];
975
- }
976
- return timer;
977
- }
978
- /**
979
- * @param {Clock} clock
980
- * @param {Timer} timer
981
- */
982
- function callTimer(clock, timer) {
983
- if (typeof timer.interval === "number") clock.timers[timer.id].callAt += timer.interval;
984
- else delete clock.timers[timer.id];
985
- if (typeof timer.func === "function") timer.func.apply(null, timer.args);
986
- else {
987
- const eval2 = eval;
988
- (function() {
989
- eval2(timer.func);
990
- })();
991
- }
992
- }
993
- /**
994
- * Gets clear handler name for a given timer type
995
- * @param {string} ttype
996
- */
997
- function getClearHandler(ttype) {
998
- if (ttype === "IdleCallback" || ttype === "AnimationFrame") return `cancel${ttype}`;
999
- return `clear${ttype}`;
1000
- }
1001
- /**
1002
- * Gets schedule handler name for a given timer type
1003
- * @param {string} ttype
1004
- */
1005
- function getScheduleHandler(ttype) {
1006
- if (ttype === "IdleCallback" || ttype === "AnimationFrame") return `request${ttype}`;
1007
- return `set${ttype}`;
1008
- }
1009
- /**
1010
- * Creates an anonymous function to warn only once
1011
- */
1012
- function createWarnOnce() {
1013
- let calls = 0;
1014
- return function(msg) {
1015
- !calls++ && console.warn(msg);
1016
- };
1017
- }
1018
- const warnOnce = createWarnOnce();
1019
- /**
1020
- * @param {Clock} clock
1021
- * @param {number} timerId
1022
- * @param {string} ttype
1023
- */
1024
- function clearTimer(clock, timerId, ttype) {
1025
- if (!timerId) return;
1026
- if (!clock.timers) clock.timers = {};
1027
- const id = Number(timerId);
1028
- if (Number.isNaN(id) || id < idCounterStart) {
1029
- const handlerName = getClearHandler(ttype);
1030
- if (clock.shouldClearNativeTimers === true) {
1031
- const nativeHandler = clock[`_${handlerName}`];
1032
- return typeof nativeHandler === "function" ? nativeHandler(timerId) : void 0;
1033
- }
1034
- warnOnce(`FakeTimers: ${handlerName} was invoked to clear a native timer instead of one created by this library.
1035
- To automatically clean-up native timers, use \`shouldClearNativeTimers\`.`);
1036
- }
1037
- if (clock.timers.hasOwnProperty(id)) {
1038
- const timer = clock.timers[id];
1039
- if (timer.type === ttype || timer.type === "Timeout" && ttype === "Interval" || timer.type === "Interval" && ttype === "Timeout") delete clock.timers[id];
1040
- else {
1041
- const clear = getClearHandler(ttype);
1042
- const schedule = getScheduleHandler(timer.type);
1043
- throw new Error(`Cannot clear timer: timer created with ${schedule}() but cleared with ${clear}()`);
1044
- }
1045
- }
1046
- }
1047
- /**
1048
- * @param {Clock} clock
1049
- * @returns {Timer[]}
1050
- */
1051
- function uninstall(clock) {
1052
- let method, i, l;
1053
- const installedHrTime = "_hrtime";
1054
- const installedNextTick = "_nextTick";
1055
- for (i = 0, l = clock.methods.length; i < l; i++) {
1056
- method = clock.methods[i];
1057
- if (method === "hrtime" && _global.process) _global.process.hrtime = clock[installedHrTime];
1058
- else if (method === "nextTick" && _global.process) _global.process.nextTick = clock[installedNextTick];
1059
- else if (method === "performance") {
1060
- const originalPerfDescriptor = Object.getOwnPropertyDescriptor(clock, `_${method}`);
1061
- if (originalPerfDescriptor && originalPerfDescriptor.get && !originalPerfDescriptor.set) Object.defineProperty(_global, method, originalPerfDescriptor);
1062
- else if (originalPerfDescriptor.configurable) _global[method] = clock[`_${method}`];
1063
- } else if (_global[method] && _global[method].hadOwnProperty) _global[method] = clock[`_${method}`];
1064
- else try {
1065
- delete _global[method];
1066
- } catch (ignore) {}
1067
- if (clock.timersModuleMethods !== void 0) for (let j = 0; j < clock.timersModuleMethods.length; j++) {
1068
- const entry = clock.timersModuleMethods[j];
1069
- timersModule[entry.methodName] = entry.original;
1070
- }
1071
- if (clock.timersPromisesModuleMethods !== void 0) for (let j = 0; j < clock.timersPromisesModuleMethods.length; j++) {
1072
- const entry = clock.timersPromisesModuleMethods[j];
1073
- timersPromisesModule[entry.methodName] = entry.original;
1074
- }
1075
- }
1076
- clock.setTickMode("manual");
1077
- clock.methods = [];
1078
- for (const [listener, signal] of clock.abortListenerMap.entries()) {
1079
- signal.removeEventListener("abort", listener);
1080
- clock.abortListenerMap.delete(listener);
1081
- }
1082
- if (!clock.timers) return [];
1083
- return Object.keys(clock.timers).map(function mapper(key) {
1084
- return clock.timers[key];
1085
- });
1086
- }
1087
- /**
1088
- * @param {object} target the target containing the method to replace
1089
- * @param {string} method the keyname of the method on the target
1090
- * @param {Clock} clock
1091
- */
1092
- function hijackMethod(target, method, clock) {
1093
- clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
1094
- clock[`_${method}`] = target[method];
1095
- if (method === "Date") target[method] = clock[method];
1096
- else if (method === "Intl") target[method] = clock[method];
1097
- else if (method === "performance") {
1098
- const originalPerfDescriptor = Object.getOwnPropertyDescriptor(target, method);
1099
- if (originalPerfDescriptor && originalPerfDescriptor.get && !originalPerfDescriptor.set) {
1100
- Object.defineProperty(clock, `_${method}`, originalPerfDescriptor);
1101
- const perfDescriptor = Object.getOwnPropertyDescriptor(clock, method);
1102
- Object.defineProperty(target, method, perfDescriptor);
1103
- } else target[method] = clock[method];
1104
- } else {
1105
- target[method] = function() {
1106
- return clock[method].apply(clock, arguments);
1107
- };
1108
- Object.defineProperties(target[method], Object.getOwnPropertyDescriptors(clock[method]));
1109
- }
1110
- target[method].clock = clock;
1111
- }
1112
- /**
1113
- * @param {Clock} clock
1114
- * @param {number} advanceTimeDelta
1115
- */
1116
- function doIntervalTick(clock, advanceTimeDelta) {
1117
- clock.tick(advanceTimeDelta);
1118
- }
1119
- /**
1120
- * @typedef {object} Timers
1121
- * @property {setTimeout} setTimeout
1122
- * @property {clearTimeout} clearTimeout
1123
- * @property {setInterval} setInterval
1124
- * @property {clearInterval} clearInterval
1125
- * @property {Date} Date
1126
- * @property {Intl} Intl
1127
- * @property {SetImmediate=} setImmediate
1128
- * @property {function(NodeImmediate): void=} clearImmediate
1129
- * @property {function(number[]):number[]=} hrtime
1130
- * @property {NextTick=} nextTick
1131
- * @property {Performance=} performance
1132
- * @property {RequestAnimationFrame=} requestAnimationFrame
1133
- * @property {boolean=} queueMicrotask
1134
- * @property {function(number): void=} cancelAnimationFrame
1135
- * @property {RequestIdleCallback=} requestIdleCallback
1136
- * @property {function(number): void=} cancelIdleCallback
1137
- */
1138
- /** @type {Timers} */
1139
- const timers = {
1140
- setTimeout: _global.setTimeout,
1141
- clearTimeout: _global.clearTimeout,
1142
- setInterval: _global.setInterval,
1143
- clearInterval: _global.clearInterval,
1144
- Date: _global.Date
1145
- };
1146
- if (isPresent.setImmediate) timers.setImmediate = _global.setImmediate;
1147
- if (isPresent.clearImmediate) timers.clearImmediate = _global.clearImmediate;
1148
- if (isPresent.hrtime) timers.hrtime = _global.process.hrtime;
1149
- if (isPresent.nextTick) timers.nextTick = _global.process.nextTick;
1150
- if (isPresent.performance) timers.performance = _global.performance;
1151
- if (isPresent.requestAnimationFrame) timers.requestAnimationFrame = _global.requestAnimationFrame;
1152
- if (isPresent.queueMicrotask) timers.queueMicrotask = _global.queueMicrotask;
1153
- if (isPresent.cancelAnimationFrame) timers.cancelAnimationFrame = _global.cancelAnimationFrame;
1154
- if (isPresent.requestIdleCallback) timers.requestIdleCallback = _global.requestIdleCallback;
1155
- if (isPresent.cancelIdleCallback) timers.cancelIdleCallback = _global.cancelIdleCallback;
1156
- if (isPresent.Intl) timers.Intl = NativeIntl;
1157
- const originalSetTimeout = _global.setImmediate || _global.setTimeout;
1158
- const originalClearInterval = _global.clearInterval;
1159
- const originalSetInterval = _global.setInterval;
1160
- /**
1161
- * @param {Date|number} [start] the system time - non-integer values are floored
1162
- * @param {number} [loopLimit] maximum number of timers that will be run when calling runAll()
1163
- * @returns {Clock}
1164
- */
1165
- function createClock(start, loopLimit) {
1166
- start = Math.floor(getEpoch(start));
1167
- loopLimit = loopLimit || 1e3;
1168
- let nanos = 0;
1169
- const adjustedSystemTime = [0, 0];
1170
- const clock = {
1171
- now: start,
1172
- Date: createDate(),
1173
- loopLimit,
1174
- tickMode: {
1175
- mode: "manual",
1176
- counter: 0,
1177
- delta: void 0
1178
- }
1179
- };
1180
- clock.Date.clock = clock;
1181
- function getTimeToNextFrame() {
1182
- return 16 - (clock.now - start) % 16;
1183
- }
1184
- function hrtime(prev) {
1185
- const millisSinceStart = clock.now - adjustedSystemTime[0] - start;
1186
- const secsSinceStart = Math.floor(millisSinceStart / 1e3);
1187
- const remainderInNanos = (millisSinceStart - secsSinceStart * 1e3) * 1e6 + nanos - adjustedSystemTime[1];
1188
- if (Array.isArray(prev)) {
1189
- if (prev[1] > 1e9) throw new TypeError("Number of nanoseconds can't exceed a billion");
1190
- const oldSecs = prev[0];
1191
- let nanoDiff = remainderInNanos - prev[1];
1192
- let secDiff = secsSinceStart - oldSecs;
1193
- if (nanoDiff < 0) {
1194
- nanoDiff += 1e9;
1195
- secDiff -= 1;
1196
- }
1197
- return [secDiff, nanoDiff];
1198
- }
1199
- return [secsSinceStart, remainderInNanos];
1200
- }
1201
- /**
1202
- * A high resolution timestamp in milliseconds.
1203
- * @typedef {number} DOMHighResTimeStamp
1204
- */
1205
- /**
1206
- * performance.now()
1207
- * @returns {DOMHighResTimeStamp}
1208
- */
1209
- function fakePerformanceNow() {
1210
- const hrt = hrtime();
1211
- return hrt[0] * 1e3 + hrt[1] / 1e6;
1212
- }
1213
- if (isPresent.hrtimeBigint) hrtime.bigint = function() {
1214
- const parts = hrtime();
1215
- return BigInt(parts[0]) * BigInt(1e9) + BigInt(parts[1]);
1216
- };
1217
- if (isPresent.Intl) {
1218
- clock.Intl = createIntl();
1219
- clock.Intl.clock = clock;
1220
- }
1221
- /**
1222
- * @param {TimerTickMode} tickModeConfig - The new configuration for how the clock should tick.
1223
- */
1224
- clock.setTickMode = function(tickModeConfig) {
1225
- const { mode: newMode, delta: newDelta } = tickModeConfig;
1226
- const { mode: oldMode, delta: oldDelta } = clock.tickMode;
1227
- if (newMode === oldMode && newDelta === oldDelta) return;
1228
- if (oldMode === "interval") originalClearInterval(clock.attachedInterval);
1229
- clock.tickMode = {
1230
- counter: clock.tickMode.counter + 1,
1231
- mode: newMode,
1232
- delta: newDelta
1233
- };
1234
- if (newMode === "nextAsync") advanceUntilModeChanges();
1235
- else if (newMode === "interval") createIntervalTick(clock, newDelta || 20);
1236
- };
1237
- async function advanceUntilModeChanges() {
1238
- async function newMacrotask() {
1239
- const channel = new MessageChannel();
1240
- await new Promise((resolve) => {
1241
- channel.port1.onmessage = () => {
1242
- resolve();
1243
- channel.port1.close();
1244
- };
1245
- channel.port2.postMessage(void 0);
1246
- });
1247
- channel.port1.close();
1248
- channel.port2.close();
1249
- await new Promise((resolve) => {
1250
- originalSetTimeout(resolve);
1251
- });
1252
- }
1253
- const { counter } = clock.tickMode;
1254
- while (clock.tickMode.counter === counter) {
1255
- await newMacrotask();
1256
- if (clock.tickMode.counter !== counter) return;
1257
- clock.next();
1258
- }
1259
- }
1260
- function pauseAutoTickUntilFinished(promise) {
1261
- if (clock.tickMode.mode !== "nextAsync") return promise;
1262
- clock.setTickMode({ mode: "manual" });
1263
- return promise.finally(() => {
1264
- clock.setTickMode({ mode: "nextAsync" });
1265
- });
1266
- }
1267
- clock.requestIdleCallback = function requestIdleCallback(func, timeout) {
1268
- let timeToNextIdlePeriod = 0;
1269
- if (clock.countTimers() > 0) timeToNextIdlePeriod = 50;
1270
- const result = addTimer(clock, {
1271
- func,
1272
- args: Array.prototype.slice.call(arguments, 2),
1273
- delay: typeof timeout === "undefined" ? timeToNextIdlePeriod : Math.min(timeout, timeToNextIdlePeriod),
1274
- idleCallback: true
1275
- });
1276
- return Number(result);
1277
- };
1278
- clock.cancelIdleCallback = function cancelIdleCallback(timerId) {
1279
- return clearTimer(clock, timerId, "IdleCallback");
1280
- };
1281
- clock.setTimeout = function setTimeout(func, timeout) {
1282
- return addTimer(clock, {
1283
- func,
1284
- args: Array.prototype.slice.call(arguments, 2),
1285
- delay: timeout
1286
- });
1287
- };
1288
- if (typeof _global.Promise !== "undefined" && utilPromisify) clock.setTimeout[utilPromisify.custom] = function promisifiedSetTimeout(timeout, arg) {
1289
- return new _global.Promise(function setTimeoutExecutor(resolve) {
1290
- addTimer(clock, {
1291
- func: resolve,
1292
- args: [arg],
1293
- delay: timeout
1294
- });
1295
- });
1296
- };
1297
- clock.clearTimeout = function clearTimeout(timerId) {
1298
- return clearTimer(clock, timerId, "Timeout");
1299
- };
1300
- clock.nextTick = function nextTick(func) {
1301
- return enqueueJob(clock, {
1302
- func,
1303
- args: Array.prototype.slice.call(arguments, 1),
1304
- error: isNearInfiniteLimit ? /* @__PURE__ */ new Error() : null
1305
- });
1306
- };
1307
- clock.queueMicrotask = function queueMicrotask(func) {
1308
- return clock.nextTick(func);
1309
- };
1310
- clock.setInterval = function setInterval(func, timeout) {
1311
- timeout = parseInt(timeout, 10);
1312
- return addTimer(clock, {
1313
- func,
1314
- args: Array.prototype.slice.call(arguments, 2),
1315
- delay: timeout,
1316
- interval: timeout
1317
- });
1318
- };
1319
- clock.clearInterval = function clearInterval(timerId) {
1320
- return clearTimer(clock, timerId, "Interval");
1321
- };
1322
- if (isPresent.setImmediate) {
1323
- clock.setImmediate = function setImmediate(func) {
1324
- return addTimer(clock, {
1325
- func,
1326
- args: Array.prototype.slice.call(arguments, 1),
1327
- immediate: true
1328
- });
1329
- };
1330
- if (typeof _global.Promise !== "undefined" && utilPromisify) clock.setImmediate[utilPromisify.custom] = function promisifiedSetImmediate(arg) {
1331
- return new _global.Promise(function setImmediateExecutor(resolve) {
1332
- addTimer(clock, {
1333
- func: resolve,
1334
- args: [arg],
1335
- immediate: true
1336
- });
1337
- });
1338
- };
1339
- clock.clearImmediate = function clearImmediate(timerId) {
1340
- return clearTimer(clock, timerId, "Immediate");
1341
- };
1342
- }
1343
- clock.countTimers = function countTimers() {
1344
- return Object.keys(clock.timers || {}).length + (clock.jobs || []).length;
1345
- };
1346
- clock.requestAnimationFrame = function requestAnimationFrame(func) {
1347
- const result = addTimer(clock, {
1348
- func,
1349
- delay: getTimeToNextFrame(),
1350
- get args() {
1351
- return [fakePerformanceNow()];
1352
- },
1353
- animation: true
1354
- });
1355
- return Number(result);
1356
- };
1357
- clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) {
1358
- return clearTimer(clock, timerId, "AnimationFrame");
1359
- };
1360
- clock.runMicrotasks = function runMicrotasks() {
1361
- runJobs(clock);
1362
- };
1363
- /**
1364
- * @param {number|string} tickValue milliseconds or a string parseable by parseTime
1365
- * @param {boolean} isAsync
1366
- * @param {Function} resolve
1367
- * @param {Function} reject
1368
- * @returns {number|undefined} will return the new `now` value or nothing for async
1369
- */
1370
- function doTick(tickValue, isAsync, resolve, reject) {
1371
- const msFloat = typeof tickValue === "number" ? tickValue : parseTime(tickValue);
1372
- const ms = Math.floor(msFloat);
1373
- const remainder = nanoRemainder(msFloat);
1374
- let nanosTotal = nanos + remainder;
1375
- let tickTo = clock.now + ms;
1376
- if (msFloat < 0) throw new TypeError("Negative ticks are not supported");
1377
- if (nanosTotal >= 1e6) {
1378
- tickTo += 1;
1379
- nanosTotal -= 1e6;
1380
- }
1381
- nanos = nanosTotal;
1382
- let tickFrom = clock.now;
1383
- let previous = clock.now;
1384
- let timer, firstException, oldNow, nextPromiseTick, compensationCheck, postTimerCall;
1385
- clock.duringTick = true;
1386
- oldNow = clock.now;
1387
- runJobs(clock);
1388
- if (oldNow !== clock.now) {
1389
- tickFrom += clock.now - oldNow;
1390
- tickTo += clock.now - oldNow;
1391
- }
1392
- function doTickInner() {
1393
- timer = firstTimerInRange(clock, tickFrom, tickTo);
1394
- while (timer && tickFrom <= tickTo) {
1395
- if (clock.timers[timer.id]) {
1396
- tickFrom = timer.callAt;
1397
- clock.now = timer.callAt;
1398
- oldNow = clock.now;
1399
- try {
1400
- runJobs(clock);
1401
- callTimer(clock, timer);
1402
- } catch (e) {
1403
- firstException = firstException || e;
1404
- }
1405
- if (isAsync) {
1406
- originalSetTimeout(nextPromiseTick);
1407
- return;
1408
- }
1409
- compensationCheck();
1410
- }
1411
- postTimerCall();
1412
- }
1413
- oldNow = clock.now;
1414
- runJobs(clock);
1415
- if (oldNow !== clock.now) {
1416
- tickFrom += clock.now - oldNow;
1417
- tickTo += clock.now - oldNow;
1418
- }
1419
- clock.duringTick = false;
1420
- timer = firstTimerInRange(clock, tickFrom, tickTo);
1421
- if (timer) try {
1422
- clock.tick(tickTo - clock.now);
1423
- } catch (e) {
1424
- firstException = firstException || e;
1425
- }
1426
- else {
1427
- clock.now = tickTo;
1428
- nanos = nanosTotal;
1429
- }
1430
- if (firstException) throw firstException;
1431
- if (isAsync) resolve(clock.now);
1432
- else return clock.now;
1433
- }
1434
- nextPromiseTick = isAsync && function() {
1435
- try {
1436
- compensationCheck();
1437
- postTimerCall();
1438
- doTickInner();
1439
- } catch (e) {
1440
- reject(e);
1441
- }
1442
- };
1443
- compensationCheck = function() {
1444
- if (oldNow !== clock.now) {
1445
- tickFrom += clock.now - oldNow;
1446
- tickTo += clock.now - oldNow;
1447
- previous += clock.now - oldNow;
1448
- }
1449
- };
1450
- postTimerCall = function() {
1451
- timer = firstTimerInRange(clock, previous, tickTo);
1452
- previous = tickFrom;
1453
- };
1454
- return doTickInner();
1455
- }
1456
- /**
1457
- * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
1458
- * @returns {number} will return the new `now` value
1459
- */
1460
- clock.tick = function tick(tickValue) {
1461
- return doTick(tickValue, false);
1462
- };
1463
- if (typeof _global.Promise !== "undefined")
1464
- /**
1465
- * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
1466
- * @returns {Promise}
1467
- */
1468
- clock.tickAsync = function tickAsync(tickValue) {
1469
- return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
1470
- originalSetTimeout(function() {
1471
- try {
1472
- doTick(tickValue, true, resolve, reject);
1473
- } catch (e) {
1474
- reject(e);
1475
- }
1476
- });
1477
- }));
1478
- };
1479
- clock.next = function next() {
1480
- runJobs(clock);
1481
- const timer = firstTimer(clock);
1482
- if (!timer) return clock.now;
1483
- clock.duringTick = true;
1484
- try {
1485
- clock.now = timer.callAt;
1486
- callTimer(clock, timer);
1487
- runJobs(clock);
1488
- return clock.now;
1489
- } finally {
1490
- clock.duringTick = false;
1491
- }
1492
- };
1493
- if (typeof _global.Promise !== "undefined") clock.nextAsync = function nextAsync() {
1494
- return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
1495
- originalSetTimeout(function() {
1496
- try {
1497
- const timer = firstTimer(clock);
1498
- if (!timer) {
1499
- resolve(clock.now);
1500
- return;
1501
- }
1502
- let err;
1503
- clock.duringTick = true;
1504
- clock.now = timer.callAt;
1505
- try {
1506
- callTimer(clock, timer);
1507
- } catch (e) {
1508
- err = e;
1509
- }
1510
- clock.duringTick = false;
1511
- originalSetTimeout(function() {
1512
- if (err) reject(err);
1513
- else resolve(clock.now);
1514
- });
1515
- } catch (e) {
1516
- reject(e);
1517
- }
1518
- });
1519
- }));
1520
- };
1521
- clock.runAll = function runAll() {
1522
- let numTimers, i;
1523
- runJobs(clock);
1524
- for (i = 0; i < clock.loopLimit; i++) {
1525
- if (!clock.timers) {
1526
- resetIsNearInfiniteLimit();
1527
- return clock.now;
1528
- }
1529
- numTimers = Object.keys(clock.timers).length;
1530
- if (numTimers === 0) {
1531
- resetIsNearInfiniteLimit();
1532
- return clock.now;
1533
- }
1534
- clock.next();
1535
- checkIsNearInfiniteLimit(clock, i);
1536
- }
1537
- const excessJob = firstTimer(clock);
1538
- throw getInfiniteLoopError(clock, excessJob);
1539
- };
1540
- clock.runToFrame = function runToFrame() {
1541
- return clock.tick(getTimeToNextFrame());
1542
- };
1543
- if (typeof _global.Promise !== "undefined") clock.runAllAsync = function runAllAsync() {
1544
- return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
1545
- let i = 0;
1546
- /**
1547
- *
1548
- */
1549
- function doRun() {
1550
- originalSetTimeout(function() {
1551
- try {
1552
- runJobs(clock);
1553
- let numTimers;
1554
- if (i < clock.loopLimit) {
1555
- if (!clock.timers) {
1556
- resetIsNearInfiniteLimit();
1557
- resolve(clock.now);
1558
- return;
1559
- }
1560
- numTimers = Object.keys(clock.timers).length;
1561
- if (numTimers === 0) {
1562
- resetIsNearInfiniteLimit();
1563
- resolve(clock.now);
1564
- return;
1565
- }
1566
- clock.next();
1567
- i++;
1568
- doRun();
1569
- checkIsNearInfiniteLimit(clock, i);
1570
- return;
1571
- }
1572
- const excessJob = firstTimer(clock);
1573
- reject(getInfiniteLoopError(clock, excessJob));
1574
- } catch (e) {
1575
- reject(e);
1576
- }
1577
- });
1578
- }
1579
- doRun();
1580
- }));
1581
- };
1582
- clock.runToLast = function runToLast() {
1583
- const timer = lastTimer(clock);
1584
- if (!timer) {
1585
- runJobs(clock);
1586
- return clock.now;
1587
- }
1588
- return clock.tick(timer.callAt - clock.now);
1589
- };
1590
- if (typeof _global.Promise !== "undefined") clock.runToLastAsync = function runToLastAsync() {
1591
- return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
1592
- originalSetTimeout(function() {
1593
- try {
1594
- const timer = lastTimer(clock);
1595
- if (!timer) {
1596
- runJobs(clock);
1597
- resolve(clock.now);
1598
- }
1599
- resolve(clock.tickAsync(timer.callAt - clock.now));
1600
- } catch (e) {
1601
- reject(e);
1602
- }
1603
- });
1604
- }));
1605
- };
1606
- clock.reset = function reset() {
1607
- nanos = 0;
1608
- clock.timers = {};
1609
- clock.jobs = [];
1610
- clock.now = start;
1611
- };
1612
- clock.setSystemTime = function setSystemTime(systemTime) {
1613
- const newNow = getEpoch(systemTime);
1614
- const difference = newNow - clock.now;
1615
- let id, timer;
1616
- adjustedSystemTime[0] = adjustedSystemTime[0] + difference;
1617
- adjustedSystemTime[1] = adjustedSystemTime[1] + nanos;
1618
- clock.now = newNow;
1619
- nanos = 0;
1620
- for (id in clock.timers) if (clock.timers.hasOwnProperty(id)) {
1621
- timer = clock.timers[id];
1622
- timer.createdAt += difference;
1623
- timer.callAt += difference;
1624
- }
1625
- };
1626
- /**
1627
- * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
1628
- * @returns {number} will return the new `now` value
1629
- */
1630
- clock.jump = function jump(tickValue) {
1631
- const msFloat = typeof tickValue === "number" ? tickValue : parseTime(tickValue);
1632
- const ms = Math.floor(msFloat);
1633
- for (const timer of Object.values(clock.timers)) if (clock.now + ms > timer.callAt) timer.callAt = clock.now + ms;
1634
- clock.tick(ms);
1635
- };
1636
- if (isPresent.performance) {
1637
- clock.performance = Object.create(null);
1638
- clock.performance.now = fakePerformanceNow;
1639
- }
1640
- if (isPresent.hrtime) clock.hrtime = hrtime;
1641
- return clock;
1642
- }
1643
- function createIntervalTick(clock, delta) {
1644
- const intervalTick = doIntervalTick.bind(null, clock, delta);
1645
- clock.attachedInterval = originalSetInterval(intervalTick, delta);
1646
- }
1647
- /**
1648
- * @param {Config=} [config] Optional config
1649
- * @returns {Clock}
1650
- */
1651
- function install(config) {
1652
- if (arguments.length > 1 || config instanceof Date || Array.isArray(config) || typeof config === "number") throw new TypeError(`FakeTimers.install called with ${String(config)} install requires an object parameter`);
1653
- if (_global.Date.isFake === true) throw new TypeError("Can't install fake timers twice on the same global object.");
1654
- config = typeof config !== "undefined" ? config : {};
1655
- config.shouldAdvanceTime = config.shouldAdvanceTime || false;
1656
- config.advanceTimeDelta = config.advanceTimeDelta || 20;
1657
- config.shouldClearNativeTimers = config.shouldClearNativeTimers || false;
1658
- if (config.target) throw new TypeError("config.target is no longer supported. Use `withGlobal(target)` instead.");
1659
- /**
1660
- * @param {string} timer/object the name of the thing that is not present
1661
- * @param timer
1662
- */
1663
- function handleMissingTimer(timer) {
1664
- if (config.ignoreMissingTimers) return;
1665
- throw new ReferenceError(`non-existent timers and/or objects cannot be faked: '${timer}'`);
1666
- }
1667
- let i, l;
1668
- const clock = createClock(config.now, config.loopLimit);
1669
- clock.shouldClearNativeTimers = config.shouldClearNativeTimers;
1670
- clock.uninstall = function() {
1671
- return uninstall(clock);
1672
- };
1673
- clock.abortListenerMap = /* @__PURE__ */ new Map();
1674
- clock.methods = config.toFake || [];
1675
- if (clock.methods.length === 0) clock.methods = Object.keys(timers);
1676
- if (config.shouldAdvanceTime === true) clock.setTickMode({
1677
- mode: "interval",
1678
- delta: config.advanceTimeDelta
1679
- });
1680
- if (clock.methods.includes("performance")) {
1681
- const proto = (() => {
1682
- if (hasPerformanceConstructorPrototype) return _global.performance.constructor.prototype;
1683
- if (hasPerformancePrototype) return _global.Performance.prototype;
1684
- })();
1685
- if (proto) {
1686
- Object.getOwnPropertyNames(proto).forEach(function(name) {
1687
- if (name !== "now") clock.performance[name] = name.indexOf("getEntries") === 0 ? NOOP_ARRAY : NOOP;
1688
- });
1689
- clock.performance.mark = (name) => new FakePerformanceEntry(name, "mark", 0, 0);
1690
- clock.performance.measure = (name) => new FakePerformanceEntry(name, "measure", 0, 100);
1691
- clock.performance.timeOrigin = getEpoch(config.now);
1692
- } else if ((config.toFake || []).includes("performance")) return handleMissingTimer("performance");
1693
- }
1694
- if (_global === globalObject && timersModule) clock.timersModuleMethods = [];
1695
- if (_global === globalObject && timersPromisesModule) clock.timersPromisesModuleMethods = [];
1696
- for (i = 0, l = clock.methods.length; i < l; i++) {
1697
- const nameOfMethodToReplace = clock.methods[i];
1698
- if (!isPresent[nameOfMethodToReplace]) {
1699
- handleMissingTimer(nameOfMethodToReplace);
1700
- continue;
1701
- }
1702
- if (nameOfMethodToReplace === "hrtime") {
1703
- if (_global.process && typeof _global.process.hrtime === "function") hijackMethod(_global.process, nameOfMethodToReplace, clock);
1704
- } else if (nameOfMethodToReplace === "nextTick") {
1705
- if (_global.process && typeof _global.process.nextTick === "function") hijackMethod(_global.process, nameOfMethodToReplace, clock);
1706
- } else hijackMethod(_global, nameOfMethodToReplace, clock);
1707
- if (clock.timersModuleMethods !== void 0 && timersModule[nameOfMethodToReplace]) {
1708
- const original = timersModule[nameOfMethodToReplace];
1709
- clock.timersModuleMethods.push({
1710
- methodName: nameOfMethodToReplace,
1711
- original
1712
- });
1713
- timersModule[nameOfMethodToReplace] = _global[nameOfMethodToReplace];
1714
- }
1715
- if (clock.timersPromisesModuleMethods !== void 0) {
1716
- if (nameOfMethodToReplace === "setTimeout") {
1717
- clock.timersPromisesModuleMethods.push({
1718
- methodName: "setTimeout",
1719
- original: timersPromisesModule.setTimeout
1720
- });
1721
- timersPromisesModule.setTimeout = (delay, value, options = {}) => new Promise((resolve, reject) => {
1722
- const abort = () => {
1723
- options.signal.removeEventListener("abort", abort);
1724
- clock.abortListenerMap.delete(abort);
1725
- clock.clearTimeout(handle);
1726
- reject(options.signal.reason);
1727
- };
1728
- const handle = clock.setTimeout(() => {
1729
- if (options.signal) {
1730
- options.signal.removeEventListener("abort", abort);
1731
- clock.abortListenerMap.delete(abort);
1732
- }
1733
- resolve(value);
1734
- }, delay);
1735
- if (options.signal) if (options.signal.aborted) abort();
1736
- else {
1737
- options.signal.addEventListener("abort", abort);
1738
- clock.abortListenerMap.set(abort, options.signal);
1739
- }
1740
- });
1741
- } else if (nameOfMethodToReplace === "setImmediate") {
1742
- clock.timersPromisesModuleMethods.push({
1743
- methodName: "setImmediate",
1744
- original: timersPromisesModule.setImmediate
1745
- });
1746
- timersPromisesModule.setImmediate = (value, options = {}) => new Promise((resolve, reject) => {
1747
- const abort = () => {
1748
- options.signal.removeEventListener("abort", abort);
1749
- clock.abortListenerMap.delete(abort);
1750
- clock.clearImmediate(handle);
1751
- reject(options.signal.reason);
1752
- };
1753
- const handle = clock.setImmediate(() => {
1754
- if (options.signal) {
1755
- options.signal.removeEventListener("abort", abort);
1756
- clock.abortListenerMap.delete(abort);
1757
- }
1758
- resolve(value);
1759
- });
1760
- if (options.signal) if (options.signal.aborted) abort();
1761
- else {
1762
- options.signal.addEventListener("abort", abort);
1763
- clock.abortListenerMap.set(abort, options.signal);
1764
- }
1765
- });
1766
- } else if (nameOfMethodToReplace === "setInterval") {
1767
- clock.timersPromisesModuleMethods.push({
1768
- methodName: "setInterval",
1769
- original: timersPromisesModule.setInterval
1770
- });
1771
- timersPromisesModule.setInterval = (delay, value, options = {}) => ({ [Symbol.asyncIterator]: () => {
1772
- const createResolvable = () => {
1773
- let resolve, reject;
1774
- const promise = new Promise((res, rej) => {
1775
- resolve = res;
1776
- reject = rej;
1777
- });
1778
- promise.resolve = resolve;
1779
- promise.reject = reject;
1780
- return promise;
1781
- };
1782
- let done = false;
1783
- let hasThrown = false;
1784
- let returnCall;
1785
- let nextAvailable = 0;
1786
- const nextQueue = [];
1787
- const handle = clock.setInterval(() => {
1788
- if (nextQueue.length > 0) nextQueue.shift().resolve();
1789
- else nextAvailable++;
1790
- }, delay);
1791
- const abort = () => {
1792
- options.signal.removeEventListener("abort", abort);
1793
- clock.abortListenerMap.delete(abort);
1794
- clock.clearInterval(handle);
1795
- done = true;
1796
- for (const resolvable of nextQueue) resolvable.resolve();
1797
- };
1798
- if (options.signal) if (options.signal.aborted) done = true;
1799
- else {
1800
- options.signal.addEventListener("abort", abort);
1801
- clock.abortListenerMap.set(abort, options.signal);
1802
- }
1803
- return {
1804
- next: async () => {
1805
- if (options.signal?.aborted && !hasThrown) {
1806
- hasThrown = true;
1807
- throw options.signal.reason;
1808
- }
1809
- if (done) return {
1810
- done: true,
1811
- value: void 0
1812
- };
1813
- if (nextAvailable > 0) {
1814
- nextAvailable--;
1815
- return {
1816
- done: false,
1817
- value
1818
- };
1819
- }
1820
- const resolvable = createResolvable();
1821
- nextQueue.push(resolvable);
1822
- await resolvable;
1823
- if (returnCall && nextQueue.length === 0) returnCall.resolve();
1824
- if (options.signal?.aborted && !hasThrown) {
1825
- hasThrown = true;
1826
- throw options.signal.reason;
1827
- }
1828
- if (done) return {
1829
- done: true,
1830
- value: void 0
1831
- };
1832
- return {
1833
- done: false,
1834
- value
1835
- };
1836
- },
1837
- return: async () => {
1838
- if (done) return {
1839
- done: true,
1840
- value: void 0
1841
- };
1842
- if (nextQueue.length > 0) {
1843
- returnCall = createResolvable();
1844
- await returnCall;
1845
- }
1846
- clock.clearInterval(handle);
1847
- done = true;
1848
- if (options.signal) {
1849
- options.signal.removeEventListener("abort", abort);
1850
- clock.abortListenerMap.delete(abort);
1851
- }
1852
- return {
1853
- done: true,
1854
- value: void 0
1855
- };
1856
- }
1857
- };
1858
- } });
1859
- }
1860
- }
1861
- }
1862
- return clock;
1863
- }
1864
- return {
1865
- timers,
1866
- createClock,
1867
- install,
1868
- withGlobal
1869
- };
1870
- }
1871
- /**
1872
- * @typedef {object} FakeTimers
1873
- * @property {Timers} timers
1874
- * @property {createClock} createClock
1875
- * @property {Function} install
1876
- * @property {withGlobal} withGlobal
1877
- */
1878
- /** @type {FakeTimers} */
1879
- const defaultImplementation = withGlobal(globalObject);
1880
- fakeTimersSrc.timers = defaultImplementation.timers;
1881
- fakeTimersSrc.createClock = defaultImplementation.createClock;
1882
- fakeTimersSrc.install = defaultImplementation.install;
1883
- fakeTimersSrc.withGlobal = withGlobal;
1884
- return fakeTimersSrc;
1885
- }
1886
- var fakeTimersSrcExports = requireFakeTimersSrc();
1887
- var FakeTimers = class {
1888
- _global;
1889
- _clock;
1890
- _fakingTime;
1891
- _fakingDate;
1892
- _fakeTimers;
1893
- _userConfig;
1894
- _now = RealDate.now;
1895
- constructor({ global, config }) {
1896
- this._userConfig = config;
1897
- this._fakingDate = null;
1898
- this._fakingTime = false;
1899
- this._fakeTimers = fakeTimersSrcExports.withGlobal(global);
1900
- this._global = global;
1901
- }
1902
- clearAllTimers() {
1903
- if (this._fakingTime) this._clock.reset();
1904
- }
1905
- dispose() {
1906
- this.useRealTimers();
1907
- }
1908
- runAllTimers() {
1909
- if (this._checkFakeTimers()) this._clock.runAll();
1910
- }
1911
- async runAllTimersAsync() {
1912
- if (this._checkFakeTimers()) await this._clock.runAllAsync();
1913
- }
1914
- runOnlyPendingTimers() {
1915
- if (this._checkFakeTimers()) this._clock.runToLast();
1916
- }
1917
- async runOnlyPendingTimersAsync() {
1918
- if (this._checkFakeTimers()) await this._clock.runToLastAsync();
1919
- }
1920
- advanceTimersToNextTimer(steps = 1) {
1921
- if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
1922
- this._clock.next();
1923
- this._clock.tick(0);
1924
- if (this._clock.countTimers() === 0) break;
1925
- }
1926
- }
1927
- async advanceTimersToNextTimerAsync(steps = 1) {
1928
- if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
1929
- await this._clock.nextAsync();
1930
- this._clock.tick(0);
1931
- if (this._clock.countTimers() === 0) break;
1932
- }
1933
- }
1934
- advanceTimersByTime(msToRun) {
1935
- if (this._checkFakeTimers()) this._clock.tick(msToRun);
1936
- }
1937
- async advanceTimersByTimeAsync(msToRun) {
1938
- if (this._checkFakeTimers()) await this._clock.tickAsync(msToRun);
1939
- }
1940
- advanceTimersToNextFrame() {
1941
- if (this._checkFakeTimers()) this._clock.runToFrame();
1942
- }
1943
- runAllTicks() {
1944
- if (this._checkFakeTimers()) this._clock.runMicrotasks();
1945
- }
1946
- useRealTimers() {
1947
- if (this._fakingDate) {
1948
- resetDate();
1949
- this._fakingDate = null;
1950
- }
1951
- if (this._fakingTime) {
1952
- this._clock.uninstall();
1953
- this._fakingTime = false;
1954
- }
1955
- }
1956
- useFakeTimers() {
1957
- const fakeDate = this._fakingDate || Date.now();
1958
- if (this._fakingDate) {
1959
- resetDate();
1960
- this._fakingDate = null;
1961
- }
1962
- if (this._fakingTime) this._clock.uninstall();
1963
- const toFake = Object.keys(this._fakeTimers.timers).filter((timer) => timer !== "nextTick" && timer !== "queueMicrotask");
1964
- if (this._userConfig?.toFake?.includes("nextTick") && isChildProcess()) throw new Error("process.nextTick cannot be mocked inside child_process");
1965
- this._clock = this._fakeTimers.install({
1966
- now: fakeDate,
1967
- ...this._userConfig,
1968
- toFake: this._userConfig?.toFake || toFake,
1969
- ignoreMissingTimers: true
1970
- });
1971
- this._fakingTime = true;
1972
- }
1973
- reset() {
1974
- if (this._checkFakeTimers()) {
1975
- const { now } = this._clock;
1976
- this._clock.reset();
1977
- this._clock.setSystemTime(now);
1978
- }
1979
- }
1980
- setSystemTime(now) {
1981
- const date = typeof now === "undefined" || now instanceof Date ? now : new Date(now);
1982
- if (this._fakingTime) this._clock.setSystemTime(date);
1983
- else {
1984
- this._fakingDate = date ?? new Date(this.getRealSystemTime());
1985
- mockDate(this._fakingDate);
1986
- }
1987
- }
1988
- getMockedSystemTime() {
1989
- return this._fakingTime ? new Date(this._clock.now) : this._fakingDate;
1990
- }
1991
- getRealSystemTime() {
1992
- return this._now();
1993
- }
1994
- getTimerCount() {
1995
- if (this._checkFakeTimers()) return this._clock.countTimers();
1996
- return 0;
1997
- }
1998
- setTimerTickMode(mode, interval) {
1999
- if (this._checkFakeTimers()) if (mode === "manual") this._clock.setTickMode({ mode: "manual" });
2000
- else if (mode === "nextTimerAsync") this._clock.setTickMode({ mode: "nextAsync" });
2001
- else if (mode === "interval") this._clock.setTickMode({
2002
- mode: "interval",
2003
- delta: interval
2004
- });
2005
- else throw new Error(`Invalid tick mode: ${mode}`);
2006
- }
2007
- configure(config) {
2008
- this._userConfig = config;
2009
- }
2010
- isFakeTimers() {
2011
- return this._fakingTime;
2012
- }
2013
- _checkFakeTimers() {
2014
- if (!this._fakingTime) throw new Error("A function to advance timers was called but the timers APIs are not mocked. Call `vi.useFakeTimers()` in the test file first.");
2015
- return this._fakingTime;
2016
- }
2017
- };
2018
- function copyStackTrace$1(target, source) {
2019
- if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message);
2020
- return target;
2021
- }
2022
- function waitFor(callback, options = {}) {
2023
- const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
2024
- const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
2025
- const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
2026
- return new Promise((resolve, reject) => {
2027
- let lastError;
2028
- let promiseStatus = "idle";
2029
- let timeoutId;
2030
- let intervalId;
2031
- const onResolve = (result) => {
2032
- if (timeoutId) clearTimeout(timeoutId);
2033
- if (intervalId) clearInterval(intervalId);
2034
- resolve(result);
2035
- };
2036
- const handleTimeout = () => {
2037
- if (intervalId) clearInterval(intervalId);
2038
- let error = lastError;
2039
- if (!error) error = copyStackTrace$1(/* @__PURE__ */ new Error("Timed out in waitFor!"), STACK_TRACE_ERROR);
2040
- reject(error);
2041
- };
2042
- const checkCallback = () => {
2043
- if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
2044
- if (promiseStatus === "pending") return;
2045
- try {
2046
- const result = callback();
2047
- if (result !== null && typeof result === "object" && typeof result.then === "function") {
2048
- const thenable = result;
2049
- promiseStatus = "pending";
2050
- thenable.then((resolvedValue) => {
2051
- promiseStatus = "resolved";
2052
- onResolve(resolvedValue);
2053
- }, (rejectedValue) => {
2054
- promiseStatus = "rejected";
2055
- lastError = rejectedValue;
2056
- });
2057
- } else {
2058
- onResolve(result);
2059
- return true;
2060
- }
2061
- } catch (error) {
2062
- lastError = error;
2063
- }
2064
- };
2065
- if (checkCallback() === true) return;
2066
- timeoutId = setTimeout(handleTimeout, timeout);
2067
- intervalId = setInterval(checkCallback, interval);
2068
- });
2069
- }
2070
- function waitUntil(callback, options = {}) {
2071
- const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
2072
- const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
2073
- const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
2074
- return new Promise((resolve, reject) => {
2075
- let promiseStatus = "idle";
2076
- let timeoutId;
2077
- let intervalId;
2078
- const onReject = (error) => {
2079
- if (intervalId) clearInterval(intervalId);
2080
- if (!error) error = copyStackTrace$1(/* @__PURE__ */ new Error("Timed out in waitUntil!"), STACK_TRACE_ERROR);
2081
- reject(error);
2082
- };
2083
- const onResolve = (result) => {
2084
- if (!result) return;
2085
- if (timeoutId) clearTimeout(timeoutId);
2086
- if (intervalId) clearInterval(intervalId);
2087
- resolve(result);
2088
- return true;
2089
- };
2090
- const checkCallback = () => {
2091
- if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
2092
- if (promiseStatus === "pending") return;
2093
- try {
2094
- const result = callback();
2095
- if (result !== null && typeof result === "object" && typeof result.then === "function") {
2096
- const thenable = result;
2097
- promiseStatus = "pending";
2098
- thenable.then((resolvedValue) => {
2099
- promiseStatus = "resolved";
2100
- onResolve(resolvedValue);
2101
- }, (rejectedValue) => {
2102
- promiseStatus = "rejected";
2103
- onReject(rejectedValue);
2104
- });
2105
- } else return onResolve(result);
2106
- } catch (error) {
2107
- onReject(error);
2108
- }
2109
- };
2110
- if (checkCallback() === true) return;
2111
- timeoutId = setTimeout(onReject, timeout);
2112
- intervalId = setInterval(checkCallback, interval);
2113
- });
2114
- }
2115
- function createVitest() {
2116
- let _config = null;
2117
- const state = () => getWorkerState();
2118
- let _timers;
2119
- const timers = () => _timers ||= new FakeTimers({
2120
- global: globalThis,
2121
- config: state().config.fakeTimers
2122
- });
2123
- const _stubsGlobal = /* @__PURE__ */ new Map();
2124
- const _stubsEnv = /* @__PURE__ */ new Map();
2125
- const _envBooleans = [
2126
- "PROD",
2127
- "DEV",
2128
- "SSR"
2129
- ];
2130
- const utils = {
2131
- useFakeTimers(config) {
2132
- if (isChildProcess()) {
2133
- if (config?.toFake?.includes("nextTick") || state().config?.fakeTimers?.toFake?.includes("nextTick")) throw new Error("vi.useFakeTimers({ toFake: [\"nextTick\"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required.");
2134
- }
2135
- if (config) timers().configure({
2136
- ...state().config.fakeTimers,
2137
- ...config
2138
- });
2139
- else timers().configure(state().config.fakeTimers);
2140
- timers().useFakeTimers();
2141
- return utils;
2142
- },
2143
- isFakeTimers() {
2144
- return timers().isFakeTimers();
2145
- },
2146
- useRealTimers() {
2147
- timers().useRealTimers();
2148
- return utils;
2149
- },
2150
- runOnlyPendingTimers() {
2151
- timers().runOnlyPendingTimers();
2152
- return utils;
2153
- },
2154
- async runOnlyPendingTimersAsync() {
2155
- await timers().runOnlyPendingTimersAsync();
2156
- return utils;
2157
- },
2158
- runAllTimers() {
2159
- timers().runAllTimers();
2160
- return utils;
2161
- },
2162
- async runAllTimersAsync() {
2163
- await timers().runAllTimersAsync();
2164
- return utils;
2165
- },
2166
- runAllTicks() {
2167
- timers().runAllTicks();
2168
- return utils;
2169
- },
2170
- advanceTimersByTime(ms) {
2171
- timers().advanceTimersByTime(ms);
2172
- return utils;
2173
- },
2174
- async advanceTimersByTimeAsync(ms) {
2175
- await timers().advanceTimersByTimeAsync(ms);
2176
- return utils;
2177
- },
2178
- advanceTimersToNextTimer() {
2179
- timers().advanceTimersToNextTimer();
2180
- return utils;
2181
- },
2182
- async advanceTimersToNextTimerAsync() {
2183
- await timers().advanceTimersToNextTimerAsync();
2184
- return utils;
2185
- },
2186
- advanceTimersToNextFrame() {
2187
- timers().advanceTimersToNextFrame();
2188
- return utils;
2189
- },
2190
- getTimerCount() {
2191
- return timers().getTimerCount();
2192
- },
2193
- setSystemTime(time) {
2194
- timers().setSystemTime(time);
2195
- return utils;
2196
- },
2197
- getMockedSystemTime() {
2198
- return timers().getMockedSystemTime();
2199
- },
2200
- getRealSystemTime() {
2201
- return timers().getRealSystemTime();
2202
- },
2203
- clearAllTimers() {
2204
- timers().clearAllTimers();
2205
- return utils;
2206
- },
2207
- setTimerTickMode(mode, interval) {
2208
- timers().setTimerTickMode(mode, interval);
2209
- return utils;
2210
- },
2211
- spyOn,
2212
- fn,
2213
- waitFor,
2214
- waitUntil,
2215
- defineHelper: (fn) => {
2216
- return function __VITEST_HELPER__(...args) {
2217
- const result = fn.apply(this, args);
2218
- if (result && typeof result === "object" && typeof result.then === "function") return (async function __VITEST_HELPER__() {
2219
- return await result;
2220
- })();
2221
- return result;
2222
- };
2223
- },
2224
- hoisted(factory) {
2225
- assertTypes(factory, "\"vi.hoisted\" factory", ["function"]);
2226
- return factory();
2227
- },
2228
- mock(path, factory) {
2229
- if (typeof path !== "string") throw new TypeError(`vi.mock() expects a string path, but received a ${typeof path}`);
2230
- const importer = getImporter("mock");
2231
- _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory);
2232
- },
2233
- unmock(path) {
2234
- if (typeof path !== "string") throw new TypeError(`vi.unmock() expects a string path, but received a ${typeof path}`);
2235
- _mocker().queueUnmock(path, getImporter("unmock"));
2236
- },
2237
- doMock(path, factory) {
2238
- if (typeof path !== "string") throw new TypeError(`vi.doMock() expects a string path, but received a ${typeof path}`);
2239
- const importer = getImporter("doMock");
2240
- _mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory);
2241
- const rv = {};
2242
- if (Symbol.dispose) rv[Symbol.dispose] = () => {
2243
- _mocker().queueUnmock(path, importer);
2244
- };
2245
- return rv;
2246
- },
2247
- doUnmock(path) {
2248
- if (typeof path !== "string") throw new TypeError(`vi.doUnmock() expects a string path, but received a ${typeof path}`);
2249
- const importer = getImporter("doUnmock");
2250
- _mocker().queueUnmock(path, importer);
2251
- },
2252
- async importActual(path) {
2253
- const importer = getImporter("importActual");
2254
- return _mocker().importActual(path, importer, _mocker().getMockContext().callstack);
2255
- },
2256
- async importMock(path) {
2257
- const importer = getImporter("importMock");
2258
- return _mocker().importMock(path, importer);
2259
- },
2260
- mockObject(value, options) {
2261
- return _mocker().mockObject({ value }, void 0, options?.spy ? "autospy" : "automock").value;
2262
- },
2263
- mocked(item, _options = {}) {
2264
- return item;
2265
- },
2266
- isMockFunction(fn) {
2267
- return isMockFunction(fn);
2268
- },
2269
- clearAllMocks() {
2270
- clearAllMocks();
2271
- return utils;
2272
- },
2273
- resetAllMocks() {
2274
- resetAllMocks();
2275
- return utils;
2276
- },
2277
- restoreAllMocks() {
2278
- restoreAllMocks();
2279
- return utils;
2280
- },
2281
- stubGlobal(name, value) {
2282
- if (!_stubsGlobal.has(name)) _stubsGlobal.set(name, Object.getOwnPropertyDescriptor(globalThis, name));
2283
- Object.defineProperty(globalThis, name, {
2284
- value,
2285
- writable: true,
2286
- configurable: true,
2287
- enumerable: true
2288
- });
2289
- return utils;
2290
- },
2291
- stubEnv(name, value) {
2292
- const env = state().metaEnv;
2293
- if (!_stubsEnv.has(name)) _stubsEnv.set(name, env[name]);
2294
- if (_envBooleans.includes(name)) env[name] = value ? "1" : "";
2295
- else if (value === void 0) delete env[name];
2296
- else env[name] = String(value);
2297
- return utils;
2298
- },
2299
- unstubAllGlobals() {
2300
- _stubsGlobal.forEach((original, name) => {
2301
- if (!original) Reflect.deleteProperty(globalThis, name);
2302
- else Object.defineProperty(globalThis, name, original);
2303
- });
2304
- _stubsGlobal.clear();
2305
- return utils;
2306
- },
2307
- unstubAllEnvs() {
2308
- const env = state().metaEnv;
2309
- _stubsEnv.forEach((original, name) => {
2310
- if (original === void 0) delete env[name];
2311
- else env[name] = original;
2312
- });
2313
- _stubsEnv.clear();
2314
- return utils;
2315
- },
2316
- resetModules() {
2317
- resetModules(state().evaluatedModules);
2318
- return utils;
2319
- },
2320
- async dynamicImportSettled() {
2321
- return waitForImportsToResolve();
2322
- },
2323
- setConfig(config) {
2324
- if (!_config) _config = { ...state().config };
2325
- Object.assign(state().config, config);
2326
- },
2327
- resetConfig() {
2328
- if (_config) Object.assign(state().config, _config);
2329
- }
2330
- };
2331
- return utils;
2332
- }
2333
- const vitest = createVitest();
2334
- const vi = vitest;
2335
- function _mocker() {
2336
- return typeof __vitest_mocker__ !== "undefined" ? __vitest_mocker__ : new Proxy({}, { get(_, name) {
2337
- throw new Error(`Vitest mocker was not initialized in this environment. vi.${String(name)}() is forbidden.`);
2338
- } });
2339
- }
2340
- function getImporter(name) {
2341
- const stackArray = createSimpleStackTrace({ stackTraceLimit: 5 }).split("\n");
2342
- return parseSingleStack(stackArray[stackArray.findLastIndex((stack) => {
2343
- return stack.includes(` at Object.${name}`) || stack.includes(`${name}@`) || stack.includes(` at ${name} (`);
2344
- }) + 1])?.file || "";
2345
- }
2346
- const unsupported = [
2347
- "matchSnapshot",
2348
- "toMatchSnapshot",
2349
- "toMatchInlineSnapshot",
2350
- "toThrowErrorMatchingSnapshot",
2351
- "toThrowErrorMatchingInlineSnapshot",
2352
- "throws",
2353
- "Throw",
2354
- "throw",
2355
- "toThrow",
2356
- "toThrowError"
2357
- ];
2358
- /**
2359
- * Attaches a `cause` property to the error if missing, copies the stack trace from the source, and throws.
2360
- *
2361
- * @param error - The error to throw
2362
- * @param source - Error to copy the stack trace from
2363
- *
2364
- * @throws Always throws the provided error with an amended stack trace
2365
- */
2366
- function throwWithCause(error, source) {
2367
- if (error.cause == null) error.cause = /* @__PURE__ */ new Error("Matcher did not succeed in time.");
2368
- throw copyStackTrace(error, source);
2369
- }
2370
- function createExpectPoll(expect) {
2371
- return function poll(fn, options = {}) {
2372
- const defaults = getWorkerState().config.expect?.poll ?? {};
2373
- const { interval = defaults.interval ?? 50, timeout = defaults.timeout ?? 1e3, message } = options;
2374
- const assertion = expect(null, message).withContext({ poll: true });
2375
- fn = fn.bind(assertion);
2376
- utils_exports.flag(assertion, "_poll.fn", fn);
2377
- utils_exports.flag(assertion, "_poll.timeout", timeout);
2378
- utils_exports.flag(assertion, "_poll.interval", interval);
2379
- const test = utils_exports.flag(assertion, "vitest-test");
2380
- if (!test) throw new Error("expect.poll() must be called inside a test");
2381
- const proxy = new Proxy(assertion, { get(target, key, receiver) {
2382
- const assertionFunction = Reflect.get(target, key, receiver);
2383
- if (typeof assertionFunction !== "function") return assertionFunction instanceof Assertion ? proxy : assertionFunction;
2384
- if (key === "assert") return assertionFunction;
2385
- if (typeof key === "string" && unsupported.includes(key)) throw new SyntaxError(`expect.poll() is not supported in combination with .${key}(). Use vi.waitFor() if your assertion condition is unstable.`);
2386
- return function __VITEST_POLL_CHAIN__(...args) {
2387
- const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
2388
- const promise = async () => {
2389
- utils_exports.flag(assertion, "_name", key);
2390
- utils_exports.flag(assertion, "error", STACK_TRACE_ERROR);
2391
- const onSettled = utils_exports.flag(assertion, "_poll.onSettled");
2392
- if (Object.getOwnPropertyDescriptor(assertionFunction, "__vitest_poll_takeover__")?.value) try {
2393
- const output = await assertionFunction.call(assertion, ...args);
2394
- await onSettled?.({
2395
- assertion,
2396
- status: "pass"
2397
- });
2398
- return output;
2399
- } catch (err) {
2400
- await onSettled?.({
2401
- assertion,
2402
- status: "fail"
2403
- });
2404
- throwWithCause(err, STACK_TRACE_ERROR);
2405
- }
2406
- const { setTimeout, clearTimeout } = getSafeTimers();
2407
- let executionPhase = "fn";
2408
- let hasTimedOut = false;
2409
- const timerId = setTimeout(() => {
2410
- hasTimedOut = true;
2411
- }, timeout);
2412
- try {
2413
- while (true) {
2414
- const isLastAttempt = hasTimedOut;
2415
- if (isLastAttempt) utils_exports.flag(assertion, "_isLastPollAttempt", true);
2416
- try {
2417
- executionPhase = "fn";
2418
- const obj = await fn();
2419
- utils_exports.flag(assertion, "object", obj);
2420
- executionPhase = "assertion";
2421
- const output = await assertionFunction.call(assertion, ...args);
2422
- await onSettled?.({
2423
- assertion,
2424
- status: "pass"
2425
- });
2426
- return output;
2427
- } catch (err) {
2428
- if (isLastAttempt || executionPhase === "assertion" && utils_exports.flag(assertion, "_poll.assert_once")) {
2429
- await onSettled?.({
2430
- assertion,
2431
- status: "fail"
2432
- });
2433
- throwWithCause(err, STACK_TRACE_ERROR);
2434
- }
2435
- await delay(interval, setTimeout);
2436
- if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
2437
- }
2438
- }
2439
- } finally {
2440
- clearTimeout(timerId);
2441
- }
2442
- };
2443
- let awaited = false;
2444
- test.onFinished ??= [];
2445
- test.onFinished.push(() => {
2446
- if (!awaited) {
2447
- const negated = utils_exports.flag(assertion, "negate") ? "not." : "";
2448
- const assertionString = `expect.${utils_exports.flag(assertion, "_poll.element") ? "element(locator)" : "poll(assertion)"}.${negated}${String(key)}()`;
2449
- throw copyStackTrace(/* @__PURE__ */ new Error(`${assertionString} was not awaited. This assertion is asynchronous and must be awaited; otherwise, it is not executed to avoid unhandled rejections:\n\nawait ${assertionString}\n`), STACK_TRACE_ERROR);
2450
- }
2451
- });
2452
- let resultPromise;
2453
- return {
2454
- then(onFulfilled, onRejected) {
2455
- awaited = true;
2456
- return (resultPromise ||= promise()).then(onFulfilled, onRejected);
2457
- },
2458
- catch(onRejected) {
2459
- awaited = true;
2460
- return (resultPromise ||= promise()).catch(onRejected);
2461
- },
2462
- finally(onFinally) {
2463
- awaited = true;
2464
- return (resultPromise ||= promise()).finally(onFinally);
2465
- },
2466
- [Symbol.toStringTag]: "Promise"
2467
- };
2468
- };
2469
- } });
2470
- return proxy;
2471
- };
2472
- }
2473
- function copyStackTrace(target, source) {
2474
- if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message);
2475
- return target;
2476
- }
2477
- let _client;
2478
- function getSnapshotClient() {
2479
- if (!_client) _client = new SnapshotClient({ isEqual: (received, expected) => {
2480
- return equals(received, expected, [iterableEquality, subsetEquality]);
2481
- } });
2482
- return _client;
2483
- }
2484
- function getError(expected, promise) {
2485
- if (typeof expected !== "function") {
2486
- if (!promise) throw new Error(`expected must be a function, received ${typeof expected}`);
2487
- return expected;
2488
- }
2489
- try {
2490
- expected();
2491
- } catch (e) {
2492
- return e;
2493
- }
2494
- throw new Error("snapshot function didn't throw");
2495
- }
2496
- function getTestNames(test) {
2497
- return {
2498
- filepath: test.file.filepath,
2499
- name: getNames(test).slice(1).join(" > "),
2500
- testId: test.id
2501
- };
2502
- }
2503
- function getAssertionName(assertion) {
2504
- const name = utils_exports.flag(assertion, "_name");
2505
- if (!name) throw new Error("Assertion name is not set. This is a bug in Vitest. Please, open a new issue with reproduction.");
2506
- return name;
2507
- }
2508
- function getTest(obj) {
2509
- const test = utils_exports.flag(obj, "vitest-test");
2510
- if (!test) throw new Error(`'${getAssertionName(obj)}' cannot be used without test context`);
2511
- return test;
2512
- }
2513
- function validateAssertion(assertion) {
2514
- if (utils_exports.flag(assertion, "negate")) throw new Error(`${getAssertionName(assertion)} cannot be used with "not"`);
2515
- }
2516
- const SnapshotPlugin = (chai, utils) => {
2517
- for (const key of ["matchSnapshot", "toMatchSnapshot"]) utils.addMethod(chai.Assertion.prototype, key, wrapAssertion(utils, key, function(propertiesOrHint, hint) {
2518
- return assertMatchResult(toMatchSnapshotImpl({
2519
- assertion: this,
2520
- received: utils.flag(this, "object"),
2521
- ...normalizeArguments(propertiesOrHint, hint)
2522
- }), chai.util.flag(this, "message"));
2523
- }));
2524
- utils.addMethod(chai.Assertion.prototype, "toMatchFileSnapshot", function(filepath, hint) {
2525
- utils.flag(this, "_name", "toMatchFileSnapshot");
2526
- validateAssertion(this);
2527
- const assertPromise = toMatchFileSnapshotImpl({
2528
- assertion: this,
2529
- received: utils.flag(this, "object"),
2530
- filepath,
2531
- hint
2532
- }).then((result) => assertMatchResult(result, chai.util.flag(this, "message")));
2533
- return recordAsyncExpect(getTest(this), assertPromise, createAssertionMessage(utils, this, true), /* @__PURE__ */ new Error("resolves"), utils.flag(this, "soft"));
2534
- });
2535
- utils.addMethod(chai.Assertion.prototype, "toMatchInlineSnapshot", wrapAssertion(utils, "toMatchInlineSnapshot", function __INLINE_SNAPSHOT_OFFSET_3__(propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint) {
2536
- return assertMatchResult(toMatchSnapshotImpl({
2537
- assertion: this,
2538
- received: utils.flag(this, "object"),
2539
- isInline: true,
2540
- ...normalizeInlineArguments(propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint)
2541
- }), chai.util.flag(this, "message"));
2542
- }));
2543
- utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingSnapshot", wrapAssertion(utils, "toThrowErrorMatchingSnapshot", function(propertiesOrHint, hint) {
2544
- validateAssertion(this);
2545
- const received = utils.flag(this, "object");
2546
- const promise = utils.flag(this, "promise");
2547
- return assertMatchResult(toMatchSnapshotImpl({
2548
- assertion: this,
2549
- received: getError(received, promise),
2550
- ...normalizeArguments(propertiesOrHint, hint)
2551
- }), chai.util.flag(this, "message"));
2552
- }));
2553
- utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingInlineSnapshot", wrapAssertion(utils, "toThrowErrorMatchingInlineSnapshot", function __INLINE_SNAPSHOT_OFFSET_3__(inlineSnapshotOrHint, hint) {
2554
- validateAssertion(this);
2555
- const received = utils.flag(this, "object");
2556
- const promise = utils.flag(this, "promise");
2557
- return assertMatchResult(toMatchSnapshotImpl({
2558
- assertion: this,
2559
- received: getError(received, promise),
2560
- isInline: true,
2561
- ...normalizeInlineArguments(void 0, inlineSnapshotOrHint, hint)
2562
- }), chai.util.flag(this, "message"));
2563
- }));
2564
- utils.addMethod(chai.expect, "addSnapshotSerializer", addSerializer);
2565
- };
2566
- function toMatchDomainSnapshotImpl(opts) {
2567
- const { assertion } = opts;
2568
- validateAssertion(assertion);
2569
- const assertionName = getAssertionName(assertion);
2570
- const test = getTest(assertion);
2571
- let { inlineSnapshot } = opts;
2572
- if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
2573
- const pollFn = utils_exports.flag(assertion, "_poll.fn");
2574
- if (pollFn) return getSnapshotClient().pollMatchDomain({
2575
- poll: pollFn,
2576
- adapter: opts.adapter,
2577
- message: opts.hint,
2578
- isInline: opts.isInline,
2579
- errorMessage: utils_exports.flag(assertion, "message"),
2580
- timeout: utils_exports.flag(assertion, "_poll.timeout"),
2581
- interval: utils_exports.flag(assertion, "_poll.interval"),
2582
- assertionName,
2583
- inlineSnapshot,
2584
- error: utils_exports.flag(assertion, "error"),
2585
- ...getTestNames(test)
2586
- });
2587
- return getSnapshotClient().matchDomain({
2588
- received: opts.received,
2589
- adapter: opts.adapter,
2590
- message: opts.hint,
2591
- isInline: opts.isInline,
2592
- errorMessage: utils_exports.flag(assertion, "message"),
2593
- assertionName,
2594
- inlineSnapshot,
2595
- error: utils_exports.flag(assertion, "error"),
2596
- ...getTestNames(test)
2597
- });
2598
- }
2599
- function normalizeArguments(propertiesOrHint, hint) {
2600
- if (typeof propertiesOrHint === "string") return { hint: propertiesOrHint };
2601
- return {
2602
- properties: propertiesOrHint,
2603
- hint
2604
- };
2605
- }
2606
- function normalizeInlineArguments(propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint) {
2607
- let inlineSnapshot;
2608
- if (typeof propertiesOrInlineSnapshot === "string") {
2609
- inlineSnapshot = stripSnapshotIndentation(propertiesOrInlineSnapshot);
2610
- return {
2611
- inlineSnapshot,
2612
- hint: inlineSnapshotOrHint
2613
- };
2614
- }
2615
- if (inlineSnapshotOrHint) inlineSnapshot = stripSnapshotIndentation(inlineSnapshotOrHint);
2616
- return {
2617
- properties: propertiesOrInlineSnapshot,
2618
- inlineSnapshot,
2619
- hint
2620
- };
2621
- }
2622
- function toMatchSnapshotImpl(options) {
2623
- const { assertion } = options;
2624
- validateAssertion(assertion);
2625
- const assertionName = getAssertionName(assertion);
2626
- const test = getTest(assertion);
2627
- return getSnapshotClient().match({
2628
- received: options.received,
2629
- properties: options.properties,
2630
- message: options.hint,
2631
- isInline: options.isInline,
2632
- inlineSnapshot: options.inlineSnapshot,
2633
- assertionName,
2634
- error: utils_exports.flag(assertion, "error"),
2635
- ...getTestNames(test)
2636
- });
2637
- }
2638
- async function toMatchFileSnapshotImpl(options) {
2639
- const { assertion } = options;
2640
- validateAssertion(assertion);
2641
- const testNames = getTestNames(getTest(assertion));
2642
- const snapshotState = getSnapshotClient().getSnapshotState(testNames.filepath);
2643
- const rawSnapshotFile = await snapshotState.environment.resolveRawPath(testNames.filepath, options.filepath);
2644
- const rawSnapshotContent = await snapshotState.environment.readSnapshotFile(rawSnapshotFile);
2645
- return getSnapshotClient().match({
2646
- received: options.received,
2647
- message: options.hint,
2648
- rawSnapshot: {
2649
- file: rawSnapshotFile,
2650
- content: rawSnapshotContent ?? void 0
2651
- },
2652
- ...testNames
2653
- });
2654
- }
2655
- function assertMatchResult(result, customMessage) {
2656
- if (!result.pass) {
2657
- const errorMessage = (customMessage ? `${customMessage}: ` : "") + result.message();
2658
- throw Object.assign(new Error(errorMessage), {
2659
- actual: result.actual,
2660
- expected: result.expected,
2661
- diffOptions: { expand: getWorkerState().config.snapshotOptions.expand }
2662
- });
2663
- }
2664
- }
2665
- /**
2666
- * Composable snapshot matcher helpers for building custom snapshot matchers
2667
- * with `expect.extend`.
2668
- *
2669
- * @experimental
2670
- * @see https://vitest.dev/guide/snapshot.html#custom-snapshot-matchers
2671
- */
2672
- const Snapshots = {
2673
- toMatchSnapshot(received, propertiesOrHint, hint) {
2674
- return toMatchSnapshotImpl({
2675
- assertion: this.assertion,
2676
- received,
2677
- ...normalizeArguments(propertiesOrHint, hint)
2678
- });
2679
- },
2680
- toMatchInlineSnapshot(received, propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint) {
2681
- return toMatchSnapshotImpl({
2682
- assertion: this.assertion,
2683
- received,
2684
- isInline: true,
2685
- ...normalizeInlineArguments(propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint)
2686
- });
2687
- },
2688
- toMatchFileSnapshot(received, filepath, hint) {
2689
- return toMatchFileSnapshotImpl({
2690
- assertion: this.assertion,
2691
- received,
2692
- filepath,
2693
- hint
2694
- });
2695
- },
2696
- toMatchDomainSnapshot(domain, received) {
2697
- return toMatchDomainSnapshotImpl({
2698
- assertion: this.assertion,
2699
- adapter: domain,
2700
- received
2701
- });
2702
- },
2703
- toMatchDomainInlineSnapshot(domain, received, inlineSnapshot) {
2704
- return toMatchDomainSnapshotImpl({
2705
- assertion: this.assertion,
2706
- adapter: domain,
2707
- received,
2708
- isInline: true,
2709
- inlineSnapshot
2710
- });
2711
- }
2712
- };
2713
- use(JestExtend);
2714
- use(JestChaiExpect);
2715
- use(ChaiStyleAssertions);
2716
- use(SnapshotPlugin);
2717
- use(JestAsymmetricMatchers);
2718
- function createExpect(test) {
2719
- const expect$1 = ((value, message) => {
2720
- const { assertionCalls } = getState(expect$1);
2721
- setState({ assertionCalls: assertionCalls + 1 }, expect$1);
2722
- const assert = expect(value, message);
2723
- const _test = test || getCurrentTest();
2724
- if (_test) return assert.withTest(_test);
2725
- else return assert;
2726
- });
2727
- Object.assign(expect$1, expect);
2728
- Object.assign(expect$1, globalThis[ASYMMETRIC_MATCHERS_OBJECT]);
2729
- expect$1.getState = () => getState(expect$1);
2730
- expect$1.setState = (state) => setState(state, expect$1);
2731
- const globalState = getState(globalThis[GLOBAL_EXPECT]) || {};
2732
- setState({
2733
- ...globalState,
2734
- assertionCalls: 0,
2735
- isExpectingAssertions: false,
2736
- isExpectingAssertionsError: null,
2737
- expectedAssertionsNumber: null,
2738
- expectedAssertionsNumberErrorGen: null,
2739
- get testPath() {
2740
- return getWorkerState().filepath;
2741
- },
2742
- currentTestName: test ? test.fullTestName ?? "" : globalState.currentTestName
2743
- }, expect$1);
2744
- expect$1.assert = assert$1;
2745
- expect$1.extend = (matchers) => expect.extend(expect$1, matchers);
2746
- expect$1.addEqualityTesters = (customTesters) => addCustomEqualityTesters(customTesters);
2747
- expect$1.soft = (...args) => {
2748
- return expect$1(...args).withContext({ soft: true });
2749
- };
2750
- expect$1.poll = createExpectPoll(expect$1);
2751
- expect$1.unreachable = (message) => {
2752
- assert$1.fail(`expected${message ? ` "${message}" ` : " "}not to be reached`);
2753
- };
2754
- function assertions(expected) {
2755
- const errorGen = () => /* @__PURE__ */ new Error(`expected number of assertions to be ${expected}, but got ${expect$1.getState().assertionCalls}`);
2756
- if (Error.captureStackTrace) Error.captureStackTrace(errorGen(), assertions);
2757
- expect$1.setState({
2758
- expectedAssertionsNumber: expected,
2759
- expectedAssertionsNumberErrorGen: errorGen
2760
- });
2761
- }
2762
- function hasAssertions() {
2763
- const error = /* @__PURE__ */ new Error("expected any number of assertion, but got none");
2764
- if (Error.captureStackTrace) Error.captureStackTrace(error, hasAssertions);
2765
- expect$1.setState({
2766
- isExpectingAssertions: true,
2767
- isExpectingAssertionsError: error
2768
- });
2769
- }
2770
- utils_exports.addMethod(expect$1, "assertions", assertions);
2771
- utils_exports.addMethod(expect$1, "hasAssertions", hasAssertions);
2772
- expect$1.extend(customMatchers);
2773
- return expect$1;
2774
- }
2775
- const globalExpect = createExpect();
2776
- Object.defineProperty(globalThis, GLOBAL_EXPECT, {
2777
- value: globalExpect,
2778
- writable: true,
2779
- configurable: true
2780
- });
2781
- const assert = assert$1;
2782
- const should = should$1;
2783
- /**
2784
- * Gives access to injected context provided from the main thread.
2785
- * This usually returns a value provided by `globalSetup` or an external library.
2786
- */
2787
- function inject(key) {
2788
- return getWorkerState().providedContext[key];
2789
- }
2790
- function createBenchmarkResult(name) {
2791
- return {
2792
- name,
2793
- rank: 0,
2794
- rme: 0,
2795
- samples: []
2796
- };
2797
- }
2798
- const benchmarkTasks = /* @__PURE__ */ new WeakMap();
2799
- async function runBenchmarkSuite(suite, runner) {
2800
- const { Task, Bench } = await runner.importTinybench();
2801
- const start = performance.now();
2802
- const benchmarkGroup = [];
2803
- const benchmarkSuiteGroup = [];
2804
- for (const task of suite.tasks) {
2805
- if (task.mode !== "run" && task.mode !== "queued") continue;
2806
- if (task.meta?.benchmark) benchmarkGroup.push(task);
2807
- else if (task.type === "suite") benchmarkSuiteGroup.push(task);
2808
- }
2809
- for (const subSuite of benchmarkSuiteGroup) await runBenchmarkSuite(subSuite, runner);
2810
- if (benchmarkGroup.length) {
2811
- const defer = createDefer();
2812
- suite.result = {
2813
- state: "run",
2814
- startTime: start,
2815
- benchmark: createBenchmarkResult(suite.name)
2816
- };
2817
- updateTask$1("suite-prepare", suite);
2818
- const addBenchTaskListener = (task, benchmark) => {
2819
- task.addEventListener("complete", (e) => {
2820
- const taskRes = e.task.result;
2821
- const result = benchmark.result.benchmark;
2822
- benchmark.result.state = "pass";
2823
- Object.assign(result, taskRes);
2824
- const samples = result.samples;
2825
- result.sampleCount = samples.length;
2826
- result.median = samples.length % 2 ? samples[Math.floor(samples.length / 2)] : (samples[samples.length / 2] + samples[samples.length / 2 - 1]) / 2;
2827
- if (!runner.config.benchmark?.includeSamples) result.samples.length = 0;
2828
- updateTask$1("test-finished", benchmark);
2829
- }, { once: true });
2830
- task.addEventListener("error", (e) => {
2831
- const task = e.task;
2832
- defer.reject(benchmark ? task.result.error : e);
2833
- }, { once: true });
2834
- };
2835
- benchmarkGroup.forEach((benchmark) => {
2836
- const benchmarkInstance = new Bench(getBenchOptions(benchmark));
2837
- const benchmarkFn = getBenchFn(benchmark);
2838
- benchmark.result = {
2839
- state: "run",
2840
- startTime: start,
2841
- benchmark: createBenchmarkResult(benchmark.name)
2842
- };
2843
- const task = new Task(benchmarkInstance, benchmark.name, benchmarkFn);
2844
- benchmarkTasks.set(benchmark, task);
2845
- addBenchTaskListener(task, benchmark);
2846
- });
2847
- const { setTimeout } = getSafeTimers();
2848
- const tasks = [];
2849
- for (const benchmark of benchmarkGroup) {
2850
- const task = benchmarkTasks.get(benchmark);
2851
- updateTask$1("test-prepare", benchmark);
2852
- await task.warmup();
2853
- tasks.push([await new Promise((resolve) => setTimeout(async () => {
2854
- resolve(await task.run());
2855
- })), benchmark]);
2856
- }
2857
- suite.result.duration = performance.now() - start;
2858
- suite.result.state = "pass";
2859
- updateTask$1("suite-finished", suite);
2860
- defer.resolve(null);
2861
- await defer;
2862
- }
2863
- function updateTask$1(event, task) {
2864
- updateTask(event, task, runner);
2865
- }
2866
- }
2867
- var NodeBenchmarkRunner = class {
2868
- moduleRunner;
2869
- constructor(config) {
2870
- this.config = config;
2871
- }
2872
- async importTinybench() {
2873
- return await import("../../../../../tinybench@2.9.0/node_modules/tinybench/dist/index.js");
2874
- }
2875
- importFile(filepath, source) {
2876
- if (source === "setup") {
2877
- const moduleNode = getWorkerState().evaluatedModules.getModuleById(filepath);
2878
- if (moduleNode) getWorkerState().evaluatedModules.invalidateModule(moduleNode);
2879
- }
2880
- return this.moduleRunner.import(filepath);
2881
- }
2882
- async runSuite(suite) {
2883
- await runBenchmarkSuite(suite, this);
2884
- }
2885
- async runTask() {
2886
- throw new Error("`test()` and `it()` is only available in test mode.");
2887
- }
2888
- };
2889
- var TestRunner = class {
2890
- snapshotClient = getSnapshotClient();
2891
- workerState = getWorkerState();
2892
- moduleRunner;
2893
- cancelRun = false;
2894
- assertionsErrors = /* @__PURE__ */ new WeakMap();
2895
- pool = this.workerState.ctx.pool;
2896
- _otel;
2897
- viteEnvironment;
2898
- viteModuleRunner;
2899
- constructor(config) {
2900
- this.config = config;
2901
- const environment = this.workerState.environment;
2902
- this.viteEnvironment = environment.viteEnvironment || environment.name;
2903
- this.viteModuleRunner = config.experimental.viteModuleRunner;
2904
- }
2905
- importFile(filepath, source) {
2906
- if (source === "setup") {
2907
- const moduleNode = this.workerState.evaluatedModules.getModuleById(filepath);
2908
- if (moduleNode) this.workerState.evaluatedModules.invalidateModule(moduleNode);
2909
- }
2910
- return this._otel.$(`vitest.module.import_${source === "setup" ? "setup" : "spec"}`, { attributes: { "code.file.path": filepath } }, () => {
2911
- if (!this.viteModuleRunner) filepath = `${filepath}?vitest=${Date.now()}`;
2912
- return this.moduleRunner.import(filepath);
2913
- });
2914
- }
2915
- onCollectStart(file) {
2916
- this.workerState.current = file;
2917
- }
2918
- onCleanupWorkerContext(listener) {
2919
- this.workerState.onCleanup(listener);
2920
- }
2921
- onAfterRunFiles() {
2922
- this.snapshotClient.clear();
2923
- this.workerState.current = void 0;
2924
- }
2925
- async onAfterRunSuite(suite) {
2926
- if (this.config.logHeapUsage && typeof process !== "undefined") suite.result.heap = process.memoryUsage().heapUsed;
2927
- if (suite.mode !== "skip" && "filepath" in suite) {
2928
- for (const test of getTests(suite)) if (test.mode === "skip") {
2929
- const name = getNames(test).slice(1).join(" > ");
2930
- this.snapshotClient.skipTest(suite.file.filepath, name);
2931
- }
2932
- const result = await this.snapshotClient.finish(suite.file.filepath);
2933
- if (this.workerState.config.snapshotOptions.updateSnapshot === "none" && result.unchecked) {
2934
- let message = `Obsolete snapshots found when no snapshot update is expected.\n`;
2935
- for (const key of result.uncheckedKeys) message += `· ${key}\n`;
2936
- suite.result.errors ??= [];
2937
- suite.result.errors.push(processError(new Error(message)));
2938
- suite.result.state = "fail";
2939
- }
2940
- await rpc().snapshotSaved(result);
2941
- }
2942
- this.workerState.current = suite.suite || suite.file;
2943
- }
2944
- onAfterRunTask(test) {
2945
- if (this.config.logHeapUsage && typeof process !== "undefined") test.result.heap = process.memoryUsage().heapUsed;
2946
- this.workerState.current = test.suite || test.file;
2947
- }
2948
- cancel(_reason) {
2949
- this.cancelRun = true;
2950
- }
2951
- injectValue(key) {
2952
- return inject(key);
2953
- }
2954
- async onBeforeRunTask(test) {
2955
- if (this.cancelRun) test.mode = "skip";
2956
- if (test.mode !== "run" && test.mode !== "queued") return;
2957
- this.workerState.current = test;
2958
- }
2959
- async onBeforeRunSuite(suite) {
2960
- if (this.cancelRun) suite.mode = "skip";
2961
- if (suite.mode !== "skip" && "filepath" in suite) await this.snapshotClient.setup(suite.file.filepath, this.workerState.config.snapshotOptions);
2962
- this.workerState.current = suite;
2963
- }
2964
- onBeforeTryTask(test) {
2965
- clearModuleMocks(this.config);
2966
- this.snapshotClient.clearTest(test.file.filepath, test.id);
2967
- setState({
2968
- assertionCalls: 0,
2969
- isExpectingAssertions: false,
2970
- isExpectingAssertionsError: null,
2971
- expectedAssertionsNumber: null,
2972
- expectedAssertionsNumberErrorGen: null,
2973
- currentTestName: getTestName(test),
2974
- snapshotState: this.snapshotClient.getSnapshotState(test.file.filepath)
2975
- }, globalThis[GLOBAL_EXPECT]);
2976
- }
2977
- onAfterTryTask(test) {
2978
- const { assertionCalls, expectedAssertionsNumber, expectedAssertionsNumberErrorGen, isExpectingAssertions, isExpectingAssertionsError } = test.context._local ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]);
2979
- if (expectedAssertionsNumber !== null && assertionCalls !== expectedAssertionsNumber) throw expectedAssertionsNumberErrorGen();
2980
- if (isExpectingAssertions === true && assertionCalls === 0) throw isExpectingAssertionsError;
2981
- if (this.config.expect.requireAssertions && assertionCalls === 0) throw this.assertionsErrors.get(test);
2982
- }
2983
- extendTaskContext(context) {
2984
- if (this.config.expect.requireAssertions) this.assertionsErrors.set(context.task, /* @__PURE__ */ new Error("expected any number of assertion, but got none"));
2985
- let _expect;
2986
- Object.defineProperty(context, "expect", { get() {
2987
- if (!_expect) _expect = createExpect(context.task);
2988
- return _expect;
2989
- } });
2990
- Object.defineProperty(context, "_local", { get() {
2991
- return _expect != null;
2992
- } });
2993
- return context;
2994
- }
2995
- getImportDurations() {
2996
- const { limit } = this.config.experimental.importDurations;
2997
- if (limit === 0) return {};
2998
- const sortedEntries = [...this.workerState.moduleExecutionInfo?.entries() || []].sort(([, a], [, b]) => b.duration - a.duration).slice(0, limit);
2999
- const importDurations = {};
3000
- for (const [filepath, { duration, selfTime, external, importer }] of sortedEntries) importDurations[normalize(filepath)] = {
3001
- selfTime,
3002
- totalTime: duration,
3003
- external,
3004
- importer
3005
- };
3006
- return importDurations;
3007
- }
3008
- trace = (name, attributes, cb) => {
3009
- const options = typeof attributes === "object" ? { attributes } : {};
3010
- return this._otel.$(`vitest.test.runner.${name}`, options, cb || attributes);
3011
- };
3012
- __setTraces(traces) {
3013
- this._otel = traces;
3014
- }
3015
- static createTaskCollector = createTaskCollector;
3016
- static getCurrentSuite = getCurrentSuite;
3017
- static getCurrentTest = getCurrentTest;
3018
- static createChainable = createChainable;
3019
- static getSuiteHooks = getHooks;
3020
- static getTestFn = getFn;
3021
- static setSuiteHooks = getHooks;
3022
- static setTestFn = getFn;
3023
- static matchesTags = matchesTags;
3024
- /**
3025
- * @deprecated
3026
- */
3027
- static getBenchFn = getBenchFn;
3028
- /**
3029
- * @deprecated
3030
- */
3031
- static getBenchOptions = getBenchOptions;
3032
- };
3033
- function clearModuleMocks(config) {
3034
- const { clearMocks, mockReset, restoreMocks, unstubEnvs, unstubGlobals } = config;
3035
- if (restoreMocks) vi.restoreAllMocks();
3036
- if (mockReset) vi.resetAllMocks();
3037
- if (clearMocks) vi.clearAllMocks();
3038
- if (unstubEnvs) vi.unstubAllEnvs();
3039
- if (unstubGlobals) vi.unstubAllGlobals();
3040
- }
3041
- //#endregion
3042
- export { NodeBenchmarkRunner as N, Snapshots as S, TestRunner as T, assert as a, vitest as b, createExpect as c, globalExpect as g, inject as i, should as s, vi as v };
3043
-
3044
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5ETm15Rmt2Si5qcyIsIm5hbWVzIjpbImNoYWkuQXNzZXJ0aW9uIiwiY2hhaS51c2UiLCJleHBlY3QiLCJjaGFpLmV4cGVjdCIsImNoYWkuYXNzZXJ0IiwiY2hhaS5zaG91bGQiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vdml0ZXN0QDQuMS4xMF9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjBfQHR5cGVzK25vZGVAMjUuMC43X0B2aXRlc3QrY292ZXJhZ2UtdjhANC4xLjEwX3ZpX2ExOTc3YjkzYWY3YmI2OTMwOGJjYjFkYmFiMzliNjE4L25vZGVfbW9kdWxlcy92aXRlc3QvZGlzdC9jaHVua3MvdGVzdC5ETm15Rmt2Si5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRDdXJyZW50VGVzdCwgdXBkYXRlVGFzaywgY3JlYXRlVGFza0NvbGxlY3RvciwgZ2V0Q3VycmVudFN1aXRlLCBnZXRIb29rcywgZ2V0Rm4gfSBmcm9tICdAdml0ZXN0L3J1bm5lcic7XG5pbXBvcnQgeyBhc3NlcnRUeXBlcywgY3JlYXRlU2ltcGxlU3RhY2tUcmFjZSwgY3JlYXRlRGVmZXIgfSBmcm9tICdAdml0ZXN0L3V0aWxzL2hlbHBlcnMnO1xuaW1wb3J0IHsgZ2V0U2FmZVRpbWVycywgZGVsYXkgfSBmcm9tICdAdml0ZXN0L3V0aWxzL3RpbWVycyc7XG5pbXBvcnQgeyBhIGFzIGdldEJlbmNoT3B0aW9ucywgZyBhcyBnZXRCZW5jaEZuIH0gZnJvbSAnLi9iZW5jaG1hcmsuQ1hfb1kwM1YuanMnO1xuaW1wb3J0IHsgaSBhcyBpc0NoaWxkUHJvY2VzcywgdyBhcyB3YWl0Rm9ySW1wb3J0c1RvUmVzb2x2ZSwgciBhcyByZXNldE1vZHVsZXMsIGcgYXMgZ2V0V29ya2VyU3RhdGUgfSBmcm9tICcuL3V0aWxzLkJYNUZnOEM0LmpzJztcbmltcG9ydCB7IGNoYWksIHdyYXBBc3NlcnRpb24sIHJlY29yZEFzeW5jRXhwZWN0LCBjcmVhdGVBc3NlcnRpb25NZXNzYWdlLCBlcXVhbHMsIGl0ZXJhYmxlRXF1YWxpdHksIHN1YnNldEVxdWFsaXR5LCBKZXN0RXh0ZW5kLCBKZXN0Q2hhaUV4cGVjdCwgQ2hhaVN0eWxlQXNzZXJ0aW9ucywgSmVzdEFzeW1tZXRyaWNNYXRjaGVycywgR0xPQkFMX0VYUEVDVCwgQVNZTU1FVFJJQ19NQVRDSEVSU19PQkpFQ1QsIGdldFN0YXRlLCBzZXRTdGF0ZSwgYWRkQ3VzdG9tRXF1YWxpdHlUZXN0ZXJzLCBjdXN0b21NYXRjaGVycyB9IGZyb20gJ0B2aXRlc3QvZXhwZWN0JztcbmltcG9ydCB7IGdldE5hbWVzLCBnZXRUZXN0cywgZ2V0VGVzdE5hbWUsIGNyZWF0ZUNoYWluYWJsZSwgbWF0Y2hlc1RhZ3MgfSBmcm9tICdAdml0ZXN0L3J1bm5lci91dGlscyc7XG5pbXBvcnQgeyBwcm9jZXNzRXJyb3IgfSBmcm9tICdAdml0ZXN0L3V0aWxzL2Vycm9yJztcbmltcG9ydCB7IG5vcm1hbGl6ZSB9IGZyb20gJ3BhdGhlJztcbmltcG9ydCB7IGZuLCBzcHlPbiwgcmVzdG9yZUFsbE1vY2tzLCByZXNldEFsbE1vY2tzLCBjbGVhckFsbE1vY2tzLCBpc01vY2tGdW5jdGlvbiB9IGZyb20gJ0B2aXRlc3Qvc3B5JztcbmltcG9ydCAnQHZpdGVzdC91dGlscy9vZmZzZXQnO1xuaW1wb3J0IHsgcGFyc2VTaW5nbGVTdGFjayB9IGZyb20gJ0B2aXRlc3QvdXRpbHMvc291cmNlLW1hcCc7XG5pbXBvcnQgeyBjIGFzIGNvbW1vbmpzR2xvYmFsIH0gZnJvbSAnLi9fY29tbW9uanNIZWxwZXJzLkQyNnR5M0V3LmpzJztcbmltcG9ydCB7IFIgYXMgUmVhbERhdGUsIGIgYXMgcmVzZXREYXRlLCBtIGFzIG1vY2tEYXRlLCByIGFzIHJwYyB9IGZyb20gJy4vcnBjLk16WGV0M2psLmpzJztcbmltcG9ydCB7IGFkZFNlcmlhbGl6ZXIsIHN0cmlwU25hcHNob3RJbmRlbnRhdGlvbiwgU25hcHNob3RDbGllbnQgfSBmcm9tICdAdml0ZXN0L3NuYXBzaG90JztcblxudmFyIGZha2VUaW1lcnNTcmMgPSB7fTtcblxudmFyIGdsb2JhbDtcbnZhciBoYXNSZXF1aXJlZEdsb2JhbDtcblxuZnVuY3Rpb24gcmVxdWlyZUdsb2JhbCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEdsb2JhbCkgcmV0dXJuIGdsb2JhbDtcblx0aGFzUmVxdWlyZWRHbG9iYWwgPSAxO1xuXG5cdC8qKlxuXHQgKiBBIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdFxuXHQgKiBAdHlwZSB7b2JqZWN0fSBnbG9iYWxPYmplY3Rcblx0ICovXG5cdHZhciBnbG9iYWxPYmplY3Q7XG5cblx0LyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cblx0aWYgKHR5cGVvZiBjb21tb25qc0dsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgLy8gTm9kZVxuXHQgICAgZ2xvYmFsT2JqZWN0ID0gY29tbW9uanNHbG9iYWw7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgLy8gQnJvd3NlclxuXHQgICAgZ2xvYmFsT2JqZWN0ID0gd2luZG93O1xuXHR9IGVsc2Uge1xuXHQgICAgLy8gV2ViV29ya2VyXG5cdCAgICBnbG9iYWxPYmplY3QgPSBzZWxmO1xuXHR9XG5cblx0Z2xvYmFsID0gZ2xvYmFsT2JqZWN0O1xuXHRyZXR1cm4gZ2xvYmFsO1xufVxuXG52YXIgdGhyb3dzT25Qcm90b18xO1xudmFyIGhhc1JlcXVpcmVkVGhyb3dzT25Qcm90bztcblxuZnVuY3Rpb24gcmVxdWlyZVRocm93c09uUHJvdG8gKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRUaHJvd3NPblByb3RvKSByZXR1cm4gdGhyb3dzT25Qcm90b18xO1xuXHRoYXNSZXF1aXJlZFRocm93c09uUHJvdG8gPSAxO1xuXG5cdC8qKlxuXHQgKiBJcyB0cnVlIHdoZW4gdGhlIGVudmlyb25tZW50IGNhdXNlcyBhbiBlcnJvciB0byBiZSB0aHJvd24gZm9yIGFjY2Vzc2luZyB0aGVcblx0ICogX19wcm90b19fIHByb3BlcnR5LlxuXHQgKiBUaGlzIGlzIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBzdXBwb3J0IGBub2RlIC0tZGlzYWJsZS1wcm90bz10aHJvd2AuXG5cdCAqXG5cdCAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvcHJvdG9cblx0ICogQHR5cGUge2Jvb2xlYW59XG5cdCAqL1xuXHRsZXQgdGhyb3dzT25Qcm90bztcblx0dHJ5IHtcblx0ICAgIGNvbnN0IG9iamVjdCA9IHt9O1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvLCBuby11bnVzZWQtZXhwcmVzc2lvbnNcblx0ICAgIG9iamVjdC5fX3Byb3RvX187XG5cdCAgICB0aHJvd3NPblByb3RvID0gZmFsc2U7XG5cdH0gY2F0Y2ggKF8pIHtcblx0ICAgIC8vIFRoaXMgYnJhbmNoIGlzIGNvdmVyZWQgd2hlbiB0ZXN0cyBhcmUgcnVuIHdpdGggYC0tZGlzYWJsZS1wcm90bz10aHJvd2AsXG5cdCAgICAvLyBob3dldmVyIHdlIGNhbiB0ZXN0IGJvdGggYnJhbmNoZXMgYXQgdGhlIHNhbWUgdGltZSwgc28gdGhpcyBpcyBpZ25vcmVkXG5cdCAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuXHQgICAgdGhyb3dzT25Qcm90byA9IHRydWU7XG5cdH1cblxuXHR0aHJvd3NPblByb3RvXzEgPSB0aHJvd3NPblByb3RvO1xuXHRyZXR1cm4gdGhyb3dzT25Qcm90b18xO1xufVxuXG52YXIgY29weVByb3RvdHlwZU1ldGhvZHM7XG52YXIgaGFzUmVxdWlyZWRDb3B5UHJvdG90eXBlTWV0aG9kcztcblxuZnVuY3Rpb24gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkQ29weVByb3RvdHlwZU1ldGhvZHMpIHJldHVybiBjb3B5UHJvdG90eXBlTWV0aG9kcztcblx0aGFzUmVxdWlyZWRDb3B5UHJvdG90eXBlTWV0aG9kcyA9IDE7XG5cblx0dmFyIGNhbGwgPSBGdW5jdGlvbi5jYWxsO1xuXHR2YXIgdGhyb3dzT25Qcm90byA9IHJlcXVpcmVUaHJvd3NPblByb3RvKCk7XG5cblx0dmFyIGRpc2FsbG93ZWRQcm9wZXJ0aWVzID0gW1xuXHQgICAgLy8gaWdub3JlIHNpemUgYmVjYXVzZSBpdCB0aHJvd3MgZnJvbSBNYXBcblx0ICAgIFwic2l6ZVwiLFxuXHQgICAgXCJjYWxsZXJcIixcblx0ICAgIFwiY2FsbGVlXCIsXG5cdCAgICBcImFyZ3VtZW50c1wiLFxuXHRdO1xuXG5cdC8vIFRoaXMgYnJhbmNoIGlzIGNvdmVyZWQgd2hlbiB0ZXN0cyBhcmUgcnVuIHdpdGggYC0tZGlzYWJsZS1wcm90bz10aHJvd2AsXG5cdC8vIGhvd2V2ZXIgd2UgY2FuIHRlc3QgYm90aCBicmFuY2hlcyBhdCB0aGUgc2FtZSB0aW1lLCBzbyB0aGlzIGlzIGlnbm9yZWRcblx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0aWYgKHRocm93c09uUHJvdG8pIHtcblx0ICAgIGRpc2FsbG93ZWRQcm9wZXJ0aWVzLnB1c2goXCJfX3Byb3RvX19cIik7XG5cdH1cblxuXHRjb3B5UHJvdG90eXBlTWV0aG9kcyA9IGZ1bmN0aW9uIGNvcHlQcm90b3R5cGVNZXRob2RzKHByb3RvdHlwZSkge1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBzaW5vbmpzL25vLXByb3RvdHlwZS1tZXRob2RzL25vLXByb3RvdHlwZS1tZXRob2RzXG5cdCAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocHJvdG90eXBlKS5yZWR1Y2UoZnVuY3Rpb24gKFxuXHQgICAgICAgIHJlc3VsdCxcblx0ICAgICAgICBuYW1lXG5cdCAgICApIHtcblx0ICAgICAgICBpZiAoZGlzYWxsb3dlZFByb3BlcnRpZXMuaW5jbHVkZXMobmFtZSkpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAodHlwZW9mIHByb3RvdHlwZVtuYW1lXSAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmVzdWx0W25hbWVdID0gY2FsbC5iaW5kKHByb3RvdHlwZVtuYW1lXSk7XG5cblx0ICAgICAgICByZXR1cm4gcmVzdWx0O1xuXHQgICAgfSxcblx0ICAgIE9iamVjdC5jcmVhdGUobnVsbCkpO1xuXHR9O1xuXHRyZXR1cm4gY29weVByb3RvdHlwZU1ldGhvZHM7XG59XG5cbnZhciBhcnJheTtcbnZhciBoYXNSZXF1aXJlZEFycmF5O1xuXG5mdW5jdGlvbiByZXF1aXJlQXJyYXkgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRBcnJheSkgcmV0dXJuIGFycmF5O1xuXHRoYXNSZXF1aXJlZEFycmF5ID0gMTtcblxuXHR2YXIgY29weVByb3RvdHlwZSA9IHJlcXVpcmVDb3B5UHJvdG90eXBlTWV0aG9kcygpO1xuXG5cdGFycmF5ID0gY29weVByb3RvdHlwZShBcnJheS5wcm90b3R5cGUpO1xuXHRyZXR1cm4gYXJyYXk7XG59XG5cbnZhciBjYWxsZWRJbk9yZGVyXzE7XG52YXIgaGFzUmVxdWlyZWRDYWxsZWRJbk9yZGVyO1xuXG5mdW5jdGlvbiByZXF1aXJlQ2FsbGVkSW5PcmRlciAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZENhbGxlZEluT3JkZXIpIHJldHVybiBjYWxsZWRJbk9yZGVyXzE7XG5cdGhhc1JlcXVpcmVkQ2FsbGVkSW5PcmRlciA9IDE7XG5cblx0dmFyIGV2ZXJ5ID0gcmVxdWlyZUFycmF5KCkuZXZlcnk7XG5cblx0LyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRmdW5jdGlvbiBoYXNDYWxsc0xlZnQoY2FsbE1hcCwgc3B5KSB7XG5cdCAgICBpZiAoY2FsbE1hcFtzcHkuaWRdID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICBjYWxsTWFwW3NweS5pZF0gPSAwO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gY2FsbE1hcFtzcHkuaWRdIDwgc3B5LmNhbGxDb3VudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0ZnVuY3Rpb24gY2hlY2tBZGphY2VudENhbGxzKGNhbGxNYXAsIHNweSwgaW5kZXgsIHNwaWVzKSB7XG5cdCAgICB2YXIgY2FsbGVkQmVmb3JlTmV4dCA9IHRydWU7XG5cblx0ICAgIGlmIChpbmRleCAhPT0gc3BpZXMubGVuZ3RoIC0gMSkge1xuXHQgICAgICAgIGNhbGxlZEJlZm9yZU5leHQgPSBzcHkuY2FsbGVkQmVmb3JlKHNwaWVzW2luZGV4ICsgMV0pO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaGFzQ2FsbHNMZWZ0KGNhbGxNYXAsIHNweSkgJiYgY2FsbGVkQmVmb3JlTmV4dCkge1xuXHQgICAgICAgIGNhbGxNYXBbc3B5LmlkXSArPSAxO1xuXHQgICAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQSBTaW5vbiBwcm94eSBvYmplY3QgKGZha2UsIHNweSwgc3R1Yilcblx0ICogQHR5cGVkZWYge29iamVjdH0gU2lub25Qcm94eVxuXHQgKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBjYWxsZWRCZWZvcmUgLSBBIG1ldGhvZCB0aGF0IGRldGVybWluZXMgaWYgdGhpcyBwcm94eSB3YXMgY2FsbGVkIGJlZm9yZSBhbm90aGVyIG9uZVxuXHQgKiBAcHJvcGVydHkge3N0cmluZ30gaWQgLSBTb21lIGlkXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjYWxsQ291bnQgLSBOdW1iZXIgb2YgdGltZXMgdGhpcyBwcm94eSBoYXMgYmVlbiBjYWxsZWRcblx0ICovXG5cblx0LyoqXG5cdCAqIFJldHVybnMgdHJ1ZSB3aGVuIHRoZSBzcGllcyBoYXZlIGJlZW4gY2FsbGVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgc3VwcGxpZWQgaW5cblx0ICogQHBhcmFtICB7U2lub25Qcm94eVtdIHwgU2lub25Qcm94eX0gc3BpZXMgQW4gYXJyYXkgb2YgcHJveGllcywgb3Igc2V2ZXJhbCBwcm94aWVzIGFzIGFyZ3VtZW50c1xuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSB3aGVuIHNwaWVzIGFyZSBjYWxsZWQgaW4gb3JkZXIsIGZhbHNlIG90aGVyd2lzZVxuXHQgKi9cblx0ZnVuY3Rpb24gY2FsbGVkSW5PcmRlcihzcGllcykge1xuXHQgICAgdmFyIGNhbGxNYXAgPSB7fTtcblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuXHQgICAgdmFyIF9zcGllcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzIDogc3BpZXM7XG5cblx0ICAgIHJldHVybiBldmVyeShfc3BpZXMsIGNoZWNrQWRqYWNlbnRDYWxscy5iaW5kKG51bGwsIGNhbGxNYXApKTtcblx0fVxuXG5cdGNhbGxlZEluT3JkZXJfMSA9IGNhbGxlZEluT3JkZXI7XG5cdHJldHVybiBjYWxsZWRJbk9yZGVyXzE7XG59XG5cbnZhciBjbGFzc05hbWVfMTtcbnZhciBoYXNSZXF1aXJlZENsYXNzTmFtZTtcblxuZnVuY3Rpb24gcmVxdWlyZUNsYXNzTmFtZSAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZENsYXNzTmFtZSkgcmV0dXJuIGNsYXNzTmFtZV8xO1xuXHRoYXNSZXF1aXJlZENsYXNzTmFtZSA9IDE7XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBkaXNwbGF5IG5hbWUgZm9yIGEgdmFsdWUgZnJvbSBhIGNvbnN0cnVjdG9yXG5cdCAqIEBwYXJhbSAge29iamVjdH0gdmFsdWUgQSB2YWx1ZSB0byBleGFtaW5lXG5cdCAqIEByZXR1cm5zIHsoc3RyaW5nfG51bGwpfSBBIHN0cmluZyBvciBudWxsXG5cdCAqL1xuXHRmdW5jdGlvbiBjbGFzc05hbWUodmFsdWUpIHtcblx0ICAgIGNvbnN0IG5hbWUgPSB2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lO1xuXHQgICAgcmV0dXJuIG5hbWUgfHwgbnVsbDtcblx0fVxuXG5cdGNsYXNzTmFtZV8xID0gY2xhc3NOYW1lO1xuXHRyZXR1cm4gY2xhc3NOYW1lXzE7XG59XG5cbnZhciBkZXByZWNhdGVkID0ge307XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cblxudmFyIGhhc1JlcXVpcmVkRGVwcmVjYXRlZDtcblxuZnVuY3Rpb24gcmVxdWlyZURlcHJlY2F0ZWQgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWREZXByZWNhdGVkKSByZXR1cm4gZGVwcmVjYXRlZDtcblx0aGFzUmVxdWlyZWREZXByZWNhdGVkID0gMTtcblx0KGZ1bmN0aW9uIChleHBvcnRzJDEpIHtcblxuXHRcdC8qKlxuXHRcdCAqIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgaW52b2tlIHRoZSBzdXBwbGllZCBmdW5jdGlvbiBhbmQgcHJpbnQgYVxuXHRcdCAqIGRlcHJlY2F0aW9uIHdhcm5pbmcgdG8gdGhlIGNvbnNvbGUgZWFjaCB0aW1lIGl0IGlzIGNhbGxlZC5cblx0XHQgKiBAcGFyYW0gIHtGdW5jdGlvbn0gZnVuY1xuXHRcdCAqIEBwYXJhbSAge3N0cmluZ30gbXNnXG5cdFx0ICogQHJldHVybnMge0Z1bmN0aW9ufVxuXHRcdCAqL1xuXHRcdGV4cG9ydHMkMS53cmFwID0gZnVuY3Rpb24gKGZ1bmMsIG1zZykge1xuXHRcdCAgICB2YXIgd3JhcHBlZCA9IGZ1bmN0aW9uICgpIHtcblx0XHQgICAgICAgIGV4cG9ydHMkMS5wcmludFdhcm5pbmcobXNnKTtcblx0XHQgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdFx0ICAgIH07XG5cdFx0ICAgIGlmIChmdW5jLnByb3RvdHlwZSkge1xuXHRcdCAgICAgICAgd3JhcHBlZC5wcm90b3R5cGUgPSBmdW5jLnByb3RvdHlwZTtcblx0XHQgICAgfVxuXHRcdCAgICByZXR1cm4gd3JhcHBlZDtcblx0XHR9O1xuXG5cdFx0LyoqXG5cdFx0ICogUmV0dXJucyBhIHN0cmluZyB3aGljaCBjYW4gYmUgc3VwcGxpZWQgdG8gYHdyYXAoKWAgdG8gbm90aWZ5IHRoZSB1c2VyIHRoYXQgYVxuXHRcdCAqIHBhcnRpY3VsYXIgcGFydCBvZiB0aGUgc2lub24gQVBJIGhhcyBiZWVuIGRlcHJlY2F0ZWQuXG5cdFx0ICogQHBhcmFtICB7c3RyaW5nfSBwYWNrYWdlTmFtZVxuXHRcdCAqIEBwYXJhbSAge3N0cmluZ30gZnVuY05hbWVcblx0XHQgKiBAcmV0dXJucyB7c3RyaW5nfVxuXHRcdCAqL1xuXHRcdGV4cG9ydHMkMS5kZWZhdWx0TXNnID0gZnVuY3Rpb24gKHBhY2thZ2VOYW1lLCBmdW5jTmFtZSkge1xuXHRcdCAgICByZXR1cm4gYCR7cGFja2FnZU5hbWV9LiR7ZnVuY05hbWV9IGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBwdWJsaWMgQVBJIGluIGEgZnV0dXJlIHZlcnNpb24gb2YgJHtwYWNrYWdlTmFtZX0uYDtcblx0XHR9O1xuXG5cdFx0LyoqXG5cdFx0ICogUHJpbnRzIGEgd2FybmluZyBvbiB0aGUgY29uc29sZSwgd2hlbiBpdCBleGlzdHNcblx0XHQgKiBAcGFyYW0gIHtzdHJpbmd9IG1zZ1xuXHRcdCAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG5cdFx0ICovXG5cdFx0ZXhwb3J0cyQxLnByaW50V2FybmluZyA9IGZ1bmN0aW9uIChtc2cpIHtcblx0XHQgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHQgICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MuZW1pdFdhcm5pbmcpIHtcblx0XHQgICAgICAgIC8vIEVtaXQgV2FybmluZ3MgaW4gTm9kZVxuXHRcdCAgICAgICAgcHJvY2Vzcy5lbWl0V2FybmluZyhtc2cpO1xuXHRcdCAgICB9IGVsc2UgaWYgKGNvbnNvbGUuaW5mbykge1xuXHRcdCAgICAgICAgY29uc29sZS5pbmZvKG1zZyk7XG5cdFx0ICAgIH0gZWxzZSB7XG5cdFx0ICAgICAgICBjb25zb2xlLmxvZyhtc2cpO1xuXHRcdCAgICB9XG5cdFx0fTsgXG5cdH0gKGRlcHJlY2F0ZWQpKTtcblx0cmV0dXJuIGRlcHJlY2F0ZWQ7XG59XG5cbnZhciBldmVyeTtcbnZhciBoYXNSZXF1aXJlZEV2ZXJ5O1xuXG5mdW5jdGlvbiByZXF1aXJlRXZlcnkgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRFdmVyeSkgcmV0dXJuIGV2ZXJ5O1xuXHRoYXNSZXF1aXJlZEV2ZXJ5ID0gMTtcblxuXHQvKipcblx0ICogUmV0dXJucyB0cnVlIHdoZW4gZm4gcmV0dXJucyB0cnVlIGZvciBhbGwgbWVtYmVycyBvZiBvYmouXG5cdCAqIFRoaXMgaXMgYW4gZXZlcnkgaW1wbGVtZW50YXRpb24gdGhhdCB3b3JrcyBmb3IgYWxsIGl0ZXJhYmxlc1xuXHQgKiBAcGFyYW0gIHtvYmplY3R9ICAgb2JqXG5cdCAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmblxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdGV2ZXJ5ID0gZnVuY3Rpb24gZXZlcnkob2JqLCBmbikge1xuXHQgICAgdmFyIHBhc3MgPSB0cnVlO1xuXG5cdCAgICB0cnkge1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAc2lub25qcy9uby1wcm90b3R5cGUtbWV0aG9kcy9uby1wcm90b3R5cGUtbWV0aG9kc1xuXHQgICAgICAgIG9iai5mb3JFYWNoKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKCFmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBUaHJvd2luZyBhbiBlcnJvciBpcyB0aGUgb25seSB3YXkgdG8gYnJlYWsgYGZvckVhY2hgXG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgIHBhc3MgPSBmYWxzZTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIHBhc3M7XG5cdH07XG5cdHJldHVybiBldmVyeTtcbn1cblxudmFyIGZ1bmN0aW9uTmFtZTtcbnZhciBoYXNSZXF1aXJlZEZ1bmN0aW9uTmFtZTtcblxuZnVuY3Rpb24gcmVxdWlyZUZ1bmN0aW9uTmFtZSAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZ1bmN0aW9uTmFtZSkgcmV0dXJuIGZ1bmN0aW9uTmFtZTtcblx0aGFzUmVxdWlyZWRGdW5jdGlvbk5hbWUgPSAxO1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgZGlzcGxheSBuYW1lIGZvciBhIGZ1bmN0aW9uXG5cdCAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmdW5jXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd9XG5cdCAqL1xuXHRmdW5jdGlvbk5hbWUgPSBmdW5jdGlvbiBmdW5jdGlvbk5hbWUoZnVuYykge1xuXHQgICAgaWYgKCFmdW5jKSB7XG5cdCAgICAgICAgcmV0dXJuIFwiXCI7XG5cdCAgICB9XG5cblx0ICAgIHRyeSB7XG5cdCAgICAgICAgcmV0dXJuIChcblx0ICAgICAgICAgICAgZnVuYy5kaXNwbGF5TmFtZSB8fFxuXHQgICAgICAgICAgICBmdW5jLm5hbWUgfHxcblx0ICAgICAgICAgICAgLy8gVXNlIGZ1bmN0aW9uIGRlY29tcG9zaXRpb24gYXMgYSBsYXN0IHJlc29ydCB0byBnZXQgZnVuY3Rpb25cblx0ICAgICAgICAgICAgLy8gbmFtZS4gRG9lcyBub3QgcmVseSBvbiBmdW5jdGlvbiBkZWNvbXBvc2l0aW9uIHRvIHdvcmsgLSBpZiBpdFxuXHQgICAgICAgICAgICAvLyBkb2Vzbid0IGRlYnVnZ2luZyB3aWxsIGJlIHNsaWdodGx5IGxlc3MgaW5mb3JtYXRpdmVcblx0ICAgICAgICAgICAgLy8gKGkuZS4gdG9TdHJpbmcgd2lsbCBzYXkgJ3NweScgcmF0aGVyIHRoYW4gJ215RnVuYycpLlxuXHQgICAgICAgICAgICAoU3RyaW5nKGZ1bmMpLm1hdGNoKC9mdW5jdGlvbiAoW15cXHMoXSspLykgfHwgW10pWzFdXG5cdCAgICAgICAgKTtcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAvLyBTdHJpbmdpZnkgbWF5IGZhaWwgYW5kIHdlIG1pZ2h0IGdldCBhbiBleGNlcHRpb24sIGFzIGEgbGFzdC1sYXN0XG5cdCAgICAgICAgLy8gcmVzb3J0IGZhbGwgYmFjayB0byBlbXB0eSBzdHJpbmcuXG5cdCAgICAgICAgcmV0dXJuIFwiXCI7XG5cdCAgICB9XG5cdH07XG5cdHJldHVybiBmdW5jdGlvbk5hbWU7XG59XG5cbnZhciBvcmRlckJ5Rmlyc3RDYWxsXzE7XG52YXIgaGFzUmVxdWlyZWRPcmRlckJ5Rmlyc3RDYWxsO1xuXG5mdW5jdGlvbiByZXF1aXJlT3JkZXJCeUZpcnN0Q2FsbCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZE9yZGVyQnlGaXJzdENhbGwpIHJldHVybiBvcmRlckJ5Rmlyc3RDYWxsXzE7XG5cdGhhc1JlcXVpcmVkT3JkZXJCeUZpcnN0Q2FsbCA9IDE7XG5cblx0dmFyIHNvcnQgPSByZXF1aXJlQXJyYXkoKS5zb3J0O1xuXHR2YXIgc2xpY2UgPSByZXF1aXJlQXJyYXkoKS5zbGljZTtcblxuXHQvKipcblx0ICogQHByaXZhdGVcblx0ICovXG5cdGZ1bmN0aW9uIGNvbXBhcmF0b3IoYSwgYikge1xuXHQgICAgLy8gdXVpZCwgd29uJ3QgZXZlciBiZSBlcXVhbFxuXHQgICAgdmFyIGFDYWxsID0gYS5nZXRDYWxsKDApO1xuXHQgICAgdmFyIGJDYWxsID0gYi5nZXRDYWxsKDApO1xuXHQgICAgdmFyIGFJZCA9IChhQ2FsbCAmJiBhQ2FsbC5jYWxsSWQpIHx8IC0xO1xuXHQgICAgdmFyIGJJZCA9IChiQ2FsbCAmJiBiQ2FsbC5jYWxsSWQpIHx8IC0xO1xuXG5cdCAgICByZXR1cm4gYUlkIDwgYklkID8gLTEgOiAxO1xuXHR9XG5cblx0LyoqXG5cdCAqIEEgU2lub24gcHJveHkgb2JqZWN0IChmYWtlLCBzcHksIHN0dWIpXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IFNpbm9uUHJveHlcblx0ICogQHByb3BlcnR5IHtGdW5jdGlvbn0gZ2V0Q2FsbCAtIEEgbWV0aG9kIHRoYXQgY2FuIHJldHVybiB0aGUgZmlyc3QgY2FsbFxuXHQgKi9cblxuXHQvKipcblx0ICogU29ydHMgYW4gYXJyYXkgb2YgU2lub25Qcm94eSBpbnN0YW5jZXMgKGZha2UsIHNweSwgc3R1YikgYnkgdGhlaXIgZmlyc3QgY2FsbFxuXHQgKiBAcGFyYW0gIHtTaW5vblByb3h5W10gfCBTaW5vblByb3h5fSBzcGllc1xuXHQgKiBAcmV0dXJucyB7U2lub25Qcm94eVtdfVxuXHQgKi9cblx0ZnVuY3Rpb24gb3JkZXJCeUZpcnN0Q2FsbChzcGllcykge1xuXHQgICAgcmV0dXJuIHNvcnQoc2xpY2Uoc3BpZXMpLCBjb21wYXJhdG9yKTtcblx0fVxuXG5cdG9yZGVyQnlGaXJzdENhbGxfMSA9IG9yZGVyQnlGaXJzdENhbGw7XG5cdHJldHVybiBvcmRlckJ5Rmlyc3RDYWxsXzE7XG59XG5cbnZhciBfZnVuY3Rpb247XG52YXIgaGFzUmVxdWlyZWRfZnVuY3Rpb247XG5cbmZ1bmN0aW9uIHJlcXVpcmVfZnVuY3Rpb24gKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRfZnVuY3Rpb24pIHJldHVybiBfZnVuY3Rpb247XG5cdGhhc1JlcXVpcmVkX2Z1bmN0aW9uID0gMTtcblxuXHR2YXIgY29weVByb3RvdHlwZSA9IHJlcXVpcmVDb3B5UHJvdG90eXBlTWV0aG9kcygpO1xuXG5cdF9mdW5jdGlvbiA9IGNvcHlQcm90b3R5cGUoRnVuY3Rpb24ucHJvdG90eXBlKTtcblx0cmV0dXJuIF9mdW5jdGlvbjtcbn1cblxudmFyIG1hcDtcbnZhciBoYXNSZXF1aXJlZE1hcDtcblxuZnVuY3Rpb24gcmVxdWlyZU1hcCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZE1hcCkgcmV0dXJuIG1hcDtcblx0aGFzUmVxdWlyZWRNYXAgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0bWFwID0gY29weVByb3RvdHlwZShNYXAucHJvdG90eXBlKTtcblx0cmV0dXJuIG1hcDtcbn1cblxudmFyIG9iamVjdDtcbnZhciBoYXNSZXF1aXJlZE9iamVjdDtcblxuZnVuY3Rpb24gcmVxdWlyZU9iamVjdCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZE9iamVjdCkgcmV0dXJuIG9iamVjdDtcblx0aGFzUmVxdWlyZWRPYmplY3QgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0b2JqZWN0ID0gY29weVByb3RvdHlwZShPYmplY3QucHJvdG90eXBlKTtcblx0cmV0dXJuIG9iamVjdDtcbn1cblxudmFyIHNldDtcbnZhciBoYXNSZXF1aXJlZFNldDtcblxuZnVuY3Rpb24gcmVxdWlyZVNldCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFNldCkgcmV0dXJuIHNldDtcblx0aGFzUmVxdWlyZWRTZXQgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0c2V0ID0gY29weVByb3RvdHlwZShTZXQucHJvdG90eXBlKTtcblx0cmV0dXJuIHNldDtcbn1cblxudmFyIHN0cmluZztcbnZhciBoYXNSZXF1aXJlZFN0cmluZztcblxuZnVuY3Rpb24gcmVxdWlyZVN0cmluZyAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFN0cmluZykgcmV0dXJuIHN0cmluZztcblx0aGFzUmVxdWlyZWRTdHJpbmcgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0c3RyaW5nID0gY29weVByb3RvdHlwZShTdHJpbmcucHJvdG90eXBlKTtcblx0cmV0dXJuIHN0cmluZztcbn1cblxudmFyIHByb3RvdHlwZXM7XG52YXIgaGFzUmVxdWlyZWRQcm90b3R5cGVzO1xuXG5mdW5jdGlvbiByZXF1aXJlUHJvdG90eXBlcyAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFByb3RvdHlwZXMpIHJldHVybiBwcm90b3R5cGVzO1xuXHRoYXNSZXF1aXJlZFByb3RvdHlwZXMgPSAxO1xuXG5cdHByb3RvdHlwZXMgPSB7XG5cdCAgICBhcnJheTogcmVxdWlyZUFycmF5KCksXG5cdCAgICBmdW5jdGlvbjogcmVxdWlyZV9mdW5jdGlvbigpLFxuXHQgICAgbWFwOiByZXF1aXJlTWFwKCksXG5cdCAgICBvYmplY3Q6IHJlcXVpcmVPYmplY3QoKSxcblx0ICAgIHNldDogcmVxdWlyZVNldCgpLFxuXHQgICAgc3RyaW5nOiByZXF1aXJlU3RyaW5nKCksXG5cdH07XG5cdHJldHVybiBwcm90b3R5cGVzO1xufVxuXG52YXIgdHlwZURldGVjdCQxID0ge2V4cG9ydHM6IHt9fTtcblxudmFyIHR5cGVEZXRlY3QgPSB0eXBlRGV0ZWN0JDEuZXhwb3J0cztcblxudmFyIGhhc1JlcXVpcmVkVHlwZURldGVjdDtcblxuZnVuY3Rpb24gcmVxdWlyZVR5cGVEZXRlY3QgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRUeXBlRGV0ZWN0KSByZXR1cm4gdHlwZURldGVjdCQxLmV4cG9ydHM7XG5cdGhhc1JlcXVpcmVkVHlwZURldGVjdCA9IDE7XG5cdChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHtcblx0XHQoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuXHRcdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgO1xuXHRcdH0odHlwZURldGVjdCwgKGZ1bmN0aW9uICgpIHtcblx0XHQvKiAhXG5cdFx0ICogdHlwZS1kZXRlY3Rcblx0XHQgKiBDb3B5cmlnaHQoYykgMjAxMyBqYWtlIGx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cblx0XHQgKiBNSVQgTGljZW5zZWRcblx0XHQgKi9cblx0XHR2YXIgcHJvbWlzZUV4aXN0cyA9IHR5cGVvZiBQcm9taXNlID09PSAnZnVuY3Rpb24nO1xuXG5cdFx0LyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cblx0XHR2YXIgZ2xvYmFsT2JqZWN0ID0gdHlwZW9mIHNlbGYgPT09ICdvYmplY3QnID8gc2VsZiA6IGNvbW1vbmpzR2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGlkLWJsYWNrbGlzdFxuXG5cdFx0dmFyIHN5bWJvbEV4aXN0cyA9IHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnO1xuXHRcdHZhciBtYXBFeGlzdHMgPSB0eXBlb2YgTWFwICE9PSAndW5kZWZpbmVkJztcblx0XHR2YXIgc2V0RXhpc3RzID0gdHlwZW9mIFNldCAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIHdlYWtNYXBFeGlzdHMgPSB0eXBlb2YgV2Vha01hcCAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIHdlYWtTZXRFeGlzdHMgPSB0eXBlb2YgV2Vha1NldCAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIGRhdGFWaWV3RXhpc3RzID0gdHlwZW9mIERhdGFWaWV3ICE9PSAndW5kZWZpbmVkJztcblx0XHR2YXIgc3ltYm9sSXRlcmF0b3JFeGlzdHMgPSBzeW1ib2xFeGlzdHMgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIHN5bWJvbFRvU3RyaW5nVGFnRXhpc3RzID0gc3ltYm9sRXhpc3RzICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgIT09ICd1bmRlZmluZWQnO1xuXHRcdHZhciBzZXRFbnRyaWVzRXhpc3RzID0gc2V0RXhpc3RzICYmIHR5cGVvZiBTZXQucHJvdG90eXBlLmVudHJpZXMgPT09ICdmdW5jdGlvbic7XG5cdFx0dmFyIG1hcEVudHJpZXNFeGlzdHMgPSBtYXBFeGlzdHMgJiYgdHlwZW9mIE1hcC5wcm90b3R5cGUuZW50cmllcyA9PT0gJ2Z1bmN0aW9uJztcblx0XHR2YXIgc2V0SXRlcmF0b3JQcm90b3R5cGUgPSBzZXRFbnRyaWVzRXhpc3RzICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihuZXcgU2V0KCkuZW50cmllcygpKTtcblx0XHR2YXIgbWFwSXRlcmF0b3JQcm90b3R5cGUgPSBtYXBFbnRyaWVzRXhpc3RzICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihuZXcgTWFwKCkuZW50cmllcygpKTtcblx0XHR2YXIgYXJyYXlJdGVyYXRvckV4aXN0cyA9IHN5bWJvbEl0ZXJhdG9yRXhpc3RzICYmIHR5cGVvZiBBcnJheS5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXSA9PT0gJ2Z1bmN0aW9uJztcblx0XHR2YXIgYXJyYXlJdGVyYXRvclByb3RvdHlwZSA9IGFycmF5SXRlcmF0b3JFeGlzdHMgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSk7XG5cdFx0dmFyIHN0cmluZ0l0ZXJhdG9yRXhpc3RzID0gc3ltYm9sSXRlcmF0b3JFeGlzdHMgJiYgdHlwZW9mIFN0cmluZy5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXSA9PT0gJ2Z1bmN0aW9uJztcblx0XHR2YXIgc3RyaW5nSXRlcmF0b3JQcm90b3R5cGUgPSBzdHJpbmdJdGVyYXRvckV4aXN0cyAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoJydbU3ltYm9sLml0ZXJhdG9yXSgpKTtcblx0XHR2YXIgdG9TdHJpbmdMZWZ0U2xpY2VMZW5ndGggPSA4O1xuXHRcdHZhciB0b1N0cmluZ1JpZ2h0U2xpY2VMZW5ndGggPSAtMTtcblx0XHQvKipcblx0XHQgKiAjIyMgdHlwZU9mIChvYmopXG5cdFx0ICpcblx0XHQgKiBVc2VzIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYCB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgYW4gb2JqZWN0LFxuXHRcdCAqIG5vcm1hbGlzaW5nIGJlaGF2aW91ciBhY3Jvc3MgZW5naW5lIHZlcnNpb25zICYgd2VsbCBvcHRpbWlzZWQuXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge01peGVkfSBvYmplY3Rcblx0XHQgKiBAcmV0dXJuIHtTdHJpbmd9IG9iamVjdCB0eXBlXG5cdFx0ICogQGFwaSBwdWJsaWNcblx0XHQgKi9cblx0XHRmdW5jdGlvbiB0eXBlRGV0ZWN0KG9iaikge1xuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICAqIFByZTpcblx0XHQgICAqICAgc3RyaW5nIGxpdGVyYWwgICAgIHggMywwMzksMDM1IG9wcy9zZWMgwrExLjYyJSAoNzggcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBib29sZWFuIGxpdGVyYWwgICAgeCAxLDQyNCwxMzggb3BzL3NlYyDCsTQuNTQlICg3NSBydW5zIHNhbXBsZWQpXG5cdFx0ICAgKiAgIG51bWJlciBsaXRlcmFsICAgICB4IDEsNjUzLDE1MyBvcHMvc2VjIMKxMS45MSUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICAqICAgdW5kZWZpbmVkICAgICAgICAgIHggOSw5NzgsNjYwIG9wcy9zZWMgwrExLjkyJSAoNzUgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBmdW5jdGlvbiAgICAgICAgICAgeCAyLDU1Niw3Njkgb3BzL3NlYyDCsTEuNzMlICg3NyBydW5zIHNhbXBsZWQpXG5cdFx0ICAgKiBQb3N0OlxuXHRcdCAgICogICBzdHJpbmcgbGl0ZXJhbCAgICAgeCAzOCw1NjQsNzk2IG9wcy9zZWMgwrExLjE1JSAoNzkgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBib29sZWFuIGxpdGVyYWwgICAgeCAzMSwxNDgsOTQwIG9wcy9zZWMgwrExLjEwJSAoNzkgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBudW1iZXIgbGl0ZXJhbCAgICAgeCAzMiw2NzksMzMwIG9wcy9zZWMgwrExLjkwJSAoNzggcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICB1bmRlZmluZWQgICAgICAgICAgeCAzMiwzNjMsMzY4IG9wcy9zZWMgwrExLjA3JSAoODIgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBmdW5jdGlvbiAgICAgICAgICAgeCAzMSwyOTYsODcwIG9wcy9zZWMgwrEwLjk2JSAoODMgcnVucyBzYW1wbGVkKVxuXHRcdCAgICovXG5cdFx0ICB2YXIgdHlwZW9mT2JqID0gdHlwZW9mIG9iajtcblx0XHQgIGlmICh0eXBlb2ZPYmogIT09ICdvYmplY3QnKSB7XG5cdFx0ICAgIHJldHVybiB0eXBlb2ZPYmo7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAgKiBQcmU6XG5cdFx0ICAgKiAgIG51bGwgICAgICAgICAgICAgICB4IDI4LDY0NSw3NjUgb3BzL3NlYyDCsTEuMTclICg4MiBydW5zIHNhbXBsZWQpXG5cdFx0ICAgKiBQb3N0OlxuXHRcdCAgICogICBudWxsICAgICAgICAgICAgICAgeCAzNiw0MjgsOTYyIG9wcy9zZWMgwrExLjM3JSAoODQgcnVucyBzYW1wbGVkKVxuXHRcdCAgICovXG5cdFx0ICBpZiAob2JqID09PSBudWxsKSB7XG5cdFx0ICAgIHJldHVybiAnbnVsbCc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh3aW5kb3cpYGBcblx0XHQgICAqICAtIE5vZGUgPT09IFwiW29iamVjdCBnbG9iYWxdXCJcblx0XHQgICAqICAtIENocm9tZSA9PT0gXCJbb2JqZWN0IGdsb2JhbF1cIlxuXHRcdCAgICogIC0gRmlyZWZveCA9PT0gXCJbb2JqZWN0IFdpbmRvd11cIlxuXHRcdCAgICogIC0gUGhhbnRvbUpTID09PSBcIltvYmplY3QgV2luZG93XVwiXG5cdFx0ICAgKiAgLSBTYWZhcmkgPT09IFwiW29iamVjdCBXaW5kb3ddXCJcblx0XHQgICAqICAtIElFIDExID09PSBcIltvYmplY3QgV2luZG93XVwiXG5cdFx0ICAgKiAgLSBJRSBFZGdlID09PSBcIltvYmplY3QgV2luZG93XVwiXG5cdFx0ICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHRoaXMpYGBcblx0XHQgICAqICAtIENocm9tZSBXb3JrZXIgPT09IFwiW29iamVjdCBnbG9iYWxdXCJcblx0XHQgICAqICAtIEZpcmVmb3ggV29ya2VyID09PSBcIltvYmplY3QgRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGVdXCJcblx0XHQgICAqICAtIFNhZmFyaSBXb3JrZXIgPT09IFwiW29iamVjdCBEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZV1cIlxuXHRcdCAgICogIC0gSUUgMTEgV29ya2VyID09PSBcIltvYmplY3QgV29ya2VyR2xvYmFsU2NvcGVdXCJcblx0XHQgICAqICAtIElFIEVkZ2UgV29ya2VyID09PSBcIltvYmplY3QgV29ya2VyR2xvYmFsU2NvcGVdXCJcblx0XHQgICAqL1xuXHRcdCAgaWYgKG9iaiA9PT0gZ2xvYmFsT2JqZWN0KSB7XG5cdFx0ICAgIHJldHVybiAnZ2xvYmFsJztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICAqIFByZTpcblx0XHQgICAqICAgYXJyYXkgbGl0ZXJhbCAgICAgIHggMiw4ODgsMzUyIG9wcy9zZWMgwrEwLjY3JSAoODIgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogUG9zdDpcblx0XHQgICAqICAgYXJyYXkgbGl0ZXJhbCAgICAgIHggMjIsNDc5LDY1MCBvcHMvc2VjIMKxMC45NiUgKDgxIHJ1bnMgc2FtcGxlZClcblx0XHQgICAqL1xuXHRcdCAgaWYgKFxuXHRcdCAgICBBcnJheS5pc0FycmF5KG9iaikgJiZcblx0XHQgICAgKHN5bWJvbFRvU3RyaW5nVGFnRXhpc3RzID09PSBmYWxzZSB8fCAhKFN5bWJvbC50b1N0cmluZ1RhZyBpbiBvYmopKVxuXHRcdCAgKSB7XG5cdFx0ICAgIHJldHVybiAnQXJyYXknO1xuXHRcdCAgfVxuXG5cdFx0ICAvLyBOb3QgY2FjaGluZyBleGlzdGVuY2Ugb2YgYHdpbmRvd2AgYW5kIHJlbGF0ZWQgcHJvcGVydGllcyBkdWUgdG8gcG90ZW50aWFsXG5cdFx0ICAvLyBmb3IgYHdpbmRvd2AgdG8gYmUgdW5zZXQgYmVmb3JlIHRlc3RzIGluIHF1YXNpLWJyb3dzZXIgZW52aXJvbm1lbnRzLlxuXHRcdCAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnICYmIHdpbmRvdyAhPT0gbnVsbCkge1xuXHRcdCAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Jyb3dzZXJzLmh0bWwjbG9jYXRpb24pXG5cdFx0ICAgICAqIFdoYXRXRyBIVE1MJDcuNy4zIC0gVGhlIGBMb2NhdGlvbmAgaW50ZXJmYWNlXG5cdFx0ICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93LmxvY2F0aW9uKWBgXG5cdFx0ICAgICAqICAtIElFIDw9MTEgPT09IFwiW29iamVjdCBPYmplY3RdXCJcblx0XHQgICAgICogIC0gSUUgRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgICAqL1xuXHRcdCAgICBpZiAodHlwZW9mIHdpbmRvdy5sb2NhdGlvbiA9PT0gJ29iamVjdCcgJiYgb2JqID09PSB3aW5kb3cubG9jYXRpb24pIHtcblx0XHQgICAgICByZXR1cm4gJ0xvY2F0aW9uJztcblx0XHQgICAgfVxuXG5cdFx0ICAgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jZG9jdW1lbnQpXG5cdFx0ICAgICAqIFdoYXRXRyBIVE1MJDMuMS4xIC0gVGhlIGBEb2N1bWVudGAgb2JqZWN0XG5cdFx0ICAgICAqIE5vdGU6IE1vc3QgYnJvd3NlcnMgY3VycmVudGx5IGFkaGVyIHRvIHRoZSBXM0MgRE9NIExldmVsIDIgc3BlY1xuXHRcdCAgICAgKiAgICAgICAoaHR0cHM6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUhUTUwvaHRtbC5odG1sI0lELTI2ODA5MjY4KVxuXHRcdCAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG5cdFx0ICAgICAqICAgICAgIGJvdGggVEQgYW5kIFRIIGVsZW1lbnRzLiBXaGF0V0cgc2VwYXJhdGVzIHRoZXNlLlxuXHRcdCAgICAgKiAgICAgICBXaGF0V0cgSFRNTCBzdGF0ZXM6XG5cdFx0ICAgICAqICAgICAgICAgPiBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCBXaW5kb3cgb2JqZWN0cyBtdXN0IGFsc28gaGF2ZSBhXG5cdFx0ICAgICAqICAgICAgICAgPiB3cml0YWJsZSwgY29uZmlndXJhYmxlLCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lZFxuXHRcdCAgICAgKiAgICAgICAgID4gSFRNTERvY3VtZW50IHdob3NlIHZhbHVlIGlzIHRoZSBEb2N1bWVudCBpbnRlcmZhY2Ugb2JqZWN0LlxuXHRcdCAgICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvY3VtZW50KWBgXG5cdFx0ICAgICAqICAtIENocm9tZSA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuXHRcdCAgICAgKiAgLSBGaXJlZm94ID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG5cdFx0ICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuXHRcdCAgICAgKiAgLSBJRSA8PTEwID09PSBcIltvYmplY3QgRG9jdW1lbnRdXCJcblx0XHQgICAgICogIC0gSUUgMTEgPT09IFwiW29iamVjdCBIVE1MRG9jdW1lbnRdXCJcblx0XHQgICAgICogIC0gSUUgRWRnZSA8PTEzID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG5cdFx0ICAgICAqL1xuXHRcdCAgICBpZiAodHlwZW9mIHdpbmRvdy5kb2N1bWVudCA9PT0gJ29iamVjdCcgJiYgb2JqID09PSB3aW5kb3cuZG9jdW1lbnQpIHtcblx0XHQgICAgICByZXR1cm4gJ0RvY3VtZW50Jztcblx0XHQgICAgfVxuXG5cdFx0ICAgIGlmICh0eXBlb2Ygd2luZG93Lm5hdmlnYXRvciA9PT0gJ29iamVjdCcpIHtcblx0XHQgICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvd2ViYXBwYXBpcy5odG1sI21pbWV0eXBlYXJyYXkpXG5cdFx0ICAgICAgICogV2hhdFdHIEhUTUwkOC42LjEuNSAtIFBsdWdpbnMgLSBJbnRlcmZhY2UgTWltZVR5cGVBcnJheVxuXHRcdCAgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmF2aWdhdG9yLm1pbWVUeXBlcylgYFxuXHRcdCAgICAgICAqICAtIElFIDw9MTAgPT09IFwiW29iamVjdCBNU01pbWVUeXBlc0NvbGxlY3Rpb25dXCJcblx0XHQgICAgICAgKi9cblx0XHQgICAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IubWltZVR5cGVzID09PSAnb2JqZWN0JyAmJlxuXHRcdCAgICAgICAgICBvYmogPT09IHdpbmRvdy5uYXZpZ2F0b3IubWltZVR5cGVzKSB7XG5cdFx0ICAgICAgICByZXR1cm4gJ01pbWVUeXBlQXJyYXknO1xuXHRcdCAgICAgIH1cblxuXHRcdCAgICAgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICAgICAqIChodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS93ZWJhcHBhcGlzLmh0bWwjcGx1Z2luYXJyYXkpXG5cdFx0ICAgICAgICogV2hhdFdHIEhUTUwkOC42LjEuNSAtIFBsdWdpbnMgLSBJbnRlcmZhY2UgUGx1Z2luQXJyYXlcblx0XHQgICAgICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5hdmlnYXRvci5wbHVnaW5zKWBgXG5cdFx0ICAgICAgICogIC0gSUUgPD0xMCA9PT0gXCJbb2JqZWN0IE1TUGx1Z2luc0NvbGxlY3Rpb25dXCJcblx0XHQgICAgICAgKi9cblx0XHQgICAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IucGx1Z2lucyA9PT0gJ29iamVjdCcgJiZcblx0XHQgICAgICAgICAgb2JqID09PSB3aW5kb3cubmF2aWdhdG9yLnBsdWdpbnMpIHtcblx0XHQgICAgICAgIHJldHVybiAnUGx1Z2luQXJyYXknO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXG5cdFx0ICAgIGlmICgodHlwZW9mIHdpbmRvdy5IVE1MRWxlbWVudCA9PT0gJ2Z1bmN0aW9uJyB8fFxuXHRcdCAgICAgICAgdHlwZW9mIHdpbmRvdy5IVE1MRWxlbWVudCA9PT0gJ29iamVjdCcpICYmXG5cdFx0ICAgICAgICBvYmogaW5zdGFuY2VvZiB3aW5kb3cuSFRNTEVsZW1lbnQpIHtcblx0XHQgICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAgICAqIChodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS93ZWJhcHBhcGlzLmh0bWwjcGx1Z2luYXJyYXkpXG5cdFx0ICAgICAgKiBXaGF0V0cgSFRNTCQ0LjQuNCAtIFRoZSBgYmxvY2txdW90ZWAgZWxlbWVudCAtIEludGVyZmFjZSBgSFRNTFF1b3RlRWxlbWVudGBcblx0XHQgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYmxvY2txdW90ZScpKWBgXG5cdFx0ICAgICAgKiAgLSBJRSA8PTEwID09PSBcIltvYmplY3QgSFRNTEJsb2NrRWxlbWVudF1cIlxuXHRcdCAgICAgICovXG5cdFx0ICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnQkxPQ0tRVU9URScpIHtcblx0XHQgICAgICAgIHJldHVybiAnSFRNTFF1b3RlRWxlbWVudCc7XG5cdFx0ICAgICAgfVxuXG5cdFx0ICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG5cdFx0ICAgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2h0bWx0YWJsZWRhdGFjZWxsZWxlbWVudClcblx0XHQgICAgICAgKiBXaGF0V0cgSFRNTCQ0LjkuOSAtIFRoZSBgdGRgIGVsZW1lbnQgLSBJbnRlcmZhY2UgYEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudGBcblx0XHQgICAgICAgKiBOb3RlOiBNb3N0IGJyb3dzZXJzIGN1cnJlbnRseSBhZGhlciB0byB0aGUgVzNDIERPTSBMZXZlbCAyIHNwZWNcblx0XHQgICAgICAgKiAgICAgICAoaHR0cHM6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUhUTUwvaHRtbC5odG1sI0lELTgyOTE1MDc1KVxuXHRcdCAgICAgICAqICAgICAgIHdoaWNoIHN1Z2dlc3RzIHRoYXQgYnJvd3NlcnMgc2hvdWxkIHVzZSBIVE1MVGFibGVDZWxsRWxlbWVudCBmb3Jcblx0XHQgICAgICAgKiAgICAgICBib3RoIFREIGFuZCBUSCBlbGVtZW50cy4gV2hhdFdHIHNlcGFyYXRlcyB0aGVzZS5cblx0XHQgICAgICAgKiBUZXN0OiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGQnKSlcblx0XHQgICAgICAgKiAgLSBDaHJvbWUgPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuXHRcdCAgICAgICAqICAtIEZpcmVmb3ggPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuXHRcdCAgICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxUYWJsZUNlbGxFbGVtZW50XVwiXG5cdFx0ICAgICAgICovXG5cdFx0ICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnVEQnKSB7XG5cdFx0ICAgICAgICByZXR1cm4gJ0hUTUxUYWJsZURhdGFDZWxsRWxlbWVudCc7XG5cdFx0ICAgICAgfVxuXG5cdFx0ICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG5cdFx0ICAgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2h0bWx0YWJsZWhlYWRlcmNlbGxlbGVtZW50KVxuXHRcdCAgICAgICAqIFdoYXRXRyBIVE1MJDQuOS45IC0gVGhlIGB0ZGAgZWxlbWVudCAtIEludGVyZmFjZSBgSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnRgXG5cdFx0ICAgICAgICogTm90ZTogTW9zdCBicm93c2VycyBjdXJyZW50bHkgYWRoZXIgdG8gdGhlIFczQyBET00gTGV2ZWwgMiBzcGVjXG5cdFx0ICAgICAgICogICAgICAgKGh0dHBzOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1IVE1ML2h0bWwuaHRtbCNJRC04MjkxNTA3NSlcblx0XHQgICAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG5cdFx0ICAgICAgICogICAgICAgYm90aCBURCBhbmQgVEggZWxlbWVudHMuIFdoYXRXRyBzZXBhcmF0ZXMgdGhlc2UuXG5cdFx0ICAgICAgICogVGVzdDogT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RoJykpXG5cdFx0ICAgICAgICogIC0gQ2hyb21lID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcblx0XHQgICAgICAgKiAgLSBGaXJlZm94ID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcblx0XHQgICAgICAgKiAgLSBTYWZhcmkgPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuXHRcdCAgICAgICAqL1xuXHRcdCAgICAgIGlmIChvYmoudGFnTmFtZSA9PT0gJ1RIJykge1xuXHRcdCAgICAgICAgcmV0dXJuICdIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudCc7XG5cdFx0ICAgICAgfVxuXHRcdCAgICB9XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICBGbG9hdDY0QXJyYXkgICAgICAgeCA2MjUsNjQ0IG9wcy9zZWMgwrExLjU4JSAoODAgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIEZsb2F0MzJBcnJheSAgICAgICB4IDEsMjc5LDg1MiBvcHMvc2VjIMKxMi45MSUgKDc3IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBVaW50MzJBcnJheSAgICAgICAgeCAxLDE3OCwxODUgb3BzL3NlYyDCsTEuOTUlICg4MyBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgVWludDE2QXJyYXkgICAgICAgIHggMSwwMDgsMzgwIG9wcy9zZWMgwrEyLjI1JSAoODAgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIFVpbnQ4QXJyYXkgICAgICAgICB4IDEsMTI4LDA0MCBvcHMvc2VjIMKxMi4xMSUgKDgxIHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBJbnQzMkFycmF5ICAgICAgICAgeCAxLDE3MCwxMTkgb3BzL3NlYyDCsTIuODglICg4MCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgSW50MTZBcnJheSAgICAgICAgIHggMSwxNzYsMzQ4IG9wcy9zZWMgwrE1Ljc5JSAoODYgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIEludDhBcnJheSAgICAgICAgICB4IDEsMDU4LDcwNyBvcHMvc2VjIMKxNC45NCUgKDc3IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBVaW50OENsYW1wZWRBcnJheSAgeCAxLDExMCw2MzMgb3BzL3NlYyDCsTQuMjAlICg4MCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgRmxvYXQ2NEFycmF5ICAgICAgIHggNywxMDUsNjcxIG9wcy9zZWMgwrExMy40NyUgKDY0IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBGbG9hdDMyQXJyYXkgICAgICAgeCA1LDg4Nyw5MTIgb3BzL3NlYyDCsTEuNDYlICg4MiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgVWludDMyQXJyYXkgICAgICAgIHggNiw0OTEsNjYxIG9wcy9zZWMgwrExLjc2JSAoNzkgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIFVpbnQxNkFycmF5ICAgICAgICB4IDYsNTU5LDc5NSBvcHMvc2VjIMKxMS42NyUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBVaW50OEFycmF5ICAgICAgICAgeCA2LDQ2Myw5NjYgb3BzL3NlYyDCsTEuNDMlICg4NSBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgSW50MzJBcnJheSAgICAgICAgIHggNSw2NDEsODQxIG9wcy9zZWMgwrEzLjQ5JSAoODEgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIEludDE2QXJyYXkgICAgICAgICB4IDYsNTgzLDUxMSBvcHMvc2VjIMKxMS45OCUgKDgwIHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBJbnQ4QXJyYXkgICAgICAgICAgeCA2LDYwNiwwNzggb3BzL3NlYyDCsTEuNzQlICg4MSBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgVWludDhDbGFtcGVkQXJyYXkgIHggNiw2MDIsMjI0IG9wcy9zZWMgwrExLjc3JSAoODMgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIHZhciBzdHJpbmdUYWcgPSAoc3ltYm9sVG9TdHJpbmdUYWdFeGlzdHMgJiYgb2JqW1N5bWJvbC50b1N0cmluZ1RhZ10pO1xuXHRcdCAgaWYgKHR5cGVvZiBzdHJpbmdUYWcgPT09ICdzdHJpbmcnKSB7XG5cdFx0ICAgIHJldHVybiBzdHJpbmdUYWc7XG5cdFx0ICB9XG5cblx0XHQgIHZhciBvYmpQcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICByZWdleCBsaXRlcmFsICAgICAgeCAxLDc3MiwzODUgb3BzL3NlYyDCsTEuODUlICg3NyBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgcmVnZXggY29uc3RydWN0b3IgIHggMiwxNDMsNjM0IG9wcy9zZWMgwrEyLjQ2JSAoNzggcnVucyBzYW1wbGVkKVxuXHRcdCAgKiBQb3N0OlxuXHRcdCAgKiAgIHJlZ2V4IGxpdGVyYWwgICAgICB4IDMsOTI4LDAwOSBvcHMvc2VjIMKxMC42NSUgKDc4IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICByZWdleCBjb25zdHJ1Y3RvciAgeCAzLDkzMSwxMDggb3BzL3NlYyDCsTAuNTglICg4NCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqL1xuXHRcdCAgaWYgKG9ialByb3RvdHlwZSA9PT0gUmVnRXhwLnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1JlZ0V4cCc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICBkYXRlICAgICAgICAgICAgICAgeCAyLDEzMCwwNzQgb3BzL3NlYyDCsTQuNDIlICg2OCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgZGF0ZSAgICAgICAgICAgICAgIHggMyw5NTMsNzc5IG9wcy9zZWMgwrExLjM1JSAoNzcgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIGlmIChvYmpQcm90b3R5cGUgPT09IERhdGUucHJvdG90eXBlKSB7XG5cdFx0ICAgIHJldHVybiAnRGF0ZSc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtcHJvbWlzZS5wcm90b3R5cGUtQEB0b3N0cmluZ3RhZylcblx0XHQgICAqIEVTNiQyNS40LjUuNCAtIFByb21pc2UucHJvdG90eXBlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlByb21pc2VcIjpcblx0XHQgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoUHJvbWlzZS5yZXNvbHZlKCkpYGBcblx0XHQgICAqICAtIENocm9tZSA8PTQ3ID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgKiAgLSBFZGdlIDw9MjAgPT09IFwiW29iamVjdCBPYmplY3RdXCJcblx0XHQgICAqICAtIEZpcmVmb3ggMjktTGF0ZXN0ID09PSBcIltvYmplY3QgUHJvbWlzZV1cIlxuXHRcdCAgICogIC0gU2FmYXJpIDcuMS1MYXRlc3QgPT09IFwiW29iamVjdCBQcm9taXNlXVwiXG5cdFx0ICAgKi9cblx0XHQgIGlmIChwcm9taXNlRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gUHJvbWlzZS5wcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdQcm9taXNlJztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICogUHJlOlxuXHRcdCAgKiAgIHNldCAgICAgICAgICAgICAgICB4IDIsMjIyLDE4NiBvcHMvc2VjIMKxMS4zMSUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICogUG9zdDpcblx0XHQgICogICBzZXQgICAgICAgICAgICAgICAgeCA0LDU0NSw4Nzkgb3BzL3NlYyDCsTEuMTMlICg4MyBydW5zIHNhbXBsZWQpXG5cdFx0ICAqL1xuXHRcdCAgaWYgKHNldEV4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IFNldC5wcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdTZXQnO1xuXHRcdCAgfVxuXG5cdFx0ICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuXHRcdCAgKiBQcmU6XG5cdFx0ICAqICAgbWFwICAgICAgICAgICAgICAgIHggMiwzOTYsODQyIG9wcy9zZWMgwrExLjU5JSAoODEgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiBQb3N0OlxuXHRcdCAgKiAgIG1hcCAgICAgICAgICAgICAgICB4IDQsMTgzLDk0NSBvcHMvc2VjIMKxNi41OSUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICovXG5cdFx0ICBpZiAobWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gTWFwLnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ01hcCc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICB3ZWFrc2V0ICAgICAgICAgICAgeCAxLDMyMywyMjAgb3BzL3NlYyDCsTIuMTclICg3NiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgd2Vha3NldCAgICAgICAgICAgIHggNCwyMzcsNTEwIG9wcy9zZWMgwrEyLjAxJSAoNzcgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIGlmICh3ZWFrU2V0RXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gV2Vha1NldC5wcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdXZWFrU2V0Jztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICogUHJlOlxuXHRcdCAgKiAgIHdlYWttYXAgICAgICAgICAgICB4IDEsNTAwLDI2MCBvcHMvc2VjIMKxMi4wMiUgKDc4IHJ1bnMgc2FtcGxlZClcblx0XHQgICogUG9zdDpcblx0XHQgICogICB3ZWFrbWFwICAgICAgICAgICAgeCAzLDg4MSwzODQgb3BzL3NlYyDCsTEuNDUlICg4MiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqL1xuXHRcdCAgaWYgKHdlYWtNYXBFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBXZWFrTWFwLnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1dlYWtNYXAnO1xuXHRcdCAgfVxuXG5cdFx0ICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLWRhdGF2aWV3LnByb3RvdHlwZS1AQHRvc3RyaW5ndGFnKVxuXHRcdCAgICogRVM2JDI0LjIuNC4yMSAtIERhdGFWaWV3LnByb3RvdHlwZVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJEYXRhVmlld1wiOlxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChuZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDEpKSlgYFxuXHRcdCAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgKi9cblx0XHQgIGlmIChkYXRhVmlld0V4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IERhdGFWaWV3LnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ0RhdGFWaWV3Jztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVjIENvbmZvcm1hbmNlXG5cdFx0ICAgKiAoaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC9pbmRleC5odG1sI3NlYy0lbWFwaXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG5cdFx0ICAgKiBFUzYkMjMuMS41LjIuMiAtICVNYXBJdGVyYXRvclByb3RvdHlwZSVbQEB0b1N0cmluZ1RhZ10gc2hvdWxkIGJlIFwiTWFwIEl0ZXJhdG9yXCI6XG5cdFx0ICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5ldyBNYXAoKS5lbnRyaWVzKCkpYGBcblx0XHQgICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuXHRcdCAgICovXG5cdFx0ICBpZiAobWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gbWFwSXRlcmF0b3JQcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdNYXAgSXRlcmF0b3InO1xuXHRcdCAgfVxuXG5cdFx0ICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLSVzZXRpdGVyYXRvcnByb3RvdHlwZSUtQEB0b3N0cmluZ3RhZylcblx0XHQgICAqIEVTNiQyMy4yLjUuMi4yIC0gJVNldEl0ZXJhdG9yUHJvdG90eXBlJVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJTZXQgSXRlcmF0b3JcIjpcblx0XHQgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmV3IFNldCgpLmVudHJpZXMoKSlgYFxuXHRcdCAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgKi9cblx0XHQgIGlmIChzZXRFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBzZXRJdGVyYXRvclByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1NldCBJdGVyYXRvcic7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJWFycmF5aXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG5cdFx0ICAgKiBFUzYkMjIuMS41LjIuMiAtICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJBcnJheSBJdGVyYXRvclwiOlxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChbXVtTeW1ib2wuaXRlcmF0b3JdKCkpYGBcblx0XHQgICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuXHRcdCAgICovXG5cdFx0ICBpZiAoYXJyYXlJdGVyYXRvckV4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IGFycmF5SXRlcmF0b3JQcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdBcnJheSBJdGVyYXRvcic7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJXN0cmluZ2l0ZXJhdG9ycHJvdG90eXBlJS1AQHRvc3RyaW5ndGFnKVxuXHRcdCAgICogRVM2JDIxLjEuNS4yLjIgLSAlU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlN0cmluZyBJdGVyYXRvclwiOlxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCgnJ1tTeW1ib2wuaXRlcmF0b3JdKCkpYGBcblx0XHQgICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuXHRcdCAgICovXG5cdFx0ICBpZiAoc3RyaW5nSXRlcmF0b3JFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBzdHJpbmdJdGVyYXRvclByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1N0cmluZyBJdGVyYXRvcic7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICBvYmplY3QgZnJvbSBudWxsICAgeCAyLDQyNCwzMjAgb3BzL3NlYyDCsTEuNjclICg3NiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgb2JqZWN0IGZyb20gbnVsbCAgIHggNSw4MzgsMDAwIG9wcy9zZWMgwrEwLjk5JSAoODQgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIGlmIChvYmpQcm90b3R5cGUgPT09IG51bGwpIHtcblx0XHQgICAgcmV0dXJuICdPYmplY3QnO1xuXHRcdCAgfVxuXG5cdFx0ICByZXR1cm4gT2JqZWN0XG5cdFx0ICAgIC5wcm90b3R5cGVcblx0XHQgICAgLnRvU3RyaW5nXG5cdFx0ICAgIC5jYWxsKG9iailcblx0XHQgICAgLnNsaWNlKHRvU3RyaW5nTGVmdFNsaWNlTGVuZ3RoLCB0b1N0cmluZ1JpZ2h0U2xpY2VMZW5ndGgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0eXBlRGV0ZWN0O1xuXG5cdFx0fSkpKTsgXG5cdH0gKHR5cGVEZXRlY3QkMSkpO1xuXHRyZXR1cm4gdHlwZURldGVjdCQxLmV4cG9ydHM7XG59XG5cbnZhciB0eXBlT2Y7XG52YXIgaGFzUmVxdWlyZWRUeXBlT2Y7XG5cbmZ1bmN0aW9uIHJlcXVpcmVUeXBlT2YgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRUeXBlT2YpIHJldHVybiB0eXBlT2Y7XG5cdGhhc1JlcXVpcmVkVHlwZU9mID0gMTtcblxuXHR2YXIgdHlwZSA9IHJlcXVpcmVUeXBlRGV0ZWN0KCk7XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGxvd2VyLWNhc2UgcmVzdWx0IG9mIHJ1bm5pbmcgdHlwZSBmcm9tIHR5cGUtZGV0ZWN0IG9uIHRoZSB2YWx1ZVxuXHQgKiBAcGFyYW0gIHsqfSB2YWx1ZVxuXHQgKiBAcmV0dXJucyB7c3RyaW5nfVxuXHQgKi9cblx0dHlwZU9mID0gZnVuY3Rpb24gdHlwZU9mKHZhbHVlKSB7XG5cdCAgICByZXR1cm4gdHlwZSh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcblx0fTtcblx0cmV0dXJuIHR5cGVPZjtcbn1cblxudmFyIHZhbHVlVG9TdHJpbmdfMTtcbnZhciBoYXNSZXF1aXJlZFZhbHVlVG9TdHJpbmc7XG5cbmZ1bmN0aW9uIHJlcXVpcmVWYWx1ZVRvU3RyaW5nICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkVmFsdWVUb1N0cmluZykgcmV0dXJuIHZhbHVlVG9TdHJpbmdfMTtcblx0aGFzUmVxdWlyZWRWYWx1ZVRvU3RyaW5nID0gMTtcblxuXHQvKipcblx0ICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFsdWVcblx0ICogQHBhcmFtICB7Kn0gdmFsdWVcblx0ICogQHJldHVybnMge3N0cmluZ31cblx0ICovXG5cdGZ1bmN0aW9uIHZhbHVlVG9TdHJpbmcodmFsdWUpIHtcblx0ICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS50b1N0cmluZykge1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAc2lub25qcy9uby1wcm90b3R5cGUtbWV0aG9kcy9uby1wcm90b3R5cGUtbWV0aG9kc1xuXHQgICAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG5cdH1cblxuXHR2YWx1ZVRvU3RyaW5nXzEgPSB2YWx1ZVRvU3RyaW5nO1xuXHRyZXR1cm4gdmFsdWVUb1N0cmluZ18xO1xufVxuXG52YXIgbGliO1xudmFyIGhhc1JlcXVpcmVkTGliO1xuXG5mdW5jdGlvbiByZXF1aXJlTGliICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkTGliKSByZXR1cm4gbGliO1xuXHRoYXNSZXF1aXJlZExpYiA9IDE7XG5cblx0bGliID0ge1xuXHQgICAgZ2xvYmFsOiByZXF1aXJlR2xvYmFsKCksXG5cdCAgICBjYWxsZWRJbk9yZGVyOiByZXF1aXJlQ2FsbGVkSW5PcmRlcigpLFxuXHQgICAgY2xhc3NOYW1lOiByZXF1aXJlQ2xhc3NOYW1lKCksXG5cdCAgICBkZXByZWNhdGVkOiByZXF1aXJlRGVwcmVjYXRlZCgpLFxuXHQgICAgZXZlcnk6IHJlcXVpcmVFdmVyeSgpLFxuXHQgICAgZnVuY3Rpb25OYW1lOiByZXF1aXJlRnVuY3Rpb25OYW1lKCksXG5cdCAgICBvcmRlckJ5Rmlyc3RDYWxsOiByZXF1aXJlT3JkZXJCeUZpcnN0Q2FsbCgpLFxuXHQgICAgcHJvdG90eXBlczogcmVxdWlyZVByb3RvdHlwZXMoKSxcblx0ICAgIHR5cGVPZjogcmVxdWlyZVR5cGVPZigpLFxuXHQgICAgdmFsdWVUb1N0cmluZzogcmVxdWlyZVZhbHVlVG9TdHJpbmcoKSxcblx0fTtcblx0cmV0dXJuIGxpYjtcbn1cblxudmFyIGhhc1JlcXVpcmVkRmFrZVRpbWVyc1NyYztcblxuZnVuY3Rpb24gcmVxdWlyZUZha2VUaW1lcnNTcmMgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRGYWtlVGltZXJzU3JjKSByZXR1cm4gZmFrZVRpbWVyc1NyYztcblx0aGFzUmVxdWlyZWRGYWtlVGltZXJzU3JjID0gMTtcblxuXHRjb25zdCBnbG9iYWxPYmplY3QgPSByZXF1aXJlTGliKCkuZ2xvYmFsO1xuXHRsZXQgdGltZXJzTW9kdWxlLCB0aW1lcnNQcm9taXNlc01vZHVsZTtcblx0aWYgKHR5cGVvZiBfX3ZpdGVzdF9yZXF1aXJlZF9fICE9PSAndW5kZWZpbmVkJykge1xuXHQgICAgdHJ5IHtcblx0ICAgICAgICB0aW1lcnNNb2R1bGUgPSBfX3ZpdGVzdF9yZXF1aXJlZF9fLnRpbWVycztcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAvLyBpZ25vcmVkXG5cdCAgICB9XG5cdCAgICB0cnkge1xuXHQgICAgICAgIHRpbWVyc1Byb21pc2VzTW9kdWxlID0gX192aXRlc3RfcmVxdWlyZWRfXy50aW1lcnNQcm9taXNlcztcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAvLyBpZ25vcmVkXG5cdCAgICB9XG5cdH1cblxuXHQvKipcblx0ICogQHR5cGVkZWYge1wibmV4dEFzeW5jXCIgfCBcIm1hbnVhbFwiIHwgXCJpbnRlcnZhbFwifSBUaWNrTW9kZVxuXHQgKi9cblxuXHQvKipcblx0ICogQHR5cGVkZWYge29iamVjdH0gTmV4dEFzeW5jVGlja01vZGVcblx0ICogQHByb3BlcnR5IHtcIm5leHRBc3luY1wifSBtb2RlXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBAdHlwZWRlZiB7b2JqZWN0fSBNYW51YWxUaWNrTW9kZVxuXHQgKiBAcHJvcGVydHkge1wibWFudWFsXCJ9IG1vZGVcblx0ICovXG5cblx0LyoqXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IEludGVydmFsVGlja01vZGVcblx0ICogQHByb3BlcnR5IHtcImludGVydmFsXCJ9IG1vZGVcblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IFtkZWx0YV1cblx0ICovXG5cblx0LyoqXG5cdCAqIEB0eXBlZGVmIHtJbnRlcnZhbFRpY2tNb2RlIHwgTmV4dEFzeW5jVGlja01vZGUgfCBNYW51YWxUaWNrTW9kZX0gVGltZXJUaWNrTW9kZVxuXHQgKi9cblxuXHQvKipcblx0ICogQHR5cGVkZWYge29iamVjdH0gSWRsZURlYWRsaW5lXG5cdCAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGlkVGltZW91dCAtIHdoZXRoZXIgb3Igbm90IHRoZSBjYWxsYmFjayB3YXMgY2FsbGVkIGJlZm9yZSByZWFjaGluZyB0aGUgb3B0aW9uYWwgdGltZW91dFxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6bnVtYmVyfSB0aW1lUmVtYWluaW5nIC0gYSBmbG9hdGluZy1wb2ludCB2YWx1ZSBwcm92aWRpbmcgYW4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgcmVtYWluaW5nIGluIHRoZSBjdXJyZW50IGlkbGUgcGVyaW9kXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBRdWV1ZXMgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgZHVyaW5nIGEgYnJvd3NlcidzIGlkbGUgcGVyaW9kc1xuXHQgKiBAY2FsbGJhY2sgUmVxdWVzdElkbGVDYWxsYmFja1xuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKElkbGVEZWFkbGluZSl9IGNhbGxiYWNrXG5cdCAqIEBwYXJhbSB7e3RpbWVvdXQ6IG51bWJlcn19IG9wdGlvbnMgLSBhbiBvcHRpb25zIG9iamVjdFxuXHQgKiBAcmV0dXJucyB7bnVtYmVyfSB0aGUgaWRcblx0ICovXG5cblx0LyoqXG5cdCAqIEBjYWxsYmFjayBOZXh0VGlja1xuXHQgKiBAcGFyYW0ge1ZvaWRWYXJBcmdzRnVuY30gY2FsbGJhY2sgLSB0aGUgY2FsbGJhY2sgdG8gcnVuXG5cdCAqIEBwYXJhbSB7Li4uKn0gYXJncyAtIG9wdGlvbmFsIGFyZ3VtZW50cyB0byBjYWxsIHRoZSBjYWxsYmFjayB3aXRoXG5cdCAqIEByZXR1cm5zIHt2b2lkfVxuXHQgKi9cblxuXHQvKipcblx0ICogQGNhbGxiYWNrIFNldEltbWVkaWF0ZVxuXHQgKiBAcGFyYW0ge1ZvaWRWYXJBcmdzRnVuY30gY2FsbGJhY2sgLSB0aGUgY2FsbGJhY2sgdG8gcnVuXG5cdCAqIEBwYXJhbSB7Li4uKn0gYXJncyAtIG9wdGlvbmFsIGFyZ3VtZW50cyB0byBjYWxsIHRoZSBjYWxsYmFjayB3aXRoXG5cdCAqIEByZXR1cm5zIHtOb2RlSW1tZWRpYXRlfVxuXHQgKi9cblxuXHQvKipcblx0ICogQGNhbGxiYWNrIFZvaWRWYXJBcmdzRnVuY1xuXHQgKiBAcGFyYW0gey4uLip9IGNhbGxiYWNrIC0gdGhlIGNhbGxiYWNrIHRvIHJ1blxuXHQgKiBAcmV0dXJucyB7dm9pZH1cblx0ICovXG5cblx0LyoqXG5cdCAqIEB0eXBlZGVmIFJlcXVlc3RBbmltYXRpb25GcmFtZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6dm9pZH0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lXG5cdCAqIEByZXR1cm5zIHtudW1iZXJ9IC0gdGhlIGlkXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBAdHlwZWRlZiBQZXJmb3JtYW5jZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IG51bWJlcn0gbm93XG5cdCAqL1xuXG5cdC8qIGVzbGludC1kaXNhYmxlIGpzZG9jL3JlcXVpcmUtcHJvcGVydHktZGVzY3JpcHRpb24gKi9cblx0LyoqXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IENsb2NrXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBub3cgLSB0aGUgY3VycmVudCB0aW1lXG5cdCAqIEBwcm9wZXJ0eSB7RGF0ZX0gRGF0ZSAtIHRoZSBEYXRlIGNvbnN0cnVjdG9yXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb29wTGltaXQgLSB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGltZXJzIGJlZm9yZSBhc3N1bWluZyBhbiBpbmZpbml0ZSBsb29wXG5cdCAqIEBwcm9wZXJ0eSB7UmVxdWVzdElkbGVDYWxsYmFja30gcmVxdWVzdElkbGVDYWxsYmFja1xuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6dm9pZH0gY2FuY2VsSWRsZUNhbGxiYWNrXG5cdCAqIEBwcm9wZXJ0eSB7c2V0VGltZW91dH0gc2V0VGltZW91dFxuXHQgKiBAcHJvcGVydHkge2NsZWFyVGltZW91dH0gY2xlYXJUaW1lb3V0XG5cdCAqIEBwcm9wZXJ0eSB7TmV4dFRpY2t9IG5leHRUaWNrXG5cdCAqIEBwcm9wZXJ0eSB7cXVldWVNaWNyb3Rhc2t9IHF1ZXVlTWljcm90YXNrXG5cdCAqIEBwcm9wZXJ0eSB7c2V0SW50ZXJ2YWx9IHNldEludGVydmFsXG5cdCAqIEBwcm9wZXJ0eSB7Y2xlYXJJbnRlcnZhbH0gY2xlYXJJbnRlcnZhbFxuXHQgKiBAcHJvcGVydHkge1NldEltbWVkaWF0ZX0gc2V0SW1tZWRpYXRlXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oTm9kZUltbWVkaWF0ZSk6dm9pZH0gY2xlYXJJbW1lZGlhdGVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOm51bWJlcn0gY291bnRUaW1lcnNcblx0ICogQHByb3BlcnR5IHtSZXF1ZXN0QW5pbWF0aW9uRnJhbWV9IHJlcXVlc3RBbmltYXRpb25GcmFtZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6dm9pZH0gY2FuY2VsQW5pbWF0aW9uRnJhbWVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOnZvaWR9IHJ1bk1pY3JvdGFza3Ncblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihzdHJpbmcgfCBudW1iZXIpOiBudW1iZXJ9IHRpY2tcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihzdHJpbmcgfCBudW1iZXIpOiBQcm9taXNlPG51bWJlcj59IHRpY2tBc3luY1xuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IG51bWJlcn0gbmV4dFxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IFByb21pc2U8bnVtYmVyPn0gbmV4dEFzeW5jXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTogbnVtYmVyfSBydW5BbGxcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBudW1iZXJ9IHJ1blRvRnJhbWVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBQcm9taXNlPG51bWJlcj59IHJ1bkFsbEFzeW5jXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTogbnVtYmVyfSBydW5Ub0xhc3Rcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBQcm9taXNlPG51bWJlcj59IHJ1blRvTGFzdEFzeW5jXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTogdm9pZH0gcmVzZXRcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIgfCBEYXRlKTogdm9pZH0gc2V0U3lzdGVtVGltZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6IHZvaWR9IGp1bXBcblx0ICogQHByb3BlcnR5IHtQZXJmb3JtYW5jZX0gcGVyZm9ybWFuY2Vcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXJbXSk6IG51bWJlcltdfSBocnRpbWUgLSBwcm9jZXNzLmhydGltZSAobGVnYWN5KVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IHZvaWR9IHVuaW5zdGFsbCBVbmluc3RhbGwgdGhlIGNsb2NrLlxuXHQgKiBAcHJvcGVydHkge0Z1bmN0aW9uW119IG1ldGhvZHMgLSB0aGUgbWV0aG9kcyB0aGF0IGFyZSBmYWtlZFxuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzaG91bGRDbGVhck5hdGl2ZVRpbWVyc10gaW5oZXJpdGVkIGZyb20gY29uZmlnXG5cdCAqIEBwcm9wZXJ0eSB7e21ldGhvZE5hbWU6c3RyaW5nLCBvcmlnaW5hbDphbnl9W10gfCB1bmRlZmluZWR9IHRpbWVyc01vZHVsZU1ldGhvZHNcblx0ICogQHByb3BlcnR5IHt7bWV0aG9kTmFtZTpzdHJpbmcsIG9yaWdpbmFsOmFueX1bXSB8IHVuZGVmaW5lZH0gdGltZXJzUHJvbWlzZXNNb2R1bGVNZXRob2RzXG5cdCAqIEBwcm9wZXJ0eSB7TWFwPGZ1bmN0aW9uKCk6IHZvaWQsIEFib3J0U2lnbmFsPn0gYWJvcnRMaXN0ZW5lck1hcFxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKFRpbWVyVGlja01vZGUpOiB2b2lkfSBzZXRUaWNrTW9kZVxuXHQgKi9cblx0LyogZXNsaW50LWVuYWJsZSBqc2RvYy9yZXF1aXJlLXByb3BlcnR5LWRlc2NyaXB0aW9uICovXG5cblx0LyoqXG5cdCAqIENvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciB0aGUgYGluc3RhbGxgIG1ldGhvZC5cblx0ICogQHR5cGVkZWYge29iamVjdH0gQ29uZmlnXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfERhdGV9IFtub3ddIGEgbnVtYmVyIChpbiBtaWxsaXNlY29uZHMpIG9yIGEgRGF0ZSBvYmplY3QgKGRlZmF1bHQgZXBvY2gpXG5cdCAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IFt0b0Zha2VdIG5hbWVzIG9mIHRoZSBtZXRob2RzIHRoYXQgc2hvdWxkIGJlIGZha2VkLlxuXHQgKiBAcHJvcGVydHkge251bWJlcn0gW2xvb3BMaW1pdF0gdGhlIG1heGltdW0gbnVtYmVyIG9mIHRpbWVycyB0aGF0IHdpbGwgYmUgcnVuIHdoZW4gY2FsbGluZyBydW5BbGwoKVxuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzaG91bGRBZHZhbmNlVGltZV0gdGVsbHMgRmFrZVRpbWVycyB0byBpbmNyZW1lbnQgbW9ja2VkIHRpbWUgYXV0b21hdGljYWxseSAoZGVmYXVsdCBmYWxzZSlcblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IFthZHZhbmNlVGltZURlbHRhXSBpbmNyZW1lbnQgbW9ja2VkIHRpbWUgZXZlcnkgPDxhZHZhbmNlVGltZURlbHRhPj4gbXMgKGRlZmF1bHQ6IDIwbXMpXG5cdCAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Nob3VsZENsZWFyTmF0aXZlVGltZXJzXSBmb3J3YXJkcyBjbGVhciB0aW1lciBjYWxscyB0byBuYXRpdmUgZnVuY3Rpb25zIGlmIHRoZXkgYXJlIG5vdCBmYWtlcyAoZGVmYXVsdDogZmFsc2UpXG5cdCAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2lnbm9yZU1pc3NpbmdUaW1lcnNdIGRlZmF1bHQgaXMgZmFsc2UsIG1lYW5pbmcgYXNraW5nIHRvIGZha2UgdGltZXJzIHRoYXQgYXJlIG5vdCBwcmVzZW50IHdpbGwgdGhyb3cgYW4gZXJyb3Jcblx0ICovXG5cblx0LyogZXNsaW50LWRpc2FibGUganNkb2MvcmVxdWlyZS1wcm9wZXJ0eS1kZXNjcmlwdGlvbiAqL1xuXHQvKipcblx0ICogVGhlIGludGVybmFsIHN0cnVjdHVyZSB0byBkZXNjcmliZSBhIHNjaGVkdWxlZCBmYWtlIHRpbWVyXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IFRpbWVyXG5cdCAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGZ1bmNcblx0ICogQHByb3BlcnR5IHsqW119IGFyZ3Ncblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IGRlbGF5XG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjYWxsQXRcblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IGNyZWF0ZWRBdFxuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IGltbWVkaWF0ZVxuXHQgKiBAcHJvcGVydHkge251bWJlcn0gaWRcblx0ICogQHByb3BlcnR5IHtFcnJvcn0gW2Vycm9yXVxuXHQgKi9cblxuXHQvKipcblx0ICogQSBOb2RlIHRpbWVyXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IE5vZGVJbW1lZGlhdGVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBib29sZWFufSBoYXNSZWZcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBOb2RlSW1tZWRpYXRlfSByZWZcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBOb2RlSW1tZWRpYXRlfSB1bnJlZlxuXHQgKi9cblx0LyogZXNsaW50LWVuYWJsZSBqc2RvYy9yZXF1aXJlLXByb3BlcnR5LWRlc2NyaXB0aW9uICovXG5cblx0LyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuXG5cdC8qKlxuXHQgKiBNb2NrcyBhdmFpbGFibGUgZmVhdHVyZXMgaW4gdGhlIHNwZWNpZmllZCBnbG9iYWwgbmFtZXNwYWNlLlxuXHQgKiBAcGFyYW0geyp9IF9nbG9iYWwgTmFtZXNwYWNlIHRvIG1vY2sgKGUuZy4gYHdpbmRvd2ApXG5cdCAqIEByZXR1cm5zIHtGYWtlVGltZXJzfVxuXHQgKi9cblx0ZnVuY3Rpb24gd2l0aEdsb2JhbChfZ2xvYmFsKSB7XG5cdCAgICBjb25zdCBtYXhUaW1lb3V0ID0gTWF0aC5wb3coMiwgMzEpIC0gMTsgLy9zZWUgaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jYWJzdHJhY3Qtb3BkZWYtY29udmVydHRvaW50XG5cdCAgICBjb25zdCBpZENvdW50ZXJTdGFydCA9IDFlMTI7IC8vIGFyYml0cmFyaWx5IGxhcmdlIG51bWJlciB0byBhdm9pZCBjb2xsaXNpb25zIHdpdGggbmF0aXZlIHRpbWVyIElEc1xuXHQgICAgY29uc3QgTk9PUCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXHQgICAgfTtcblx0ICAgIGNvbnN0IE5PT1BfQVJSQVkgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIFtdO1xuXHQgICAgfTtcblx0ICAgIGNvbnN0IGlzUHJlc2VudCA9IHt9O1xuXHQgICAgbGV0IHRpbWVvdXRSZXN1bHQsXG5cdCAgICAgICAgYWRkVGltZXJSZXR1cm5zT2JqZWN0ID0gZmFsc2U7XG5cblx0ICAgIGlmIChfZ2xvYmFsLnNldFRpbWVvdXQpIHtcblx0ICAgICAgICBpc1ByZXNlbnQuc2V0VGltZW91dCA9IHRydWU7XG5cdCAgICAgICAgdGltZW91dFJlc3VsdCA9IF9nbG9iYWwuc2V0VGltZW91dChOT09QLCAwKTtcblx0ICAgICAgICBhZGRUaW1lclJldHVybnNPYmplY3QgPSB0eXBlb2YgdGltZW91dFJlc3VsdCA9PT0gXCJvYmplY3RcIjtcblx0ICAgIH1cblx0ICAgIGlzUHJlc2VudC5jbGVhclRpbWVvdXQgPSBCb29sZWFuKF9nbG9iYWwuY2xlYXJUaW1lb3V0KTtcblx0ICAgIGlzUHJlc2VudC5zZXRJbnRlcnZhbCA9IEJvb2xlYW4oX2dsb2JhbC5zZXRJbnRlcnZhbCk7XG5cdCAgICBpc1ByZXNlbnQuY2xlYXJJbnRlcnZhbCA9IEJvb2xlYW4oX2dsb2JhbC5jbGVhckludGVydmFsKTtcblx0ICAgIGlzUHJlc2VudC5ocnRpbWUgPVxuXHQgICAgICAgIF9nbG9iYWwucHJvY2VzcyAmJiB0eXBlb2YgX2dsb2JhbC5wcm9jZXNzLmhydGltZSA9PT0gXCJmdW5jdGlvblwiO1xuXHQgICAgaXNQcmVzZW50LmhydGltZUJpZ2ludCA9XG5cdCAgICAgICAgaXNQcmVzZW50LmhydGltZSAmJiB0eXBlb2YgX2dsb2JhbC5wcm9jZXNzLmhydGltZS5iaWdpbnQgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGlzUHJlc2VudC5uZXh0VGljayA9XG5cdCAgICAgICAgX2dsb2JhbC5wcm9jZXNzICYmIHR5cGVvZiBfZ2xvYmFsLnByb2Nlc3MubmV4dFRpY2sgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGNvbnN0IHV0aWxQcm9taXNpZnkgPSBfZ2xvYmFsLnByb2Nlc3MgJiYgX2dsb2JhbC5fX3ZpdGVzdF9yZXF1aXJlZF9fICYmIF9nbG9iYWwuX192aXRlc3RfcmVxdWlyZWRfXy51dGlsLnByb21pc2lmeTtcblx0ICAgIGlzUHJlc2VudC5wZXJmb3JtYW5jZSA9XG5cdCAgICAgICAgX2dsb2JhbC5wZXJmb3JtYW5jZSAmJiB0eXBlb2YgX2dsb2JhbC5wZXJmb3JtYW5jZS5ub3cgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGNvbnN0IGhhc1BlcmZvcm1hbmNlUHJvdG90eXBlID1cblx0ICAgICAgICBfZ2xvYmFsLlBlcmZvcm1hbmNlICYmXG5cdCAgICAgICAgKHR5cGVvZiBfZ2xvYmFsLlBlcmZvcm1hbmNlKS5tYXRjaCgvXihmdW5jdGlvbnxvYmplY3QpJC8pO1xuXHQgICAgY29uc3QgaGFzUGVyZm9ybWFuY2VDb25zdHJ1Y3RvclByb3RvdHlwZSA9XG5cdCAgICAgICAgX2dsb2JhbC5wZXJmb3JtYW5jZSAmJlxuXHQgICAgICAgIF9nbG9iYWwucGVyZm9ybWFuY2UuY29uc3RydWN0b3IgJiZcblx0ICAgICAgICBfZ2xvYmFsLnBlcmZvcm1hbmNlLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcblx0ICAgIGlzUHJlc2VudC5xdWV1ZU1pY3JvdGFzayA9IF9nbG9iYWwuaGFzT3duUHJvcGVydHkoXCJxdWV1ZU1pY3JvdGFza1wiKTtcblx0ICAgIGlzUHJlc2VudC5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPVxuXHQgICAgICAgIF9nbG9iYWwucmVxdWVzdEFuaW1hdGlvbkZyYW1lICYmXG5cdCAgICAgICAgdHlwZW9mIF9nbG9iYWwucmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSBcImZ1bmN0aW9uXCI7XG5cdCAgICBpc1ByZXNlbnQuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPVxuXHQgICAgICAgIF9nbG9iYWwuY2FuY2VsQW5pbWF0aW9uRnJhbWUgJiZcblx0ICAgICAgICB0eXBlb2YgX2dsb2JhbC5jYW5jZWxBbmltYXRpb25GcmFtZSA9PT0gXCJmdW5jdGlvblwiO1xuXHQgICAgaXNQcmVzZW50LnJlcXVlc3RJZGxlQ2FsbGJhY2sgPVxuXHQgICAgICAgIF9nbG9iYWwucmVxdWVzdElkbGVDYWxsYmFjayAmJlxuXHQgICAgICAgIHR5cGVvZiBfZ2xvYmFsLnJlcXVlc3RJZGxlQ2FsbGJhY2sgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGlzUHJlc2VudC5jYW5jZWxJZGxlQ2FsbGJhY2tQcmVzZW50ID1cblx0ICAgICAgICBfZ2xvYmFsLmNhbmNlbElkbGVDYWxsYmFjayAmJlxuXHQgICAgICAgIHR5cGVvZiBfZ2xvYmFsLmNhbmNlbElkbGVDYWxsYmFjayA9PT0gXCJmdW5jdGlvblwiO1xuXHQgICAgaXNQcmVzZW50LnNldEltbWVkaWF0ZSA9XG5cdCAgICAgICAgX2dsb2JhbC5zZXRJbW1lZGlhdGUgJiYgdHlwZW9mIF9nbG9iYWwuc2V0SW1tZWRpYXRlID09PSBcImZ1bmN0aW9uXCI7XG5cdCAgICBpc1ByZXNlbnQuY2xlYXJJbW1lZGlhdGUgPVxuXHQgICAgICAgIF9nbG9iYWwuY2xlYXJJbW1lZGlhdGUgJiYgdHlwZW9mIF9nbG9iYWwuY2xlYXJJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGlzUHJlc2VudC5JbnRsID0gX2dsb2JhbC5JbnRsICYmIHR5cGVvZiBfZ2xvYmFsLkludGwgPT09IFwib2JqZWN0XCI7XG5cblx0ICAgIGlmIChfZ2xvYmFsLmNsZWFyVGltZW91dCkge1xuXHQgICAgICAgIF9nbG9iYWwuY2xlYXJUaW1lb3V0KHRpbWVvdXRSZXN1bHQpO1xuXHQgICAgfVxuXG5cdCAgICBjb25zdCBOYXRpdmVEYXRlID0gX2dsb2JhbC5EYXRlO1xuXHQgICAgY29uc3QgTmF0aXZlSW50bCA9IGlzUHJlc2VudC5JbnRsXG5cdCAgICAgICAgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhcblx0ICAgICAgICAgICAgICBPYmplY3QuY3JlYXRlKG51bGwpLFxuXHQgICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKF9nbG9iYWwuSW50bCksXG5cdCAgICAgICAgICApXG5cdCAgICAgICAgOiB1bmRlZmluZWQ7XG5cdCAgICBsZXQgdW5pcXVlVGltZXJJZCA9IGlkQ291bnRlclN0YXJ0O1xuXG5cdCAgICBpZiAoTmF0aXZlRGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuXHQgICAgICAgICAgICBcIlRoZSBnbG9iYWwgc2NvcGUgZG9lc24ndCBoYXZlIGEgYERhdGVgIG9iamVjdFwiICtcblx0ICAgICAgICAgICAgICAgIFwiIChzZWUgaHR0cHM6Ly9naXRodWIuY29tL3Npbm9uanMvc2lub24vaXNzdWVzLzE4NTIjaXNzdWVjb21tZW50LTQxOTYyMjc4MClcIixcblx0ICAgICAgICApO1xuXHQgICAgfVxuXHQgICAgaXNQcmVzZW50LkRhdGUgPSB0cnVlO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFRoZSBQZXJmb3JtYW5jZUVudHJ5IG9iamVjdCBlbmNhcHN1bGF0ZXMgYSBzaW5nbGUgcGVyZm9ybWFuY2UgbWV0cmljXG5cdCAgICAgKiB0aGF0IGlzIHBhcnQgb2YgdGhlIGJyb3dzZXIncyBwZXJmb3JtYW5jZSB0aW1lbGluZS5cblx0ICAgICAqXG5cdCAgICAgKiBUaGlzIGlzIGFuIG9iamVjdCByZXR1cm5lZCBieSB0aGUgYG1hcmtgIGFuZCBgbWVhc3VyZWAgbWV0aG9kcyBvbiB0aGUgUGVyZm9ybWFuY2UgcHJvdG90eXBlXG5cdCAgICAgKi9cblx0ICAgIGNsYXNzIEZha2VQZXJmb3JtYW5jZUVudHJ5IHtcblx0ICAgICAgICBjb25zdHJ1Y3RvcihuYW1lLCBlbnRyeVR5cGUsIHN0YXJ0VGltZSwgZHVyYXRpb24pIHtcblx0ICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcblx0ICAgICAgICAgICAgdGhpcy5lbnRyeVR5cGUgPSBlbnRyeVR5cGU7XG5cdCAgICAgICAgICAgIHRoaXMuc3RhcnRUaW1lID0gc3RhcnRUaW1lO1xuXHQgICAgICAgICAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgdG9KU09OKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoeyAuLi50aGlzIH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtXG5cdCAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gaXNOdW1iZXJGaW5pdGUobnVtKSB7XG5cdCAgICAgICAgaWYgKE51bWJlci5pc0Zpbml0ZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG51bSk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmV0dXJuIGlzRmluaXRlKG51bSk7XG5cdCAgICB9XG5cblx0ICAgIGxldCBpc05lYXJJbmZpbml0ZUxpbWl0ID0gZmFsc2U7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpXG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGNoZWNrSXNOZWFySW5maW5pdGVMaW1pdChjbG9jaywgaSkge1xuXHQgICAgICAgIGlmIChjbG9jay5sb29wTGltaXQgJiYgaSA9PT0gY2xvY2subG9vcExpbWl0IC0gMSkge1xuXHQgICAgICAgICAgICBpc05lYXJJbmZpbml0ZUxpbWl0ID0gdHJ1ZTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICpcblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gcmVzZXRJc05lYXJJbmZpbml0ZUxpbWl0KCkge1xuXHQgICAgICAgIGlzTmVhckluZmluaXRlTGltaXQgPSBmYWxzZTtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBQYXJzZSBzdHJpbmdzIGxpa2UgXCIwMToxMDowMFwiIChtZWFuaW5nIDEgaG91ciwgMTAgbWludXRlcywgMCBzZWNvbmRzKSBpbnRvXG5cdCAgICAgKiBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLiBUaGlzIGlzIHVzZWQgdG8gc3VwcG9ydCBodW1hbi1yZWFkYWJsZSBzdHJpbmdzIHBhc3NlZFxuXHQgICAgICogdG8gY2xvY2sudGljaygpXG5cdCAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG5cdCAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBwYXJzZVRpbWUoc3RyKSB7XG5cdCAgICAgICAgaWYgKCFzdHIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY29uc3Qgc3RyaW5ncyA9IHN0ci5zcGxpdChcIjpcIik7XG5cdCAgICAgICAgY29uc3QgbCA9IHN0cmluZ3MubGVuZ3RoO1xuXHQgICAgICAgIGxldCBpID0gbDtcblx0ICAgICAgICBsZXQgbXMgPSAwO1xuXHQgICAgICAgIGxldCBwYXJzZWQ7XG5cblx0ICAgICAgICBpZiAobCA+IDMgfHwgIS9eKFxcZFxcZDopezAsMn1cXGRcXGQ/JC8udGVzdChzdHIpKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcblx0ICAgICAgICAgICAgICAgIFwidGljayBvbmx5IHVuZGVyc3RhbmRzIG51bWJlcnMsICdtOnMnIGFuZCAnaDptOnMnLiBFYWNoIHBhcnQgbXVzdCBiZSB0d28gZGlnaXRzXCIsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgd2hpbGUgKGktLSkge1xuXHQgICAgICAgICAgICBwYXJzZWQgPSBwYXJzZUludChzdHJpbmdzW2ldLCAxMCk7XG5cblx0ICAgICAgICAgICAgaWYgKHBhcnNlZCA+PSA2MCkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRpbWUgJHtzdHJ9YCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBtcyArPSBwYXJzZWQgKiBNYXRoLnBvdyg2MCwgbCAtIGkgLSAxKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gbXMgKiAxMDAwO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEdldCB0aGUgZGVjaW1hbCBwYXJ0IG9mIHRoZSBtaWxsaXNlY29uZCB2YWx1ZSBhcyBuYW5vc2Vjb25kc1xuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IG1zRmxvYXQgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHNcblx0ICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IGFuIGludGVnZXIgbnVtYmVyIG9mIG5hbm9zZWNvbmRzIGluIHRoZSByYW5nZSBbMCwxZTYpXG5cdCAgICAgKlxuXHQgICAgICogRXhhbXBsZTogbmFub1JlbWFpbmVyKDEyMy40NTY3ODkpIC0+IDQ1Njc4OVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBuYW5vUmVtYWluZGVyKG1zRmxvYXQpIHtcblx0ICAgICAgICBjb25zdCBtb2R1bG8gPSAxZTY7XG5cdCAgICAgICAgY29uc3QgcmVtYWluZGVyID0gKG1zRmxvYXQgKiAxZTYpICUgbW9kdWxvO1xuXHQgICAgICAgIGNvbnN0IHBvc2l0aXZlUmVtYWluZGVyID1cblx0ICAgICAgICAgICAgcmVtYWluZGVyIDwgMCA/IHJlbWFpbmRlciArIG1vZHVsbyA6IHJlbWFpbmRlcjtcblxuXHQgICAgICAgIHJldHVybiBNYXRoLmZsb29yKHBvc2l0aXZlUmVtYWluZGVyKTtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBVc2VkIHRvIGdyb2sgdGhlIGBub3dgIHBhcmFtZXRlciB0byBjcmVhdGVDbG9jay5cblx0ICAgICAqIEBwYXJhbSB7RGF0ZXxudW1iZXJ9IGVwb2NoIHRoZSBzeXN0ZW0gdGltZVxuXHQgICAgICogQHJldHVybnMge251bWJlcn1cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gZ2V0RXBvY2goZXBvY2gpIHtcblx0ICAgICAgICBpZiAoIWVwb2NoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAwO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAodHlwZW9mIGVwb2NoLmdldFRpbWUgPT09IFwiZnVuY3Rpb25cIikge1xuXHQgICAgICAgICAgICByZXR1cm4gZXBvY2guZ2V0VGltZSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAodHlwZW9mIGVwb2NoID09PSBcIm51bWJlclwiKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBlcG9jaDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm5vdyBzaG91bGQgYmUgbWlsbGlzZWNvbmRzIHNpbmNlIFVOSVggZXBvY2hcIik7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21cblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0b1xuXHQgICAgICogQHBhcmFtIHtUaW1lcn0gdGltZXJcblx0ICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBpblJhbmdlKGZyb20sIHRvLCB0aW1lcikge1xuXHQgICAgICAgIHJldHVybiB0aW1lciAmJiB0aW1lci5jYWxsQXQgPj0gZnJvbSAmJiB0aW1lci5jYWxsQXQgPD0gdG87XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEBwYXJhbSB7VGltZXJ9IGpvYlxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBnZXRJbmZpbml0ZUxvb3BFcnJvcihjbG9jaywgam9iKSB7XG5cdCAgICAgICAgY29uc3QgaW5maW5pdGVMb29wRXJyb3IgPSBuZXcgRXJyb3IoXG5cdCAgICAgICAgICAgIGBBYm9ydGluZyBhZnRlciBydW5uaW5nICR7Y2xvY2subG9vcExpbWl0fSB0aW1lcnMsIGFzc3VtaW5nIGFuIGluZmluaXRlIGxvb3AhYCxcblx0ICAgICAgICApO1xuXG5cdCAgICAgICAgaWYgKCFqb2IuZXJyb3IpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGluZmluaXRlTG9vcEVycm9yO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIHBhdHRlcm4gbmV2ZXIgbWF0Y2hlZCBpbiBOb2RlXG5cdCAgICAgICAgY29uc3QgY29tcHV0ZWRUYXJnZXRQYXR0ZXJuID0gL3RhcmdldFxcLipbPHwofFtdLio/Wz58XFxdfCldXFxzKi87XG5cdCAgICAgICAgbGV0IGNsb2NrTWV0aG9kUGF0dGVybiA9IG5ldyBSZWdFeHAoXG5cdCAgICAgICAgICAgIFN0cmluZyhPYmplY3Qua2V5cyhjbG9jaykuam9pbihcInxcIikpLFxuXHQgICAgICAgICk7XG5cblx0ICAgICAgICBpZiAoYWRkVGltZXJSZXR1cm5zT2JqZWN0KSB7XG5cdCAgICAgICAgICAgIC8vIG5vZGUuanMgZW52aXJvbm1lbnRcblx0ICAgICAgICAgICAgY2xvY2tNZXRob2RQYXR0ZXJuID0gbmV3IFJlZ0V4cChcblx0ICAgICAgICAgICAgICAgIGBcXFxccythdCAoT2JqZWN0XFxcXC4pPyg/OiR7T2JqZWN0LmtleXMoY2xvY2spLmpvaW4oXCJ8XCIpfSlcXFxccytgLFxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGxldCBtYXRjaGVkTGluZUluZGV4ID0gLTE7XG5cdCAgICAgICAgam9iLmVycm9yLnN0YWNrLnNwbGl0KFwiXFxuXCIpLnNvbWUoZnVuY3Rpb24gKGxpbmUsIGkpIHtcblx0ICAgICAgICAgICAgLy8gSWYgd2UndmUgbWF0Y2hlZCBhIGNvbXB1dGVkIHRhcmdldCBsaW5lIChlLmcuIHNldFRpbWVvdXQpIHRoZW4gd2Vcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgbmVlZCB0byBsb29rIGFueSBmdXJ0aGVyLiBSZXR1cm4gdHJ1ZSB0byBzdG9wIGl0ZXJhdGluZy5cblx0ICAgICAgICAgICAgY29uc3QgbWF0Y2hlZENvbXB1dGVkVGFyZ2V0ID0gbGluZS5tYXRjaChjb21wdXRlZFRhcmdldFBhdHRlcm4pO1xuXHQgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cblx0ICAgICAgICAgICAgaWYgKG1hdGNoZWRDb21wdXRlZFRhcmdldCkge1xuXHQgICAgICAgICAgICAgICAgbWF0Y2hlZExpbmVJbmRleCA9IGk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElmIHdlJ3ZlIG1hdGNoZWQgYSBjbG9jayBtZXRob2QgbGluZSwgdGhlbiB0aGVyZSBtYXkgc3RpbGwgYmVcblx0ICAgICAgICAgICAgLy8gb3RoZXJzIGZ1cnRoZXIgZG93biB0aGUgdHJhY2UuIFJldHVybiBmYWxzZSB0byBrZWVwIGl0ZXJhdGluZy5cblx0ICAgICAgICAgICAgY29uc3QgbWF0Y2hlZENsb2NrTWV0aG9kID0gbGluZS5tYXRjaChjbG9ja01ldGhvZFBhdHRlcm4pO1xuXHQgICAgICAgICAgICBpZiAobWF0Y2hlZENsb2NrTWV0aG9kKSB7XG5cdCAgICAgICAgICAgICAgICBtYXRjaGVkTGluZUluZGV4ID0gaTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElmIHdlIGhhdmVuJ3QgbWF0Y2hlZCBhbnl0aGluZyBvbiB0aGlzIGxpbmUsIGJ1dCB3ZSBtYXRjaGVkXG5cdCAgICAgICAgICAgIC8vIHByZXZpb3VzbHkgYW5kIHNldCB0aGUgbWF0Y2hlZCBsaW5lIGluZGV4LCB0aGVuIHdlIGNhbiBzdG9wLlxuXHQgICAgICAgICAgICAvLyBJZiB3ZSBoYXZlbid0IG1hdGNoZWQgcHJldmlvdXNseSwgdGhlbiB3ZSBzaG91bGQga2VlcCBpdGVyYXRpbmcuXG5cdCAgICAgICAgICAgIHJldHVybiBtYXRjaGVkTGluZUluZGV4ID49IDA7XG5cdCAgICAgICAgfSk7XG5cblx0ICAgICAgICBjb25zdCBzdGFjayA9IGAke2luZmluaXRlTG9vcEVycm9yfVxcbiR7am9iLnR5cGUgfHwgXCJNaWNyb3Rhc2tcIn0gLSAke1xuXHQgICAgICAgICAgICBqb2IuZnVuYy5uYW1lIHx8IFwiYW5vbnltb3VzXCJcblx0ICAgICAgICB9XFxuJHtqb2IuZXJyb3Iuc3RhY2tcblx0ICAgICAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG5cdCAgICAgICAgICAgIC5zbGljZShtYXRjaGVkTGluZUluZGV4ICsgMSlcblx0ICAgICAgICAgICAgLmpvaW4oXCJcXG5cIil9YDtcblxuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbmZpbml0ZUxvb3BFcnJvciwgXCJzdGFja1wiLCB7XG5cdCAgICAgICAgICAgICAgICB2YWx1ZTogc3RhY2ssXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgLy8gbm9vcFxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBpbmZpbml0ZUxvb3BFcnJvcjtcblx0ICAgIH1cblxuXHQgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlRGF0ZSgpIHtcblx0ICAgICAgICBjbGFzcyBDbG9ja0RhdGUgZXh0ZW5kcyBOYXRpdmVEYXRlIHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ZWFyXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtb250aFxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gZGF0ZVxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gaG91clxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbWludXRlXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzZWNvbmRcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG1zXG5cdCAgICAgICAgICAgICAqIEByZXR1cm5zIHZvaWRcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuXHQgICAgICAgICAgICBjb25zdHJ1Y3Rvcih5ZWFyLCBtb250aCwgZGF0ZSwgaG91ciwgbWludXRlLCBzZWNvbmQsIG1zKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBEZWZlbnNpdmUgYW5kIHZlcmJvc2UgdG8gYXZvaWQgcG90ZW50aWFsIGhhcm0gaW4gcGFzc2luZ1xuXHQgICAgICAgICAgICAgICAgLy8gZXhwbGljaXQgdW5kZWZpbmVkIHdoZW4gdXNlciBkb2VzIG5vdCBwYXNzIGFyZ3VtZW50XG5cdCAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1cGVyKENsb2NrRGF0ZS5jbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAvLyBlbnN1cmVzIGlkZW50aXR5IGNoZWNrcyB1c2luZyB0aGUgY29uc3RydWN0b3IgcHJvcCBzdGlsbCB3b3Jrc1xuXHQgICAgICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgaGF2ZSBubyBvdGhlciBmdW5jdGlvbmFsIGVmZmVjdFxuXHQgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwiY29uc3RydWN0b3JcIiwge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBOYXRpdmVEYXRlLFxuXHQgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBzdGF0aWMgW1N5bWJvbC5oYXNJbnN0YW5jZV0oaW5zdGFuY2UpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZSBpbnN0YW5jZW9mIE5hdGl2ZURhdGU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICBDbG9ja0RhdGUuaXNGYWtlID0gdHJ1ZTtcblxuXHQgICAgICAgIGlmIChOYXRpdmVEYXRlLm5vdykge1xuXHQgICAgICAgICAgICBDbG9ja0RhdGUubm93ID0gZnVuY3Rpb24gbm93KCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIENsb2NrRGF0ZS5jbG9jay5ub3c7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKE5hdGl2ZURhdGUudG9Tb3VyY2UpIHtcblx0ICAgICAgICAgICAgQ2xvY2tEYXRlLnRvU291cmNlID0gZnVuY3Rpb24gdG9Tb3VyY2UoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gTmF0aXZlRGF0ZS50b1NvdXJjZSgpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIENsb2NrRGF0ZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gTmF0aXZlRGF0ZS50b1N0cmluZygpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICAvLyBub2luc3BlY3Rpb24gVW5uZWNlc3NhcnlMb2NhbFZhcmlhYmxlSlNcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBIG5vcm1hbCBDbGFzcyBjb25zdHJ1Y3RvciBjYW5ub3QgYmUgY2FsbGVkIHdpdGhvdXQgYG5ld2AsIGJ1dCBEYXRlIGNhbiwgc28gd2UgbmVlZFxuXHQgICAgICAgICAqIHRvIHdyYXAgaXQgaW4gYSBQcm94eSBpbiBvcmRlciB0byBlbnN1cmUgdGhpcyBmdW5jdGlvbmFsaXR5IG9mIERhdGUgaXMga2VwdCBpbnRhY3Rcblx0ICAgICAgICAgKiBAdHlwZSB7Q2xvY2tEYXRlfVxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbnN0IENsb2NrRGF0ZVByb3h5ID0gbmV3IFByb3h5KENsb2NrRGF0ZSwge1xuXHQgICAgICAgICAgICAvLyBoYW5kbGVyIGZvciBbW0NhbGxdXSBpbnZvY2F0aW9ucyAoaS5lLiBub3QgdXNpbmcgYG5ld2ApXG5cdCAgICAgICAgICAgIGFwcGx5KCkge1xuXHQgICAgICAgICAgICAgICAgLy8gdGhlIERhdGUgY29uc3RydWN0b3IgY2FsbGVkIGFzIGEgZnVuY3Rpb24sIHJlZiBFY21hLTI2MiBFZGl0aW9uIDUuMSwgc2VjdGlvbiAxNS45LjIuXG5cdCAgICAgICAgICAgICAgICAvLyBUaGlzIHJlbWFpbnMgc28gaW4gdGhlIDEwdGggZWRpdGlvbiBvZiAyMDE5IGFzIHdlbGwuXG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENsb2NrRGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIFwiQSBQcm94eSBzaG91bGQgb25seSBjYXB0dXJlIGBuZXdgIGNhbGxzIHdpdGggdGhlIGBjb25zdHJ1Y3RgIGhhbmRsZXIuIFRoaXMgaXMgbm90IHN1cHBvc2VkIHRvIGJlIHBvc3NpYmxlLCBzbyBjaGVjayB0aGUgbG9naWMuXCIsXG5cdCAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVEYXRlKENsb2NrRGF0ZS5jbG9jay5ub3cpLnRvU3RyaW5nKCk7XG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgfSk7XG5cblx0ICAgICAgICByZXR1cm4gQ2xvY2tEYXRlUHJveHk7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogTWlycm9yIEludGwgYnkgZGVmYXVsdCBvbiBvdXIgZmFrZSBpbXBsZW1lbnRhdGlvblxuXHQgICAgICpcblx0ICAgICAqIE1vc3Qgb2YgdGhlIHByb3BlcnRpZXMgYXJlIHRoZSBvcmlnaW5hbCBuYXRpdmUgb25lcyxcblx0ICAgICAqIGJ1dCB3ZSBuZWVkIHRvIHRha2UgY29udHJvbCBvZiB0aG9zZSB0aGF0IGhhdmUgYVxuXHQgICAgICogZGVwZW5kZW5jeSBvbiB0aGUgY3VycmVudCBjbG9jay5cblx0ICAgICAqIEByZXR1cm5zIHtvYmplY3R9IHRoZSBwYXJ0bHkgZmFrZSBJbnRsIGltcGxlbWVudGF0aW9uXG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGNyZWF0ZUludGwoKSB7XG5cdCAgICAgICAgY29uc3QgQ2xvY2tJbnRsID0ge307XG5cdCAgICAgICAgLypcblx0ICAgICAgICAgKiBBbGwgcHJvcGVydGllcyBvZiBJbnRsIGFyZSBub24tZW51bWVyYWJsZSwgc28gd2UgbmVlZFxuXHQgICAgICAgICAqIHRvIGRvIGEgYml0IG9mIHdvcmsgdG8gZ2V0IHRoZW0gb3V0LlxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE5hdGl2ZUludGwpLmZvckVhY2goXG5cdCAgICAgICAgICAgIChwcm9wZXJ0eSkgPT4gKENsb2NrSW50bFtwcm9wZXJ0eV0gPSBOYXRpdmVJbnRsW3Byb3BlcnR5XSksXG5cdCAgICAgICAgKTtcblxuXHQgICAgICAgIENsb2NrSW50bC5EYXRlVGltZUZvcm1hdCA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHJlYWxGb3JtYXR0ZXIgPSBuZXcgTmF0aXZlSW50bC5EYXRlVGltZUZvcm1hdCguLi5hcmdzKTtcblx0ICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVyID0ge307XG5cblx0ICAgICAgICAgICAgW1wiZm9ybWF0UmFuZ2VcIiwgXCJmb3JtYXRSYW5nZVRvUGFydHNcIiwgXCJyZXNvbHZlZE9wdGlvbnNcIl0uZm9yRWFjaChcblx0ICAgICAgICAgICAgICAgIChtZXRob2QpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZXJbbWV0aG9kXSA9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxGb3JtYXR0ZXJbbWV0aG9kXS5iaW5kKHJlYWxGb3JtYXR0ZXIpO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgKTtcblxuXHQgICAgICAgICAgICBbXCJmb3JtYXRcIiwgXCJmb3JtYXRUb1BhcnRzXCJdLmZvckVhY2goKG1ldGhvZCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgZm9ybWF0dGVyW21ldGhvZF0gPSBmdW5jdGlvbiAoZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFsRm9ybWF0dGVyW21ldGhvZF0oZGF0ZSB8fCBDbG9ja0ludGwuY2xvY2subm93KTtcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIH0pO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBmb3JtYXR0ZXI7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIENsb2NrSW50bC5EYXRlVGltZUZvcm1hdC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFxuXHQgICAgICAgICAgICBOYXRpdmVJbnRsLkRhdGVUaW1lRm9ybWF0LnByb3RvdHlwZSxcblx0ICAgICAgICApO1xuXG5cdCAgICAgICAgQ2xvY2tJbnRsLkRhdGVUaW1lRm9ybWF0LnN1cHBvcnRlZExvY2FsZXNPZiA9XG5cdCAgICAgICAgICAgIE5hdGl2ZUludGwuRGF0ZVRpbWVGb3JtYXQuc3VwcG9ydGVkTG9jYWxlc09mO1xuXG5cdCAgICAgICAgcmV0dXJuIENsb2NrSW50bDtcblx0ICAgIH1cblxuXHQgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgZnVuY3Rpb24gZW5xdWV1ZUpvYihjbG9jaywgam9iKSB7XG5cdCAgICAgICAgLy8gZW5xdWV1ZXMgYSBtaWNyb3RpY2stZGVmZXJyZWQgdGFzayAtIGVjbWEyNjIvI3NlYy1lbnF1ZXVlam9iXG5cdCAgICAgICAgaWYgKCFjbG9jay5qb2JzKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLmpvYnMgPSBbXTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2xvY2suam9icy5wdXNoKGpvYik7XG5cdCAgICB9XG5cblx0ICAgIC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2Ncblx0ICAgIGZ1bmN0aW9uIHJ1bkpvYnMoY2xvY2spIHtcblx0ICAgICAgICAvLyBydW5zIGFsbCBtaWNyb3RpY2stZGVmZXJyZWQgdGFza3MgLSBlY21hMjYyLyNzZWMtcnVuam9ic1xuXHQgICAgICAgIGlmICghY2xvY2suam9icykge1xuXHQgICAgICAgICAgICByZXR1cm47XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2xvY2suam9icy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICBjb25zdCBqb2IgPSBjbG9jay5qb2JzW2ldO1xuXHQgICAgICAgICAgICBqb2IuZnVuYy5hcHBseShudWxsLCBqb2IuYXJncyk7XG5cblx0ICAgICAgICAgICAgY2hlY2tJc05lYXJJbmZpbml0ZUxpbWl0KGNsb2NrLCBpKTtcblx0ICAgICAgICAgICAgaWYgKGNsb2NrLmxvb3BMaW1pdCAmJiBpID4gY2xvY2subG9vcExpbWl0KSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBnZXRJbmZpbml0ZUxvb3BFcnJvcihjbG9jaywgam9iKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXNldElzTmVhckluZmluaXRlTGltaXQoKTtcblx0ICAgICAgICBjbG9jay5qb2JzID0gW107XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEBwYXJhbSB7VGltZXJ9IHRpbWVyXG5cdCAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBpZCBvZiB0aGUgY3JlYXRlZCB0aW1lclxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBhZGRUaW1lcihjbG9jaywgdGltZXIpIHtcblx0ICAgICAgICBpZiAodGltZXIuZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbGxiYWNrIG11c3QgYmUgcHJvdmlkZWQgdG8gdGltZXIgY2FsbHNcIik7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKGFkZFRpbWVyUmV0dXJuc09iamVjdCkge1xuXHQgICAgICAgICAgICAvLyBOb2RlLmpzIGVudmlyb25tZW50XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgdGltZXIuZnVuYyAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuXHQgICAgICAgICAgICAgICAgICAgIGBbRVJSX0lOVkFMSURfQ0FMTEJBQ0tdOiBDYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24uIFJlY2VpdmVkICR7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVyLmZ1bmNcblx0ICAgICAgICAgICAgICAgICAgICB9IG9mIHR5cGUgJHt0eXBlb2YgdGltZXIuZnVuY31gLFxuXHQgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChpc05lYXJJbmZpbml0ZUxpbWl0KSB7XG5cdCAgICAgICAgICAgIHRpbWVyLmVycm9yID0gbmV3IEVycm9yKCk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgdGltZXIudHlwZSA9IHRpbWVyLmltbWVkaWF0ZSA/IFwiSW1tZWRpYXRlXCIgOiBcIlRpbWVvdXRcIjtcblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImRlbGF5XCIpKSB7XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgdGltZXIuZGVsYXkgIT09IFwibnVtYmVyXCIpIHtcblx0ICAgICAgICAgICAgICAgIHRpbWVyLmRlbGF5ID0gcGFyc2VJbnQodGltZXIuZGVsYXksIDEwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIGlmICghaXNOdW1iZXJGaW5pdGUodGltZXIuZGVsYXkpKSB7XG5cdCAgICAgICAgICAgICAgICB0aW1lci5kZWxheSA9IDA7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGltZXIuZGVsYXkgPSB0aW1lci5kZWxheSA+IG1heFRpbWVvdXQgPyAxIDogdGltZXIuZGVsYXk7XG5cdCAgICAgICAgICAgIHRpbWVyLmRlbGF5ID0gTWF0aC5tYXgoMCwgdGltZXIuZGVsYXkpO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImludGVydmFsXCIpKSB7XG5cdCAgICAgICAgICAgIHRpbWVyLnR5cGUgPSBcIkludGVydmFsXCI7XG5cdCAgICAgICAgICAgIHRpbWVyLmludGVydmFsID0gdGltZXIuaW50ZXJ2YWwgPiBtYXhUaW1lb3V0ID8gMSA6IHRpbWVyLmludGVydmFsO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImFuaW1hdGlvblwiKSkge1xuXHQgICAgICAgICAgICB0aW1lci50eXBlID0gXCJBbmltYXRpb25GcmFtZVwiO1xuXHQgICAgICAgICAgICB0aW1lci5hbmltYXRpb24gPSB0cnVlO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImlkbGVDYWxsYmFja1wiKSkge1xuXHQgICAgICAgICAgICB0aW1lci50eXBlID0gXCJJZGxlQ2FsbGJhY2tcIjtcblx0ICAgICAgICAgICAgdGltZXIuaWRsZUNhbGxiYWNrID0gdHJ1ZTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoIWNsb2NrLnRpbWVycykge1xuXHQgICAgICAgICAgICBjbG9jay50aW1lcnMgPSB7fTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICB0aW1lci5pZCA9IHVuaXF1ZVRpbWVySWQrKztcblx0ICAgICAgICB0aW1lci5jcmVhdGVkQXQgPSBjbG9jay5ub3c7XG5cdCAgICAgICAgdGltZXIuY2FsbEF0ID1cblx0ICAgICAgICAgICAgY2xvY2subm93ICsgKHBhcnNlSW50KHRpbWVyLmRlbGF5KSB8fCAoY2xvY2suZHVyaW5nVGljayA/IDEgOiAwKSk7XG5cblx0ICAgICAgICBjbG9jay50aW1lcnNbdGltZXIuaWRdID0gdGltZXI7XG5cblx0ICAgICAgICBpZiAoYWRkVGltZXJSZXR1cm5zT2JqZWN0KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHJlcyA9IHtcblx0ICAgICAgICAgICAgICAgIHJlZmVkOiB0cnVlLFxuXHQgICAgICAgICAgICAgICAgcmVmOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZlZCA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcztcblx0ICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICB1bnJlZjogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMucmVmZWQgPSBmYWxzZTtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIGhhc1JlZjogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlZmVkO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIHJlZnJlc2g6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aW1lci5jYWxsQXQgPVxuXHQgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5ub3cgK1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAocGFyc2VJbnQodGltZXIuZGVsYXkpIHx8IChjbG9jay5kdXJpbmdUaWNrID8gMSA6IDApKTtcblxuXHQgICAgICAgICAgICAgICAgICAgIC8vIGl0IF9taWdodF8gaGF2ZSBiZWVuIHJlbW92ZWQsIGJ1dCBpZiBub3QgdGhlIGFzc2lnbm1lbnQgaXMgcGVyZmVjdGx5IGZpbmVcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jay50aW1lcnNbdGltZXIuaWRdID0gdGltZXI7XG5cblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIFtTeW1ib2wudG9QcmltaXRpdmVdOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRpbWVyLmlkO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgcmV0dXJuIHJlcztcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gdGltZXIuaWQ7XG5cdCAgICB9XG5cblx0ICAgIC8qIGVzbGludCBjb25zaXN0ZW50LXJldHVybjogXCJvZmZcIiAqL1xuXHQgICAgLyoqXG5cdCAgICAgKiBUaW1lciBjb21wYXJpdG9yXG5cdCAgICAgKiBAcGFyYW0ge1RpbWVyfSBhXG5cdCAgICAgKiBAcGFyYW0ge1RpbWVyfSBiXG5cdCAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBjb21wYXJlVGltZXJzKGEsIGIpIHtcblx0ICAgICAgICAvLyBTb3J0IGZpcnN0IGJ5IGFic29sdXRlIHRpbWluZ1xuXHQgICAgICAgIGlmIChhLmNhbGxBdCA8IGIuY2FsbEF0KSB7XG5cdCAgICAgICAgICAgIHJldHVybiAtMTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGEuY2FsbEF0ID4gYi5jYWxsQXQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIDE7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gU29ydCBuZXh0IGJ5IGltbWVkaWF0ZSwgaW1tZWRpYXRlIHRpbWVycyB0YWtlIHByZWNlZGVuY2Vcblx0ICAgICAgICBpZiAoYS5pbW1lZGlhdGUgJiYgIWIuaW1tZWRpYXRlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAtMTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKCFhLmltbWVkaWF0ZSAmJiBiLmltbWVkaWF0ZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gMTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBTb3J0IG5leHQgYnkgY3JlYXRpb24gdGltZSwgZWFybGllci1jcmVhdGVkIHRpbWVycyB0YWtlIHByZWNlZGVuY2Vcblx0ICAgICAgICBpZiAoYS5jcmVhdGVkQXQgPCBiLmNyZWF0ZWRBdCkge1xuXHQgICAgICAgICAgICByZXR1cm4gLTE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChhLmNyZWF0ZWRBdCA+IGIuY3JlYXRlZEF0KSB7XG5cdCAgICAgICAgICAgIHJldHVybiAxO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIFNvcnQgbmV4dCBieSBpZCwgbG93ZXItaWQgdGltZXJzIHRha2UgcHJlY2VkZW5jZVxuXHQgICAgICAgIGlmIChhLmlkIDwgYi5pZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gLTE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChhLmlkID4gYi5pZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gMTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBBcyB0aW1lciBpZHMgYXJlIHVuaXF1ZSwgbm8gZmFsbGJhY2sgYDBgIGlzIG5lY2Vzc2FyeVxuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEBwYXJhbSB7Q2xvY2t9IGNsb2NrXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbVxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IHRvXG5cdCAgICAgKiBAcmV0dXJucyB7VGltZXJ9XG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGZpcnN0VGltZXJJblJhbmdlKGNsb2NrLCBmcm9tLCB0bykge1xuXHQgICAgICAgIGNvbnN0IHRpbWVycyA9IGNsb2NrLnRpbWVycztcblx0ICAgICAgICBsZXQgdGltZXIgPSBudWxsO1xuXHQgICAgICAgIGxldCBpZCwgaXNJblJhbmdlO1xuXG5cdCAgICAgICAgZm9yIChpZCBpbiB0aW1lcnMpIHtcblx0ICAgICAgICAgICAgaWYgKHRpbWVycy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcblx0ICAgICAgICAgICAgICAgIGlzSW5SYW5nZSA9IGluUmFuZ2UoZnJvbSwgdG8sIHRpbWVyc1tpZF0pO1xuXG5cdCAgICAgICAgICAgICAgICBpZiAoXG5cdCAgICAgICAgICAgICAgICAgICAgaXNJblJhbmdlICYmXG5cdCAgICAgICAgICAgICAgICAgICAgKCF0aW1lciB8fCBjb21wYXJlVGltZXJzKHRpbWVyLCB0aW1lcnNbaWRdKSA9PT0gMSlcblx0ICAgICAgICAgICAgICAgICkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyID0gdGltZXJzW2lkXTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiB0aW1lcjtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge0Nsb2NrfSBjbG9ja1xuXHQgICAgICogQHJldHVybnMge1RpbWVyfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBmaXJzdFRpbWVyKGNsb2NrKSB7XG5cdCAgICAgICAgY29uc3QgdGltZXJzID0gY2xvY2sudGltZXJzO1xuXHQgICAgICAgIGxldCB0aW1lciA9IG51bGw7XG5cdCAgICAgICAgbGV0IGlkO1xuXG5cdCAgICAgICAgZm9yIChpZCBpbiB0aW1lcnMpIHtcblx0ICAgICAgICAgICAgaWYgKHRpbWVycy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcblx0ICAgICAgICAgICAgICAgIGlmICghdGltZXIgfHwgY29tcGFyZVRpbWVycyh0aW1lciwgdGltZXJzW2lkXSkgPT09IDEpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aW1lciA9IHRpbWVyc1tpZF07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gdGltZXI7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEByZXR1cm5zIHtUaW1lcn1cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gbGFzdFRpbWVyKGNsb2NrKSB7XG5cdCAgICAgICAgY29uc3QgdGltZXJzID0gY2xvY2sudGltZXJzO1xuXHQgICAgICAgIGxldCB0aW1lciA9IG51bGw7XG5cdCAgICAgICAgbGV0IGlkO1xuXG5cdCAgICAgICAgZm9yIChpZCBpbiB0aW1lcnMpIHtcblx0ICAgICAgICAgICAgaWYgKHRpbWVycy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcblx0ICAgICAgICAgICAgICAgIGlmICghdGltZXIgfHwgY29tcGFyZVRpbWVycyh0aW1lciwgdGltZXJzW2lkXSkgPT09IC0xKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGltZXIgPSB0aW1lcnNbaWRdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmV0dXJuIHRpbWVyO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEBwYXJhbSB7Q2xvY2t9IGNsb2NrXG5cdCAgICAgKiBAcGFyYW0ge1RpbWVyfSB0aW1lclxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKSB7XG5cdCAgICAgICAgaWYgKHR5cGVvZiB0aW1lci5pbnRlcnZhbCA9PT0gXCJudW1iZXJcIikge1xuXHQgICAgICAgICAgICBjbG9jay50aW1lcnNbdGltZXIuaWRdLmNhbGxBdCArPSB0aW1lci5pbnRlcnZhbDtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBkZWxldGUgY2xvY2sudGltZXJzW3RpbWVyLmlkXTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAodHlwZW9mIHRpbWVyLmZ1bmMgPT09IFwiZnVuY3Rpb25cIikge1xuXHQgICAgICAgICAgICB0aW1lci5mdW5jLmFwcGx5KG51bGwsIHRpbWVyLmFyZ3MpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIC8qIGVzbGludCBuby1ldmFsOiBcIm9mZlwiICovXG5cdCAgICAgICAgICAgIGNvbnN0IGV2YWwyID0gZXZhbDtcblx0ICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIGV2YWwyKHRpbWVyLmZ1bmMpO1xuXHQgICAgICAgICAgICB9KSgpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIGNsZWFyIGhhbmRsZXIgbmFtZSBmb3IgYSBnaXZlbiB0aW1lciB0eXBlXG5cdCAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHR5cGVcblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gZ2V0Q2xlYXJIYW5kbGVyKHR0eXBlKSB7XG5cdCAgICAgICAgaWYgKHR0eXBlID09PSBcIklkbGVDYWxsYmFja1wiIHx8IHR0eXBlID09PSBcIkFuaW1hdGlvbkZyYW1lXCIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGBjYW5jZWwke3R0eXBlfWA7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBgY2xlYXIke3R0eXBlfWA7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyBzY2hlZHVsZSBoYW5kbGVyIG5hbWUgZm9yIGEgZ2l2ZW4gdGltZXIgdHlwZVxuXHQgICAgICogQHBhcmFtIHtzdHJpbmd9IHR0eXBlXG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGdldFNjaGVkdWxlSGFuZGxlcih0dHlwZSkge1xuXHQgICAgICAgIGlmICh0dHlwZSA9PT0gXCJJZGxlQ2FsbGJhY2tcIiB8fCB0dHlwZSA9PT0gXCJBbmltYXRpb25GcmFtZVwiKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBgcmVxdWVzdCR7dHR5cGV9YDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGBzZXQke3R0eXBlfWA7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQ3JlYXRlcyBhbiBhbm9ueW1vdXMgZnVuY3Rpb24gdG8gd2FybiBvbmx5IG9uY2Vcblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlV2Fybk9uY2UoKSB7XG5cdCAgICAgICAgbGV0IGNhbGxzID0gMDtcblx0ICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1zZykge1xuXHQgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0ICAgICAgICAgICAgIWNhbGxzKysgJiYgY29uc29sZS53YXJuKG1zZyk7XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIGNvbnN0IHdhcm5PbmNlID0gY3JlYXRlV2Fybk9uY2UoKTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge0Nsb2NrfSBjbG9ja1xuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVySWRcblx0ICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0dHlwZVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBjbGVhclRpbWVyKGNsb2NrLCB0aW1lcklkLCB0dHlwZSkge1xuXHQgICAgICAgIGlmICghdGltZXJJZCkge1xuXHQgICAgICAgICAgICAvLyBudWxsIGFwcGVhcnMgdG8gYmUgYWxsb3dlZCBpbiBtb3N0IGJyb3dzZXJzLCBhbmQgYXBwZWFycyB0byBiZVxuXHQgICAgICAgICAgICAvLyByZWxpZWQgdXBvbiBieSBzb21lIGxpYnJhcmllcywgbGlrZSBCb290c3RyYXAgY2Fyb3VzZWxcblx0ICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICghY2xvY2sudGltZXJzKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnRpbWVycyA9IHt9O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIGluIE5vZGUsIHRoZSBJRCBpcyBzdG9yZWQgYXMgdGhlIHByaW1pdGl2ZSB2YWx1ZSBmb3IgYFRpbWVvdXRgIG9iamVjdHNcblx0ICAgICAgICAvLyBmb3IgYEltbWVkaWF0ZWAgb2JqZWN0cywgbm8gSUQgZXhpc3RzLCBzbyBpdCBnZXRzIGNvZXJjZWQgdG8gTmFOXG5cdCAgICAgICAgY29uc3QgaWQgPSBOdW1iZXIodGltZXJJZCk7XG5cblx0ICAgICAgICBpZiAoTnVtYmVyLmlzTmFOKGlkKSB8fCBpZCA8IGlkQ291bnRlclN0YXJ0KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJOYW1lID0gZ2V0Q2xlYXJIYW5kbGVyKHR0eXBlKTtcblxuXHQgICAgICAgICAgICBpZiAoY2xvY2suc2hvdWxkQ2xlYXJOYXRpdmVUaW1lcnMgPT09IHRydWUpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUhhbmRsZXIgPSBjbG9ja1tgXyR7aGFuZGxlck5hbWV9YF07XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdHlwZW9mIG5hdGl2ZUhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIlxuXHQgICAgICAgICAgICAgICAgICAgID8gbmF0aXZlSGFuZGxlcih0aW1lcklkKVxuXHQgICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHdhcm5PbmNlKFxuXHQgICAgICAgICAgICAgICAgYEZha2VUaW1lcnM6ICR7aGFuZGxlck5hbWV9IHdhcyBpbnZva2VkIHRvIGNsZWFyIGEgbmF0aXZlIHRpbWVyIGluc3RlYWQgb2Ygb25lIGNyZWF0ZWQgYnkgdGhpcyBsaWJyYXJ5LmAgK1xuXHQgICAgICAgICAgICAgICAgICAgIFwiXFxuVG8gYXV0b21hdGljYWxseSBjbGVhbi11cCBuYXRpdmUgdGltZXJzLCB1c2UgYHNob3VsZENsZWFyTmF0aXZlVGltZXJzYC5cIixcblx0ICAgICAgICAgICAgKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoY2xvY2sudGltZXJzLmhhc093blByb3BlcnR5KGlkKSkge1xuXHQgICAgICAgICAgICAvLyBjaGVjayB0aGF0IHRoZSBJRCBtYXRjaGVzIGEgdGltZXIgb2YgdGhlIGNvcnJlY3QgdHlwZVxuXHQgICAgICAgICAgICBjb25zdCB0aW1lciA9IGNsb2NrLnRpbWVyc1tpZF07XG5cdCAgICAgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgICAgIHRpbWVyLnR5cGUgPT09IHR0eXBlIHx8XG5cdCAgICAgICAgICAgICAgICAodGltZXIudHlwZSA9PT0gXCJUaW1lb3V0XCIgJiYgdHR5cGUgPT09IFwiSW50ZXJ2YWxcIikgfHxcblx0ICAgICAgICAgICAgICAgICh0aW1lci50eXBlID09PSBcIkludGVydmFsXCIgJiYgdHR5cGUgPT09IFwiVGltZW91dFwiKVxuXHQgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgIGRlbGV0ZSBjbG9jay50aW1lcnNbaWRdO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY2xlYXIgPSBnZXRDbGVhckhhbmRsZXIodHR5cGUpO1xuXHQgICAgICAgICAgICAgICAgY29uc3Qgc2NoZWR1bGUgPSBnZXRTY2hlZHVsZUhhbmRsZXIodGltZXIudHlwZSk7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG5cdCAgICAgICAgICAgICAgICAgICAgYENhbm5vdCBjbGVhciB0aW1lcjogdGltZXIgY3JlYXRlZCB3aXRoICR7c2NoZWR1bGV9KCkgYnV0IGNsZWFyZWQgd2l0aCAke2NsZWFyfSgpYCxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEByZXR1cm5zIHtUaW1lcltdfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiB1bmluc3RhbGwoY2xvY2spIHtcblx0ICAgICAgICBsZXQgbWV0aG9kLCBpLCBsO1xuXHQgICAgICAgIGNvbnN0IGluc3RhbGxlZEhyVGltZSA9IFwiX2hydGltZVwiO1xuXHQgICAgICAgIGNvbnN0IGluc3RhbGxlZE5leHRUaWNrID0gXCJfbmV4dFRpY2tcIjtcblxuXHQgICAgICAgIGZvciAoaSA9IDAsIGwgPSBjbG9jay5tZXRob2RzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuXHQgICAgICAgICAgICBtZXRob2QgPSBjbG9jay5tZXRob2RzW2ldO1xuXHQgICAgICAgICAgICBpZiAobWV0aG9kID09PSBcImhydGltZVwiICYmIF9nbG9iYWwucHJvY2Vzcykge1xuXHQgICAgICAgICAgICAgICAgX2dsb2JhbC5wcm9jZXNzLmhydGltZSA9IGNsb2NrW2luc3RhbGxlZEhyVGltZV07XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09PSBcIm5leHRUaWNrXCIgJiYgX2dsb2JhbC5wcm9jZXNzKSB7XG5cdCAgICAgICAgICAgICAgICBfZ2xvYmFsLnByb2Nlc3MubmV4dFRpY2sgPSBjbG9ja1tpbnN0YWxsZWROZXh0VGlja107XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09PSBcInBlcmZvcm1hbmNlXCIpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsUGVyZkRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuXHQgICAgICAgICAgICAgICAgICAgIGNsb2NrLFxuXHQgICAgICAgICAgICAgICAgICAgIGBfJHttZXRob2R9YCxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICBpZiAoXG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvciAmJlxuXHQgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsUGVyZkRlc2NyaXB0b3IuZ2V0ICYmXG5cdCAgICAgICAgICAgICAgICAgICAgIW9yaWdpbmFsUGVyZkRlc2NyaXB0b3Iuc2V0XG5cdCAgICAgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIF9nbG9iYWwsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvcixcblx0ICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvcmlnaW5hbFBlcmZEZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIF9nbG9iYWxbbWV0aG9kXSA9IGNsb2NrW2BfJHttZXRob2R9YF07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoX2dsb2JhbFttZXRob2RdICYmIF9nbG9iYWxbbWV0aG9kXS5oYWRPd25Qcm9wZXJ0eSkge1xuXHQgICAgICAgICAgICAgICAgICAgIF9nbG9iYWxbbWV0aG9kXSA9IGNsb2NrW2BfJHttZXRob2R9YF07XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBfZ2xvYmFsW21ldGhvZF07XG5cdCAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoaWdub3JlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVzbGludCBuby1lbXB0eTogXCJvZmZcIiAqL1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoY2xvY2sudGltZXJzTW9kdWxlTWV0aG9kcyAhPT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNsb2NrLnRpbWVyc01vZHVsZU1ldGhvZHMubGVuZ3RoOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICBjb25zdCBlbnRyeSA9IGNsb2NrLnRpbWVyc01vZHVsZU1ldGhvZHNbal07XG5cdCAgICAgICAgICAgICAgICAgICAgdGltZXJzTW9kdWxlW2VudHJ5Lm1ldGhvZE5hbWVdID0gZW50cnkub3JpZ2luYWw7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGNsb2NrLnRpbWVyc1Byb21pc2VzTW9kdWxlTWV0aG9kcyAhPT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKFxuXHQgICAgICAgICAgICAgICAgICAgIGxldCBqID0gMDtcblx0ICAgICAgICAgICAgICAgICAgICBqIDwgY2xvY2sudGltZXJzUHJvbWlzZXNNb2R1bGVNZXRob2RzLmxlbmd0aDtcblx0ICAgICAgICAgICAgICAgICAgICBqKytcblx0ICAgICAgICAgICAgICAgICkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gY2xvY2sudGltZXJzUHJvbWlzZXNNb2R1bGVNZXRob2RzW2pdO1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyc1Byb21pc2VzTW9kdWxlW2VudHJ5Lm1ldGhvZE5hbWVdID0gZW50cnkub3JpZ2luYWw7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICBjbG9jay5zZXRUaWNrTW9kZShcIm1hbnVhbFwiKTtcblxuXHQgICAgICAgIC8vIFByZXZlbnQgbXVsdGlwbGUgZXhlY3V0aW9ucyB3aGljaCB3aWxsIGNvbXBsZXRlbHkgcmVtb3ZlIHRoZXNlIHByb3BzXG5cdCAgICAgICAgY2xvY2subWV0aG9kcyA9IFtdO1xuXG5cdCAgICAgICAgZm9yIChjb25zdCBbbGlzdGVuZXIsIHNpZ25hbF0gb2YgY2xvY2suYWJvcnRMaXN0ZW5lck1hcC5lbnRyaWVzKCkpIHtcblx0ICAgICAgICAgICAgc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBsaXN0ZW5lcik7XG5cdCAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGxpc3RlbmVyKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyByZXR1cm4gcGVuZGluZyB0aW1lcnMsIHRvIGVuYWJsZSBjaGVja2luZyB3aGF0IHRpbWVycyByZW1haW5lZCBvbiB1bmluc3RhbGxcblx0ICAgICAgICBpZiAoIWNsb2NrLnRpbWVycykge1xuXHQgICAgICAgICAgICByZXR1cm4gW107XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhjbG9jay50aW1lcnMpLm1hcChmdW5jdGlvbiBtYXBwZXIoa2V5KSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbG9jay50aW1lcnNba2V5XTtcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0IHRoZSB0YXJnZXQgY29udGFpbmluZyB0aGUgbWV0aG9kIHRvIHJlcGxhY2Vcblx0ICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2QgdGhlIGtleW5hbWUgb2YgdGhlIG1ldGhvZCBvbiB0aGUgdGFyZ2V0XG5cdCAgICAgKiBAcGFyYW0ge0Nsb2NrfSBjbG9ja1xuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBoaWphY2tNZXRob2QodGFyZ2V0LCBtZXRob2QsIGNsb2NrKSB7XG5cdCAgICAgICAgY2xvY2tbbWV0aG9kXS5oYWRPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcblx0ICAgICAgICAgICAgdGFyZ2V0LFxuXHQgICAgICAgICAgICBtZXRob2QsXG5cdCAgICAgICAgKTtcblx0ICAgICAgICBjbG9ja1tgXyR7bWV0aG9kfWBdID0gdGFyZ2V0W21ldGhvZF07XG5cblx0ICAgICAgICBpZiAobWV0aG9kID09PSBcIkRhdGVcIikge1xuXHQgICAgICAgICAgICB0YXJnZXRbbWV0aG9kXSA9IGNsb2NrW21ldGhvZF07XG5cdCAgICAgICAgfSBlbHNlIGlmIChtZXRob2QgPT09IFwiSW50bFwiKSB7XG5cdCAgICAgICAgICAgIHRhcmdldFttZXRob2RdID0gY2xvY2tbbWV0aG9kXTtcblx0ICAgICAgICB9IGVsc2UgaWYgKG1ldGhvZCA9PT0gXCJwZXJmb3JtYW5jZVwiKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsUGVyZkRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuXHQgICAgICAgICAgICAgICAgdGFyZ2V0LFxuXHQgICAgICAgICAgICAgICAgbWV0aG9kLFxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAvLyBKU0RPTSBoYXMgYSByZWFkIG9ubHkgcGVyZm9ybWFuY2UgZmllbGQgc28gd2UgaGF2ZSB0byBzYXZlL2NvcHkgaXQgZGlmZmVyZW50bHlcblx0ICAgICAgICAgICAgaWYgKFxuXHQgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvciAmJlxuXHQgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvci5nZXQgJiZcblx0ICAgICAgICAgICAgICAgICFvcmlnaW5hbFBlcmZEZXNjcmlwdG9yLnNldFxuXHQgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jayxcblx0ICAgICAgICAgICAgICAgICAgICBgXyR7bWV0aG9kfWAsXG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvcixcblx0ICAgICAgICAgICAgICAgICk7XG5cblx0ICAgICAgICAgICAgICAgIGNvbnN0IHBlcmZEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jayxcblx0ICAgICAgICAgICAgICAgICAgICBtZXRob2QsXG5cdCAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgbWV0aG9kLCBwZXJmRGVzY3JpcHRvcik7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB0YXJnZXRbbWV0aG9kXSA9IGNsb2NrW21ldGhvZF07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0YXJnZXRbbWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBjbG9ja1ttZXRob2RdLmFwcGx5KGNsb2NrLCBhcmd1bWVudHMpO1xuXHQgICAgICAgICAgICB9O1xuXG5cdCAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFxuXHQgICAgICAgICAgICAgICAgdGFyZ2V0W21ldGhvZF0sXG5cdCAgICAgICAgICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhjbG9ja1ttZXRob2RdKSxcblx0ICAgICAgICAgICAgKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICB0YXJnZXRbbWV0aG9kXS5jbG9jayA9IGNsb2NrO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEBwYXJhbSB7Q2xvY2t9IGNsb2NrXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gYWR2YW5jZVRpbWVEZWx0YVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBkb0ludGVydmFsVGljayhjbG9jaywgYWR2YW5jZVRpbWVEZWx0YSkge1xuXHQgICAgICAgIGNsb2NrLnRpY2soYWR2YW5jZVRpbWVEZWx0YSk7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHR5cGVkZWYge29iamVjdH0gVGltZXJzXG5cdCAgICAgKiBAcHJvcGVydHkge3NldFRpbWVvdXR9IHNldFRpbWVvdXRcblx0ICAgICAqIEBwcm9wZXJ0eSB7Y2xlYXJUaW1lb3V0fSBjbGVhclRpbWVvdXRcblx0ICAgICAqIEBwcm9wZXJ0eSB7c2V0SW50ZXJ2YWx9IHNldEludGVydmFsXG5cdCAgICAgKiBAcHJvcGVydHkge2NsZWFySW50ZXJ2YWx9IGNsZWFySW50ZXJ2YWxcblx0ICAgICAqIEBwcm9wZXJ0eSB7RGF0ZX0gRGF0ZVxuXHQgICAgICogQHByb3BlcnR5IHtJbnRsfSBJbnRsXG5cdCAgICAgKiBAcHJvcGVydHkge1NldEltbWVkaWF0ZT19IHNldEltbWVkaWF0ZVxuXHQgICAgICogQHByb3BlcnR5IHtmdW5jdGlvbihOb2RlSW1tZWRpYXRlKTogdm9pZD19IGNsZWFySW1tZWRpYXRlXG5cdCAgICAgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcltdKTpudW1iZXJbXT19IGhydGltZVxuXHQgICAgICogQHByb3BlcnR5IHtOZXh0VGljaz19IG5leHRUaWNrXG5cdCAgICAgKiBAcHJvcGVydHkge1BlcmZvcm1hbmNlPX0gcGVyZm9ybWFuY2Vcblx0ICAgICAqIEBwcm9wZXJ0eSB7UmVxdWVzdEFuaW1hdGlvbkZyYW1lPX0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lXG5cdCAgICAgKiBAcHJvcGVydHkge2Jvb2xlYW49fSBxdWV1ZU1pY3JvdGFza1xuXHQgICAgICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIpOiB2b2lkPX0gY2FuY2VsQW5pbWF0aW9uRnJhbWVcblx0ICAgICAqIEBwcm9wZXJ0eSB7UmVxdWVzdElkbGVDYWxsYmFjaz19IHJlcXVlc3RJZGxlQ2FsbGJhY2tcblx0ICAgICAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24obnVtYmVyKTogdm9pZD19IGNhbmNlbElkbGVDYWxsYmFja1xuXHQgICAgICovXG5cblx0ICAgIC8qKiBAdHlwZSB7VGltZXJzfSAqL1xuXHQgICAgY29uc3QgdGltZXJzID0ge1xuXHQgICAgICAgIHNldFRpbWVvdXQ6IF9nbG9iYWwuc2V0VGltZW91dCxcblx0ICAgICAgICBjbGVhclRpbWVvdXQ6IF9nbG9iYWwuY2xlYXJUaW1lb3V0LFxuXHQgICAgICAgIHNldEludGVydmFsOiBfZ2xvYmFsLnNldEludGVydmFsLFxuXHQgICAgICAgIGNsZWFySW50ZXJ2YWw6IF9nbG9iYWwuY2xlYXJJbnRlcnZhbCxcblx0ICAgICAgICBEYXRlOiBfZ2xvYmFsLkRhdGUsXG5cdCAgICB9O1xuXG5cdCAgICBpZiAoaXNQcmVzZW50LnNldEltbWVkaWF0ZSkge1xuXHQgICAgICAgIHRpbWVycy5zZXRJbW1lZGlhdGUgPSBfZ2xvYmFsLnNldEltbWVkaWF0ZTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUHJlc2VudC5jbGVhckltbWVkaWF0ZSkge1xuXHQgICAgICAgIHRpbWVycy5jbGVhckltbWVkaWF0ZSA9IF9nbG9iYWwuY2xlYXJJbW1lZGlhdGU7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQuaHJ0aW1lKSB7XG5cdCAgICAgICAgdGltZXJzLmhydGltZSA9IF9nbG9iYWwucHJvY2Vzcy5ocnRpbWU7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQubmV4dFRpY2spIHtcblx0ICAgICAgICB0aW1lcnMubmV4dFRpY2sgPSBfZ2xvYmFsLnByb2Nlc3MubmV4dFRpY2s7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQucGVyZm9ybWFuY2UpIHtcblx0ICAgICAgICB0aW1lcnMucGVyZm9ybWFuY2UgPSBfZ2xvYmFsLnBlcmZvcm1hbmNlO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaXNQcmVzZW50LnJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuXHQgICAgICAgIHRpbWVycy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSBfZ2xvYmFsLnJlcXVlc3RBbmltYXRpb25GcmFtZTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUHJlc2VudC5xdWV1ZU1pY3JvdGFzaykge1xuXHQgICAgICAgIHRpbWVycy5xdWV1ZU1pY3JvdGFzayA9IF9nbG9iYWwucXVldWVNaWNyb3Rhc2s7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQuY2FuY2VsQW5pbWF0aW9uRnJhbWUpIHtcblx0ICAgICAgICB0aW1lcnMuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSBfZ2xvYmFsLmNhbmNlbEFuaW1hdGlvbkZyYW1lO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaXNQcmVzZW50LnJlcXVlc3RJZGxlQ2FsbGJhY2spIHtcblx0ICAgICAgICB0aW1lcnMucmVxdWVzdElkbGVDYWxsYmFjayA9IF9nbG9iYWwucmVxdWVzdElkbGVDYWxsYmFjaztcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUHJlc2VudC5jYW5jZWxJZGxlQ2FsbGJhY2spIHtcblx0ICAgICAgICB0aW1lcnMuY2FuY2VsSWRsZUNhbGxiYWNrID0gX2dsb2JhbC5jYW5jZWxJZGxlQ2FsbGJhY2s7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQuSW50bCkge1xuXHQgICAgICAgIHRpbWVycy5JbnRsID0gTmF0aXZlSW50bDtcblx0ICAgIH1cblxuXHQgICAgY29uc3Qgb3JpZ2luYWxTZXRUaW1lb3V0ID0gX2dsb2JhbC5zZXRJbW1lZGlhdGUgfHwgX2dsb2JhbC5zZXRUaW1lb3V0O1xuXHQgICAgY29uc3Qgb3JpZ2luYWxDbGVhckludGVydmFsID0gX2dsb2JhbC5jbGVhckludGVydmFsO1xuXHQgICAgY29uc3Qgb3JpZ2luYWxTZXRJbnRlcnZhbCA9IF9nbG9iYWwuc2V0SW50ZXJ2YWw7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtEYXRlfG51bWJlcn0gW3N0YXJ0XSB0aGUgc3lzdGVtIHRpbWUgLSBub24taW50ZWdlciB2YWx1ZXMgYXJlIGZsb29yZWRcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbG9vcExpbWl0XSBtYXhpbXVtIG51bWJlciBvZiB0aW1lcnMgdGhhdCB3aWxsIGJlIHJ1biB3aGVuIGNhbGxpbmcgcnVuQWxsKClcblx0ICAgICAqIEByZXR1cm5zIHtDbG9ja31cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlQ2xvY2soc3RhcnQsIGxvb3BMaW1pdCkge1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHQgICAgICAgIHN0YXJ0ID0gTWF0aC5mbG9vcihnZXRFcG9jaChzdGFydCkpO1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHQgICAgICAgIGxvb3BMaW1pdCA9IGxvb3BMaW1pdCB8fCAxMDAwO1xuXHQgICAgICAgIGxldCBuYW5vcyA9IDA7XG5cdCAgICAgICAgY29uc3QgYWRqdXN0ZWRTeXN0ZW1UaW1lID0gWzAsIDBdOyAvLyBbbWlsbGlzLCBuYW5vcmVtYWluZGVyXVxuXG5cdCAgICAgICAgY29uc3QgY2xvY2sgPSB7XG5cdCAgICAgICAgICAgIG5vdzogc3RhcnQsXG5cdCAgICAgICAgICAgIERhdGU6IGNyZWF0ZURhdGUoKSxcblx0ICAgICAgICAgICAgbG9vcExpbWl0OiBsb29wTGltaXQsXG5cdCAgICAgICAgICAgIHRpY2tNb2RlOiB7IG1vZGU6IFwibWFudWFsXCIsIGNvdW50ZXI6IDAsIGRlbHRhOiB1bmRlZmluZWQgfSxcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2suRGF0ZS5jbG9jayA9IGNsb2NrO1xuXG5cdCAgICAgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgICAgIGZ1bmN0aW9uIGdldFRpbWVUb05leHRGcmFtZSgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIDE2IC0gKChjbG9jay5ub3cgLSBzdGFydCkgJSAxNik7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgICAgIGZ1bmN0aW9uIGhydGltZShwcmV2KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IG1pbGxpc1NpbmNlU3RhcnQgPSBjbG9jay5ub3cgLSBhZGp1c3RlZFN5c3RlbVRpbWVbMF0gLSBzdGFydDtcblx0ICAgICAgICAgICAgY29uc3Qgc2Vjc1NpbmNlU3RhcnQgPSBNYXRoLmZsb29yKG1pbGxpc1NpbmNlU3RhcnQgLyAxMDAwKTtcblx0ICAgICAgICAgICAgY29uc3QgcmVtYWluZGVySW5OYW5vcyA9XG5cdCAgICAgICAgICAgICAgICAobWlsbGlzU2luY2VTdGFydCAtIHNlY3NTaW5jZVN0YXJ0ICogMWUzKSAqIDFlNiArXG5cdCAgICAgICAgICAgICAgICBuYW5vcyAtXG5cdCAgICAgICAgICAgICAgICBhZGp1c3RlZFN5c3RlbVRpbWVbMV07XG5cblx0ICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocHJldikpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChwcmV2WzFdID4gMWU5KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgXCJOdW1iZXIgb2YgbmFub3NlY29uZHMgY2FuJ3QgZXhjZWVkIGEgYmlsbGlvblwiLFxuXHQgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIGNvbnN0IG9sZFNlY3MgPSBwcmV2WzBdO1xuXHQgICAgICAgICAgICAgICAgbGV0IG5hbm9EaWZmID0gcmVtYWluZGVySW5OYW5vcyAtIHByZXZbMV07XG5cdCAgICAgICAgICAgICAgICBsZXQgc2VjRGlmZiA9IHNlY3NTaW5jZVN0YXJ0IC0gb2xkU2VjcztcblxuXHQgICAgICAgICAgICAgICAgaWYgKG5hbm9EaWZmIDwgMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIG5hbm9EaWZmICs9IDFlOTtcblx0ICAgICAgICAgICAgICAgICAgICBzZWNEaWZmIC09IDE7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIHJldHVybiBbc2VjRGlmZiwgbmFub0RpZmZdO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiBbc2Vjc1NpbmNlU3RhcnQsIHJlbWFpbmRlckluTmFub3NdO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEEgaGlnaCByZXNvbHV0aW9uIHRpbWVzdGFtcCBpbiBtaWxsaXNlY29uZHMuXG5cdCAgICAgICAgICogQHR5cGVkZWYge251bWJlcn0gRE9NSGlnaFJlc1RpbWVTdGFtcFxuXHQgICAgICAgICAqL1xuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogcGVyZm9ybWFuY2Uubm93KClcblx0ICAgICAgICAgKiBAcmV0dXJucyB7RE9NSGlnaFJlc1RpbWVTdGFtcH1cblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmdW5jdGlvbiBmYWtlUGVyZm9ybWFuY2VOb3coKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGhydCA9IGhydGltZSgpO1xuXHQgICAgICAgICAgICBjb25zdCBtaWxsaXMgPSBocnRbMF0gKiAxMDAwICsgaHJ0WzFdIC8gMWU2O1xuXHQgICAgICAgICAgICByZXR1cm4gbWlsbGlzO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChpc1ByZXNlbnQuaHJ0aW1lQmlnaW50KSB7XG5cdCAgICAgICAgICAgIGhydGltZS5iaWdpbnQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBwYXJ0cyA9IGhydGltZSgpO1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIEJpZ0ludChwYXJ0c1swXSkgKiBCaWdJbnQoMWU5KSArIEJpZ0ludChwYXJ0c1sxXSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoaXNQcmVzZW50LkludGwpIHtcblx0ICAgICAgICAgICAgY2xvY2suSW50bCA9IGNyZWF0ZUludGwoKTtcblx0ICAgICAgICAgICAgY2xvY2suSW50bC5jbG9jayA9IGNsb2NrO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEBwYXJhbSB7VGltZXJUaWNrTW9kZX0gdGlja01vZGVDb25maWcgLSBUaGUgbmV3IGNvbmZpZ3VyYXRpb24gZm9yIGhvdyB0aGUgY2xvY2sgc2hvdWxkIHRpY2suXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvY2suc2V0VGlja01vZGUgPSBmdW5jdGlvbiAodGlja01vZGVDb25maWcpIHtcblx0ICAgICAgICAgICAgY29uc3QgeyBtb2RlOiBuZXdNb2RlLCBkZWx0YTogbmV3RGVsdGEgfSA9IHRpY2tNb2RlQ29uZmlnO1xuXHQgICAgICAgICAgICBjb25zdCB7IG1vZGU6IG9sZE1vZGUsIGRlbHRhOiBvbGREZWx0YSB9ID0gY2xvY2sudGlja01vZGU7XG5cdCAgICAgICAgICAgIGlmIChuZXdNb2RlID09PSBvbGRNb2RlICYmIG5ld0RlbHRhID09PSBvbGREZWx0YSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgaWYgKG9sZE1vZGUgPT09IFwiaW50ZXJ2YWxcIikge1xuXHQgICAgICAgICAgICAgICAgb3JpZ2luYWxDbGVhckludGVydmFsKGNsb2NrLmF0dGFjaGVkSW50ZXJ2YWwpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY2xvY2sudGlja01vZGUgPSB7XG5cdCAgICAgICAgICAgICAgICBjb3VudGVyOiBjbG9jay50aWNrTW9kZS5jb3VudGVyICsgMSxcblx0ICAgICAgICAgICAgICAgIG1vZGU6IG5ld01vZGUsXG5cdCAgICAgICAgICAgICAgICBkZWx0YTogbmV3RGVsdGEsXG5cdCAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgaWYgKG5ld01vZGUgPT09IFwibmV4dEFzeW5jXCIpIHtcblx0ICAgICAgICAgICAgICAgIGFkdmFuY2VVbnRpbE1vZGVDaGFuZ2VzKCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3TW9kZSA9PT0gXCJpbnRlcnZhbFwiKSB7XG5cdCAgICAgICAgICAgICAgICBjcmVhdGVJbnRlcnZhbFRpY2soY2xvY2ssIG5ld0RlbHRhIHx8IDIwKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBhc3luYyBmdW5jdGlvbiBhZHZhbmNlVW50aWxNb2RlQ2hhbmdlcygpIHtcblx0ICAgICAgICAgICAgYXN5bmMgZnVuY3Rpb24gbmV3TWFjcm90YXNrKCkge1xuXHQgICAgICAgICAgICAgICAgLy8gTWVzc2FnZUNoYW5uZWwgZW5zdXJlcyB0aGF0IHNldFRpbWVvdXQgaXMgbm90IHRocm90dGxlZCB0byA0bXMuXG5cdCAgICAgICAgICAgICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvc2V0VGltZW91dCNyZWFzb25zX2Zvcl9kZWxheXNfbG9uZ2VyX3RoYW5fc3BlY2lmaWVkXG5cdCAgICAgICAgICAgICAgICAvLyBodHRwczovL3N0YWNrYmxpdHouY29tL2VkaXQvc3RhY2tibGl0ei1zdGFydGVycy1xdGxwY2Ncblx0ICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5jbG9zZSgpO1xuXHQgICAgICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSh1bmRlZmluZWQpO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICBjaGFubmVsLnBvcnQxLmNsb3NlKCk7XG5cdCAgICAgICAgICAgICAgICBjaGFubmVsLnBvcnQyLmNsb3NlKCk7XG5cdCAgICAgICAgICAgICAgICAvLyBzZXRUaW1lb3V0IGVuc3VyZXMgbWljcm90YXNrIHF1ZXVlIGlzIGVtcHRpZWRcblx0ICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxTZXRUaW1lb3V0KHJlc29sdmUpO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBjb25zdCB7IGNvdW50ZXIgfSA9IGNsb2NrLnRpY2tNb2RlO1xuXHQgICAgICAgICAgICB3aGlsZSAoY2xvY2sudGlja01vZGUuY291bnRlciA9PT0gY291bnRlcikge1xuXHQgICAgICAgICAgICAgICAgYXdhaXQgbmV3TWFjcm90YXNrKCk7XG5cdCAgICAgICAgICAgICAgICBpZiAoY2xvY2sudGlja01vZGUuY291bnRlciAhPT0gY291bnRlcikge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNsb2NrLm5leHQoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGZ1bmN0aW9uIHBhdXNlQXV0b1RpY2tVbnRpbEZpbmlzaGVkKHByb21pc2UpIHtcblx0ICAgICAgICAgICAgaWYgKGNsb2NrLnRpY2tNb2RlLm1vZGUgIT09IFwibmV4dEFzeW5jXCIpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNsb2NrLnNldFRpY2tNb2RlKHsgbW9kZTogXCJtYW51YWxcIiB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuZmluYWxseSgoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjbG9jay5zZXRUaWNrTW9kZSh7IG1vZGU6IFwibmV4dEFzeW5jXCIgfSk7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGNsb2NrLnJlcXVlc3RJZGxlQ2FsbGJhY2sgPSBmdW5jdGlvbiByZXF1ZXN0SWRsZUNhbGxiYWNrKFxuXHQgICAgICAgICAgICBmdW5jLFxuXHQgICAgICAgICAgICB0aW1lb3V0LFxuXHQgICAgICAgICkge1xuXHQgICAgICAgICAgICBsZXQgdGltZVRvTmV4dElkbGVQZXJpb2QgPSAwO1xuXG5cdCAgICAgICAgICAgIGlmIChjbG9jay5jb3VudFRpbWVycygpID4gMCkge1xuXHQgICAgICAgICAgICAgICAgdGltZVRvTmV4dElkbGVQZXJpb2QgPSA1MDsgLy8gY29uc3QgZm9yIG5vd1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYWRkVGltZXIoY2xvY2ssIHtcblx0ICAgICAgICAgICAgICAgIGZ1bmM6IGZ1bmMsXG5cdCAgICAgICAgICAgICAgICBhcmdzOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpLFxuXHQgICAgICAgICAgICAgICAgZGVsYXk6XG5cdCAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHRpbWVvdXQgPT09IFwidW5kZWZpbmVkXCJcblx0ICAgICAgICAgICAgICAgICAgICAgICAgPyB0aW1lVG9OZXh0SWRsZVBlcmlvZFxuXHQgICAgICAgICAgICAgICAgICAgICAgICA6IE1hdGgubWluKHRpbWVvdXQsIHRpbWVUb05leHRJZGxlUGVyaW9kKSxcblx0ICAgICAgICAgICAgICAgIGlkbGVDYWxsYmFjazogdHJ1ZSxcblx0ICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIE51bWJlcihyZXN1bHQpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBjbG9jay5jYW5jZWxJZGxlQ2FsbGJhY2sgPSBmdW5jdGlvbiBjYW5jZWxJZGxlQ2FsbGJhY2sodGltZXJJZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gY2xlYXJUaW1lcihjbG9jaywgdGltZXJJZCwgXCJJZGxlQ2FsbGJhY2tcIik7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLnNldFRpbWVvdXQgPSBmdW5jdGlvbiBzZXRUaW1lb3V0KGZ1bmMsIHRpbWVvdXQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGFkZFRpbWVyKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICBmdW5jOiBmdW5jLFxuXHQgICAgICAgICAgICAgICAgYXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKSxcblx0ICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lb3V0LFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiICYmIHV0aWxQcm9taXNpZnkpIHtcblx0ICAgICAgICAgICAgY2xvY2suc2V0VGltZW91dFt1dGlsUHJvbWlzaWZ5LmN1c3RvbV0gPVxuXHQgICAgICAgICAgICAgICAgZnVuY3Rpb24gcHJvbWlzaWZpZWRTZXRUaW1lb3V0KHRpbWVvdXQsIGFyZykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgX2dsb2JhbC5Qcm9taXNlKGZ1bmN0aW9uIHNldFRpbWVvdXRFeGVjdXRvcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSxcblx0ICAgICAgICAgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgYWRkVGltZXIoY2xvY2ssIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmM6IHJlc29sdmUsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbYXJnXSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lb3V0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2suY2xlYXJUaW1lb3V0ID0gZnVuY3Rpb24gY2xlYXJUaW1lb3V0KHRpbWVySWQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGNsZWFyVGltZXIoY2xvY2ssIHRpbWVySWQsIFwiVGltZW91dFwiKTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2submV4dFRpY2sgPSBmdW5jdGlvbiBuZXh0VGljayhmdW5jKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBlbnF1ZXVlSm9iKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICBmdW5jOiBmdW5jLFxuXHQgICAgICAgICAgICAgICAgYXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcblx0ICAgICAgICAgICAgICAgIGVycm9yOiBpc05lYXJJbmZpbml0ZUxpbWl0ID8gbmV3IEVycm9yKCkgOiBudWxsLFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2sucXVldWVNaWNyb3Rhc2sgPSBmdW5jdGlvbiBxdWV1ZU1pY3JvdGFzayhmdW5jKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbG9jay5uZXh0VGljayhmdW5jKTsgLy8gZXhwbGljaXRseSBkcm9wIGFkZGl0aW9uYWwgYXJndW1lbnRzXG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLnNldEludGVydmFsID0gZnVuY3Rpb24gc2V0SW50ZXJ2YWwoZnVuYywgdGltZW91dCkge1xuXHQgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0ICAgICAgICAgICAgdGltZW91dCA9IHBhcnNlSW50KHRpbWVvdXQsIDEwKTtcblx0ICAgICAgICAgICAgcmV0dXJuIGFkZFRpbWVyKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICBmdW5jOiBmdW5jLFxuXHQgICAgICAgICAgICAgICAgYXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKSxcblx0ICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lb3V0LFxuXHQgICAgICAgICAgICAgICAgaW50ZXJ2YWw6IHRpbWVvdXQsXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBjbG9jay5jbGVhckludGVydmFsID0gZnVuY3Rpb24gY2xlYXJJbnRlcnZhbCh0aW1lcklkKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbGVhclRpbWVyKGNsb2NrLCB0aW1lcklkLCBcIkludGVydmFsXCIpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAoaXNQcmVzZW50LnNldEltbWVkaWF0ZSkge1xuXHQgICAgICAgICAgICBjbG9jay5zZXRJbW1lZGlhdGUgPSBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZnVuYykge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGFkZFRpbWVyKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICAgICAgZnVuYzogZnVuYyxcblx0ICAgICAgICAgICAgICAgICAgICBhcmdzOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuXHQgICAgICAgICAgICAgICAgICAgIGltbWVkaWF0ZTogdHJ1ZSxcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB9O1xuXG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiICYmIHV0aWxQcm9taXNpZnkpIHtcblx0ICAgICAgICAgICAgICAgIGNsb2NrLnNldEltbWVkaWF0ZVt1dGlsUHJvbWlzaWZ5LmN1c3RvbV0gPVxuXHQgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHByb21pc2lmaWVkU2V0SW1tZWRpYXRlKGFyZykge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IF9nbG9iYWwuUHJvbWlzZShcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldEltbWVkaWF0ZUV4ZWN1dG9yKHJlc29sdmUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUaW1lcihjbG9jaywge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jOiByZXNvbHZlLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbYXJnXSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1tZWRpYXRlOiB0cnVlLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY2xvY2suY2xlYXJJbW1lZGlhdGUgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZSh0aW1lcklkKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2xlYXJUaW1lcihjbG9jaywgdGltZXJJZCwgXCJJbW1lZGlhdGVcIik7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2suY291bnRUaW1lcnMgPSBmdW5jdGlvbiBjb3VudFRpbWVycygpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIChcblx0ICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGNsb2NrLnRpbWVycyB8fCB7fSkubGVuZ3RoICtcblx0ICAgICAgICAgICAgICAgIChjbG9jay5qb2JzIHx8IFtdKS5sZW5ndGhcblx0ICAgICAgICAgICAgKTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2sucmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gZnVuY3Rpb24gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmMpIHtcblx0ICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYWRkVGltZXIoY2xvY2ssIHtcblx0ICAgICAgICAgICAgICAgIGZ1bmM6IGZ1bmMsXG5cdCAgICAgICAgICAgICAgICBkZWxheTogZ2V0VGltZVRvTmV4dEZyYW1lKCksXG5cdCAgICAgICAgICAgICAgICBnZXQgYXJncygpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gW2Zha2VQZXJmb3JtYW5jZU5vdygpXTtcblx0ICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICBhbmltYXRpb246IHRydWUsXG5cdCAgICAgICAgICAgIH0pO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBOdW1iZXIocmVzdWx0KTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2suY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSBmdW5jdGlvbiBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbGVhclRpbWVyKGNsb2NrLCB0aW1lcklkLCBcIkFuaW1hdGlvbkZyYW1lXCIpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBjbG9jay5ydW5NaWNyb3Rhc2tzID0gZnVuY3Rpb24gcnVuTWljcm90YXNrcygpIHtcblx0ICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gdGlja1ZhbHVlIG1pbGxpc2Vjb25kcyBvciBhIHN0cmluZyBwYXJzZWFibGUgYnkgcGFyc2VUaW1lXG5cdCAgICAgICAgICogQHBhcmFtIHtib29sZWFufSBpc0FzeW5jXG5cdCAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZVxuXHQgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlamVjdFxuXHQgICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ8dW5kZWZpbmVkfSB3aWxsIHJldHVybiB0aGUgbmV3IGBub3dgIHZhbHVlIG9yIG5vdGhpbmcgZm9yIGFzeW5jXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZnVuY3Rpb24gZG9UaWNrKHRpY2tWYWx1ZSwgaXNBc3luYywgcmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IG1zRmxvYXQgPVxuXHQgICAgICAgICAgICAgICAgdHlwZW9mIHRpY2tWYWx1ZSA9PT0gXCJudW1iZXJcIlxuXHQgICAgICAgICAgICAgICAgICAgID8gdGlja1ZhbHVlXG5cdCAgICAgICAgICAgICAgICAgICAgOiBwYXJzZVRpbWUodGlja1ZhbHVlKTtcblx0ICAgICAgICAgICAgY29uc3QgbXMgPSBNYXRoLmZsb29yKG1zRmxvYXQpO1xuXHQgICAgICAgICAgICBjb25zdCByZW1haW5kZXIgPSBuYW5vUmVtYWluZGVyKG1zRmxvYXQpO1xuXHQgICAgICAgICAgICBsZXQgbmFub3NUb3RhbCA9IG5hbm9zICsgcmVtYWluZGVyO1xuXHQgICAgICAgICAgICBsZXQgdGlja1RvID0gY2xvY2subm93ICsgbXM7XG5cblx0ICAgICAgICAgICAgaWYgKG1zRmxvYXQgPCAwKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTmVnYXRpdmUgdGlja3MgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBhZGp1c3QgZm9yIHBvc2l0aXZlIG92ZXJmbG93XG5cdCAgICAgICAgICAgIGlmIChuYW5vc1RvdGFsID49IDFlNikge1xuXHQgICAgICAgICAgICAgICAgdGlja1RvICs9IDE7XG5cdCAgICAgICAgICAgICAgICBuYW5vc1RvdGFsIC09IDFlNjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIG5hbm9zID0gbmFub3NUb3RhbDtcblx0ICAgICAgICAgICAgbGV0IHRpY2tGcm9tID0gY2xvY2subm93O1xuXHQgICAgICAgICAgICBsZXQgcHJldmlvdXMgPSBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgIC8vIEVTTGludCBmYWlscyB0byBkZXRlY3QgdGhpcyBjb3JyZWN0bHlcblx0ICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgcHJlZmVyLWNvbnN0ICovXG5cdCAgICAgICAgICAgIGxldCB0aW1lcixcblx0ICAgICAgICAgICAgICAgIGZpcnN0RXhjZXB0aW9uLFxuXHQgICAgICAgICAgICAgICAgb2xkTm93LFxuXHQgICAgICAgICAgICAgICAgbmV4dFByb21pc2VUaWNrLFxuXHQgICAgICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2ssXG5cdCAgICAgICAgICAgICAgICBwb3N0VGltZXJDYWxsO1xuXHQgICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIHByZWZlci1jb25zdCAqL1xuXG5cdCAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSB0cnVlO1xuXG5cdCAgICAgICAgICAgIC8vIHBlcmZvcm0gbWljcm90YXNrc1xuXHQgICAgICAgICAgICBvbGROb3cgPSBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgIHJ1bkpvYnMoY2xvY2spO1xuXHQgICAgICAgICAgICBpZiAob2xkTm93ICE9PSBjbG9jay5ub3cpIHtcblx0ICAgICAgICAgICAgICAgIC8vIGNvbXBlbnNhdGUgZm9yIGFueSBzZXRTeXN0ZW1UaW1lKCkgY2FsbCBkdXJpbmcgbWljcm90YXNrIGNhbGxiYWNrXG5cdCAgICAgICAgICAgICAgICB0aWNrRnJvbSArPSBjbG9jay5ub3cgLSBvbGROb3c7XG5cdCAgICAgICAgICAgICAgICB0aWNrVG8gKz0gY2xvY2subm93IC0gb2xkTm93O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgICAgICAgICBmdW5jdGlvbiBkb1RpY2tJbm5lcigpIHtcblx0ICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gZWFjaCB0aW1lciBpbiB0aGUgcmVxdWVzdGVkIHJhbmdlXG5cdCAgICAgICAgICAgICAgICB0aW1lciA9IGZpcnN0VGltZXJJblJhbmdlKGNsb2NrLCB0aWNrRnJvbSwgdGlja1RvKTtcblx0ICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bm1vZGlmaWVkLWxvb3AtY29uZGl0aW9uXG5cdCAgICAgICAgICAgICAgICB3aGlsZSAodGltZXIgJiYgdGlja0Zyb20gPD0gdGlja1RvKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGNsb2NrLnRpbWVyc1t0aW1lci5pZF0pIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdGlja0Zyb20gPSB0aW1lci5jYWxsQXQ7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLm5vdyA9IHRpbWVyLmNhbGxBdDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb2xkTm93ID0gY2xvY2subm93O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RFeGNlcHRpb24gPSBmaXJzdEV4Y2VwdGlvbiB8fCBlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXN5bmMpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmlzaCB1cCBhZnRlciBuYXRpdmUgc2V0SW1tZWRpYXRlIGNhbGxiYWNrIHRvIGFsbG93XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbGwgbmF0aXZlIGVzNiBwcm9taXNlcyB0byBwcm9jZXNzIHRoZWlyIGNhbGxiYWNrcyBhZnRlclxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWFjaCB0aW1lciBmaXJlcy5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChuZXh0UHJvbWlzZVRpY2spO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2soKTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICBwb3N0VGltZXJDYWxsKCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gcHJvY2Vzcy5uZXh0VGljaygpcyBhZ2FpblxuXHQgICAgICAgICAgICAgICAgb2xkTm93ID0gY2xvY2subm93O1xuXHQgICAgICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cdCAgICAgICAgICAgICAgICBpZiAob2xkTm93ICE9PSBjbG9jay5ub3cpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBjb21wZW5zYXRlIGZvciBhbnkgc2V0U3lzdGVtVGltZSgpIGNhbGwgZHVyaW5nIHByb2Nlc3MubmV4dFRpY2soKSBjYWxsYmFja1xuXHQgICAgICAgICAgICAgICAgICAgIHRpY2tGcm9tICs9IGNsb2NrLm5vdyAtIG9sZE5vdztcblx0ICAgICAgICAgICAgICAgICAgICB0aWNrVG8gKz0gY2xvY2subm93IC0gb2xkTm93O1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgY2xvY2suZHVyaW5nVGljayA9IGZhbHNlO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBjb3JuZXIgY2FzZTogZHVyaW5nIHJ1bkpvYnMgbmV3IHRpbWVycyB3ZXJlIHNjaGVkdWxlZCB3aGljaCBjb3VsZCBiZSBpbiB0aGUgcmFuZ2UgW2Nsb2NrLm5vdywgdGlja1RvXVxuXHQgICAgICAgICAgICAgICAgdGltZXIgPSBmaXJzdFRpbWVySW5SYW5nZShjbG9jaywgdGlja0Zyb20sIHRpY2tUbyk7XG5cdCAgICAgICAgICAgICAgICBpZiAodGltZXIpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay50aWNrKHRpY2tUbyAtIGNsb2NrLm5vdyk7IC8vIGRvIGl0IGFsbCBhZ2FpbiAtIGZvciB0aGUgcmVtYWluZGVyIG9mIHRoZSByZXF1ZXN0ZWQgcmFuZ2Vcblx0ICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0RXhjZXB0aW9uID0gZmlyc3RFeGNlcHRpb24gfHwgZTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIG5vIHRpbWVycyByZW1haW5pbmcgaW4gdGhlIHJlcXVlc3RlZCByYW5nZTogbW92ZSB0aGUgY2xvY2sgYWxsIHRoZSB3YXkgdG8gdGhlIGVuZFxuXHQgICAgICAgICAgICAgICAgICAgIGNsb2NrLm5vdyA9IHRpY2tUbztcblxuXHQgICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBuYW5vc1xuXHQgICAgICAgICAgICAgICAgICAgIG5hbm9zID0gbmFub3NUb3RhbDtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChmaXJzdEV4Y2VwdGlvbikge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IGZpcnN0RXhjZXB0aW9uO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICBpZiAoaXNBc3luYykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoY2xvY2subm93KTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsb2NrLm5vdztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIG5leHRQcm9taXNlVGljayA9XG5cdCAgICAgICAgICAgICAgICBpc0FzeW5jICYmXG5cdCAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2soKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcG9zdFRpbWVyQ2FsbCgpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBkb1RpY2tJbm5lcigpO1xuXHQgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2sgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBjb21wZW5zYXRlIGZvciBhbnkgc2V0U3lzdGVtVGltZSgpIGNhbGwgZHVyaW5nIHRpbWVyIGNhbGxiYWNrXG5cdCAgICAgICAgICAgICAgICBpZiAob2xkTm93ICE9PSBjbG9jay5ub3cpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aWNrRnJvbSArPSBjbG9jay5ub3cgLSBvbGROb3c7XG5cdCAgICAgICAgICAgICAgICAgICAgdGlja1RvICs9IGNsb2NrLm5vdyAtIG9sZE5vdztcblx0ICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyArPSBjbG9jay5ub3cgLSBvbGROb3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgcG9zdFRpbWVyQ2FsbCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHRpbWVyID0gZmlyc3RUaW1lckluUmFuZ2UoY2xvY2ssIHByZXZpb3VzLCB0aWNrVG8pO1xuXHQgICAgICAgICAgICAgICAgcHJldmlvdXMgPSB0aWNrRnJvbTtcblx0ICAgICAgICAgICAgfTtcblxuXHQgICAgICAgICAgICByZXR1cm4gZG9UaWNrSW5uZXIoKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHRpY2tWYWx1ZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIG9yIGEgaHVtYW4tcmVhZGFibGUgdmFsdWUgbGlrZSBcIjAxOjExOjE1XCJcblx0ICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSB3aWxsIHJldHVybiB0aGUgbmV3IGBub3dgIHZhbHVlXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvY2sudGljayA9IGZ1bmN0aW9uIHRpY2sodGlja1ZhbHVlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBkb1RpY2sodGlja1ZhbHVlLCBmYWxzZSk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiKSB7XG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHRpY2tWYWx1ZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIG9yIGEgaHVtYW4tcmVhZGFibGUgdmFsdWUgbGlrZSBcIjAxOjExOjE1XCJcblx0ICAgICAgICAgICAgICogQHJldHVybnMge1Byb21pc2V9XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBjbG9jay50aWNrQXN5bmMgPSBmdW5jdGlvbiB0aWNrQXN5bmModGlja1ZhbHVlKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gcGF1c2VBdXRvVGlja1VudGlsRmluaXNoZWQoXG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IF9nbG9iYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvVGljayh0aWNrVmFsdWUsIHRydWUsIHJlc29sdmUsIHJlamVjdCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KSxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2submV4dCA9IGZ1bmN0aW9uIG5leHQoKSB7XG5cdCAgICAgICAgICAgIHJ1bkpvYnMoY2xvY2spO1xuXHQgICAgICAgICAgICBjb25zdCB0aW1lciA9IGZpcnN0VGltZXIoY2xvY2spO1xuXHQgICAgICAgICAgICBpZiAoIXRpbWVyKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2xvY2subm93O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY2xvY2suZHVyaW5nVGljayA9IHRydWU7XG5cdCAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICBjbG9jay5ub3cgPSB0aW1lci5jYWxsQXQ7XG5cdCAgICAgICAgICAgICAgICBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKTtcblx0ICAgICAgICAgICAgICAgIHJ1bkpvYnMoY2xvY2spO1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGNsb2NrLm5vdztcblx0ICAgICAgICAgICAgfSBmaW5hbGx5IHtcblx0ICAgICAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSBmYWxzZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAodHlwZW9mIF9nbG9iYWwuUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgICAgICAgICBjbG9jay5uZXh0QXN5bmMgPSBmdW5jdGlvbiBuZXh0QXN5bmMoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gcGF1c2VBdXRvVGlja1VudGlsRmluaXNoZWQoXG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IF9nbG9iYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWVyID0gZmlyc3RUaW1lcihjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aW1lcikge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGNsb2NrLm5vdyk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXJyO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSB0cnVlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLm5vdyA9IHRpbWVyLmNhbGxBdDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyciA9IGU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSBmYWxzZTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KSxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2sucnVuQWxsID0gZnVuY3Rpb24gcnVuQWxsKCkge1xuXHQgICAgICAgICAgICBsZXQgbnVtVGltZXJzLCBpO1xuXHQgICAgICAgICAgICBydW5Kb2JzKGNsb2NrKTtcblx0ICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNsb2NrLmxvb3BMaW1pdDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoIWNsb2NrLnRpbWVycykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc2V0SXNOZWFySW5maW5pdGVMaW1pdCgpO1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIG51bVRpbWVycyA9IE9iamVjdC5rZXlzKGNsb2NrLnRpbWVycykubGVuZ3RoO1xuXHQgICAgICAgICAgICAgICAgaWYgKG51bVRpbWVycyA9PT0gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc2V0SXNOZWFySW5maW5pdGVMaW1pdCgpO1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIGNsb2NrLm5leHQoKTtcblx0ICAgICAgICAgICAgICAgIGNoZWNrSXNOZWFySW5maW5pdGVMaW1pdChjbG9jaywgaSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBjb25zdCBleGNlc3NKb2IgPSBmaXJzdFRpbWVyKGNsb2NrKTtcblx0ICAgICAgICAgICAgdGhyb3cgZ2V0SW5maW5pdGVMb29wRXJyb3IoY2xvY2ssIGV4Y2Vzc0pvYik7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLnJ1blRvRnJhbWUgPSBmdW5jdGlvbiBydW5Ub0ZyYW1lKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gY2xvY2sudGljayhnZXRUaW1lVG9OZXh0RnJhbWUoKSk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnJ1bkFsbEFzeW5jID0gZnVuY3Rpb24gcnVuQWxsQXN5bmMoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gcGF1c2VBdXRvVGlja1VudGlsRmluaXNoZWQoXG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IF9nbG9iYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpID0gMDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb1J1bigpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG51bVRpbWVycztcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBjbG9jay5sb29wTGltaXQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2xvY2sudGltZXJzKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXRJc05lYXJJbmZpbml0ZUxpbWl0KCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtVGltZXJzID0gT2JqZWN0LmtleXMoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2sudGltZXJzLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKS5sZW5ndGg7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobnVtVGltZXJzID09PSAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXRJc05lYXJJbmZpbml0ZUxpbWl0KCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2submV4dCgpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpKys7XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvUnVuKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0lzTmVhckluZmluaXRlTGltaXQoY2xvY2ssIGkpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXhjZXNzSm9iID0gZmlyc3RUaW1lcihjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEluZmluaXRlTG9vcEVycm9yKGNsb2NrLCBleGNlc3NKb2IpLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGRvUnVuKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgfSksXG5cdCAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGNsb2NrLnJ1blRvTGFzdCA9IGZ1bmN0aW9uIHJ1blRvTGFzdCgpIHtcblx0ICAgICAgICAgICAgY29uc3QgdGltZXIgPSBsYXN0VGltZXIoY2xvY2spO1xuXHQgICAgICAgICAgICBpZiAoIXRpbWVyKSB7XG5cdCAgICAgICAgICAgICAgICBydW5Kb2JzKGNsb2NrKTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gY2xvY2sudGljayh0aW1lci5jYWxsQXQgLSBjbG9jay5ub3cpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAodHlwZW9mIF9nbG9iYWwuUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgICAgICAgICBjbG9jay5ydW5Ub0xhc3RBc3luYyA9IGZ1bmN0aW9uIHJ1blRvTGFzdEFzeW5jKCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHBhdXNlQXV0b1RpY2tVbnRpbEZpbmlzaGVkKFxuXHQgICAgICAgICAgICAgICAgICAgIG5ldyBfZ2xvYmFsLlByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbFNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lciA9IGxhc3RUaW1lcihjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aW1lcikge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5Kb2JzKGNsb2NrKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLnRpY2tBc3luYyh0aW1lci5jYWxsQXQgLSBjbG9jay5ub3cpLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KSxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2sucmVzZXQgPSBmdW5jdGlvbiByZXNldCgpIHtcblx0ICAgICAgICAgICAgbmFub3MgPSAwO1xuXHQgICAgICAgICAgICBjbG9jay50aW1lcnMgPSB7fTtcblx0ICAgICAgICAgICAgY2xvY2suam9icyA9IFtdO1xuXHQgICAgICAgICAgICBjbG9jay5ub3cgPSBzdGFydDtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2suc2V0U3lzdGVtVGltZSA9IGZ1bmN0aW9uIHNldFN5c3RlbVRpbWUoc3lzdGVtVGltZSkge1xuXHQgICAgICAgICAgICAvLyBkZXRlcm1pbmUgdGltZSBkaWZmZXJlbmNlXG5cdCAgICAgICAgICAgIGNvbnN0IG5ld05vdyA9IGdldEVwb2NoKHN5c3RlbVRpbWUpO1xuXHQgICAgICAgICAgICBjb25zdCBkaWZmZXJlbmNlID0gbmV3Tm93IC0gY2xvY2subm93O1xuXHQgICAgICAgICAgICBsZXQgaWQsIHRpbWVyO1xuXG5cdCAgICAgICAgICAgIGFkanVzdGVkU3lzdGVtVGltZVswXSA9IGFkanVzdGVkU3lzdGVtVGltZVswXSArIGRpZmZlcmVuY2U7XG5cdCAgICAgICAgICAgIGFkanVzdGVkU3lzdGVtVGltZVsxXSA9IGFkanVzdGVkU3lzdGVtVGltZVsxXSArIG5hbm9zO1xuXHQgICAgICAgICAgICAvLyB1cGRhdGUgJ3N5c3RlbSBjbG9jaydcblx0ICAgICAgICAgICAgY2xvY2subm93ID0gbmV3Tm93O1xuXHQgICAgICAgICAgICBuYW5vcyA9IDA7XG5cblx0ICAgICAgICAgICAgLy8gdXBkYXRlIHRpbWVycyBhbmQgaW50ZXJ2YWxzIHRvIGtlZXAgdGhlbSBzdGFibGVcblx0ICAgICAgICAgICAgZm9yIChpZCBpbiBjbG9jay50aW1lcnMpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChjbG9jay50aW1lcnMuaGFzT3duUHJvcGVydHkoaWQpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGltZXIgPSBjbG9jay50aW1lcnNbaWRdO1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyLmNyZWF0ZWRBdCArPSBkaWZmZXJlbmNlO1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyLmNhbGxBdCArPSBkaWZmZXJlbmNlO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gdGlja1ZhbHVlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgb3IgYSBodW1hbi1yZWFkYWJsZSB2YWx1ZSBsaWtlIFwiMDE6MTE6MTVcIlxuXHQgICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IHdpbGwgcmV0dXJuIHRoZSBuZXcgYG5vd2AgdmFsdWVcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjbG9jay5qdW1wID0gZnVuY3Rpb24ganVtcCh0aWNrVmFsdWUpIHtcblx0ICAgICAgICAgICAgY29uc3QgbXNGbG9hdCA9XG5cdCAgICAgICAgICAgICAgICB0eXBlb2YgdGlja1ZhbHVlID09PSBcIm51bWJlclwiXG5cdCAgICAgICAgICAgICAgICAgICAgPyB0aWNrVmFsdWVcblx0ICAgICAgICAgICAgICAgICAgICA6IHBhcnNlVGltZSh0aWNrVmFsdWUpO1xuXHQgICAgICAgICAgICBjb25zdCBtcyA9IE1hdGguZmxvb3IobXNGbG9hdCk7XG5cblx0ICAgICAgICAgICAgZm9yIChjb25zdCB0aW1lciBvZiBPYmplY3QudmFsdWVzKGNsb2NrLnRpbWVycykpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChjbG9jay5ub3cgKyBtcyA+IHRpbWVyLmNhbGxBdCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyLmNhbGxBdCA9IGNsb2NrLm5vdyArIG1zO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNsb2NrLnRpY2sobXMpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAoaXNQcmVzZW50LnBlcmZvcm1hbmNlKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnBlcmZvcm1hbmNlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblx0ICAgICAgICAgICAgY2xvY2sucGVyZm9ybWFuY2Uubm93ID0gZmFrZVBlcmZvcm1hbmNlTm93O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChpc1ByZXNlbnQuaHJ0aW1lKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLmhydGltZSA9IGhydGltZTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gY2xvY2s7XG5cdCAgICB9XG5cblx0ICAgIGZ1bmN0aW9uIGNyZWF0ZUludGVydmFsVGljayhjbG9jaywgZGVsdGEpIHtcblx0ICAgICAgICBjb25zdCBpbnRlcnZhbFRpY2sgPSBkb0ludGVydmFsVGljay5iaW5kKG51bGwsIGNsb2NrLCBkZWx0YSk7XG5cdCAgICAgICAgY29uc3QgaW50ZXJ2YWxJZCA9IG9yaWdpbmFsU2V0SW50ZXJ2YWwoaW50ZXJ2YWxUaWNrLCBkZWx0YSk7XG5cdCAgICAgICAgY2xvY2suYXR0YWNoZWRJbnRlcnZhbCA9IGludGVydmFsSWQ7XG5cdCAgICB9XG5cblx0ICAgIC8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge0NvbmZpZz19IFtjb25maWddIE9wdGlvbmFsIGNvbmZpZ1xuXHQgICAgICogQHJldHVybnMge0Nsb2NrfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBpbnN0YWxsKGNvbmZpZykge1xuXHQgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA+IDEgfHxcblx0ICAgICAgICAgICAgY29uZmlnIGluc3RhbmNlb2YgRGF0ZSB8fFxuXHQgICAgICAgICAgICBBcnJheS5pc0FycmF5KGNvbmZpZykgfHxcblx0ICAgICAgICAgICAgdHlwZW9mIGNvbmZpZyA9PT0gXCJudW1iZXJcIlxuXHQgICAgICAgICkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuXHQgICAgICAgICAgICAgICAgYEZha2VUaW1lcnMuaW5zdGFsbCBjYWxsZWQgd2l0aCAke1N0cmluZyhcblx0ICAgICAgICAgICAgICAgICAgICBjb25maWcsXG5cdCAgICAgICAgICAgICAgICApfSBpbnN0YWxsIHJlcXVpcmVzIGFuIG9iamVjdCBwYXJhbWV0ZXJgLFxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChfZ2xvYmFsLkRhdGUuaXNGYWtlID09PSB0cnVlKSB7XG5cdCAgICAgICAgICAgIC8vIFRpbWVycyBhcmUgYWxyZWFkeSBmYWtlZDsgdGhpcyBpcyBhIHByb2JsZW0uXG5cdCAgICAgICAgICAgIC8vIE1ha2UgdGhlIHVzZXIgcmVzZXQgdGltZXJzIGJlZm9yZSBjb250aW51aW5nLlxuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuXHQgICAgICAgICAgICAgICAgXCJDYW4ndCBpbnN0YWxsIGZha2UgdGltZXJzIHR3aWNlIG9uIHRoZSBzYW1lIGdsb2JhbCBvYmplY3QuXCIsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdCAgICAgICAgY29uZmlnID0gdHlwZW9mIGNvbmZpZyAhPT0gXCJ1bmRlZmluZWRcIiA/IGNvbmZpZyA6IHt9O1xuXHQgICAgICAgIGNvbmZpZy5zaG91bGRBZHZhbmNlVGltZSA9IGNvbmZpZy5zaG91bGRBZHZhbmNlVGltZSB8fCBmYWxzZTtcblx0ICAgICAgICBjb25maWcuYWR2YW5jZVRpbWVEZWx0YSA9IGNvbmZpZy5hZHZhbmNlVGltZURlbHRhIHx8IDIwO1xuXHQgICAgICAgIGNvbmZpZy5zaG91bGRDbGVhck5hdGl2ZVRpbWVycyA9XG5cdCAgICAgICAgICAgIGNvbmZpZy5zaG91bGRDbGVhck5hdGl2ZVRpbWVycyB8fCBmYWxzZTtcblxuXHQgICAgICAgIGlmIChjb25maWcudGFyZ2V0KSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG5cdCAgICAgICAgICAgICAgICBcImNvbmZpZy50YXJnZXQgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC4gVXNlIGB3aXRoR2xvYmFsKHRhcmdldClgIGluc3RlYWQuXCIsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHRpbWVyL29iamVjdCB0aGUgbmFtZSBvZiB0aGUgdGhpbmcgdGhhdCBpcyBub3QgcHJlc2VudFxuXHQgICAgICAgICAqIEBwYXJhbSB0aW1lclxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZ1bmN0aW9uIGhhbmRsZU1pc3NpbmdUaW1lcih0aW1lcikge1xuXHQgICAgICAgICAgICBpZiAoY29uZmlnLmlnbm9yZU1pc3NpbmdUaW1lcnMpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcblx0ICAgICAgICAgICAgICAgIGBub24tZXhpc3RlbnQgdGltZXJzIGFuZC9vciBvYmplY3RzIGNhbm5vdCBiZSBmYWtlZDogJyR7dGltZXJ9J2AsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgbGV0IGksIGw7XG5cdCAgICAgICAgY29uc3QgY2xvY2sgPSBjcmVhdGVDbG9jayhjb25maWcubm93LCBjb25maWcubG9vcExpbWl0KTtcblx0ICAgICAgICBjbG9jay5zaG91bGRDbGVhck5hdGl2ZVRpbWVycyA9IGNvbmZpZy5zaG91bGRDbGVhck5hdGl2ZVRpbWVycztcblxuXHQgICAgICAgIGNsb2NrLnVuaW5zdGFsbCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHVuaW5zdGFsbChjbG9jayk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAgPSBuZXcgTWFwKCk7XG5cblx0ICAgICAgICBjbG9jay5tZXRob2RzID0gY29uZmlnLnRvRmFrZSB8fCBbXTtcblxuXHQgICAgICAgIGlmIChjbG9jay5tZXRob2RzLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgICAgICAgICBjbG9jay5tZXRob2RzID0gT2JqZWN0LmtleXModGltZXJzKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoY29uZmlnLnNob3VsZEFkdmFuY2VUaW1lID09PSB0cnVlKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnNldFRpY2tNb2RlKHtcblx0ICAgICAgICAgICAgICAgIG1vZGU6IFwiaW50ZXJ2YWxcIixcblx0ICAgICAgICAgICAgICAgIGRlbHRhOiBjb25maWcuYWR2YW5jZVRpbWVEZWx0YSxcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKGNsb2NrLm1ldGhvZHMuaW5jbHVkZXMoXCJwZXJmb3JtYW5jZVwiKSkge1xuXHQgICAgICAgICAgICBjb25zdCBwcm90byA9ICgoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBpZiAoaGFzUGVyZm9ybWFuY2VDb25zdHJ1Y3RvclByb3RvdHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBfZ2xvYmFsLnBlcmZvcm1hbmNlLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChoYXNQZXJmb3JtYW5jZVByb3RvdHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBfZ2xvYmFsLlBlcmZvcm1hbmNlLnByb3RvdHlwZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSkoKTtcblx0ICAgICAgICAgICAgaWYgKHByb3RvKSB7XG5cdCAgICAgICAgICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhwcm90bykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lICE9PSBcIm5vd1wiKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLnBlcmZvcm1hbmNlW25hbWVdID1cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuaW5kZXhPZihcImdldEVudHJpZXNcIikgPT09IDBcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IE5PT1BfQVJSQVlcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IE5PT1A7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICAvLyBlbnN1cmUgYG1hcmtgIHJldHVybnMgYSB2YWx1ZSB0aGF0IGlzIHZhbGlkXG5cdCAgICAgICAgICAgICAgICBjbG9jay5wZXJmb3JtYW5jZS5tYXJrID0gKG5hbWUpID0+XG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IEZha2VQZXJmb3JtYW5jZUVudHJ5KG5hbWUsIFwibWFya1wiLCAwLCAwKTtcblx0ICAgICAgICAgICAgICAgIGNsb2NrLnBlcmZvcm1hbmNlLm1lYXN1cmUgPSAobmFtZSkgPT5cblx0ICAgICAgICAgICAgICAgICAgICBuZXcgRmFrZVBlcmZvcm1hbmNlRW50cnkobmFtZSwgXCJtZWFzdXJlXCIsIDAsIDEwMCk7XG5cdCAgICAgICAgICAgICAgICAvLyBgdGltZU9yaWdpbmAgc2hvdWxkIHJldHVybiB0aGUgdGltZSBvZiB3aGVuIHRoZSBXaW5kb3cgc2Vzc2lvbiBzdGFydGVkXG5cdCAgICAgICAgICAgICAgICAvLyAob3IgdGhlIFdvcmtlciB3YXMgaW5zdGFsbGVkKVxuXHQgICAgICAgICAgICAgICAgY2xvY2sucGVyZm9ybWFuY2UudGltZU9yaWdpbiA9IGdldEVwb2NoKGNvbmZpZy5ub3cpO1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKChjb25maWcudG9GYWtlIHx8IFtdKS5pbmNsdWRlcyhcInBlcmZvcm1hbmNlXCIpKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlTWlzc2luZ1RpbWVyKFwicGVyZm9ybWFuY2VcIik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKF9nbG9iYWwgPT09IGdsb2JhbE9iamVjdCAmJiB0aW1lcnNNb2R1bGUpIHtcblx0ICAgICAgICAgICAgY2xvY2sudGltZXJzTW9kdWxlTWV0aG9kcyA9IFtdO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoX2dsb2JhbCA9PT0gZ2xvYmFsT2JqZWN0ICYmIHRpbWVyc1Byb21pc2VzTW9kdWxlKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnRpbWVyc1Byb21pc2VzTW9kdWxlTWV0aG9kcyA9IFtdO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBmb3IgKGkgPSAwLCBsID0gY2xvY2subWV0aG9kcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblx0ICAgICAgICAgICAgY29uc3QgbmFtZU9mTWV0aG9kVG9SZXBsYWNlID0gY2xvY2subWV0aG9kc1tpXTtcblxuXHQgICAgICAgICAgICBpZiAoIWlzUHJlc2VudFtuYW1lT2ZNZXRob2RUb1JlcGxhY2VdKSB7XG5cdCAgICAgICAgICAgICAgICBoYW5kbGVNaXNzaW5nVGltZXIobmFtZU9mTWV0aG9kVG9SZXBsYWNlKTtcblx0ICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXHQgICAgICAgICAgICAgICAgY29udGludWU7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBpZiAobmFtZU9mTWV0aG9kVG9SZXBsYWNlID09PSBcImhydGltZVwiKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoXG5cdCAgICAgICAgICAgICAgICAgICAgX2dsb2JhbC5wcm9jZXNzICYmXG5cdCAgICAgICAgICAgICAgICAgICAgdHlwZW9mIF9nbG9iYWwucHJvY2Vzcy5ocnRpbWUgPT09IFwiZnVuY3Rpb25cIlxuXHQgICAgICAgICAgICAgICAgKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaGlqYWNrTWV0aG9kKF9nbG9iYWwucHJvY2VzcywgbmFtZU9mTWV0aG9kVG9SZXBsYWNlLCBjbG9jayk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZU9mTWV0aG9kVG9SZXBsYWNlID09PSBcIm5leHRUaWNrXCIpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgICAgICAgICBfZ2xvYmFsLnByb2Nlc3MgJiZcblx0ICAgICAgICAgICAgICAgICAgICB0eXBlb2YgX2dsb2JhbC5wcm9jZXNzLm5leHRUaWNrID09PSBcImZ1bmN0aW9uXCJcblx0ICAgICAgICAgICAgICAgICkge1xuXHQgICAgICAgICAgICAgICAgICAgIGhpamFja01ldGhvZChfZ2xvYmFsLnByb2Nlc3MsIG5hbWVPZk1ldGhvZFRvUmVwbGFjZSwgY2xvY2spO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgaGlqYWNrTWV0aG9kKF9nbG9iYWwsIG5hbWVPZk1ldGhvZFRvUmVwbGFjZSwgY2xvY2spO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgICAgIGNsb2NrLnRpbWVyc01vZHVsZU1ldGhvZHMgIT09IHVuZGVmaW5lZCAmJlxuXHQgICAgICAgICAgICAgICAgdGltZXJzTW9kdWxlW25hbWVPZk1ldGhvZFRvUmVwbGFjZV1cblx0ICAgICAgICAgICAgKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW5hbCA9IHRpbWVyc01vZHVsZVtuYW1lT2ZNZXRob2RUb1JlcGxhY2VdO1xuXHQgICAgICAgICAgICAgICAgY2xvY2sudGltZXJzTW9kdWxlTWV0aG9kcy5wdXNoKHtcblx0ICAgICAgICAgICAgICAgICAgICBtZXRob2ROYW1lOiBuYW1lT2ZNZXRob2RUb1JlcGxhY2UsXG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWw6IG9yaWdpbmFsLFxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB0aW1lcnNNb2R1bGVbbmFtZU9mTWV0aG9kVG9SZXBsYWNlXSA9XG5cdCAgICAgICAgICAgICAgICAgICAgX2dsb2JhbFtuYW1lT2ZNZXRob2RUb1JlcGxhY2VdO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChjbG9jay50aW1lcnNQcm9taXNlc01vZHVsZU1ldGhvZHMgIT09IHVuZGVmaW5lZCkge1xuXHQgICAgICAgICAgICAgICAgaWYgKG5hbWVPZk1ldGhvZFRvUmVwbGFjZSA9PT0gXCJzZXRUaW1lb3V0XCIpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jay50aW1lcnNQcm9taXNlc01vZHVsZU1ldGhvZHMucHVzaCh7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWU6IFwic2V0VGltZW91dFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbDogdGltZXJzUHJvbWlzZXNNb2R1bGUuc2V0VGltZW91dCxcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblxuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyc1Byb21pc2VzTW9kdWxlLnNldFRpbWVvdXQgPSAoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGRlbGF5LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9LFxuXHQgICAgICAgICAgICAgICAgICAgICkgPT5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWJvcnQgPSAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgc2FmZSwgdGhlcmUgaXMgbm8gY29kZSBwYXRoIHRoYXQgbGVhZHMgdG8gdGhpcyBmdW5jdGlvblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlaW5nIGludm9rZWQgYmVmb3JlIGhhbmRsZSBoYXMgYmVlbiBhc3NpZ25lZC5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5jbGVhclRpbWVvdXQoaGFuZGxlKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3Qob3B0aW9ucy5zaWduYWwucmVhc29uKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZSA9IGNsb2NrLnNldFRpbWVvdXQoKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNpZ25hbCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHZhbHVlKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIGRlbGF5KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsLmFib3J0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuc2V0KFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lT2ZNZXRob2RUb1JlcGxhY2UgPT09IFwic2V0SW1tZWRpYXRlXCIpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jay50aW1lcnNQcm9taXNlc01vZHVsZU1ldGhvZHMucHVzaCh7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWU6IFwic2V0SW1tZWRpYXRlXCIsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsOiB0aW1lcnNQcm9taXNlc01vZHVsZS5zZXRJbW1lZGlhdGUsXG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgICAgICAgICB0aW1lcnNQcm9taXNlc01vZHVsZS5zZXRJbW1lZGlhdGUgPSAodmFsdWUsIG9wdGlvbnMgPSB7fSkgPT5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWJvcnQgPSAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgc2FmZSwgdGhlcmUgaXMgbm8gY29kZSBwYXRoIHRoYXQgbGVhZHMgdG8gdGhpcyBmdW5jdGlvblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlaW5nIGludm9rZWQgYmVmb3JlIGhhbmRsZSBoYXMgYmVlbiBhc3NpZ25lZC5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5jbGVhckltbWVkaWF0ZShoYW5kbGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChvcHRpb25zLnNpZ25hbC5yZWFzb24pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlID0gY2xvY2suc2V0SW1tZWRpYXRlKCgpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zaWduYWwpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYWJvcnRcIixcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5hYm9ydExpc3RlbmVyTWFwLmRlbGV0ZShhYm9ydCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsLmFib3J0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuc2V0KFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lT2ZNZXRob2RUb1JlcGxhY2UgPT09IFwic2V0SW50ZXJ2YWxcIikge1xuXHQgICAgICAgICAgICAgICAgICAgIGNsb2NrLnRpbWVyc1Byb21pc2VzTW9kdWxlTWV0aG9kcy5wdXNoKHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kTmFtZTogXCJzZXRJbnRlcnZhbFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbDogdGltZXJzUHJvbWlzZXNNb2R1bGUuc2V0SW50ZXJ2YWwsXG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgICAgICAgICB0aW1lcnNQcm9taXNlc01vZHVsZS5zZXRJbnRlcnZhbCA9IChcblx0ICAgICAgICAgICAgICAgICAgICAgICAgZGVsYXksXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0ge30sXG5cdCAgICAgICAgICAgICAgICAgICAgKSA9PiAoe1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBbU3ltYm9sLmFzeW5jSXRlcmF0b3JdOiAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjcmVhdGVSZXNvbHZhYmxlID0gKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZXNvbHZlLCByZWplY3Q7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXMsIHJlaikgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlID0gcmVzO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QgPSByZWo7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZS5yZXNvbHZlID0gcmVzb2x2ZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlLnJlamVjdCA9IHJlamVjdDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkb25lID0gZmFsc2U7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaGFzVGhyb3duID0gZmFsc2U7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmV0dXJuQ2FsbDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXh0QXZhaWxhYmxlID0gMDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHRRdWV1ZSA9IFtdO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGUgPSBjbG9jay5zZXRJbnRlcnZhbCgoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRRdWV1ZS5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRRdWV1ZS5zaGlmdCgpLnJlc29sdmUoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0QXZhaWxhYmxlKys7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgZGVsYXkpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhYm9ydCA9ICgpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImFib3J0XCIsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2suYWJvcnRMaXN0ZW5lck1hcC5kZWxldGUoYWJvcnQpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2suY2xlYXJJbnRlcnZhbChoYW5kbGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVzb2x2YWJsZSBvZiBuZXh0UXVldWUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2YWJsZS5yZXNvbHZlKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsLmFib3J0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYWJvcnRcIixcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5hYm9ydExpc3RlbmVyTWFwLnNldChcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQ6IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsPy5hYm9ydGVkICYmICFoYXNUaHJvd24pIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Rocm93biA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBvcHRpb25zLnNpZ25hbC5yZWFzb247XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRBdmFpbGFibGUgPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0QXZhaWxhYmxlLS07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBkb25lOiBmYWxzZSwgdmFsdWU6IHZhbHVlIH07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZhYmxlID0gY3JlYXRlUmVzb2x2YWJsZSgpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0UXVldWUucHVzaChyZXNvbHZhYmxlKTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXNvbHZhYmxlO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXR1cm5DYWxsICYmIG5leHRRdWV1ZS5sZW5ndGggPT09IDApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybkNhbGwucmVzb2x2ZSgpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsPy5hYm9ydGVkICYmICFoYXNUaHJvd24pIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Rocm93biA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBvcHRpb25zLnNpZ25hbC5yZWFzb247XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZG9uZTogZmFsc2UsIHZhbHVlOiB2YWx1ZSB9O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOiBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb25lKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBkb25lOiB0cnVlLCB2YWx1ZTogdW5kZWZpbmVkIH07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFF1ZXVlLmxlbmd0aCA+IDApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybkNhbGwgPSBjcmVhdGVSZXNvbHZhYmxlKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXR1cm5DYWxsO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2suY2xlYXJJbnRlcnZhbChoYW5kbGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zaWduYWwpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBjbG9jaztcblx0ICAgIH1cblxuXHQgICAgLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovXG5cblx0ICAgIHJldHVybiB7XG5cdCAgICAgICAgdGltZXJzOiB0aW1lcnMsXG5cdCAgICAgICAgY3JlYXRlQ2xvY2s6IGNyZWF0ZUNsb2NrLFxuXHQgICAgICAgIGluc3RhbGw6IGluc3RhbGwsXG5cdCAgICAgICAgd2l0aEdsb2JhbDogd2l0aEdsb2JhbCxcblx0ICAgIH07XG5cdH1cblxuXHQvKipcblx0ICogQHR5cGVkZWYge29iamVjdH0gRmFrZVRpbWVyc1xuXHQgKiBAcHJvcGVydHkge1RpbWVyc30gdGltZXJzXG5cdCAqIEBwcm9wZXJ0eSB7Y3JlYXRlQ2xvY2t9IGNyZWF0ZUNsb2NrXG5cdCAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGluc3RhbGxcblx0ICogQHByb3BlcnR5IHt3aXRoR2xvYmFsfSB3aXRoR2xvYmFsXG5cdCAqL1xuXG5cdC8qIGVzbGludC1lbmFibGUgY29tcGxleGl0eSAqL1xuXG5cdC8qKiBAdHlwZSB7RmFrZVRpbWVyc30gKi9cblx0Y29uc3QgZGVmYXVsdEltcGxlbWVudGF0aW9uID0gd2l0aEdsb2JhbChnbG9iYWxPYmplY3QpO1xuXG5cdGZha2VUaW1lcnNTcmMudGltZXJzID0gZGVmYXVsdEltcGxlbWVudGF0aW9uLnRpbWVycztcblx0ZmFrZVRpbWVyc1NyYy5jcmVhdGVDbG9jayA9IGRlZmF1bHRJbXBsZW1lbnRhdGlvbi5jcmVhdGVDbG9jaztcblx0ZmFrZVRpbWVyc1NyYy5pbnN0YWxsID0gZGVmYXVsdEltcGxlbWVudGF0aW9uLmluc3RhbGw7XG5cdGZha2VUaW1lcnNTcmMud2l0aEdsb2JhbCA9IHdpdGhHbG9iYWw7XG5cdHJldHVybiBmYWtlVGltZXJzU3JjO1xufVxuXG52YXIgZmFrZVRpbWVyc1NyY0V4cG9ydHMgPSByZXF1aXJlRmFrZVRpbWVyc1NyYygpO1xuXG5jbGFzcyBGYWtlVGltZXJzIHtcblx0X2dsb2JhbDtcblx0X2Nsb2NrO1xuXHQvLyB8IF9mYWtpbmdUaW1lIHwgX2Zha2luZ0RhdGUgfFxuXHQvLyArLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tK1xuXHQvLyB8IGZhbHNlICAgICAgIHwgZmFsc3kgICAgICAgfCBpbml0aWFsXG5cdC8vIHwgZmFsc2UgICAgICAgfCB0cnV0aHkgICAgICB8IHZpLnNldFN5c3RlbVRpbWUgY2FsbGVkIGZpcnN0IChmb3IgbW9ja2luZyBvbmx5IERhdGUgd2l0aG91dCBmYWtlIHRpbWVycylcblx0Ly8gfCB0cnVlICAgICAgICB8IGZhbHN5ICAgICAgIHwgdmkudXNlRmFrZVRpbWVycyBjYWxsZWQgZmlyc3Rcblx0Ly8gfCB0cnVlICAgICAgICB8IHRydXRoeSAgICAgIHwgdW5yZWFjaGFibGVcblx0X2Zha2luZ1RpbWU7XG5cdF9mYWtpbmdEYXRlO1xuXHRfZmFrZVRpbWVycztcblx0X3VzZXJDb25maWc7XG5cdF9ub3cgPSBSZWFsRGF0ZS5ub3c7XG5cdGNvbnN0cnVjdG9yKHsgZ2xvYmFsLCBjb25maWcgfSkge1xuXHRcdHRoaXMuX3VzZXJDb25maWcgPSBjb25maWc7XG5cdFx0dGhpcy5fZmFraW5nRGF0ZSA9IG51bGw7XG5cdFx0dGhpcy5fZmFraW5nVGltZSA9IGZhbHNlO1xuXHRcdHRoaXMuX2Zha2VUaW1lcnMgPSBmYWtlVGltZXJzU3JjRXhwb3J0cy53aXRoR2xvYmFsKGdsb2JhbCk7XG5cdFx0dGhpcy5fZ2xvYmFsID0gZ2xvYmFsO1xuXHR9XG5cdGNsZWFyQWxsVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9mYWtpbmdUaW1lKSB0aGlzLl9jbG9jay5yZXNldCgpO1xuXHR9XG5cdGRpc3Bvc2UoKSB7XG5cdFx0dGhpcy51c2VSZWFsVGltZXJzKCk7XG5cdH1cblx0cnVuQWxsVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgdGhpcy5fY2xvY2sucnVuQWxsKCk7XG5cdH1cblx0YXN5bmMgcnVuQWxsVGltZXJzQXN5bmMoKSB7XG5cdFx0aWYgKHRoaXMuX2NoZWNrRmFrZVRpbWVycygpKSBhd2FpdCB0aGlzLl9jbG9jay5ydW5BbGxBc3luYygpO1xuXHR9XG5cdHJ1bk9ubHlQZW5kaW5nVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgdGhpcy5fY2xvY2sucnVuVG9MYXN0KCk7XG5cdH1cblx0YXN5bmMgcnVuT25seVBlbmRpbmdUaW1lcnNBc3luYygpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIGF3YWl0IHRoaXMuX2Nsb2NrLnJ1blRvTGFzdEFzeW5jKCk7XG5cdH1cblx0YWR2YW5jZVRpbWVyc1RvTmV4dFRpbWVyKHN0ZXBzID0gMSkge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgZm9yIChsZXQgaSA9IHN0ZXBzOyBpID4gMDsgaS0tKSB7XG5cdFx0XHR0aGlzLl9jbG9jay5uZXh0KCk7XG5cdFx0XHQvLyBGaXJlIGFsbCB0aW1lcnMgYXQgdGhpcyBwb2ludDogaHR0cHM6Ly9naXRodWIuY29tL3Npbm9uanMvZmFrZS10aW1lcnMvaXNzdWVzLzI1MFxuXHRcdFx0dGhpcy5fY2xvY2sudGljaygwKTtcblx0XHRcdGlmICh0aGlzLl9jbG9jay5jb3VudFRpbWVycygpID09PSAwKSBicmVhaztcblx0XHR9XG5cdH1cblx0YXN5bmMgYWR2YW5jZVRpbWVyc1RvTmV4dFRpbWVyQXN5bmMoc3RlcHMgPSAxKSB7XG5cdFx0aWYgKHRoaXMuX2NoZWNrRmFrZVRpbWVycygpKSBmb3IgKGxldCBpID0gc3RlcHM7IGkgPiAwOyBpLS0pIHtcblx0XHRcdGF3YWl0IHRoaXMuX2Nsb2NrLm5leHRBc3luYygpO1xuXHRcdFx0Ly8gRmlyZSBhbGwgdGltZXJzIGF0IHRoaXMgcG9pbnQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9zaW5vbmpzL2Zha2UtdGltZXJzL2lzc3Vlcy8yNTBcblx0XHRcdHRoaXMuX2Nsb2NrLnRpY2soMCk7XG5cdFx0XHRpZiAodGhpcy5fY2xvY2suY291bnRUaW1lcnMoKSA9PT0gMCkgYnJlYWs7XG5cdFx0fVxuXHR9XG5cdGFkdmFuY2VUaW1lcnNCeVRpbWUobXNUb1J1bikge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgdGhpcy5fY2xvY2sudGljayhtc1RvUnVuKTtcblx0fVxuXHRhc3luYyBhZHZhbmNlVGltZXJzQnlUaW1lQXN5bmMobXNUb1J1bikge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgYXdhaXQgdGhpcy5fY2xvY2sudGlja0FzeW5jKG1zVG9SdW4pO1xuXHR9XG5cdGFkdmFuY2VUaW1lcnNUb05leHRGcmFtZSgpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHRoaXMuX2Nsb2NrLnJ1blRvRnJhbWUoKTtcblx0fVxuXHRydW5BbGxUaWNrcygpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHRoaXMuX2Nsb2NrLnJ1bk1pY3JvdGFza3MoKTtcblx0fVxuXHR1c2VSZWFsVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9mYWtpbmdEYXRlKSB7XG5cdFx0XHRyZXNldERhdGUoKTtcblx0XHRcdHRoaXMuX2Zha2luZ0RhdGUgPSBudWxsO1xuXHRcdH1cblx0XHRpZiAodGhpcy5fZmFraW5nVGltZSkge1xuXHRcdFx0dGhpcy5fY2xvY2sudW5pbnN0YWxsKCk7XG5cdFx0XHR0aGlzLl9mYWtpbmdUaW1lID0gZmFsc2U7XG5cdFx0fVxuXHR9XG5cdHVzZUZha2VUaW1lcnMoKSB7XG5cdFx0Y29uc3QgZmFrZURhdGUgPSB0aGlzLl9mYWtpbmdEYXRlIHx8IERhdGUubm93KCk7XG5cdFx0aWYgKHRoaXMuX2Zha2luZ0RhdGUpIHtcblx0XHRcdHJlc2V0RGF0ZSgpO1xuXHRcdFx0dGhpcy5fZmFraW5nRGF0ZSA9IG51bGw7XG5cdFx0fVxuXHRcdGlmICh0aGlzLl9mYWtpbmdUaW1lKSB0aGlzLl9jbG9jay51bmluc3RhbGwoKTtcblx0XHRjb25zdCB0b0Zha2UgPSBPYmplY3Qua2V5cyh0aGlzLl9mYWtlVGltZXJzLnRpbWVycykuZmlsdGVyKCh0aW1lcikgPT4gdGltZXIgIT09IFwibmV4dFRpY2tcIiAmJiB0aW1lciAhPT0gXCJxdWV1ZU1pY3JvdGFza1wiKTtcblx0XHRpZiAodGhpcy5fdXNlckNvbmZpZz8udG9GYWtlPy5pbmNsdWRlcyhcIm5leHRUaWNrXCIpICYmIGlzQ2hpbGRQcm9jZXNzKCkpIHRocm93IG5ldyBFcnJvcihcInByb2Nlc3MubmV4dFRpY2sgY2Fubm90IGJlIG1vY2tlZCBpbnNpZGUgY2hpbGRfcHJvY2Vzc1wiKTtcblx0XHR0aGlzLl9jbG9jayA9IHRoaXMuX2Zha2VUaW1lcnMuaW5zdGFsbCh7XG5cdFx0XHRub3c6IGZha2VEYXRlLFxuXHRcdFx0Li4udGhpcy5fdXNlckNvbmZpZyxcblx0XHRcdHRvRmFrZTogdGhpcy5fdXNlckNvbmZpZz8udG9GYWtlIHx8IHRvRmFrZSxcblx0XHRcdGlnbm9yZU1pc3NpbmdUaW1lcnM6IHRydWVcblx0XHR9KTtcblx0XHR0aGlzLl9mYWtpbmdUaW1lID0gdHJ1ZTtcblx0fVxuXHRyZXNldCgpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHtcblx0XHRcdGNvbnN0IHsgbm93IH0gPSB0aGlzLl9jbG9jaztcblx0XHRcdHRoaXMuX2Nsb2NrLnJlc2V0KCk7XG5cdFx0XHR0aGlzLl9jbG9jay5zZXRTeXN0ZW1UaW1lKG5vdyk7XG5cdFx0fVxuXHR9XG5cdHNldFN5c3RlbVRpbWUobm93KSB7XG5cdFx0Y29uc3QgZGF0ZSA9IHR5cGVvZiBub3cgPT09IFwidW5kZWZpbmVkXCIgfHwgbm93IGluc3RhbmNlb2YgRGF0ZSA/IG5vdyA6IG5ldyBEYXRlKG5vdyk7XG5cdFx0aWYgKHRoaXMuX2Zha2luZ1RpbWUpIHRoaXMuX2Nsb2NrLnNldFN5c3RlbVRpbWUoZGF0ZSk7XG5cdFx0ZWxzZSB7XG5cdFx0XHR0aGlzLl9mYWtpbmdEYXRlID0gZGF0ZSA/PyBuZXcgRGF0ZSh0aGlzLmdldFJlYWxTeXN0ZW1UaW1lKCkpO1xuXHRcdFx0bW9ja0RhdGUodGhpcy5fZmFraW5nRGF0ZSk7XG5cdFx0fVxuXHR9XG5cdGdldE1vY2tlZFN5c3RlbVRpbWUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2Zha2luZ1RpbWUgPyBuZXcgRGF0ZSh0aGlzLl9jbG9jay5ub3cpIDogdGhpcy5fZmFraW5nRGF0ZTtcblx0fVxuXHRnZXRSZWFsU3lzdGVtVGltZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5fbm93KCk7XG5cdH1cblx0Z2V0VGltZXJDb3VudCgpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHJldHVybiB0aGlzLl9jbG9jay5jb3VudFRpbWVycygpO1xuXHRcdHJldHVybiAwO1xuXHR9XG5cdHNldFRpbWVyVGlja01vZGUobW9kZSwgaW50ZXJ2YWwpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIGlmIChtb2RlID09PSBcIm1hbnVhbFwiKSB0aGlzLl9jbG9jay5zZXRUaWNrTW9kZSh7IG1vZGU6IFwibWFudWFsXCIgfSk7XG5cdFx0ZWxzZSBpZiAobW9kZSA9PT0gXCJuZXh0VGltZXJBc3luY1wiKSB0aGlzLl9jbG9jay5zZXRUaWNrTW9kZSh7IG1vZGU6IFwibmV4dEFzeW5jXCIgfSk7XG5cdFx0ZWxzZSBpZiAobW9kZSA9PT0gXCJpbnRlcnZhbFwiKSB0aGlzLl9jbG9jay5zZXRUaWNrTW9kZSh7XG5cdFx0XHRtb2RlOiBcImludGVydmFsXCIsXG5cdFx0XHRkZWx0YTogaW50ZXJ2YWxcblx0XHR9KTtcblx0XHRlbHNlIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0aWNrIG1vZGU6ICR7bW9kZX1gKTtcblx0fVxuXHRjb25maWd1cmUoY29uZmlnKSB7XG5cdFx0dGhpcy5fdXNlckNvbmZpZyA9IGNvbmZpZztcblx0fVxuXHRpc0Zha2VUaW1lcnMoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2Zha2luZ1RpbWU7XG5cdH1cblx0X2NoZWNrRmFrZVRpbWVycygpIHtcblx0XHRpZiAoIXRoaXMuX2Zha2luZ1RpbWUpIHRocm93IG5ldyBFcnJvcihcIkEgZnVuY3Rpb24gdG8gYWR2YW5jZSB0aW1lcnMgd2FzIGNhbGxlZCBidXQgdGhlIHRpbWVycyBBUElzIGFyZSBub3QgbW9ja2VkLiBDYWxsIGB2aS51c2VGYWtlVGltZXJzKClgIGluIHRoZSB0ZXN0IGZpbGUgZmlyc3QuXCIpO1xuXHRcdHJldHVybiB0aGlzLl9mYWtpbmdUaW1lO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNvcHlTdGFja1RyYWNlJDEodGFyZ2V0LCBzb3VyY2UpIHtcblx0aWYgKHNvdXJjZS5zdGFjayAhPT0gdm9pZCAwKSB0YXJnZXQuc3RhY2sgPSBzb3VyY2Uuc3RhY2sucmVwbGFjZShzb3VyY2UubWVzc2FnZSwgdGFyZ2V0Lm1lc3NhZ2UpO1xuXHRyZXR1cm4gdGFyZ2V0O1xufVxuZnVuY3Rpb24gd2FpdEZvcihjYWxsYmFjaywgb3B0aW9ucyA9IHt9KSB7XG5cdGNvbnN0IHsgc2V0VGltZW91dCwgc2V0SW50ZXJ2YWwsIGNsZWFyVGltZW91dCwgY2xlYXJJbnRlcnZhbCB9ID0gZ2V0U2FmZVRpbWVycygpO1xuXHRjb25zdCB7IGludGVydmFsID0gNTAsIHRpbWVvdXQgPSAxZTMgfSA9IHR5cGVvZiBvcHRpb25zID09PSBcIm51bWJlclwiID8geyB0aW1lb3V0OiBvcHRpb25zIH0gOiBvcHRpb25zO1xuXHRjb25zdCBTVEFDS19UUkFDRV9FUlJPUiA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoXCJTVEFDS19UUkFDRV9FUlJPUlwiKTtcblx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRsZXQgbGFzdEVycm9yO1xuXHRcdGxldCBwcm9taXNlU3RhdHVzID0gXCJpZGxlXCI7XG5cdFx0bGV0IHRpbWVvdXRJZDtcblx0XHRsZXQgaW50ZXJ2YWxJZDtcblx0XHRjb25zdCBvblJlc29sdmUgPSAocmVzdWx0KSA9PiB7XG5cdFx0XHRpZiAodGltZW91dElkKSBjbGVhclRpbWVvdXQodGltZW91dElkKTtcblx0XHRcdGlmIChpbnRlcnZhbElkKSBjbGVhckludGVydmFsKGludGVydmFsSWQpO1xuXHRcdFx0cmVzb2x2ZShyZXN1bHQpO1xuXHRcdH07XG5cdFx0Y29uc3QgaGFuZGxlVGltZW91dCA9ICgpID0+IHtcblx0XHRcdGlmIChpbnRlcnZhbElkKSBjbGVhckludGVydmFsKGludGVydmFsSWQpO1xuXHRcdFx0bGV0IGVycm9yID0gbGFzdEVycm9yO1xuXHRcdFx0aWYgKCFlcnJvcikgZXJyb3IgPSBjb3B5U3RhY2tUcmFjZSQxKC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoXCJUaW1lZCBvdXQgaW4gd2FpdEZvciFcIiksIFNUQUNLX1RSQUNFX0VSUk9SKTtcblx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0fTtcblx0XHRjb25zdCBjaGVja0NhbGxiYWNrID0gKCkgPT4ge1xuXHRcdFx0aWYgKHZpLmlzRmFrZVRpbWVycygpKSB2aS5hZHZhbmNlVGltZXJzQnlUaW1lKGludGVydmFsKTtcblx0XHRcdGlmIChwcm9taXNlU3RhdHVzID09PSBcInBlbmRpbmdcIikgcmV0dXJuO1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gY2FsbGJhY2soKTtcblx0XHRcdFx0aWYgKHJlc3VsdCAhPT0gbnVsbCAmJiB0eXBlb2YgcmVzdWx0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRcdFx0Y29uc3QgdGhlbmFibGUgPSByZXN1bHQ7XG5cdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicGVuZGluZ1wiO1xuXHRcdFx0XHRcdHRoZW5hYmxlLnRoZW4oKHJlc29sdmVkVmFsdWUpID0+IHtcblx0XHRcdFx0XHRcdHByb21pc2VTdGF0dXMgPSBcInJlc29sdmVkXCI7XG5cdFx0XHRcdFx0XHRvblJlc29sdmUocmVzb2x2ZWRWYWx1ZSk7XG5cdFx0XHRcdFx0fSwgKHJlamVjdGVkVmFsdWUpID0+IHtcblx0XHRcdFx0XHRcdHByb21pc2VTdGF0dXMgPSBcInJlamVjdGVkXCI7XG5cdFx0XHRcdFx0XHRsYXN0RXJyb3IgPSByZWplY3RlZFZhbHVlO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdG9uUmVzb2x2ZShyZXN1bHQpO1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0XHRsYXN0RXJyb3IgPSBlcnJvcjtcblx0XHRcdH1cblx0XHR9O1xuXHRcdGlmIChjaGVja0NhbGxiYWNrKCkgPT09IHRydWUpIHJldHVybjtcblx0XHR0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGhhbmRsZVRpbWVvdXQsIHRpbWVvdXQpO1xuXHRcdGludGVydmFsSWQgPSBzZXRJbnRlcnZhbChjaGVja0NhbGxiYWNrLCBpbnRlcnZhbCk7XG5cdH0pO1xufVxuZnVuY3Rpb24gd2FpdFVudGlsKGNhbGxiYWNrLCBvcHRpb25zID0ge30pIHtcblx0Y29uc3QgeyBzZXRUaW1lb3V0LCBzZXRJbnRlcnZhbCwgY2xlYXJUaW1lb3V0LCBjbGVhckludGVydmFsIH0gPSBnZXRTYWZlVGltZXJzKCk7XG5cdGNvbnN0IHsgaW50ZXJ2YWwgPSA1MCwgdGltZW91dCA9IDFlMyB9ID0gdHlwZW9mIG9wdGlvbnMgPT09IFwibnVtYmVyXCIgPyB7IHRpbWVvdXQ6IG9wdGlvbnMgfSA6IG9wdGlvbnM7XG5cdGNvbnN0IFNUQUNLX1RSQUNFX0VSUk9SID0gLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIlNUQUNLX1RSQUNFX0VSUk9SXCIpO1xuXHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdGxldCBwcm9taXNlU3RhdHVzID0gXCJpZGxlXCI7XG5cdFx0bGV0IHRpbWVvdXRJZDtcblx0XHRsZXQgaW50ZXJ2YWxJZDtcblx0XHRjb25zdCBvblJlamVjdCA9IChlcnJvcikgPT4ge1xuXHRcdFx0aWYgKGludGVydmFsSWQpIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG5cdFx0XHRpZiAoIWVycm9yKSBlcnJvciA9IGNvcHlTdGFja1RyYWNlJDEoLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIlRpbWVkIG91dCBpbiB3YWl0VW50aWwhXCIpLCBTVEFDS19UUkFDRV9FUlJPUik7XG5cdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdH07XG5cdFx0Y29uc3Qgb25SZXNvbHZlID0gKHJlc3VsdCkgPT4ge1xuXHRcdFx0aWYgKCFyZXN1bHQpIHJldHVybjtcblx0XHRcdGlmICh0aW1lb3V0SWQpIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuXHRcdFx0aWYgKGludGVydmFsSWQpIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG5cdFx0XHRyZXNvbHZlKHJlc3VsdCk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9O1xuXHRcdGNvbnN0IGNoZWNrQ2FsbGJhY2sgPSAoKSA9PiB7XG5cdFx0XHRpZiAodmkuaXNGYWtlVGltZXJzKCkpIHZpLmFkdmFuY2VUaW1lcnNCeVRpbWUoaW50ZXJ2YWwpO1xuXHRcdFx0aWYgKHByb21pc2VTdGF0dXMgPT09IFwicGVuZGluZ1wiKSByZXR1cm47XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICE9PSBudWxsICYmIHR5cGVvZiByZXN1bHQgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0XHRjb25zdCB0aGVuYWJsZSA9IHJlc3VsdDtcblx0XHRcdFx0XHRwcm9taXNlU3RhdHVzID0gXCJwZW5kaW5nXCI7XG5cdFx0XHRcdFx0dGhlbmFibGUudGhlbigocmVzb2x2ZWRWYWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicmVzb2x2ZWRcIjtcblx0XHRcdFx0XHRcdG9uUmVzb2x2ZShyZXNvbHZlZFZhbHVlKTtcblx0XHRcdFx0XHR9LCAocmVqZWN0ZWRWYWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicmVqZWN0ZWRcIjtcblx0XHRcdFx0XHRcdG9uUmVqZWN0KHJlamVjdGVkVmFsdWUpO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9IGVsc2UgcmV0dXJuIG9uUmVzb2x2ZShyZXN1bHQpO1xuXHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0b25SZWplY3QoZXJyb3IpO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0aWYgKGNoZWNrQ2FsbGJhY2soKSA9PT0gdHJ1ZSkgcmV0dXJuO1xuXHRcdHRpbWVvdXRJZCA9IHNldFRpbWVvdXQob25SZWplY3QsIHRpbWVvdXQpO1xuXHRcdGludGVydmFsSWQgPSBzZXRJbnRlcnZhbChjaGVja0NhbGxiYWNrLCBpbnRlcnZhbCk7XG5cdH0pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXRlc3QoKSB7XG5cdGxldCBfY29uZmlnID0gbnVsbDtcblx0Y29uc3Qgc3RhdGUgPSAoKSA9PiBnZXRXb3JrZXJTdGF0ZSgpO1xuXHRsZXQgX3RpbWVycztcblx0Y29uc3QgdGltZXJzID0gKCkgPT4gX3RpbWVycyB8fD0gbmV3IEZha2VUaW1lcnMoe1xuXHRcdGdsb2JhbDogZ2xvYmFsVGhpcyxcblx0XHRjb25maWc6IHN0YXRlKCkuY29uZmlnLmZha2VUaW1lcnNcblx0fSk7XG5cdGNvbnN0IF9zdHVic0dsb2JhbCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG5cdGNvbnN0IF9zdHVic0VudiA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG5cdGNvbnN0IF9lbnZCb29sZWFucyA9IFtcblx0XHRcIlBST0RcIixcblx0XHRcIkRFVlwiLFxuXHRcdFwiU1NSXCJcblx0XTtcblx0Y29uc3QgdXRpbHMgPSB7XG5cdFx0dXNlRmFrZVRpbWVycyhjb25maWcpIHtcblx0XHRcdGlmIChpc0NoaWxkUHJvY2VzcygpKSB7XG5cdFx0XHRcdGlmIChjb25maWc/LnRvRmFrZT8uaW5jbHVkZXMoXCJuZXh0VGlja1wiKSB8fCBzdGF0ZSgpLmNvbmZpZz8uZmFrZVRpbWVycz8udG9GYWtlPy5pbmNsdWRlcyhcIm5leHRUaWNrXCIpKSB0aHJvdyBuZXcgRXJyb3IoXCJ2aS51c2VGYWtlVGltZXJzKHsgdG9GYWtlOiBbXFxcIm5leHRUaWNrXFxcIl0gfSkgaXMgbm90IHN1cHBvcnRlZCBpbiBub2RlOmNoaWxkX3Byb2Nlc3MuIFVzZSAtLXBvb2w9dGhyZWFkcyBpZiBtb2NraW5nIG5leHRUaWNrIGlzIHJlcXVpcmVkLlwiKTtcblx0XHRcdH1cblx0XHRcdGlmIChjb25maWcpIHRpbWVycygpLmNvbmZpZ3VyZSh7XG5cdFx0XHRcdC4uLnN0YXRlKCkuY29uZmlnLmZha2VUaW1lcnMsXG5cdFx0XHRcdC4uLmNvbmZpZ1xuXHRcdFx0fSk7XG5cdFx0XHRlbHNlIHRpbWVycygpLmNvbmZpZ3VyZShzdGF0ZSgpLmNvbmZpZy5mYWtlVGltZXJzKTtcblx0XHRcdHRpbWVycygpLnVzZUZha2VUaW1lcnMoKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGlzRmFrZVRpbWVycygpIHtcblx0XHRcdHJldHVybiB0aW1lcnMoKS5pc0Zha2VUaW1lcnMoKTtcblx0XHR9LFxuXHRcdHVzZVJlYWxUaW1lcnMoKSB7XG5cdFx0XHR0aW1lcnMoKS51c2VSZWFsVGltZXJzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRydW5Pbmx5UGVuZGluZ1RpbWVycygpIHtcblx0XHRcdHRpbWVycygpLnJ1bk9ubHlQZW5kaW5nVGltZXJzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhc3luYyBydW5Pbmx5UGVuZGluZ1RpbWVyc0FzeW5jKCkge1xuXHRcdFx0YXdhaXQgdGltZXJzKCkucnVuT25seVBlbmRpbmdUaW1lcnNBc3luYygpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0cnVuQWxsVGltZXJzKCkge1xuXHRcdFx0dGltZXJzKCkucnVuQWxsVGltZXJzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhc3luYyBydW5BbGxUaW1lcnNBc3luYygpIHtcblx0XHRcdGF3YWl0IHRpbWVycygpLnJ1bkFsbFRpbWVyc0FzeW5jKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRydW5BbGxUaWNrcygpIHtcblx0XHRcdHRpbWVycygpLnJ1bkFsbFRpY2tzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhZHZhbmNlVGltZXJzQnlUaW1lKG1zKSB7XG5cdFx0XHR0aW1lcnMoKS5hZHZhbmNlVGltZXJzQnlUaW1lKG1zKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGFzeW5jIGFkdmFuY2VUaW1lcnNCeVRpbWVBc3luYyhtcykge1xuXHRcdFx0YXdhaXQgdGltZXJzKCkuYWR2YW5jZVRpbWVyc0J5VGltZUFzeW5jKG1zKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGFkdmFuY2VUaW1lcnNUb05leHRUaW1lcigpIHtcblx0XHRcdHRpbWVycygpLmFkdmFuY2VUaW1lcnNUb05leHRUaW1lcigpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0YXN5bmMgYWR2YW5jZVRpbWVyc1RvTmV4dFRpbWVyQXN5bmMoKSB7XG5cdFx0XHRhd2FpdCB0aW1lcnMoKS5hZHZhbmNlVGltZXJzVG9OZXh0VGltZXJBc3luYygpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0YWR2YW5jZVRpbWVyc1RvTmV4dEZyYW1lKCkge1xuXHRcdFx0dGltZXJzKCkuYWR2YW5jZVRpbWVyc1RvTmV4dEZyYW1lKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRnZXRUaW1lckNvdW50KCkge1xuXHRcdFx0cmV0dXJuIHRpbWVycygpLmdldFRpbWVyQ291bnQoKTtcblx0XHR9LFxuXHRcdHNldFN5c3RlbVRpbWUodGltZSkge1xuXHRcdFx0dGltZXJzKCkuc2V0U3lzdGVtVGltZSh0aW1lKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGdldE1vY2tlZFN5c3RlbVRpbWUoKSB7XG5cdFx0XHRyZXR1cm4gdGltZXJzKCkuZ2V0TW9ja2VkU3lzdGVtVGltZSgpO1xuXHRcdH0sXG5cdFx0Z2V0UmVhbFN5c3RlbVRpbWUoKSB7XG5cdFx0XHRyZXR1cm4gdGltZXJzKCkuZ2V0UmVhbFN5c3RlbVRpbWUoKTtcblx0XHR9LFxuXHRcdGNsZWFyQWxsVGltZXJzKCkge1xuXHRcdFx0dGltZXJzKCkuY2xlYXJBbGxUaW1lcnMoKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdHNldFRpbWVyVGlja01vZGUobW9kZSwgaW50ZXJ2YWwpIHtcblx0XHRcdHRpbWVycygpLnNldFRpbWVyVGlja01vZGUobW9kZSwgaW50ZXJ2YWwpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0c3B5T24sXG5cdFx0Zm4sXG5cdFx0d2FpdEZvcixcblx0XHR3YWl0VW50aWwsXG5cdFx0ZGVmaW5lSGVscGVyOiAoZm4pID0+IHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiBfX1ZJVEVTVF9IRUxQRVJfXyguLi5hcmdzKSB7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICYmIHR5cGVvZiByZXN1bHQgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiAoYXN5bmMgZnVuY3Rpb24gX19WSVRFU1RfSEVMUEVSX18oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGF3YWl0IHJlc3VsdDtcblx0XHRcdFx0fSkoKTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH07XG5cdFx0fSxcblx0XHRob2lzdGVkKGZhY3RvcnkpIHtcblx0XHRcdGFzc2VydFR5cGVzKGZhY3RvcnksIFwiXFxcInZpLmhvaXN0ZWRcXFwiIGZhY3RvcnlcIiwgW1wiZnVuY3Rpb25cIl0pO1xuXHRcdFx0cmV0dXJuIGZhY3RvcnkoKTtcblx0XHR9LFxuXHRcdG1vY2socGF0aCwgZmFjdG9yeSkge1xuXHRcdFx0aWYgKHR5cGVvZiBwYXRoICE9PSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgVHlwZUVycm9yKGB2aS5tb2NrKCkgZXhwZWN0cyBhIHN0cmluZyBwYXRoLCBidXQgcmVjZWl2ZWQgYSAke3R5cGVvZiBwYXRofWApO1xuXHRcdFx0Y29uc3QgaW1wb3J0ZXIgPSBnZXRJbXBvcnRlcihcIm1vY2tcIik7XG5cdFx0XHRfbW9ja2VyKCkucXVldWVNb2NrKHBhdGgsIGltcG9ydGVyLCB0eXBlb2YgZmFjdG9yeSA9PT0gXCJmdW5jdGlvblwiID8gKCkgPT4gZmFjdG9yeSgoKSA9PiBfbW9ja2VyKCkuaW1wb3J0QWN0dWFsKHBhdGgsIGltcG9ydGVyLCBfbW9ja2VyKCkuZ2V0TW9ja0NvbnRleHQoKS5jYWxsc3RhY2spKSA6IGZhY3RvcnkpO1xuXHRcdH0sXG5cdFx0dW5tb2NrKHBhdGgpIHtcblx0XHRcdGlmICh0eXBlb2YgcGF0aCAhPT0gXCJzdHJpbmdcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihgdmkudW5tb2NrKCkgZXhwZWN0cyBhIHN0cmluZyBwYXRoLCBidXQgcmVjZWl2ZWQgYSAke3R5cGVvZiBwYXRofWApO1xuXHRcdFx0X21vY2tlcigpLnF1ZXVlVW5tb2NrKHBhdGgsIGdldEltcG9ydGVyKFwidW5tb2NrXCIpKTtcblx0XHR9LFxuXHRcdGRvTW9jayhwYXRoLCBmYWN0b3J5KSB7XG5cdFx0XHRpZiAodHlwZW9mIHBhdGggIT09IFwic3RyaW5nXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoYHZpLmRvTW9jaygpIGV4cGVjdHMgYSBzdHJpbmcgcGF0aCwgYnV0IHJlY2VpdmVkIGEgJHt0eXBlb2YgcGF0aH1gKTtcblx0XHRcdGNvbnN0IGltcG9ydGVyID0gZ2V0SW1wb3J0ZXIoXCJkb01vY2tcIik7XG5cdFx0XHRfbW9ja2VyKCkucXVldWVNb2NrKHBhdGgsIGltcG9ydGVyLCB0eXBlb2YgZmFjdG9yeSA9PT0gXCJmdW5jdGlvblwiID8gKCkgPT4gZmFjdG9yeSgoKSA9PiBfbW9ja2VyKCkuaW1wb3J0QWN0dWFsKHBhdGgsIGltcG9ydGVyLCBfbW9ja2VyKCkuZ2V0TW9ja0NvbnRleHQoKS5jYWxsc3RhY2spKSA6IGZhY3RvcnkpO1xuXHRcdFx0Y29uc3QgcnYgPSB7fTtcblx0XHRcdGlmIChTeW1ib2wuZGlzcG9zZSkgcnZbU3ltYm9sLmRpc3Bvc2VdID0gKCkgPT4ge1xuXHRcdFx0XHRfbW9ja2VyKCkucXVldWVVbm1vY2socGF0aCwgaW1wb3J0ZXIpO1xuXHRcdFx0fTtcblx0XHRcdHJldHVybiBydjtcblx0XHR9LFxuXHRcdGRvVW5tb2NrKHBhdGgpIHtcblx0XHRcdGlmICh0eXBlb2YgcGF0aCAhPT0gXCJzdHJpbmdcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihgdmkuZG9Vbm1vY2soKSBleHBlY3RzIGEgc3RyaW5nIHBhdGgsIGJ1dCByZWNlaXZlZCBhICR7dHlwZW9mIHBhdGh9YCk7XG5cdFx0XHRjb25zdCBpbXBvcnRlciA9IGdldEltcG9ydGVyKFwiZG9Vbm1vY2tcIik7XG5cdFx0XHRfbW9ja2VyKCkucXVldWVVbm1vY2socGF0aCwgaW1wb3J0ZXIpO1xuXHRcdH0sXG5cdFx0YXN5bmMgaW1wb3J0QWN0dWFsKHBhdGgpIHtcblx0XHRcdGNvbnN0IGltcG9ydGVyID0gZ2V0SW1wb3J0ZXIoXCJpbXBvcnRBY3R1YWxcIik7XG5cdFx0XHRyZXR1cm4gX21vY2tlcigpLmltcG9ydEFjdHVhbChwYXRoLCBpbXBvcnRlciwgX21vY2tlcigpLmdldE1vY2tDb250ZXh0KCkuY2FsbHN0YWNrKTtcblx0XHR9LFxuXHRcdGFzeW5jIGltcG9ydE1vY2socGF0aCkge1xuXHRcdFx0Y29uc3QgaW1wb3J0ZXIgPSBnZXRJbXBvcnRlcihcImltcG9ydE1vY2tcIik7XG5cdFx0XHRyZXR1cm4gX21vY2tlcigpLmltcG9ydE1vY2socGF0aCwgaW1wb3J0ZXIpO1xuXHRcdH0sXG5cdFx0bW9ja09iamVjdCh2YWx1ZSwgb3B0aW9ucykge1xuXHRcdFx0cmV0dXJuIF9tb2NrZXIoKS5tb2NrT2JqZWN0KHsgdmFsdWUgfSwgdm9pZCAwLCBvcHRpb25zPy5zcHkgPyBcImF1dG9zcHlcIiA6IFwiYXV0b21vY2tcIikudmFsdWU7XG5cdFx0fSxcblx0XHRtb2NrZWQoaXRlbSwgX29wdGlvbnMgPSB7fSkge1xuXHRcdFx0cmV0dXJuIGl0ZW07XG5cdFx0fSxcblx0XHRpc01vY2tGdW5jdGlvbihmbikge1xuXHRcdFx0cmV0dXJuIGlzTW9ja0Z1bmN0aW9uKGZuKTtcblx0XHR9LFxuXHRcdGNsZWFyQWxsTW9ja3MoKSB7XG5cdFx0XHRjbGVhckFsbE1vY2tzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRyZXNldEFsbE1vY2tzKCkge1xuXHRcdFx0cmVzZXRBbGxNb2NrcygpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0cmVzdG9yZUFsbE1vY2tzKCkge1xuXHRcdFx0cmVzdG9yZUFsbE1vY2tzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRzdHViR2xvYmFsKG5hbWUsIHZhbHVlKSB7XG5cdFx0XHRpZiAoIV9zdHVic0dsb2JhbC5oYXMobmFtZSkpIF9zdHVic0dsb2JhbC5zZXQobmFtZSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihnbG9iYWxUaGlzLCBuYW1lKSk7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgbmFtZSwge1xuXHRcdFx0XHR2YWx1ZSxcblx0XHRcdFx0d3JpdGFibGU6IHRydWUsXG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRzdHViRW52KG5hbWUsIHZhbHVlKSB7XG5cdFx0XHRjb25zdCBlbnYgPSBzdGF0ZSgpLm1ldGFFbnY7XG5cdFx0XHRpZiAoIV9zdHVic0Vudi5oYXMobmFtZSkpIF9zdHVic0Vudi5zZXQobmFtZSwgZW52W25hbWVdKTtcblx0XHRcdGlmIChfZW52Qm9vbGVhbnMuaW5jbHVkZXMobmFtZSkpIGVudltuYW1lXSA9IHZhbHVlID8gXCIxXCIgOiBcIlwiO1xuXHRcdFx0ZWxzZSBpZiAodmFsdWUgPT09IHZvaWQgMCkgZGVsZXRlIGVudltuYW1lXTtcblx0XHRcdGVsc2UgZW52W25hbWVdID0gU3RyaW5nKHZhbHVlKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdHVuc3R1YkFsbEdsb2JhbHMoKSB7XG5cdFx0XHRfc3R1YnNHbG9iYWwuZm9yRWFjaCgob3JpZ2luYWwsIG5hbWUpID0+IHtcblx0XHRcdFx0aWYgKCFvcmlnaW5hbCkgUmVmbGVjdC5kZWxldGVQcm9wZXJ0eShnbG9iYWxUaGlzLCBuYW1lKTtcblx0XHRcdFx0ZWxzZSBPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgbmFtZSwgb3JpZ2luYWwpO1xuXHRcdFx0fSk7XG5cdFx0XHRfc3R1YnNHbG9iYWwuY2xlYXIoKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdHVuc3R1YkFsbEVudnMoKSB7XG5cdFx0XHRjb25zdCBlbnYgPSBzdGF0ZSgpLm1ldGFFbnY7XG5cdFx0XHRfc3R1YnNFbnYuZm9yRWFjaCgob3JpZ2luYWwsIG5hbWUpID0+IHtcblx0XHRcdFx0aWYgKG9yaWdpbmFsID09PSB2b2lkIDApIGRlbGV0ZSBlbnZbbmFtZV07XG5cdFx0XHRcdGVsc2UgZW52W25hbWVdID0gb3JpZ2luYWw7XG5cdFx0XHR9KTtcblx0XHRcdF9zdHVic0Vudi5jbGVhcigpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0cmVzZXRNb2R1bGVzKCkge1xuXHRcdFx0cmVzZXRNb2R1bGVzKHN0YXRlKCkuZXZhbHVhdGVkTW9kdWxlcyk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhc3luYyBkeW5hbWljSW1wb3J0U2V0dGxlZCgpIHtcblx0XHRcdHJldHVybiB3YWl0Rm9ySW1wb3J0c1RvUmVzb2x2ZSgpO1xuXHRcdH0sXG5cdFx0c2V0Q29uZmlnKGNvbmZpZykge1xuXHRcdFx0aWYgKCFfY29uZmlnKSBfY29uZmlnID0geyAuLi5zdGF0ZSgpLmNvbmZpZyB9O1xuXHRcdFx0T2JqZWN0LmFzc2lnbihzdGF0ZSgpLmNvbmZpZywgY29uZmlnKTtcblx0XHR9LFxuXHRcdHJlc2V0Q29uZmlnKCkge1xuXHRcdFx0aWYgKF9jb25maWcpIE9iamVjdC5hc3NpZ24oc3RhdGUoKS5jb25maWcsIF9jb25maWcpO1xuXHRcdH1cblx0fTtcblx0cmV0dXJuIHV0aWxzO1xufVxuY29uc3Qgdml0ZXN0ID0gY3JlYXRlVml0ZXN0KCk7XG5jb25zdCB2aSA9IHZpdGVzdDtcbmZ1bmN0aW9uIF9tb2NrZXIoKSB7XG5cdC8vIEB0cy1leHBlY3QtZXJyb3IgaW5qZWN0ZWQgYnkgdml0ZS1uaWRlXG5cdHJldHVybiB0eXBlb2YgX192aXRlc3RfbW9ja2VyX18gIT09IFwidW5kZWZpbmVkXCIgPyBfX3ZpdGVzdF9tb2NrZXJfXyA6IG5ldyBQcm94eSh7fSwgeyBnZXQoXywgbmFtZSkge1xuXHRcdHRocm93IG5ldyBFcnJvcihgVml0ZXN0IG1vY2tlciB3YXMgbm90IGluaXRpYWxpemVkIGluIHRoaXMgZW52aXJvbm1lbnQuIHZpLiR7U3RyaW5nKG5hbWUpfSgpIGlzIGZvcmJpZGRlbi5gKTtcblx0fSB9KTtcbn1cbmZ1bmN0aW9uIGdldEltcG9ydGVyKG5hbWUpIHtcblx0Y29uc3Qgc3RhY2tBcnJheSA9IGNyZWF0ZVNpbXBsZVN0YWNrVHJhY2UoeyBzdGFja1RyYWNlTGltaXQ6IDUgfSkuc3BsaXQoXCJcXG5cIik7XG5cdHJldHVybiBwYXJzZVNpbmdsZVN0YWNrKHN0YWNrQXJyYXlbc3RhY2tBcnJheS5maW5kTGFzdEluZGV4KChzdGFjaykgPT4ge1xuXHRcdHJldHVybiBzdGFjay5pbmNsdWRlcyhgIGF0IE9iamVjdC4ke25hbWV9YCkgfHwgc3RhY2suaW5jbHVkZXMoYCR7bmFtZX1AYCkgfHwgc3RhY2suaW5jbHVkZXMoYCBhdCAke25hbWV9IChgKTtcblx0fSkgKyAxXSk/LmZpbGUgfHwgXCJcIjtcbn1cblxuLy8gdGhlc2UgbWF0Y2hlcnMgYXJlIG5vdCBzdXBwb3J0ZWQgYmVjYXVzZSB0aGV5IGRvbid0IG1ha2Ugc2Vuc2Ugd2l0aCBwb2xsXG5jb25zdCB1bnN1cHBvcnRlZCA9IFtcblx0XCJtYXRjaFNuYXBzaG90XCIsXG5cdFwidG9NYXRjaFNuYXBzaG90XCIsXG5cdFwidG9NYXRjaElubGluZVNuYXBzaG90XCIsXG5cdFwidG9UaHJvd0Vycm9yTWF0Y2hpbmdTbmFwc2hvdFwiLFxuXHRcInRvVGhyb3dFcnJvck1hdGNoaW5nSW5saW5lU25hcHNob3RcIixcblx0XCJ0aHJvd3NcIixcblx0XCJUaHJvd1wiLFxuXHRcInRocm93XCIsXG5cdFwidG9UaHJvd1wiLFxuXHRcInRvVGhyb3dFcnJvclwiXG5dO1xuLyoqXG4qIEF0dGFjaGVzIGEgYGNhdXNlYCBwcm9wZXJ0eSB0byB0aGUgZXJyb3IgaWYgbWlzc2luZywgY29waWVzIHRoZSBzdGFjayB0cmFjZSBmcm9tIHRoZSBzb3VyY2UsIGFuZCB0aHJvd3MuXG4qXG4qIEBwYXJhbSBlcnJvciAtIFRoZSBlcnJvciB0byB0aHJvd1xuKiBAcGFyYW0gc291cmNlIC0gRXJyb3IgdG8gY29weSB0aGUgc3RhY2sgdHJhY2UgZnJvbVxuKlxuKiBAdGhyb3dzIEFsd2F5cyB0aHJvd3MgdGhlIHByb3ZpZGVkIGVycm9yIHdpdGggYW4gYW1lbmRlZCBzdGFjayB0cmFjZVxuKi9cbmZ1bmN0aW9uIHRocm93V2l0aENhdXNlKGVycm9yLCBzb3VyY2UpIHtcblx0aWYgKGVycm9yLmNhdXNlID09IG51bGwpIGVycm9yLmNhdXNlID0gLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIk1hdGNoZXIgZGlkIG5vdCBzdWNjZWVkIGluIHRpbWUuXCIpO1xuXHR0aHJvdyBjb3B5U3RhY2tUcmFjZShlcnJvciwgc291cmNlKTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUV4cGVjdFBvbGwoZXhwZWN0KSB7XG5cdHJldHVybiBmdW5jdGlvbiBwb2xsKGZuLCBvcHRpb25zID0ge30pIHtcblx0XHRjb25zdCBkZWZhdWx0cyA9IGdldFdvcmtlclN0YXRlKCkuY29uZmlnLmV4cGVjdD8ucG9sbCA/PyB7fTtcblx0XHRjb25zdCB7IGludGVydmFsID0gZGVmYXVsdHMuaW50ZXJ2YWwgPz8gNTAsIHRpbWVvdXQgPSBkZWZhdWx0cy50aW1lb3V0ID8/IDFlMywgbWVzc2FnZSB9ID0gb3B0aW9ucztcblx0XHQvLyBAdHMtZXhwZWN0LWVycm9yIHByaXZhdGUgcG9sbCBhY2Nlc3Ncblx0XHRjb25zdCBhc3NlcnRpb24gPSBleHBlY3QobnVsbCwgbWVzc2FnZSkud2l0aENvbnRleHQoeyBwb2xsOiB0cnVlIH0pO1xuXHRcdGZuID0gZm4uYmluZChhc3NlcnRpb24pO1xuXHRcdC8vIGluamVjdGVkIHNvIHRoYXQgZG9tYWluIHNuYXBzaG90IGNhbiB0YWtlIG92ZXIgcG9sbCBpbXBsZW1lbnRhdGlvbi5cblx0XHRjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwiX3BvbGwuZm5cIiwgZm4pO1xuXHRcdGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfcG9sbC50aW1lb3V0XCIsIHRpbWVvdXQpO1xuXHRcdGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfcG9sbC5pbnRlcnZhbFwiLCBpbnRlcnZhbCk7XG5cdFx0Y29uc3QgdGVzdCA9IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJ2aXRlc3QtdGVzdFwiKTtcblx0XHRpZiAoIXRlc3QpIHRocm93IG5ldyBFcnJvcihcImV4cGVjdC5wb2xsKCkgbXVzdCBiZSBjYWxsZWQgaW5zaWRlIGEgdGVzdFwiKTtcblx0XHRjb25zdCBwcm94eSA9IG5ldyBQcm94eShhc3NlcnRpb24sIHsgZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcikge1xuXHRcdFx0Y29uc3QgYXNzZXJ0aW9uRnVuY3Rpb24gPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuXHRcdFx0aWYgKHR5cGVvZiBhc3NlcnRpb25GdW5jdGlvbiAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4gYXNzZXJ0aW9uRnVuY3Rpb24gaW5zdGFuY2VvZiBjaGFpLkFzc2VydGlvbiA/IHByb3h5IDogYXNzZXJ0aW9uRnVuY3Rpb247XG5cdFx0XHRpZiAoa2V5ID09PSBcImFzc2VydFwiKSByZXR1cm4gYXNzZXJ0aW9uRnVuY3Rpb247XG5cdFx0XHRpZiAodHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiAmJiB1bnN1cHBvcnRlZC5pbmNsdWRlcyhrZXkpKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYGV4cGVjdC5wb2xsKCkgaXMgbm90IHN1cHBvcnRlZCBpbiBjb21iaW5hdGlvbiB3aXRoIC4ke2tleX0oKS4gVXNlIHZpLndhaXRGb3IoKSBpZiB5b3VyIGFzc2VydGlvbiBjb25kaXRpb24gaXMgdW5zdGFibGUuYCk7XG5cdFx0XHQvLyBDb3JlIHBvbGwgc3RhY2stdHJhY2UgdHJpY2s6XG5cdFx0XHQvLyAgIDEuIGNhcHR1cmUgU1RBQ0tfVFJBQ0VfRVJST1IgaGVyZSBiZWZvcmUgZW50ZXJpbmcgdGhlIGFzeW5jIHBvbGwgbG9vcFxuXHRcdFx0Ly8gICAyLiB3aGVuIHRoZSBtYXRjaGVyIGV2ZW50dWFsbHkgZmFpbHMsIHJldGhyb3cgdmlhIHRocm93V2l0aENhdXNlKClcblx0XHRcdC8vICAgICAgc28gdGhlIGZpbmFsIGVycm9yIGtlZXBzIHRoaXMgZWFybGllciBzdGFja1xuXHRcdFx0Ly9cblx0XHRcdC8vIEZvciBleGFtcGxlLCB3aGVuIHVzZXIgd3JpdGVzOlxuXHRcdFx0Ly8gICAgYXdhaXQgZXhwZWN0LnBvbGwoLi4uKS50b0JlU29tZXRoaW5nKClcblx0XHRcdC8vIFNUQUNLX1RSQUNFX0VSUk9SLnN0YWNrIHdvdWxkIGxvb2sgbGlrZVxuXHRcdFx0Ly8gICBhdCAuLi4obW9yZSBpbnRlcm5hbCBzdGFja3MpLi4uXG5cdFx0XHQvLyAgIGF0IF9fVklURVNUX1BPTExfQ0hBSU5fXyAuLi4vcGFja2FnZXMvdml0ZXN0L2Rpc3QvLi4uXG5cdFx0XHQvLyAgIGF0IC4uLi9teS1maWxlLnRlc3QudHM6MTI6MyAgICh0aGlzIHBvaW50cyB0byBgdG9CZVNvbWV0aGluZygpYCBjYWxsc2l0ZSBpbiB1c2VyIHRlc3QgZmlsZSlcblx0XHRcdC8vIFZpdGVzdCBsYXRlciBmaWx0ZXJzIG91dCBpbnRlcm5hbCBzdGFja3MgZnJvbSBgdml0ZXN0L2Rpc3RgLCBzbyB0aGUgcmVwb3J0ZWQgZXJyb3JzIGNvcnJlY3RseVxuXHRcdFx0Ly8gcG9pbnRzIHRvIHRoZSB1c2VyIGNhbGxzaXRlIGZvciBwb2xsIGFzc2VydGlvbiBlcnJvcnMuXG5cdFx0XHQvL1xuXHRcdFx0Ly8gSW5saW5lIHNuYXBzaG90cyBwaWdneWJhY2sgb24gdGhlIHNhbWUgaWRlYS4gV2UgcGFzc1xuXHRcdFx0Ly8gU1RBQ0tfVFJBQ0VfRVJST1IgdGhyb3VnaCBgY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCAnZXJyb3InLCAuLi4pYC5cblx0XHRcdC8vIElubGluZSBzbmFwc2hvdCBhc3NlcnRpb24gYWNjZXNzIHRoZSBzYW1lIGVycm9yIHN0YWNrIGZvclxuXHRcdFx0Ly8gZXh0cmFjdGluZyBpbmxpbmUgc25hcHNob3QgbG9jYXRpb24gdG8gdmFsaWRhdGUgYW5kIHVwZGF0ZSBuZXcgc25hcHNob3RzLlxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uIF9fVklURVNUX1BPTExfQ0hBSU5fXyguLi5hcmdzKSB7XG5cdFx0XHRcdGNvbnN0IFNUQUNLX1RSQUNFX0VSUk9SID0gLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIlNUQUNLX1RSQUNFX0VSUk9SXCIpO1xuXHRcdFx0XHRjb25zdCBwcm9taXNlID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfbmFtZVwiLCBrZXkpO1xuXHRcdFx0XHRcdGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJlcnJvclwiLCBTVEFDS19UUkFDRV9FUlJPUik7XG5cdFx0XHRcdFx0Y29uc3Qgb25TZXR0bGVkID0gY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9wb2xsLm9uU2V0dGxlZFwiKTtcblx0XHRcdFx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihhc3NlcnRpb25GdW5jdGlvbiwgXCJfX3ZpdGVzdF9wb2xsX3Rha2VvdmVyX19cIik/LnZhbHVlKSB0cnkge1xuXHRcdFx0XHRcdFx0Y29uc3Qgb3V0cHV0ID0gYXdhaXQgYXNzZXJ0aW9uRnVuY3Rpb24uY2FsbChhc3NlcnRpb24sIC4uLmFyZ3MpO1xuXHRcdFx0XHRcdFx0YXdhaXQgb25TZXR0bGVkPy4oe1xuXHRcdFx0XHRcdFx0XHRhc3NlcnRpb24sXG5cdFx0XHRcdFx0XHRcdHN0YXR1czogXCJwYXNzXCJcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0cmV0dXJuIG91dHB1dDtcblx0XHRcdFx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdFx0XHRcdGF3YWl0IG9uU2V0dGxlZD8uKHtcblx0XHRcdFx0XHRcdFx0YXNzZXJ0aW9uLFxuXHRcdFx0XHRcdFx0XHRzdGF0dXM6IFwiZmFpbFwiXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdHRocm93V2l0aENhdXNlKGVyciwgU1RBQ0tfVFJBQ0VfRVJST1IpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb25zdCB7IHNldFRpbWVvdXQsIGNsZWFyVGltZW91dCB9ID0gZ2V0U2FmZVRpbWVycygpO1xuXHRcdFx0XHRcdGxldCBleGVjdXRpb25QaGFzZSA9IFwiZm5cIjtcblx0XHRcdFx0XHRsZXQgaGFzVGltZWRPdXQgPSBmYWxzZTtcblx0XHRcdFx0XHRjb25zdCB0aW1lcklkID0gc2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdFx0XHRoYXNUaW1lZE91dCA9IHRydWU7XG5cdFx0XHRcdFx0fSwgdGltZW91dCk7XG5cdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdHdoaWxlICh0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IGlzTGFzdEF0dGVtcHQgPSBoYXNUaW1lZE91dDtcblx0XHRcdFx0XHRcdFx0aWYgKGlzTGFzdEF0dGVtcHQpIGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfaXNMYXN0UG9sbEF0dGVtcHRcIiwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdFx0ZXhlY3V0aW9uUGhhc2UgPSBcImZuXCI7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3Qgb2JqID0gYXdhaXQgZm4oKTtcblx0XHRcdFx0XHRcdFx0XHRjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwib2JqZWN0XCIsIG9iaik7XG5cdFx0XHRcdFx0XHRcdFx0ZXhlY3V0aW9uUGhhc2UgPSBcImFzc2VydGlvblwiO1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IG91dHB1dCA9IGF3YWl0IGFzc2VydGlvbkZ1bmN0aW9uLmNhbGwoYXNzZXJ0aW9uLCAuLi5hcmdzKTtcblx0XHRcdFx0XHRcdFx0XHRhd2FpdCBvblNldHRsZWQ/Lih7XG5cdFx0XHRcdFx0XHRcdFx0XHRhc3NlcnRpb24sXG5cdFx0XHRcdFx0XHRcdFx0XHRzdGF0dXM6IFwicGFzc1wiXG5cdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG91dHB1dDtcblx0XHRcdFx0XHRcdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKGlzTGFzdEF0dGVtcHQgfHwgZXhlY3V0aW9uUGhhc2UgPT09IFwiYXNzZXJ0aW9uXCIgJiYgY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9wb2xsLmFzc2VydF9vbmNlXCIpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRhd2FpdCBvblNldHRsZWQ/Lih7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGFzc2VydGlvbixcblx0XHRcdFx0XHRcdFx0XHRcdFx0c3RhdHVzOiBcImZhaWxcIlxuXHRcdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0XHR0aHJvd1dpdGhDYXVzZShlcnIsIFNUQUNLX1RSQUNFX0VSUk9SKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0YXdhaXQgZGVsYXkoaW50ZXJ2YWwsIHNldFRpbWVvdXQpO1xuXHRcdFx0XHRcdFx0XHRcdGlmICh2aS5pc0Zha2VUaW1lcnMoKSkgdmkuYWR2YW5jZVRpbWVyc0J5VGltZShpbnRlcnZhbCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdFx0Y2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdFx0bGV0IGF3YWl0ZWQgPSBmYWxzZTtcblx0XHRcdFx0dGVzdC5vbkZpbmlzaGVkID8/PSBbXTtcblx0XHRcdFx0dGVzdC5vbkZpbmlzaGVkLnB1c2goKCkgPT4ge1xuXHRcdFx0XHRcdGlmICghYXdhaXRlZCkge1xuXHRcdFx0XHRcdFx0Y29uc3QgbmVnYXRlZCA9IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJuZWdhdGVcIikgPyBcIm5vdC5cIiA6IFwiXCI7XG5cdFx0XHRcdFx0XHRjb25zdCBhc3NlcnRpb25TdHJpbmcgPSBgZXhwZWN0LiR7Y2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9wb2xsLmVsZW1lbnRcIikgPyBcImVsZW1lbnQobG9jYXRvcilcIiA6IFwicG9sbChhc3NlcnRpb24pXCJ9LiR7bmVnYXRlZH0ke1N0cmluZyhrZXkpfSgpYDtcblx0XHRcdFx0XHRcdHRocm93IGNvcHlTdGFja1RyYWNlKC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoYCR7YXNzZXJ0aW9uU3RyaW5nfSB3YXMgbm90IGF3YWl0ZWQuIFRoaXMgYXNzZXJ0aW9uIGlzIGFzeW5jaHJvbm91cyBhbmQgbXVzdCBiZSBhd2FpdGVkOyBvdGhlcndpc2UsIGl0IGlzIG5vdCBleGVjdXRlZCB0byBhdm9pZCB1bmhhbmRsZWQgcmVqZWN0aW9uczpcXG5cXG5hd2FpdCAke2Fzc2VydGlvblN0cmluZ31cXG5gKSwgU1RBQ0tfVFJBQ0VfRVJST1IpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdGxldCByZXN1bHRQcm9taXNlO1xuXHRcdFx0XHQvLyBvbmx5IC50aGVuIGlzIGVub3VnaCB0byBjaGVjayBhd2FpdGVkLCBidXQgd2UgdHlwZSB0aGlzIGFzIGBQcm9taXNlPHZvaWQ+YCBpbiBnbG9iYWwgdHlwZXNcblx0XHRcdFx0Ly8gc28gbGV0J3MgZm9sbG93IGl0XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0dGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuXHRcdFx0XHRcdFx0YXdhaXRlZCA9IHRydWU7XG5cdFx0XHRcdFx0XHRyZXR1cm4gKHJlc3VsdFByb21pc2UgfHw9IHByb21pc2UoKSkudGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCk7XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRjYXRjaChvblJlamVjdGVkKSB7XG5cdFx0XHRcdFx0XHRhd2FpdGVkID0gdHJ1ZTtcblx0XHRcdFx0XHRcdHJldHVybiAocmVzdWx0UHJvbWlzZSB8fD0gcHJvbWlzZSgpKS5jYXRjaChvblJlamVjdGVkKTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdGZpbmFsbHkob25GaW5hbGx5KSB7XG5cdFx0XHRcdFx0XHRhd2FpdGVkID0gdHJ1ZTtcblx0XHRcdFx0XHRcdHJldHVybiAocmVzdWx0UHJvbWlzZSB8fD0gcHJvbWlzZSgpKS5maW5hbGx5KG9uRmluYWxseSk7XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRbU3ltYm9sLnRvU3RyaW5nVGFnXTogXCJQcm9taXNlXCJcblx0XHRcdFx0fTtcblx0XHRcdH07XG5cdFx0fSB9KTtcblx0XHRyZXR1cm4gcHJveHk7XG5cdH07XG59XG5mdW5jdGlvbiBjb3B5U3RhY2tUcmFjZSh0YXJnZXQsIHNvdXJjZSkge1xuXHRpZiAoc291cmNlLnN0YWNrICE9PSB2b2lkIDApIHRhcmdldC5zdGFjayA9IHNvdXJjZS5zdGFjay5yZXBsYWNlKHNvdXJjZS5tZXNzYWdlLCB0YXJnZXQubWVzc2FnZSk7XG5cdHJldHVybiB0YXJnZXQ7XG59XG5cbmxldCBfY2xpZW50O1xuZnVuY3Rpb24gZ2V0U25hcHNob3RDbGllbnQoKSB7XG5cdGlmICghX2NsaWVudCkgX2NsaWVudCA9IG5ldyBTbmFwc2hvdENsaWVudCh7IGlzRXF1YWw6IChyZWNlaXZlZCwgZXhwZWN0ZWQpID0+IHtcblx0XHRyZXR1cm4gZXF1YWxzKHJlY2VpdmVkLCBleHBlY3RlZCwgW2l0ZXJhYmxlRXF1YWxpdHksIHN1YnNldEVxdWFsaXR5XSk7XG5cdH0gfSk7XG5cdHJldHVybiBfY2xpZW50O1xufVxuZnVuY3Rpb24gZ2V0RXJyb3IoZXhwZWN0ZWQsIHByb21pc2UpIHtcblx0aWYgKHR5cGVvZiBleHBlY3RlZCAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0aWYgKCFwcm9taXNlKSB0aHJvdyBuZXcgRXJyb3IoYGV4cGVjdGVkIG11c3QgYmUgYSBmdW5jdGlvbiwgcmVjZWl2ZWQgJHt0eXBlb2YgZXhwZWN0ZWR9YCk7XG5cdFx0Ly8gd2hlbiBcInByb21pc2VkXCIsIGl0IHJlY2VpdmVzIHRocm93biBlcnJvclxuXHRcdHJldHVybiBleHBlY3RlZDtcblx0fVxuXHR0cnkge1xuXHRcdGV4cGVjdGVkKCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZTtcblx0fVxuXHR0aHJvdyBuZXcgRXJyb3IoXCJzbmFwc2hvdCBmdW5jdGlvbiBkaWRuJ3QgdGhyb3dcIik7XG59XG5mdW5jdGlvbiBnZXRUZXN0TmFtZXModGVzdCkge1xuXHRyZXR1cm4ge1xuXHRcdGZpbGVwYXRoOiB0ZXN0LmZpbGUuZmlsZXBhdGgsXG5cdFx0bmFtZTogZ2V0TmFtZXModGVzdCkuc2xpY2UoMSkuam9pbihcIiA+IFwiKSxcblx0XHR0ZXN0SWQ6IHRlc3QuaWRcblx0fTtcbn1cbmZ1bmN0aW9uIGdldEFzc2VydGlvbk5hbWUoYXNzZXJ0aW9uKSB7XG5cdGNvbnN0IG5hbWUgPSBjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwiX25hbWVcIik7XG5cdGlmICghbmFtZSkgdGhyb3cgbmV3IEVycm9yKFwiQXNzZXJ0aW9uIG5hbWUgaXMgbm90IHNldC4gVGhpcyBpcyBhIGJ1ZyBpbiBWaXRlc3QuIFBsZWFzZSwgb3BlbiBhIG5ldyBpc3N1ZSB3aXRoIHJlcHJvZHVjdGlvbi5cIik7XG5cdHJldHVybiBuYW1lO1xufVxuZnVuY3Rpb24gZ2V0VGVzdChvYmopIHtcblx0Y29uc3QgdGVzdCA9IGNoYWkudXRpbC5mbGFnKG9iaiwgXCJ2aXRlc3QtdGVzdFwiKTtcblx0aWYgKCF0ZXN0KSB0aHJvdyBuZXcgRXJyb3IoYCcke2dldEFzc2VydGlvbk5hbWUob2JqKX0nIGNhbm5vdCBiZSB1c2VkIHdpdGhvdXQgdGVzdCBjb250ZXh0YCk7XG5cdHJldHVybiB0ZXN0O1xufVxuZnVuY3Rpb24gdmFsaWRhdGVBc3NlcnRpb24oYXNzZXJ0aW9uKSB7XG5cdGlmIChjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwibmVnYXRlXCIpKSB0aHJvdyBuZXcgRXJyb3IoYCR7Z2V0QXNzZXJ0aW9uTmFtZShhc3NlcnRpb24pfSBjYW5ub3QgYmUgdXNlZCB3aXRoIFwibm90XCJgKTtcbn1cbmNvbnN0IFNuYXBzaG90UGx1Z2luID0gKGNoYWksIHV0aWxzKSA9PiB7XG5cdGZvciAoY29uc3Qga2V5IG9mIFtcIm1hdGNoU25hcHNob3RcIiwgXCJ0b01hdGNoU25hcHNob3RcIl0pIHV0aWxzLmFkZE1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIGtleSwgd3JhcEFzc2VydGlvbih1dGlscywga2V5LCBmdW5jdGlvbihwcm9wZXJ0aWVzT3JIaW50LCBoaW50KSB7XG5cdFx0cmV0dXJuIGFzc2VydE1hdGNoUmVzdWx0KHRvTWF0Y2hTbmFwc2hvdEltcGwoe1xuXHRcdFx0YXNzZXJ0aW9uOiB0aGlzLFxuXHRcdFx0cmVjZWl2ZWQ6IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIiksXG5cdFx0XHQuLi5ub3JtYWxpemVBcmd1bWVudHMocHJvcGVydGllc09ySGludCwgaGludClcblx0XHR9KSwgY2hhaS51dGlsLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpKTtcblx0fSkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBcInRvTWF0Y2hGaWxlU25hcHNob3RcIiwgZnVuY3Rpb24oZmlsZXBhdGgsIGhpbnQpIHtcblx0XHQvLyBzZXQgbmFtZSBtYW51YWxseSBzaW5jZSBpdCdzIG5vdCB3cmFwcGVkIGJ5IHdyYXBBc3NlcnRpb25cblx0XHR1dGlscy5mbGFnKHRoaXMsIFwiX25hbWVcIiwgXCJ0b01hdGNoRmlsZVNuYXBzaG90XCIpO1xuXHRcdC8vIHZhbGlkYXRlIGVhcmx5IHN5bmNocm9ub3VzbHkganVzdCBub3QgdG8gYnJlYWsgc29tZSBleGlzdGluZyB0ZXN0c1xuXHRcdHZhbGlkYXRlQXNzZXJ0aW9uKHRoaXMpO1xuXHRcdGNvbnN0IGFzc2VydFByb21pc2UgPSB0b01hdGNoRmlsZVNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMsXG5cdFx0XHRyZWNlaXZlZDogdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKSxcblx0XHRcdGZpbGVwYXRoLFxuXHRcdFx0aGludFxuXHRcdH0pLnRoZW4oKHJlc3VsdCkgPT4gYXNzZXJ0TWF0Y2hSZXN1bHQocmVzdWx0LCBjaGFpLnV0aWwuZmxhZyh0aGlzLCBcIm1lc3NhZ2VcIikpKTtcblx0XHRyZXR1cm4gcmVjb3JkQXN5bmNFeHBlY3QoZ2V0VGVzdCh0aGlzKSwgYXNzZXJ0UHJvbWlzZSwgY3JlYXRlQXNzZXJ0aW9uTWVzc2FnZSh1dGlscywgdGhpcywgdHJ1ZSksIC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoXCJyZXNvbHZlc1wiKSwgdXRpbHMuZmxhZyh0aGlzLCBcInNvZnRcIikpO1xuXHR9KTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgXCJ0b01hdGNoSW5saW5lU25hcHNob3RcIiwgd3JhcEFzc2VydGlvbih1dGlscywgXCJ0b01hdGNoSW5saW5lU25hcHNob3RcIiwgZnVuY3Rpb24gX19JTkxJTkVfU05BUFNIT1RfT0ZGU0VUXzNfXyhwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCwgaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpIHtcblx0XHRyZXR1cm4gYXNzZXJ0TWF0Y2hSZXN1bHQodG9NYXRjaFNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMsXG5cdFx0XHRyZWNlaXZlZDogdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKSxcblx0XHRcdGlzSW5saW5lOiB0cnVlLFxuXHRcdFx0Li4ubm9ybWFsaXplSW5saW5lQXJndW1lbnRzKHByb3BlcnRpZXNPcklubGluZVNuYXBzaG90LCBpbmxpbmVTbmFwc2hvdE9ySGludCwgaGludClcblx0XHR9KSwgY2hhaS51dGlsLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpKTtcblx0fSkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBcInRvVGhyb3dFcnJvck1hdGNoaW5nU25hcHNob3RcIiwgd3JhcEFzc2VydGlvbih1dGlscywgXCJ0b1Rocm93RXJyb3JNYXRjaGluZ1NuYXBzaG90XCIsIGZ1bmN0aW9uKHByb3BlcnRpZXNPckhpbnQsIGhpbnQpIHtcblx0XHR2YWxpZGF0ZUFzc2VydGlvbih0aGlzKTtcblx0XHRjb25zdCByZWNlaXZlZCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3QgcHJvbWlzZSA9IHV0aWxzLmZsYWcodGhpcywgXCJwcm9taXNlXCIpO1xuXHRcdHJldHVybiBhc3NlcnRNYXRjaFJlc3VsdCh0b01hdGNoU25hcHNob3RJbXBsKHtcblx0XHRcdGFzc2VydGlvbjogdGhpcyxcblx0XHRcdHJlY2VpdmVkOiBnZXRFcnJvcihyZWNlaXZlZCwgcHJvbWlzZSksXG5cdFx0XHQuLi5ub3JtYWxpemVBcmd1bWVudHMocHJvcGVydGllc09ySGludCwgaGludClcblx0XHR9KSwgY2hhaS51dGlsLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpKTtcblx0fSkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBcInRvVGhyb3dFcnJvck1hdGNoaW5nSW5saW5lU25hcHNob3RcIiwgd3JhcEFzc2VydGlvbih1dGlscywgXCJ0b1Rocm93RXJyb3JNYXRjaGluZ0lubGluZVNuYXBzaG90XCIsIGZ1bmN0aW9uIF9fSU5MSU5FX1NOQVBTSE9UX09GRlNFVF8zX18oaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpIHtcblx0XHR2YWxpZGF0ZUFzc2VydGlvbih0aGlzKTtcblx0XHRjb25zdCByZWNlaXZlZCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3QgcHJvbWlzZSA9IHV0aWxzLmZsYWcodGhpcywgXCJwcm9taXNlXCIpO1xuXHRcdHJldHVybiBhc3NlcnRNYXRjaFJlc3VsdCh0b01hdGNoU25hcHNob3RJbXBsKHtcblx0XHRcdGFzc2VydGlvbjogdGhpcyxcblx0XHRcdHJlY2VpdmVkOiBnZXRFcnJvcihyZWNlaXZlZCwgcHJvbWlzZSksXG5cdFx0XHRpc0lubGluZTogdHJ1ZSxcblx0XHRcdC4uLm5vcm1hbGl6ZUlubGluZUFyZ3VtZW50cyh2b2lkIDAsIGlubGluZVNuYXBzaG90T3JIaW50LCBoaW50KVxuXHRcdH0pLCBjaGFpLnV0aWwuZmxhZyh0aGlzLCBcIm1lc3NhZ2VcIikpO1xuXHR9KSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJhZGRTbmFwc2hvdFNlcmlhbGl6ZXJcIiwgYWRkU2VyaWFsaXplcik7XG59O1xuZnVuY3Rpb24gdG9NYXRjaERvbWFpblNuYXBzaG90SW1wbChvcHRzKSB7XG5cdGNvbnN0IHsgYXNzZXJ0aW9uIH0gPSBvcHRzO1xuXHR2YWxpZGF0ZUFzc2VydGlvbihhc3NlcnRpb24pO1xuXHRjb25zdCBhc3NlcnRpb25OYW1lID0gZ2V0QXNzZXJ0aW9uTmFtZShhc3NlcnRpb24pO1xuXHRjb25zdCB0ZXN0ID0gZ2V0VGVzdChhc3NlcnRpb24pO1xuXHRsZXQgeyBpbmxpbmVTbmFwc2hvdCB9ID0gb3B0cztcblx0aWYgKGlubGluZVNuYXBzaG90KSBpbmxpbmVTbmFwc2hvdCA9IHN0cmlwU25hcHNob3RJbmRlbnRhdGlvbihpbmxpbmVTbmFwc2hvdCk7XG5cdGNvbnN0IHBvbGxGbiA9IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfcG9sbC5mblwiKTtcblx0aWYgKHBvbGxGbikgcmV0dXJuIGdldFNuYXBzaG90Q2xpZW50KCkucG9sbE1hdGNoRG9tYWluKHtcblx0XHRwb2xsOiBwb2xsRm4sXG5cdFx0YWRhcHRlcjogb3B0cy5hZGFwdGVyLFxuXHRcdG1lc3NhZ2U6IG9wdHMuaGludCxcblx0XHRpc0lubGluZTogb3B0cy5pc0lubGluZSxcblx0XHRlcnJvck1lc3NhZ2U6IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJtZXNzYWdlXCIpLFxuXHRcdHRpbWVvdXQ6IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfcG9sbC50aW1lb3V0XCIpLFxuXHRcdGludGVydmFsOiBjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwiX3BvbGwuaW50ZXJ2YWxcIiksXG5cdFx0YXNzZXJ0aW9uTmFtZSxcblx0XHRpbmxpbmVTbmFwc2hvdCxcblx0XHRlcnJvcjogY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcImVycm9yXCIpLFxuXHRcdC4uLmdldFRlc3ROYW1lcyh0ZXN0KVxuXHR9KTtcblx0cmV0dXJuIGdldFNuYXBzaG90Q2xpZW50KCkubWF0Y2hEb21haW4oe1xuXHRcdHJlY2VpdmVkOiBvcHRzLnJlY2VpdmVkLFxuXHRcdGFkYXB0ZXI6IG9wdHMuYWRhcHRlcixcblx0XHRtZXNzYWdlOiBvcHRzLmhpbnQsXG5cdFx0aXNJbmxpbmU6IG9wdHMuaXNJbmxpbmUsXG5cdFx0ZXJyb3JNZXNzYWdlOiBjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwibWVzc2FnZVwiKSxcblx0XHRhc3NlcnRpb25OYW1lLFxuXHRcdGlubGluZVNuYXBzaG90LFxuXHRcdGVycm9yOiBjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwiZXJyb3JcIiksXG5cdFx0Li4uZ2V0VGVzdE5hbWVzKHRlc3QpXG5cdH0pO1xufVxuLy8gdG9NYXRjaFNuYXBzaG90KHByb3BlcnRpZXNPckhpbnQ/LCBoaW50PylcbmZ1bmN0aW9uIG5vcm1hbGl6ZUFyZ3VtZW50cyhwcm9wZXJ0aWVzT3JIaW50LCBoaW50KSB7XG5cdGlmICh0eXBlb2YgcHJvcGVydGllc09ySGludCA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHsgaGludDogcHJvcGVydGllc09ySGludCB9O1xuXHRyZXR1cm4ge1xuXHRcdHByb3BlcnRpZXM6IHByb3BlcnRpZXNPckhpbnQsXG5cdFx0aGludFxuXHR9O1xufVxuLy8gdG9NYXRjaElubGluZVNuYXBzaG90KHByb3BlcnRpZXNPcklubGluZVNuYXBzaG90PywgaW5saW5lU25hcHNob3RPckhpbnQ/LCBoaW50PylcbmZ1bmN0aW9uIG5vcm1hbGl6ZUlubGluZUFyZ3VtZW50cyhwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCwgaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpIHtcblx0bGV0IGlubGluZVNuYXBzaG90O1xuXHRpZiAodHlwZW9mIHByb3BlcnRpZXNPcklubGluZVNuYXBzaG90ID09PSBcInN0cmluZ1wiKSB7XG5cdFx0aW5saW5lU25hcHNob3QgPSBzdHJpcFNuYXBzaG90SW5kZW50YXRpb24ocHJvcGVydGllc09ySW5saW5lU25hcHNob3QpO1xuXHRcdHJldHVybiB7XG5cdFx0XHRpbmxpbmVTbmFwc2hvdCxcblx0XHRcdGhpbnQ6IGlubGluZVNuYXBzaG90T3JIaW50XG5cdFx0fTtcblx0fVxuXHRpZiAoaW5saW5lU25hcHNob3RPckhpbnQpIGlubGluZVNuYXBzaG90ID0gc3RyaXBTbmFwc2hvdEluZGVudGF0aW9uKGlubGluZVNuYXBzaG90T3JIaW50KTtcblx0cmV0dXJuIHtcblx0XHRwcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCxcblx0XHRpbmxpbmVTbmFwc2hvdCxcblx0XHRoaW50XG5cdH07XG59XG5mdW5jdGlvbiB0b01hdGNoU25hcHNob3RJbXBsKG9wdGlvbnMpIHtcblx0Y29uc3QgeyBhc3NlcnRpb24gfSA9IG9wdGlvbnM7XG5cdHZhbGlkYXRlQXNzZXJ0aW9uKGFzc2VydGlvbik7XG5cdGNvbnN0IGFzc2VydGlvbk5hbWUgPSBnZXRBc3NlcnRpb25OYW1lKGFzc2VydGlvbik7XG5cdGNvbnN0IHRlc3QgPSBnZXRUZXN0KGFzc2VydGlvbik7XG5cdHJldHVybiBnZXRTbmFwc2hvdENsaWVudCgpLm1hdGNoKHtcblx0XHRyZWNlaXZlZDogb3B0aW9ucy5yZWNlaXZlZCxcblx0XHRwcm9wZXJ0aWVzOiBvcHRpb25zLnByb3BlcnRpZXMsXG5cdFx0bWVzc2FnZTogb3B0aW9ucy5oaW50LFxuXHRcdGlzSW5saW5lOiBvcHRpb25zLmlzSW5saW5lLFxuXHRcdGlubGluZVNuYXBzaG90OiBvcHRpb25zLmlubGluZVNuYXBzaG90LFxuXHRcdGFzc2VydGlvbk5hbWUsXG5cdFx0ZXJyb3I6IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJlcnJvclwiKSxcblx0XHQuLi5nZXRUZXN0TmFtZXModGVzdClcblx0fSk7XG59XG5hc3luYyBmdW5jdGlvbiB0b01hdGNoRmlsZVNuYXBzaG90SW1wbChvcHRpb25zKSB7XG5cdGNvbnN0IHsgYXNzZXJ0aW9uIH0gPSBvcHRpb25zO1xuXHR2YWxpZGF0ZUFzc2VydGlvbihhc3NlcnRpb24pO1xuXHRjb25zdCB0ZXN0TmFtZXMgPSBnZXRUZXN0TmFtZXMoZ2V0VGVzdChhc3NlcnRpb24pKTtcblx0Y29uc3Qgc25hcHNob3RTdGF0ZSA9IGdldFNuYXBzaG90Q2xpZW50KCkuZ2V0U25hcHNob3RTdGF0ZSh0ZXN0TmFtZXMuZmlsZXBhdGgpO1xuXHRjb25zdCByYXdTbmFwc2hvdEZpbGUgPSBhd2FpdCBzbmFwc2hvdFN0YXRlLmVudmlyb25tZW50LnJlc29sdmVSYXdQYXRoKHRlc3ROYW1lcy5maWxlcGF0aCwgb3B0aW9ucy5maWxlcGF0aCk7XG5cdGNvbnN0IHJhd1NuYXBzaG90Q29udGVudCA9IGF3YWl0IHNuYXBzaG90U3RhdGUuZW52aXJvbm1lbnQucmVhZFNuYXBzaG90RmlsZShyYXdTbmFwc2hvdEZpbGUpO1xuXHRyZXR1cm4gZ2V0U25hcHNob3RDbGllbnQoKS5tYXRjaCh7XG5cdFx0cmVjZWl2ZWQ6IG9wdGlvbnMucmVjZWl2ZWQsXG5cdFx0bWVzc2FnZTogb3B0aW9ucy5oaW50LFxuXHRcdHJhd1NuYXBzaG90OiB7XG5cdFx0XHRmaWxlOiByYXdTbmFwc2hvdEZpbGUsXG5cdFx0XHRjb250ZW50OiByYXdTbmFwc2hvdENvbnRlbnQgPz8gdm9pZCAwXG5cdFx0fSxcblx0XHQuLi50ZXN0TmFtZXNcblx0fSk7XG59XG5mdW5jdGlvbiBhc3NlcnRNYXRjaFJlc3VsdChyZXN1bHQsIGN1c3RvbU1lc3NhZ2UpIHtcblx0aWYgKCFyZXN1bHQucGFzcykge1xuXHRcdGNvbnN0IGVycm9yTWVzc2FnZSA9IChjdXN0b21NZXNzYWdlID8gYCR7Y3VzdG9tTWVzc2FnZX06IGAgOiBcIlwiKSArIHJlc3VsdC5tZXNzYWdlKCk7XG5cdFx0dGhyb3cgT2JqZWN0LmFzc2lnbihuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKSwge1xuXHRcdFx0YWN0dWFsOiByZXN1bHQuYWN0dWFsLFxuXHRcdFx0ZXhwZWN0ZWQ6IHJlc3VsdC5leHBlY3RlZCxcblx0XHRcdGRpZmZPcHRpb25zOiB7IGV4cGFuZDogZ2V0V29ya2VyU3RhdGUoKS5jb25maWcuc25hcHNob3RPcHRpb25zLmV4cGFuZCB9XG5cdFx0fSk7XG5cdH1cbn1cbi8qKlxuKiBDb21wb3NhYmxlIHNuYXBzaG90IG1hdGNoZXIgaGVscGVycyBmb3IgYnVpbGRpbmcgY3VzdG9tIHNuYXBzaG90IG1hdGNoZXJzXG4qIHdpdGggYGV4cGVjdC5leHRlbmRgLlxuKlxuKiBAZXhwZXJpbWVudGFsXG4qIEBzZWUgaHR0cHM6Ly92aXRlc3QuZGV2L2d1aWRlL3NuYXBzaG90Lmh0bWwjY3VzdG9tLXNuYXBzaG90LW1hdGNoZXJzXG4qL1xuY29uc3QgU25hcHNob3RzID0ge1xuXHR0b01hdGNoU25hcHNob3QocmVjZWl2ZWQsIHByb3BlcnRpZXNPckhpbnQsIGhpbnQpIHtcblx0XHRyZXR1cm4gdG9NYXRjaFNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMuYXNzZXJ0aW9uLFxuXHRcdFx0cmVjZWl2ZWQsXG5cdFx0XHQuLi5ub3JtYWxpemVBcmd1bWVudHMocHJvcGVydGllc09ySGludCwgaGludClcblx0XHR9KTtcblx0fSxcblx0dG9NYXRjaElubGluZVNuYXBzaG90KHJlY2VpdmVkLCBwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCwgaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpIHtcblx0XHRyZXR1cm4gdG9NYXRjaFNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMuYXNzZXJ0aW9uLFxuXHRcdFx0cmVjZWl2ZWQsXG5cdFx0XHRpc0lubGluZTogdHJ1ZSxcblx0XHRcdC4uLm5vcm1hbGl6ZUlubGluZUFyZ3VtZW50cyhwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCwgaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpXG5cdFx0fSk7XG5cdH0sXG5cdHRvTWF0Y2hGaWxlU25hcHNob3QocmVjZWl2ZWQsIGZpbGVwYXRoLCBoaW50KSB7XG5cdFx0cmV0dXJuIHRvTWF0Y2hGaWxlU25hcHNob3RJbXBsKHtcblx0XHRcdGFzc2VydGlvbjogdGhpcy5hc3NlcnRpb24sXG5cdFx0XHRyZWNlaXZlZCxcblx0XHRcdGZpbGVwYXRoLFxuXHRcdFx0aGludFxuXHRcdH0pO1xuXHR9LFxuXHR0b01hdGNoRG9tYWluU25hcHNob3QoZG9tYWluLCByZWNlaXZlZCkge1xuXHRcdHJldHVybiB0b01hdGNoRG9tYWluU25hcHNob3RJbXBsKHtcblx0XHRcdGFzc2VydGlvbjogdGhpcy5hc3NlcnRpb24sXG5cdFx0XHRhZGFwdGVyOiBkb21haW4sXG5cdFx0XHRyZWNlaXZlZFxuXHRcdH0pO1xuXHR9LFxuXHR0b01hdGNoRG9tYWluSW5saW5lU25hcHNob3QoZG9tYWluLCByZWNlaXZlZCwgaW5saW5lU25hcHNob3QpIHtcblx0XHRyZXR1cm4gdG9NYXRjaERvbWFpblNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMuYXNzZXJ0aW9uLFxuXHRcdFx0YWRhcHRlcjogZG9tYWluLFxuXHRcdFx0cmVjZWl2ZWQsXG5cdFx0XHRpc0lubGluZTogdHJ1ZSxcblx0XHRcdGlubGluZVNuYXBzaG90XG5cdFx0fSk7XG5cdH1cbn07XG5cbmNoYWkudXNlKEplc3RFeHRlbmQpO1xuY2hhaS51c2UoSmVzdENoYWlFeHBlY3QpO1xuY2hhaS51c2UoQ2hhaVN0eWxlQXNzZXJ0aW9ucyk7XG5jaGFpLnVzZShTbmFwc2hvdFBsdWdpbik7XG5jaGFpLnVzZShKZXN0QXN5bW1ldHJpY01hdGNoZXJzKTtcblxuZnVuY3Rpb24gY3JlYXRlRXhwZWN0KHRlc3QpIHtcblx0Y29uc3QgZXhwZWN0ID0gKCh2YWx1ZSwgbWVzc2FnZSkgPT4ge1xuXHRcdGNvbnN0IHsgYXNzZXJ0aW9uQ2FsbHMgfSA9IGdldFN0YXRlKGV4cGVjdCk7XG5cdFx0c2V0U3RhdGUoeyBhc3NlcnRpb25DYWxsczogYXNzZXJ0aW9uQ2FsbHMgKyAxIH0sIGV4cGVjdCk7XG5cdFx0Y29uc3QgYXNzZXJ0ID0gY2hhaS5leHBlY3QodmFsdWUsIG1lc3NhZ2UpO1xuXHRcdGNvbnN0IF90ZXN0ID0gdGVzdCB8fCBnZXRDdXJyZW50VGVzdCgpO1xuXHRcdGlmIChfdGVzdClcbiAvLyBAdHMtZXhwZWN0LWVycm9yIGludGVybmFsXG5cdFx0cmV0dXJuIGFzc2VydC53aXRoVGVzdChfdGVzdCk7XG5cdFx0ZWxzZSByZXR1cm4gYXNzZXJ0O1xuXHR9KTtcblx0T2JqZWN0LmFzc2lnbihleHBlY3QsIGNoYWkuZXhwZWN0KTtcblx0T2JqZWN0LmFzc2lnbihleHBlY3QsIGdsb2JhbFRoaXNbQVNZTU1FVFJJQ19NQVRDSEVSU19PQkpFQ1RdKTtcblx0ZXhwZWN0LmdldFN0YXRlID0gKCkgPT4gZ2V0U3RhdGUoZXhwZWN0KTtcblx0ZXhwZWN0LnNldFN0YXRlID0gKHN0YXRlKSA9PiBzZXRTdGF0ZShzdGF0ZSwgZXhwZWN0KTtcblx0Ly8gQHRzLWV4cGVjdC1lcnJvciBnbG9iYWwgaXMgbm90IHR5cGVkXG5cdGNvbnN0IGdsb2JhbFN0YXRlID0gZ2V0U3RhdGUoZ2xvYmFsVGhpc1tHTE9CQUxfRVhQRUNUXSkgfHwge307XG5cdHNldFN0YXRlKHtcblx0XHQuLi5nbG9iYWxTdGF0ZSxcblx0XHRhc3NlcnRpb25DYWxsczogMCxcblx0XHRpc0V4cGVjdGluZ0Fzc2VydGlvbnM6IGZhbHNlLFxuXHRcdGlzRXhwZWN0aW5nQXNzZXJ0aW9uc0Vycm9yOiBudWxsLFxuXHRcdGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlcjogbnVsbCxcblx0XHRleHBlY3RlZEFzc2VydGlvbnNOdW1iZXJFcnJvckdlbjogbnVsbCxcblx0XHRnZXQgdGVzdFBhdGgoKSB7XG5cdFx0XHRyZXR1cm4gZ2V0V29ya2VyU3RhdGUoKS5maWxlcGF0aDtcblx0XHR9LFxuXHRcdGN1cnJlbnRUZXN0TmFtZTogdGVzdCA/IHRlc3QuZnVsbFRlc3ROYW1lID8/IFwiXCIgOiBnbG9iYWxTdGF0ZS5jdXJyZW50VGVzdE5hbWVcblx0fSwgZXhwZWN0KTtcblx0ZXhwZWN0LmFzc2VydCA9IGNoYWkuYXNzZXJ0O1xuXHQvLyBAdHMtZXhwZWN0LWVycm9yIHVudHlwZWRcblx0ZXhwZWN0LmV4dGVuZCA9IChtYXRjaGVycykgPT4gY2hhaS5leHBlY3QuZXh0ZW5kKGV4cGVjdCwgbWF0Y2hlcnMpO1xuXHRleHBlY3QuYWRkRXF1YWxpdHlUZXN0ZXJzID0gKGN1c3RvbVRlc3RlcnMpID0+IGFkZEN1c3RvbUVxdWFsaXR5VGVzdGVycyhjdXN0b21UZXN0ZXJzKTtcblx0ZXhwZWN0LnNvZnQgPSAoLi4uYXJncykgPT4ge1xuXHRcdC8vIEB0cy1leHBlY3QtZXJyb3IgcHJpdmF0ZSBzb2Z0IGFjY2Vzc1xuXHRcdHJldHVybiBleHBlY3QoLi4uYXJncykud2l0aENvbnRleHQoeyBzb2Z0OiB0cnVlIH0pO1xuXHR9O1xuXHRleHBlY3QucG9sbCA9IGNyZWF0ZUV4cGVjdFBvbGwoZXhwZWN0KTtcblx0ZXhwZWN0LnVucmVhY2hhYmxlID0gKG1lc3NhZ2UpID0+IHtcblx0XHRjaGFpLmFzc2VydC5mYWlsKGBleHBlY3RlZCR7bWVzc2FnZSA/IGAgXCIke21lc3NhZ2V9XCIgYCA6IFwiIFwifW5vdCB0byBiZSByZWFjaGVkYCk7XG5cdH07XG5cdGZ1bmN0aW9uIGFzc2VydGlvbnMoZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBlcnJvckdlbiA9ICgpID0+IC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoYGV4cGVjdGVkIG51bWJlciBvZiBhc3NlcnRpb25zIHRvIGJlICR7ZXhwZWN0ZWR9LCBidXQgZ290ICR7ZXhwZWN0LmdldFN0YXRlKCkuYXNzZXJ0aW9uQ2FsbHN9YCk7XG5cdFx0aWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZShlcnJvckdlbigpLCBhc3NlcnRpb25zKTtcblx0XHRleHBlY3Quc2V0U3RhdGUoe1xuXHRcdFx0ZXhwZWN0ZWRBc3NlcnRpb25zTnVtYmVyOiBleHBlY3RlZCxcblx0XHRcdGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlckVycm9yR2VuOiBlcnJvckdlblxuXHRcdH0pO1xuXHR9XG5cdGZ1bmN0aW9uIGhhc0Fzc2VydGlvbnMoKSB7XG5cdFx0Y29uc3QgZXJyb3IgPSAvKiBAX19QVVJFX18gKi8gbmV3IEVycm9yKFwiZXhwZWN0ZWQgYW55IG51bWJlciBvZiBhc3NlcnRpb24sIGJ1dCBnb3Qgbm9uZVwiKTtcblx0XHRpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKGVycm9yLCBoYXNBc3NlcnRpb25zKTtcblx0XHRleHBlY3Quc2V0U3RhdGUoe1xuXHRcdFx0aXNFeHBlY3RpbmdBc3NlcnRpb25zOiB0cnVlLFxuXHRcdFx0aXNFeHBlY3RpbmdBc3NlcnRpb25zRXJyb3I6IGVycm9yXG5cdFx0fSk7XG5cdH1cblx0Y2hhaS51dGlsLmFkZE1ldGhvZChleHBlY3QsIFwiYXNzZXJ0aW9uc1wiLCBhc3NlcnRpb25zKTtcblx0Y2hhaS51dGlsLmFkZE1ldGhvZChleHBlY3QsIFwiaGFzQXNzZXJ0aW9uc1wiLCBoYXNBc3NlcnRpb25zKTtcblx0ZXhwZWN0LmV4dGVuZChjdXN0b21NYXRjaGVycyk7XG5cdHJldHVybiBleHBlY3Q7XG59XG5jb25zdCBnbG9iYWxFeHBlY3QgPSBjcmVhdGVFeHBlY3QoKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzLCBHTE9CQUxfRVhQRUNULCB7XG5cdHZhbHVlOiBnbG9iYWxFeHBlY3QsXG5cdHdyaXRhYmxlOiB0cnVlLFxuXHRjb25maWd1cmFibGU6IHRydWVcbn0pO1xuY29uc3QgYXNzZXJ0ID0gY2hhaS5hc3NlcnQ7XG5jb25zdCBzaG91bGQgPSBjaGFpLnNob3VsZDtcblxuLyoqXG4qIEdpdmVzIGFjY2VzcyB0byBpbmplY3RlZCBjb250ZXh0IHByb3ZpZGVkIGZyb20gdGhlIG1haW4gdGhyZWFkLlxuKiBUaGlzIHVzdWFsbHkgcmV0dXJucyBhIHZhbHVlIHByb3ZpZGVkIGJ5IGBnbG9iYWxTZXR1cGAgb3IgYW4gZXh0ZXJuYWwgbGlicmFyeS5cbiovXG5mdW5jdGlvbiBpbmplY3Qoa2V5KSB7XG5cdHJldHVybiBnZXRXb3JrZXJTdGF0ZSgpLnByb3ZpZGVkQ29udGV4dFtrZXldO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVCZW5jaG1hcmtSZXN1bHQobmFtZSkge1xuXHRyZXR1cm4ge1xuXHRcdG5hbWUsXG5cdFx0cmFuazogMCxcblx0XHRybWU6IDAsXG5cdFx0c2FtcGxlczogW11cblx0fTtcbn1cbmNvbnN0IGJlbmNobWFya1Rhc2tzID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7XG5hc3luYyBmdW5jdGlvbiBydW5CZW5jaG1hcmtTdWl0ZShzdWl0ZSwgcnVubmVyKSB7XG5cdGNvbnN0IHsgVGFzaywgQmVuY2ggfSA9IGF3YWl0IHJ1bm5lci5pbXBvcnRUaW55YmVuY2goKTtcblx0Y29uc3Qgc3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcblx0Y29uc3QgYmVuY2htYXJrR3JvdXAgPSBbXTtcblx0Y29uc3QgYmVuY2htYXJrU3VpdGVHcm91cCA9IFtdO1xuXHRmb3IgKGNvbnN0IHRhc2sgb2Ygc3VpdGUudGFza3MpIHtcblx0XHRpZiAodGFzay5tb2RlICE9PSBcInJ1blwiICYmIHRhc2subW9kZSAhPT0gXCJxdWV1ZWRcIikgY29udGludWU7XG5cdFx0aWYgKHRhc2subWV0YT8uYmVuY2htYXJrKSBiZW5jaG1hcmtHcm91cC5wdXNoKHRhc2spO1xuXHRcdGVsc2UgaWYgKHRhc2sudHlwZSA9PT0gXCJzdWl0ZVwiKSBiZW5jaG1hcmtTdWl0ZUdyb3VwLnB1c2godGFzayk7XG5cdH1cblx0Ly8gcnVuIHN1YiBzdWl0ZXMgc2VxdWVudGlhbGx5XG5cdGZvciAoY29uc3Qgc3ViU3VpdGUgb2YgYmVuY2htYXJrU3VpdGVHcm91cCkgYXdhaXQgcnVuQmVuY2htYXJrU3VpdGUoc3ViU3VpdGUsIHJ1bm5lcik7XG5cdGlmIChiZW5jaG1hcmtHcm91cC5sZW5ndGgpIHtcblx0XHRjb25zdCBkZWZlciA9IGNyZWF0ZURlZmVyKCk7XG5cdFx0c3VpdGUucmVzdWx0ID0ge1xuXHRcdFx0c3RhdGU6IFwicnVuXCIsXG5cdFx0XHRzdGFydFRpbWU6IHN0YXJ0LFxuXHRcdFx0YmVuY2htYXJrOiBjcmVhdGVCZW5jaG1hcmtSZXN1bHQoc3VpdGUubmFtZSlcblx0XHR9O1xuXHRcdHVwZGF0ZVRhc2skMShcInN1aXRlLXByZXBhcmVcIiwgc3VpdGUpO1xuXHRcdGNvbnN0IGFkZEJlbmNoVGFza0xpc3RlbmVyID0gKHRhc2ssIGJlbmNobWFyaykgPT4ge1xuXHRcdFx0dGFzay5hZGRFdmVudExpc3RlbmVyKFwiY29tcGxldGVcIiwgKGUpID0+IHtcblx0XHRcdFx0Y29uc3QgdGFza1JlcyA9IGUudGFzay5yZXN1bHQ7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGJlbmNobWFyay5yZXN1bHQuYmVuY2htYXJrO1xuXHRcdFx0XHRiZW5jaG1hcmsucmVzdWx0LnN0YXRlID0gXCJwYXNzXCI7XG5cdFx0XHRcdE9iamVjdC5hc3NpZ24ocmVzdWx0LCB0YXNrUmVzKTtcblx0XHRcdFx0Ly8gY29tcHV0ZSBleHRyYSBzdGF0cyBhbmQgZnJlZSByYXcgc2FtcGxlcyBhcyBlYXJseSBhcyBwb3NzaWJsZVxuXHRcdFx0XHRjb25zdCBzYW1wbGVzID0gcmVzdWx0LnNhbXBsZXM7XG5cdFx0XHRcdHJlc3VsdC5zYW1wbGVDb3VudCA9IHNhbXBsZXMubGVuZ3RoO1xuXHRcdFx0XHRyZXN1bHQubWVkaWFuID0gc2FtcGxlcy5sZW5ndGggJSAyID8gc2FtcGxlc1tNYXRoLmZsb29yKHNhbXBsZXMubGVuZ3RoIC8gMildIDogKHNhbXBsZXNbc2FtcGxlcy5sZW5ndGggLyAyXSArIHNhbXBsZXNbc2FtcGxlcy5sZW5ndGggLyAyIC0gMV0pIC8gMjtcblx0XHRcdFx0aWYgKCFydW5uZXIuY29uZmlnLmJlbmNobWFyaz8uaW5jbHVkZVNhbXBsZXMpIHJlc3VsdC5zYW1wbGVzLmxlbmd0aCA9IDA7XG5cdFx0XHRcdHVwZGF0ZVRhc2skMShcInRlc3QtZmluaXNoZWRcIiwgYmVuY2htYXJrKTtcblx0XHRcdH0sIHsgb25jZTogdHJ1ZSB9KTtcblx0XHRcdHRhc2suYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIChlKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHRhc2sgPSBlLnRhc2s7XG5cdFx0XHRcdGRlZmVyLnJlamVjdChiZW5jaG1hcmsgPyB0YXNrLnJlc3VsdC5lcnJvciA6IGUpO1xuXHRcdFx0fSwgeyBvbmNlOiB0cnVlIH0pO1xuXHRcdH07XG5cdFx0YmVuY2htYXJrR3JvdXAuZm9yRWFjaCgoYmVuY2htYXJrKSA9PiB7XG5cdFx0XHRjb25zdCBiZW5jaG1hcmtJbnN0YW5jZSA9IG5ldyBCZW5jaChnZXRCZW5jaE9wdGlvbnMoYmVuY2htYXJrKSk7XG5cdFx0XHRjb25zdCBiZW5jaG1hcmtGbiA9IGdldEJlbmNoRm4oYmVuY2htYXJrKTtcblx0XHRcdGJlbmNobWFyay5yZXN1bHQgPSB7XG5cdFx0XHRcdHN0YXRlOiBcInJ1blwiLFxuXHRcdFx0XHRzdGFydFRpbWU6IHN0YXJ0LFxuXHRcdFx0XHRiZW5jaG1hcms6IGNyZWF0ZUJlbmNobWFya1Jlc3VsdChiZW5jaG1hcmsubmFtZSlcblx0XHRcdH07XG5cdFx0XHRjb25zdCB0YXNrID0gbmV3IFRhc2soYmVuY2htYXJrSW5zdGFuY2UsIGJlbmNobWFyay5uYW1lLCBiZW5jaG1hcmtGbik7XG5cdFx0XHRiZW5jaG1hcmtUYXNrcy5zZXQoYmVuY2htYXJrLCB0YXNrKTtcblx0XHRcdGFkZEJlbmNoVGFza0xpc3RlbmVyKHRhc2ssIGJlbmNobWFyayk7XG5cdFx0fSk7XG5cdFx0Y29uc3QgeyBzZXRUaW1lb3V0IH0gPSBnZXRTYWZlVGltZXJzKCk7XG5cdFx0Y29uc3QgdGFza3MgPSBbXTtcblx0XHRmb3IgKGNvbnN0IGJlbmNobWFyayBvZiBiZW5jaG1hcmtHcm91cCkge1xuXHRcdFx0Y29uc3QgdGFzayA9IGJlbmNobWFya1Rhc2tzLmdldChiZW5jaG1hcmspO1xuXHRcdFx0dXBkYXRlVGFzayQxKFwidGVzdC1wcmVwYXJlXCIsIGJlbmNobWFyayk7XG5cdFx0XHRhd2FpdCB0YXNrLndhcm11cCgpO1xuXHRcdFx0dGFza3MucHVzaChbYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRyZXNvbHZlKGF3YWl0IHRhc2sucnVuKCkpO1xuXHRcdFx0fSkpLCBiZW5jaG1hcmtdKTtcblx0XHR9XG5cdFx0c3VpdGUucmVzdWx0LmR1cmF0aW9uID0gcGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydDtcblx0XHRzdWl0ZS5yZXN1bHQuc3RhdGUgPSBcInBhc3NcIjtcblx0XHR1cGRhdGVUYXNrJDEoXCJzdWl0ZS1maW5pc2hlZFwiLCBzdWl0ZSk7XG5cdFx0ZGVmZXIucmVzb2x2ZShudWxsKTtcblx0XHRhd2FpdCBkZWZlcjtcblx0fVxuXHRmdW5jdGlvbiB1cGRhdGVUYXNrJDEoZXZlbnQsIHRhc2spIHtcblx0XHR1cGRhdGVUYXNrKGV2ZW50LCB0YXNrLCBydW5uZXIpO1xuXHR9XG59XG5jbGFzcyBOb2RlQmVuY2htYXJrUnVubmVyIHtcblx0bW9kdWxlUnVubmVyO1xuXHRjb25zdHJ1Y3Rvcihjb25maWcpIHtcblx0XHR0aGlzLmNvbmZpZyA9IGNvbmZpZztcblx0fVxuXHRhc3luYyBpbXBvcnRUaW55YmVuY2goKSB7XG5cdFx0cmV0dXJuIGF3YWl0IGltcG9ydCgndGlueWJlbmNoJyk7XG5cdH1cblx0aW1wb3J0RmlsZShmaWxlcGF0aCwgc291cmNlKSB7XG5cdFx0aWYgKHNvdXJjZSA9PT0gXCJzZXR1cFwiKSB7XG5cdFx0XHRjb25zdCBtb2R1bGVOb2RlID0gZ2V0V29ya2VyU3RhdGUoKS5ldmFsdWF0ZWRNb2R1bGVzLmdldE1vZHVsZUJ5SWQoZmlsZXBhdGgpO1xuXHRcdFx0aWYgKG1vZHVsZU5vZGUpIGdldFdvcmtlclN0YXRlKCkuZXZhbHVhdGVkTW9kdWxlcy5pbnZhbGlkYXRlTW9kdWxlKG1vZHVsZU5vZGUpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5tb2R1bGVSdW5uZXIuaW1wb3J0KGZpbGVwYXRoKTtcblx0fVxuXHRhc3luYyBydW5TdWl0ZShzdWl0ZSkge1xuXHRcdGF3YWl0IHJ1bkJlbmNobWFya1N1aXRlKHN1aXRlLCB0aGlzKTtcblx0fVxuXHRhc3luYyBydW5UYXNrKCkge1xuXHRcdHRocm93IG5ldyBFcnJvcihcImB0ZXN0KClgIGFuZCBgaXQoKWAgaXMgb25seSBhdmFpbGFibGUgaW4gdGVzdCBtb2RlLlwiKTtcblx0fVxufVxuXG5jbGFzcyBUZXN0UnVubmVyIHtcblx0c25hcHNob3RDbGllbnQgPSBnZXRTbmFwc2hvdENsaWVudCgpO1xuXHR3b3JrZXJTdGF0ZSA9IGdldFdvcmtlclN0YXRlKCk7XG5cdG1vZHVsZVJ1bm5lcjtcblx0Y2FuY2VsUnVuID0gZmFsc2U7XG5cdGFzc2VydGlvbnNFcnJvcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTtcblx0cG9vbCA9IHRoaXMud29ya2VyU3RhdGUuY3R4LnBvb2w7XG5cdF9vdGVsO1xuXHR2aXRlRW52aXJvbm1lbnQ7XG5cdHZpdGVNb2R1bGVSdW5uZXI7XG5cdGNvbnN0cnVjdG9yKGNvbmZpZykge1xuXHRcdHRoaXMuY29uZmlnID0gY29uZmlnO1xuXHRcdGNvbnN0IGVudmlyb25tZW50ID0gdGhpcy53b3JrZXJTdGF0ZS5lbnZpcm9ubWVudDtcblx0XHR0aGlzLnZpdGVFbnZpcm9ubWVudCA9IGVudmlyb25tZW50LnZpdGVFbnZpcm9ubWVudCB8fCBlbnZpcm9ubWVudC5uYW1lO1xuXHRcdHRoaXMudml0ZU1vZHVsZVJ1bm5lciA9IGNvbmZpZy5leHBlcmltZW50YWwudml0ZU1vZHVsZVJ1bm5lcjtcblx0fVxuXHRpbXBvcnRGaWxlKGZpbGVwYXRoLCBzb3VyY2UpIHtcblx0XHRpZiAoc291cmNlID09PSBcInNldHVwXCIpIHtcblx0XHRcdGNvbnN0IG1vZHVsZU5vZGUgPSB0aGlzLndvcmtlclN0YXRlLmV2YWx1YXRlZE1vZHVsZXMuZ2V0TW9kdWxlQnlJZChmaWxlcGF0aCk7XG5cdFx0XHRpZiAobW9kdWxlTm9kZSkgdGhpcy53b3JrZXJTdGF0ZS5ldmFsdWF0ZWRNb2R1bGVzLmludmFsaWRhdGVNb2R1bGUobW9kdWxlTm9kZSk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLl9vdGVsLiQoYHZpdGVzdC5tb2R1bGUuaW1wb3J0XyR7c291cmNlID09PSBcInNldHVwXCIgPyBcInNldHVwXCIgOiBcInNwZWNcIn1gLCB7IGF0dHJpYnV0ZXM6IHsgXCJjb2RlLmZpbGUucGF0aFwiOiBmaWxlcGF0aCB9IH0sICgpID0+IHtcblx0XHRcdGlmICghdGhpcy52aXRlTW9kdWxlUnVubmVyKSBmaWxlcGF0aCA9IGAke2ZpbGVwYXRofT92aXRlc3Q9JHtEYXRlLm5vdygpfWA7XG5cdFx0XHRyZXR1cm4gdGhpcy5tb2R1bGVSdW5uZXIuaW1wb3J0KGZpbGVwYXRoKTtcblx0XHR9KTtcblx0fVxuXHRvbkNvbGxlY3RTdGFydChmaWxlKSB7XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5jdXJyZW50ID0gZmlsZTtcblx0fVxuXHRvbkNsZWFudXBXb3JrZXJDb250ZXh0KGxpc3RlbmVyKSB7XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5vbkNsZWFudXAobGlzdGVuZXIpO1xuXHR9XG5cdG9uQWZ0ZXJSdW5GaWxlcygpIHtcblx0XHR0aGlzLnNuYXBzaG90Q2xpZW50LmNsZWFyKCk7XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5jdXJyZW50ID0gdm9pZCAwO1xuXHR9XG5cdGFzeW5jIG9uQWZ0ZXJSdW5TdWl0ZShzdWl0ZSkge1xuXHRcdGlmICh0aGlzLmNvbmZpZy5sb2dIZWFwVXNhZ2UgJiYgdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIpIHN1aXRlLnJlc3VsdC5oZWFwID0gcHJvY2Vzcy5tZW1vcnlVc2FnZSgpLmhlYXBVc2VkO1xuXHRcdGlmIChzdWl0ZS5tb2RlICE9PSBcInNraXBcIiAmJiBcImZpbGVwYXRoXCIgaW4gc3VpdGUpIHtcblx0XHRcdC8vIG1hcmsgc25hcHNob3RzIGluIHNraXBwZWQgdGVzdHMgYXMgbm90IG9ic29sZXRlXG5cdFx0XHRmb3IgKGNvbnN0IHRlc3Qgb2YgZ2V0VGVzdHMoc3VpdGUpKSBpZiAodGVzdC5tb2RlID09PSBcInNraXBcIikge1xuXHRcdFx0XHRjb25zdCBuYW1lID0gZ2V0TmFtZXModGVzdCkuc2xpY2UoMSkuam9pbihcIiA+IFwiKTtcblx0XHRcdFx0dGhpcy5zbmFwc2hvdENsaWVudC5za2lwVGVzdChzdWl0ZS5maWxlLmZpbGVwYXRoLCBuYW1lKTtcblx0XHRcdH1cblx0XHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc25hcHNob3RDbGllbnQuZmluaXNoKHN1aXRlLmZpbGUuZmlsZXBhdGgpO1xuXHRcdFx0aWYgKHRoaXMud29ya2VyU3RhdGUuY29uZmlnLnNuYXBzaG90T3B0aW9ucy51cGRhdGVTbmFwc2hvdCA9PT0gXCJub25lXCIgJiYgcmVzdWx0LnVuY2hlY2tlZCkge1xuXHRcdFx0XHRsZXQgbWVzc2FnZSA9IGBPYnNvbGV0ZSBzbmFwc2hvdHMgZm91bmQgd2hlbiBubyBzbmFwc2hvdCB1cGRhdGUgaXMgZXhwZWN0ZWQuXFxuYDtcblx0XHRcdFx0Zm9yIChjb25zdCBrZXkgb2YgcmVzdWx0LnVuY2hlY2tlZEtleXMpIG1lc3NhZ2UgKz0gYMK3ICR7a2V5fVxcbmA7XG5cdFx0XHRcdHN1aXRlLnJlc3VsdC5lcnJvcnMgPz89IFtdO1xuXHRcdFx0XHRzdWl0ZS5yZXN1bHQuZXJyb3JzLnB1c2gocHJvY2Vzc0Vycm9yKG5ldyBFcnJvcihtZXNzYWdlKSkpO1xuXHRcdFx0XHRzdWl0ZS5yZXN1bHQuc3RhdGUgPSBcImZhaWxcIjtcblx0XHRcdH1cblx0XHRcdGF3YWl0IHJwYygpLnNuYXBzaG90U2F2ZWQocmVzdWx0KTtcblx0XHR9XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5jdXJyZW50ID0gc3VpdGUuc3VpdGUgfHwgc3VpdGUuZmlsZTtcblx0fVxuXHRvbkFmdGVyUnVuVGFzayh0ZXN0KSB7XG5cdFx0aWYgKHRoaXMuY29uZmlnLmxvZ0hlYXBVc2FnZSAmJiB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIikgdGVzdC5yZXN1bHQuaGVhcCA9IHByb2Nlc3MubWVtb3J5VXNhZ2UoKS5oZWFwVXNlZDtcblx0XHR0aGlzLndvcmtlclN0YXRlLmN1cnJlbnQgPSB0ZXN0LnN1aXRlIHx8IHRlc3QuZmlsZTtcblx0fVxuXHRjYW5jZWwoX3JlYXNvbikge1xuXHRcdHRoaXMuY2FuY2VsUnVuID0gdHJ1ZTtcblx0fVxuXHRpbmplY3RWYWx1ZShrZXkpIHtcblx0XHQvLyBpbmplY3QgaGFzIGEgdmVyeSBsaW1pdGluZyB0eXBlIGNvbnRyb2xsZWQgYnkgUHJvdmlkZWRDb250ZXh0XG5cdFx0Ly8gc29tZSB0ZXN0cyBvdmVycmlkZSBpdCB3aGljaCBjYXVzZXMgdGhlIGJ1aWxkIHRvIGZhaWxcblx0XHRyZXR1cm4gaW5qZWN0KGtleSk7XG5cdH1cblx0YXN5bmMgb25CZWZvcmVSdW5UYXNrKHRlc3QpIHtcblx0XHRpZiAodGhpcy5jYW5jZWxSdW4pIHRlc3QubW9kZSA9IFwic2tpcFwiO1xuXHRcdGlmICh0ZXN0Lm1vZGUgIT09IFwicnVuXCIgJiYgdGVzdC5tb2RlICE9PSBcInF1ZXVlZFwiKSByZXR1cm47XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5jdXJyZW50ID0gdGVzdDtcblx0fVxuXHRhc3luYyBvbkJlZm9yZVJ1blN1aXRlKHN1aXRlKSB7XG5cdFx0aWYgKHRoaXMuY2FuY2VsUnVuKSBzdWl0ZS5tb2RlID0gXCJza2lwXCI7XG5cdFx0Ly8gaW5pdGlhbGl6ZSBzbmFwc2hvdCBzdGF0ZSBiZWZvcmUgcnVubmluZyBmaWxlIHN1aXRlXG5cdFx0aWYgKHN1aXRlLm1vZGUgIT09IFwic2tpcFwiICYmIFwiZmlsZXBhdGhcIiBpbiBzdWl0ZSkgYXdhaXQgdGhpcy5zbmFwc2hvdENsaWVudC5zZXR1cChzdWl0ZS5maWxlLmZpbGVwYXRoLCB0aGlzLndvcmtlclN0YXRlLmNvbmZpZy5zbmFwc2hvdE9wdGlvbnMpO1xuXHRcdHRoaXMud29ya2VyU3RhdGUuY3VycmVudCA9IHN1aXRlO1xuXHR9XG5cdG9uQmVmb3JlVHJ5VGFzayh0ZXN0KSB7XG5cdFx0Y2xlYXJNb2R1bGVNb2Nrcyh0aGlzLmNvbmZpZyk7XG5cdFx0dGhpcy5zbmFwc2hvdENsaWVudC5jbGVhclRlc3QodGVzdC5maWxlLmZpbGVwYXRoLCB0ZXN0LmlkKTtcblx0XHRzZXRTdGF0ZSh7XG5cdFx0XHRhc3NlcnRpb25DYWxsczogMCxcblx0XHRcdGlzRXhwZWN0aW5nQXNzZXJ0aW9uczogZmFsc2UsXG5cdFx0XHRpc0V4cGVjdGluZ0Fzc2VydGlvbnNFcnJvcjogbnVsbCxcblx0XHRcdGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlcjogbnVsbCxcblx0XHRcdGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlckVycm9yR2VuOiBudWxsLFxuXHRcdFx0Y3VycmVudFRlc3ROYW1lOiBnZXRUZXN0TmFtZSh0ZXN0KSxcblx0XHRcdHNuYXBzaG90U3RhdGU6IHRoaXMuc25hcHNob3RDbGllbnQuZ2V0U25hcHNob3RTdGF0ZSh0ZXN0LmZpbGUuZmlsZXBhdGgpXG5cdFx0fSwgZ2xvYmFsVGhpc1tHTE9CQUxfRVhQRUNUXSk7XG5cdH1cblx0b25BZnRlclRyeVRhc2sodGVzdCkge1xuXHRcdGNvbnN0IHsgYXNzZXJ0aW9uQ2FsbHMsIGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlciwgZXhwZWN0ZWRBc3NlcnRpb25zTnVtYmVyRXJyb3JHZW4sIGlzRXhwZWN0aW5nQXNzZXJ0aW9ucywgaXNFeHBlY3RpbmdBc3NlcnRpb25zRXJyb3IgfSA9IHRlc3QuY29udGV4dC5fbG9jYWwgPyB0ZXN0LmNvbnRleHQuZXhwZWN0LmdldFN0YXRlKCkgOiBnZXRTdGF0ZShnbG9iYWxUaGlzW0dMT0JBTF9FWFBFQ1RdKTtcblx0XHRpZiAoZXhwZWN0ZWRBc3NlcnRpb25zTnVtYmVyICE9PSBudWxsICYmIGFzc2VydGlvbkNhbGxzICE9PSBleHBlY3RlZEFzc2VydGlvbnNOdW1iZXIpIHRocm93IGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlckVycm9yR2VuKCk7XG5cdFx0aWYgKGlzRXhwZWN0aW5nQXNzZXJ0aW9ucyA9PT0gdHJ1ZSAmJiBhc3NlcnRpb25DYWxscyA9PT0gMCkgdGhyb3cgaXNFeHBlY3RpbmdBc3NlcnRpb25zRXJyb3I7XG5cdFx0aWYgKHRoaXMuY29uZmlnLmV4cGVjdC5yZXF1aXJlQXNzZXJ0aW9ucyAmJiBhc3NlcnRpb25DYWxscyA9PT0gMCkgdGhyb3cgdGhpcy5hc3NlcnRpb25zRXJyb3JzLmdldCh0ZXN0KTtcblx0fVxuXHRleHRlbmRUYXNrQ29udGV4dChjb250ZXh0KSB7XG5cdFx0Ly8gY3JlYXRlIGVycm9yIGR1cmluZyB0aGUgdGVzdCBpbml0aWFsaXphdGlvbiBzbyB3ZSBoYXZlIGEgbmljZSBzdGFjayB0cmFjZVxuXHRcdGlmICh0aGlzLmNvbmZpZy5leHBlY3QucmVxdWlyZUFzc2VydGlvbnMpIHRoaXMuYXNzZXJ0aW9uc0Vycm9ycy5zZXQoY29udGV4dC50YXNrLCAvKiBAX19QVVJFX18gKi8gbmV3IEVycm9yKFwiZXhwZWN0ZWQgYW55IG51bWJlciBvZiBhc3NlcnRpb24sIGJ1dCBnb3Qgbm9uZVwiKSk7XG5cdFx0bGV0IF9leHBlY3Q7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbnRleHQsIFwiZXhwZWN0XCIsIHsgZ2V0KCkge1xuXHRcdFx0aWYgKCFfZXhwZWN0KSBfZXhwZWN0ID0gY3JlYXRlRXhwZWN0KGNvbnRleHQudGFzayk7XG5cdFx0XHRyZXR1cm4gX2V4cGVjdDtcblx0XHR9IH0pO1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb250ZXh0LCBcIl9sb2NhbFwiLCB7IGdldCgpIHtcblx0XHRcdHJldHVybiBfZXhwZWN0ICE9IG51bGw7XG5cdFx0fSB9KTtcblx0XHRyZXR1cm4gY29udGV4dDtcblx0fVxuXHRnZXRJbXBvcnREdXJhdGlvbnMoKSB7XG5cdFx0Y29uc3QgeyBsaW1pdCB9ID0gdGhpcy5jb25maWcuZXhwZXJpbWVudGFsLmltcG9ydER1cmF0aW9ucztcblx0XHQvLyBza2lwIHNvcnRpbmcgaWYgbGltaXQgaXMgMFxuXHRcdGlmIChsaW1pdCA9PT0gMCkgcmV0dXJuIHt9O1xuXHRcdC8vIFNvcnQgYnkgZHVyYXRpb24gZGVzY2VuZGluZyBhbmQga2VlcCB0b3AgZW50cmllc1xuXHRcdGNvbnN0IHNvcnRlZEVudHJpZXMgPSBbLi4udGhpcy53b3JrZXJTdGF0ZS5tb2R1bGVFeGVjdXRpb25JbmZvPy5lbnRyaWVzKCkgfHwgW11dLnNvcnQoKFssIGFdLCBbLCBiXSkgPT4gYi5kdXJhdGlvbiAtIGEuZHVyYXRpb24pLnNsaWNlKDAsIGxpbWl0KTtcblx0XHRjb25zdCBpbXBvcnREdXJhdGlvbnMgPSB7fTtcblx0XHRmb3IgKGNvbnN0IFtmaWxlcGF0aCwgeyBkdXJhdGlvbiwgc2VsZlRpbWUsIGV4dGVybmFsLCBpbXBvcnRlciB9XSBvZiBzb3J0ZWRFbnRyaWVzKSBpbXBvcnREdXJhdGlvbnNbbm9ybWFsaXplKGZpbGVwYXRoKV0gPSB7XG5cdFx0XHRzZWxmVGltZSxcblx0XHRcdHRvdGFsVGltZTogZHVyYXRpb24sXG5cdFx0XHRleHRlcm5hbCxcblx0XHRcdGltcG9ydGVyXG5cdFx0fTtcblx0XHRyZXR1cm4gaW1wb3J0RHVyYXRpb25zO1xuXHR9XG5cdHRyYWNlID0gKG5hbWUsIGF0dHJpYnV0ZXMsIGNiKSA9PiB7XG5cdFx0Y29uc3Qgb3B0aW9ucyA9IHR5cGVvZiBhdHRyaWJ1dGVzID09PSBcIm9iamVjdFwiID8geyBhdHRyaWJ1dGVzIH0gOiB7fTtcblx0XHRyZXR1cm4gdGhpcy5fb3RlbC4kKGB2aXRlc3QudGVzdC5ydW5uZXIuJHtuYW1lfWAsIG9wdGlvbnMsIGNiIHx8IGF0dHJpYnV0ZXMpO1xuXHR9O1xuXHRfX3NldFRyYWNlcyh0cmFjZXMpIHtcblx0XHR0aGlzLl9vdGVsID0gdHJhY2VzO1xuXHR9XG5cdHN0YXRpYyBjcmVhdGVUYXNrQ29sbGVjdG9yID0gY3JlYXRlVGFza0NvbGxlY3Rvcjtcblx0c3RhdGljIGdldEN1cnJlbnRTdWl0ZSA9IGdldEN1cnJlbnRTdWl0ZTtcblx0c3RhdGljIGdldEN1cnJlbnRUZXN0ID0gZ2V0Q3VycmVudFRlc3Q7XG5cdHN0YXRpYyBjcmVhdGVDaGFpbmFibGUgPSBjcmVhdGVDaGFpbmFibGU7XG5cdHN0YXRpYyBnZXRTdWl0ZUhvb2tzID0gZ2V0SG9va3M7XG5cdHN0YXRpYyBnZXRUZXN0Rm4gPSBnZXRGbjtcblx0c3RhdGljIHNldFN1aXRlSG9va3MgPSBnZXRIb29rcztcblx0c3RhdGljIHNldFRlc3RGbiA9IGdldEZuO1xuXHRzdGF0aWMgbWF0Y2hlc1RhZ3MgPSBtYXRjaGVzVGFncztcblx0LyoqXG5cdCogQGRlcHJlY2F0ZWRcblx0Ki9cblx0c3RhdGljIGdldEJlbmNoRm4gPSBnZXRCZW5jaEZuO1xuXHQvKipcblx0KiBAZGVwcmVjYXRlZFxuXHQqL1xuXHRzdGF0aWMgZ2V0QmVuY2hPcHRpb25zID0gZ2V0QmVuY2hPcHRpb25zO1xufVxuZnVuY3Rpb24gY2xlYXJNb2R1bGVNb2Nrcyhjb25maWcpIHtcblx0Y29uc3QgeyBjbGVhck1vY2tzLCBtb2NrUmVzZXQsIHJlc3RvcmVNb2NrcywgdW5zdHViRW52cywgdW5zdHViR2xvYmFscyB9ID0gY29uZmlnO1xuXHRpZiAocmVzdG9yZU1vY2tzKSB2aS5yZXN0b3JlQWxsTW9ja3MoKTtcblx0aWYgKG1vY2tSZXNldCkgdmkucmVzZXRBbGxNb2NrcygpO1xuXHRpZiAoY2xlYXJNb2NrcykgdmkuY2xlYXJBbGxNb2NrcygpO1xuXHRpZiAodW5zdHViRW52cykgdmkudW5zdHViQWxsRW52cygpO1xuXHRpZiAodW5zdHViR2xvYmFscykgdmkudW5zdHViQWxsR2xvYmFscygpO1xufVxuXG5leHBvcnQgeyBOb2RlQmVuY2htYXJrUnVubmVyIGFzIE4sIFNuYXBzaG90cyBhcyBTLCBUZXN0UnVubmVyIGFzIFQsIGFzc2VydCBhcyBhLCB2aXRlc3QgYXMgYiwgY3JlYXRlRXhwZWN0IGFzIGMsIGdsb2JhbEV4cGVjdCBhcyBnLCBpbmplY3QgYXMgaSwgc2hvdWxkIGFzIHMsIHZpIGFzIHYgfTtcbiJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JBLElBQUksZ0JBQWdCLENBQUM7QUFFckIsSUFBSTtBQUNKLElBQUk7QUFFSixTQUFTLGdCQUFpQjtDQUN6QixJQUFJLG1CQUFtQixPQUFPO0NBQzlCLG9CQUFvQjs7Ozs7Q0FNcEIsSUFBSTs7Q0FHSixJQUFJLE9BQU8sbUJBQW1CLGFBRTFCLGVBQWU7TUFDWixJQUFJLE9BQU8sV0FBVyxhQUV6QixlQUFlO01BR2YsZUFBZTtDQUduQixTQUFTO0NBQ1QsT0FBTztBQUNSO0FBRUEsSUFBSTtBQUNKLElBQUk7QUFFSixTQUFTLHVCQUF3QjtDQUNoQyxJQUFJLDBCQUEwQixPQUFPO0NBQ3JDLDJC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