@logixjs/sandbox 0.0.1 → 0.0.2

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 (248) hide show
  1. package/LICENSE +201 -0
  2. package/package.json +3 -1
  3. package/public/sandbox/chunks/chunk-2AUQRESB.js +1114 -0
  4. package/public/sandbox/chunks/chunk-2F72LQKW.js +194 -0
  5. package/public/sandbox/chunks/chunk-2PYDGDD3.js +4071 -0
  6. package/public/sandbox/chunks/chunk-2UGKSXDZ.js +16 -0
  7. package/public/sandbox/chunks/chunk-2XVE7F26.js +153 -0
  8. package/public/sandbox/chunks/chunk-3A7TFNZN.js +219 -0
  9. package/public/sandbox/chunks/chunk-3BHC6JAV.js +1070 -0
  10. package/public/sandbox/chunks/chunk-3U4CAKCX.js +61 -0
  11. package/public/sandbox/chunks/chunk-3VU3JLZO.js +272 -0
  12. package/public/sandbox/chunks/chunk-4CPONKWY.js +1170 -0
  13. package/public/sandbox/chunks/chunk-4GMUQTWH.js +850 -0
  14. package/public/sandbox/chunks/chunk-4KIYG5E4.js +749 -0
  15. package/public/sandbox/chunks/chunk-4MY35XR3.js +175 -0
  16. package/public/sandbox/chunks/chunk-5DNHJMHA.js +69 -0
  17. package/public/sandbox/chunks/chunk-5EC4S7X6.js +42 -0
  18. package/public/sandbox/chunks/chunk-5FB7QFSH.js +227 -0
  19. package/public/sandbox/chunks/chunk-5GEYCJW2.js +206 -0
  20. package/public/sandbox/chunks/chunk-5PT7Q5SS.js +373 -0
  21. package/public/sandbox/chunks/chunk-5WN5IGKA.js +166 -0
  22. package/public/sandbox/chunks/chunk-5XOBKSOT.js +213 -0
  23. package/public/sandbox/chunks/chunk-67RVISUC.js +313 -0
  24. package/public/sandbox/chunks/chunk-6ELJEKZS.js +12 -0
  25. package/public/sandbox/chunks/chunk-6FKWRVP4.js +85 -0
  26. package/public/sandbox/chunks/chunk-6JRP52YT.js +34 -0
  27. package/public/sandbox/chunks/chunk-6JYAC3G6.js +42 -0
  28. package/public/sandbox/chunks/chunk-6TUOP63Q.js +86 -0
  29. package/public/sandbox/chunks/{chunk-A6JFUNQQ.js → chunk-74C5VW7Z.js} +2 -2
  30. package/public/sandbox/chunks/chunk-75DQFC5M.js +16 -0
  31. package/public/sandbox/chunks/{chunk-UCFEP3BH.js → chunk-7GPAF2UK.js} +1 -1
  32. package/public/sandbox/chunks/chunk-7KQFTS2Y.js +135 -0
  33. package/public/sandbox/chunks/chunk-7POKWYE3.js +112 -0
  34. package/public/sandbox/chunks/chunk-7VUEF5F3.js +395 -0
  35. package/public/sandbox/chunks/chunk-7W5APZS2.js +77 -0
  36. package/public/sandbox/chunks/chunk-A6OFCXDQ.js +397 -0
  37. package/public/sandbox/chunks/chunk-A7HLOSO6.js +216 -0
  38. package/public/sandbox/chunks/chunk-AGF4RRCB.js +408 -0
  39. package/public/sandbox/chunks/chunk-ASJSJAAL.js +122 -0
  40. package/public/sandbox/chunks/chunk-ASVMK364.js +283 -0
  41. package/public/sandbox/chunks/chunk-AUDTI2BQ.js +895 -0
  42. package/public/sandbox/chunks/chunk-B2SZTA3M.js +16 -0
  43. package/public/sandbox/chunks/chunk-B6YS2UMV.js +372 -0
  44. package/public/sandbox/chunks/chunk-BCEO3MGD.js +244 -0
  45. package/public/sandbox/chunks/chunk-BCOO65D4.js +373 -0
  46. package/public/sandbox/chunks/chunk-BJOWSSEL.js +38 -0
  47. package/public/sandbox/chunks/chunk-BS2WBFW4.js +373 -0
  48. package/public/sandbox/chunks/chunk-BUVHG3NJ.js +439 -0
  49. package/public/sandbox/chunks/chunk-BVE33AN6.js +42 -0
  50. package/public/sandbox/chunks/chunk-BWTGJZVP.js +19 -0
  51. package/public/sandbox/chunks/chunk-BXD7GZC3.js +1025 -0
  52. package/public/sandbox/chunks/chunk-BZH4EUUD.js +164 -0
  53. package/public/sandbox/chunks/{chunk-HFV5GJPK.js → chunk-C2MYMMO4.js} +3 -3
  54. package/public/sandbox/chunks/chunk-CRE4NJJ6.js +271 -0
  55. package/public/sandbox/chunks/chunk-CVZPRIDB.js +706 -0
  56. package/public/sandbox/chunks/chunk-CWOXD5NG.js +991 -0
  57. package/public/sandbox/chunks/chunk-D6DOC3BJ.js +373 -0
  58. package/public/sandbox/chunks/chunk-DEPSGFSY.js +1698 -0
  59. package/public/sandbox/chunks/chunk-DM7C5NP5.js +819 -0
  60. package/public/sandbox/chunks/chunk-DN33LMOF.js +1112 -0
  61. package/public/sandbox/chunks/{chunk-S46P7MC6.js → chunk-DT7YIIWE.js} +2 -2
  62. package/public/sandbox/chunks/chunk-DVB5WRCI.js +260 -0
  63. package/public/sandbox/chunks/{chunk-TOHCFMQS.js → chunk-E3EVW7NR.js} +11 -18
  64. package/public/sandbox/chunks/chunk-E5BV567Q.js +417 -0
  65. package/public/sandbox/chunks/chunk-E7BIWMQQ.js +203 -0
  66. package/public/sandbox/chunks/chunk-EAKGPSOQ.js +83 -0
  67. package/public/sandbox/chunks/chunk-EGUYL2ER.js +75 -0
  68. package/public/sandbox/chunks/chunk-EP5GQYZ5.js +85 -0
  69. package/public/sandbox/chunks/chunk-ET6CJEHC.js +221 -0
  70. package/public/sandbox/chunks/chunk-EU67YZHZ.js +1070 -0
  71. package/public/sandbox/chunks/{chunk-PTSJJANP.js → chunk-EYNDQLSB.js} +1 -1
  72. package/public/sandbox/chunks/{chunk-CEGSWZ5S.js → chunk-EZTMVCJF.js} +1 -1
  73. package/public/sandbox/chunks/chunk-F5CLVIS6.js +907 -0
  74. package/public/sandbox/chunks/chunk-F743SKYD.js +85 -0
  75. package/public/sandbox/chunks/chunk-FEGFZ5OX.js +86 -0
  76. package/public/sandbox/chunks/chunk-FG5B7ZX3.js +373 -0
  77. package/public/sandbox/chunks/chunk-FKZPYMDG.js +373 -0
  78. package/public/sandbox/chunks/chunk-FNLXHWIU.js +220 -0
  79. package/public/sandbox/chunks/chunk-FQRUTYAD.js +1991 -0
  80. package/public/sandbox/chunks/{chunk-VLYP4WUS.js → chunk-FY5A73NK.js} +5 -5
  81. package/public/sandbox/chunks/chunk-G7FAOG3O.js +221 -0
  82. package/public/sandbox/chunks/chunk-GFXHUC7Y.js +73 -0
  83. package/public/sandbox/chunks/chunk-GIPXUIZQ.js +534 -0
  84. package/public/sandbox/chunks/chunk-GP37MEGJ.js +52 -0
  85. package/public/sandbox/chunks/chunk-GXL5QCMF.js +4511 -0
  86. package/public/sandbox/chunks/chunk-GZ2NSE6A.js +177 -0
  87. package/public/sandbox/chunks/chunk-GZATW4YD.js +69 -0
  88. package/public/sandbox/chunks/chunk-H4EBXROQ.js +166 -0
  89. package/public/sandbox/chunks/chunk-HETCPK6Z.js +153 -0
  90. package/public/sandbox/chunks/chunk-HGUFQ2QC.js +4431 -0
  91. package/public/sandbox/chunks/chunk-HGV3VNH3.js +255 -0
  92. package/public/sandbox/chunks/chunk-HIJ67QWR.js +5397 -0
  93. package/public/sandbox/chunks/chunk-IDHERBKW.js +1114 -0
  94. package/public/sandbox/chunks/chunk-IDTK4FIY.js +102 -0
  95. package/public/sandbox/chunks/chunk-ILFVY7H5.js +164 -0
  96. package/public/sandbox/chunks/chunk-ISGSRYGO.js +57 -0
  97. package/public/sandbox/chunks/chunk-J45VPU24.js +408 -0
  98. package/public/sandbox/chunks/chunk-JAUIM3O5.js +42 -0
  99. package/public/sandbox/chunks/chunk-JB7OQEM6.js +373 -0
  100. package/public/sandbox/chunks/chunk-JCKW6NHD.js +15 -0
  101. package/public/sandbox/chunks/chunk-JMA7GY7Z.js +221 -0
  102. package/public/sandbox/chunks/chunk-JY46J6IL.js +836 -0
  103. package/public/sandbox/chunks/{chunk-X72PZOFA.js → chunk-K2MQ66O7.js} +1 -1
  104. package/public/sandbox/chunks/chunk-KA7PZA6F.js +464 -0
  105. package/public/sandbox/chunks/chunk-KDEQTUID.js +102 -0
  106. package/public/sandbox/chunks/chunk-KDJR27JV.js +1696 -0
  107. package/public/sandbox/chunks/chunk-KFE3JO6N.js +77 -0
  108. package/public/sandbox/chunks/chunk-KLDSYWT5.js +536 -0
  109. package/public/sandbox/chunks/chunk-KQWWFYBF.js +203 -0
  110. package/public/sandbox/chunks/chunk-KTFZSXOW.js +6473 -0
  111. package/public/sandbox/chunks/chunk-KXVIC55U.js +108 -0
  112. package/public/sandbox/chunks/{chunk-HNEDTEGQ.js → chunk-L4PNO2H6.js} +1 -1
  113. package/public/sandbox/chunks/{chunk-WE4STGO2.js → chunk-L4ZNW5DI.js} +2 -2
  114. package/public/sandbox/chunks/chunk-LBUINGZ4.js +836 -0
  115. package/public/sandbox/chunks/chunk-LIYPPU6I.js +112 -0
  116. package/public/sandbox/chunks/chunk-LJHTOJXW.js +221 -0
  117. package/public/sandbox/chunks/{chunk-BWSNPKO5.js → chunk-LQL23SWJ.js} +2 -2
  118. package/public/sandbox/chunks/chunk-LTFCYZQ6.js +46 -0
  119. package/public/sandbox/chunks/chunk-LTWLVCKQ.js +166 -0
  120. package/public/sandbox/chunks/chunk-LWI7BXFN.js +395 -0
  121. package/public/sandbox/chunks/chunk-LYBBX6WM.js +225 -0
  122. package/public/sandbox/chunks/chunk-MXE7HIBM.js +474 -0
  123. package/public/sandbox/chunks/chunk-MYBDYNK4.js +6004 -0
  124. package/public/sandbox/chunks/chunk-NC2MIWZX.js +732 -0
  125. package/public/sandbox/chunks/chunk-NE447XAF.js +597 -0
  126. package/public/sandbox/chunks/chunk-NEAYV5C2.js +255 -0
  127. package/public/sandbox/chunks/chunk-NMGFJZ4I.js +26 -0
  128. package/public/sandbox/chunks/chunk-NWCJJZNQ.js +71 -0
  129. package/public/sandbox/chunks/chunk-O57OZBDR.js +214 -0
  130. package/public/sandbox/chunks/chunk-OJJT664Q.js +731 -0
  131. package/public/sandbox/chunks/chunk-OKTBUTCH.js +1175 -0
  132. package/public/sandbox/chunks/chunk-OQ4SYV5D.js +534 -0
  133. package/public/sandbox/chunks/chunk-OTVVIHJD.js +219 -0
  134. package/public/sandbox/chunks/chunk-OWTMSCF7.js +1052 -0
  135. package/public/sandbox/chunks/chunk-P5ZQNFC3.js +122 -0
  136. package/public/sandbox/chunks/chunk-PBPT2U2N.js +1698 -0
  137. package/public/sandbox/chunks/chunk-PHBJLCP3.js +836 -0
  138. package/public/sandbox/chunks/chunk-PHV4HYHB.js +397 -0
  139. package/public/sandbox/chunks/chunk-PIXQ6SOX.js +4071 -0
  140. package/public/sandbox/chunks/chunk-PKJL6YLK.js +73 -0
  141. package/public/sandbox/chunks/chunk-PKPOITIU.js +221 -0
  142. package/public/sandbox/chunks/{chunk-NQW73ACJ.js → chunk-PMXBOYQI.js} +1 -1
  143. package/public/sandbox/chunks/chunk-PQLZD7NR.js +836 -0
  144. package/public/sandbox/chunks/chunk-QEESVOZU.js +16 -0
  145. package/public/sandbox/chunks/chunk-QGIM3FQK.js +159 -0
  146. package/public/sandbox/chunks/chunk-QL5JNEDO.js +69 -0
  147. package/public/sandbox/chunks/chunk-QQOZ3RMH.js +867 -0
  148. package/public/sandbox/chunks/chunk-QUMEVT2F.js +194 -0
  149. package/public/sandbox/chunks/chunk-QVZBXYVY.js +102 -0
  150. package/public/sandbox/chunks/chunk-R5HQS6RB.js +135 -0
  151. package/public/sandbox/chunks/chunk-R75Q2CTT.js +900 -0
  152. package/public/sandbox/chunks/chunk-RBB6SHW2.js +253 -0
  153. package/public/sandbox/chunks/chunk-RDHNRWQP.js +383 -0
  154. package/public/sandbox/chunks/chunk-RIWOEI3T.js +1101 -0
  155. package/public/sandbox/chunks/chunk-RS5FFPUV.js +103 -0
  156. package/public/sandbox/chunks/chunk-RYSSJBGX.js +203 -0
  157. package/public/sandbox/chunks/chunk-S3KBAE5Z.js +1114 -0
  158. package/public/sandbox/chunks/chunk-S6ZZHV6G.js +244 -0
  159. package/public/sandbox/chunks/chunk-SFXJ24HY.js +499 -0
  160. package/public/sandbox/chunks/chunk-SH7TP5CJ.js +1109 -0
  161. package/public/sandbox/chunks/chunk-SI5OKFFY.js +317 -0
  162. package/public/sandbox/chunks/chunk-SIXNQNIR.js +86 -0
  163. package/public/sandbox/chunks/chunk-ST353BOX.js +42 -0
  164. package/public/sandbox/chunks/chunk-SYEHKMLP.js +1140 -0
  165. package/public/sandbox/chunks/chunk-SZ4KQUJU.js +69 -0
  166. package/public/sandbox/chunks/{chunk-5SOP6EKV.js → chunk-SZI65PSP.js} +5 -10
  167. package/public/sandbox/chunks/chunk-T7RLTSMX.js +78 -0
  168. package/public/sandbox/chunks/chunk-TJ2RLUTW.js +57 -0
  169. package/public/sandbox/chunks/chunk-TJB73XPN.js +4071 -0
  170. package/public/sandbox/chunks/chunk-TXJCYO56.js +4046 -0
  171. package/public/sandbox/chunks/chunk-U5J3LCYI.js +731 -0
  172. package/public/sandbox/chunks/chunk-UABFN3NH.js +208 -0
  173. package/public/sandbox/chunks/chunk-UBMUY7WO.js +13 -0
  174. package/public/sandbox/chunks/chunk-UC27CE32.js +69 -0
  175. package/public/sandbox/chunks/chunk-UJGVDFZN.js +147 -0
  176. package/public/sandbox/chunks/chunk-UNVLTK4N.js +122 -0
  177. package/public/sandbox/chunks/chunk-UQKQ6V3V.js +208 -0
  178. package/public/sandbox/chunks/chunk-UZZBHWIO.js +703 -0
  179. package/public/sandbox/chunks/chunk-VKZIJERL.js +1114 -0
  180. package/public/sandbox/chunks/chunk-VQQEAGID.js +372 -0
  181. package/public/sandbox/chunks/{chunk-3LX3KIQQ.js → chunk-W365QUZ5.js} +3 -5
  182. package/public/sandbox/chunks/chunk-WJY2LSWG.js +1052 -0
  183. package/public/sandbox/chunks/chunk-WNOBN3DX.js +391 -0
  184. package/public/sandbox/chunks/chunk-X2Z5VYG3.js +245 -0
  185. package/public/sandbox/chunks/chunk-X74KU74D.js +959 -0
  186. package/public/sandbox/chunks/chunk-XE7ULSGQ.js +46 -0
  187. package/public/sandbox/chunks/chunk-XRXUJZ3X.js +431 -0
  188. package/public/sandbox/chunks/chunk-XWHIN7CC.js +85 -0
  189. package/public/sandbox/chunks/chunk-Y2TVGGVL.js +527 -0
  190. package/public/sandbox/chunks/chunk-YMVMZA3U.js +1395 -0
  191. package/public/sandbox/chunks/chunk-YOBLFWDV.js +431 -0
  192. package/public/sandbox/chunks/chunk-YR2RFEZA.js +11 -0
  193. package/public/sandbox/chunks/chunk-YTD6A35P.js +836 -0
  194. package/public/sandbox/chunks/chunk-Z5L7EZXS.js +81 -0
  195. package/public/sandbox/chunks/chunk-Z65I5ET2.js +108 -0
  196. package/public/sandbox/chunks/chunk-Z6LV34RO.js +390 -0
  197. package/public/sandbox/chunks/chunk-ZAKUP6QG.js +1634 -0
  198. package/public/sandbox/chunks/chunk-ZHNYE2YH.js +731 -0
  199. package/public/sandbox/chunks/chunk-ZHQX3B3Y.js +867 -0
  200. package/public/sandbox/chunks/chunk-ZIXDFRHJ.js +731 -0
  201. package/public/sandbox/chunks/chunk-ZPZ2MZ4D.js +528 -0
  202. package/public/sandbox/chunks/chunk-ZQD6NZXB.js +373 -0
  203. package/public/sandbox/chunks/chunk-ZVVBP7ON.js +16 -0
  204. package/public/sandbox/chunks/chunk-ZWE3P6X2.js +11 -0
  205. package/public/sandbox/logix-core/Bound.js +14 -14
  206. package/public/sandbox/logix-core/Debug.js +12 -10
  207. package/public/sandbox/logix-core/EffectOp.js +3 -4
  208. package/public/sandbox/logix-core/Env.js +5 -2
  209. package/public/sandbox/logix-core/ExternalStore.js +239 -0
  210. package/public/sandbox/logix-core/Flow.js +7 -8
  211. package/public/sandbox/logix-core/Kernel.js +7 -4
  212. package/public/sandbox/logix-core/Link.js +33 -25
  213. package/public/sandbox/logix-core/Middleware.js +13 -11
  214. package/public/sandbox/logix-core/Module.js +93 -30
  215. package/public/sandbox/logix-core/ModuleTag.js +28 -25
  216. package/public/sandbox/logix-core/Observability.js +21 -19
  217. package/public/sandbox/logix-core/Process.js +27 -22
  218. package/public/sandbox/logix-core/ReadQuery.js +7 -11
  219. package/public/sandbox/logix-core/Reflection.js +173 -53
  220. package/public/sandbox/logix-core/Resource.js +6 -3
  221. package/public/sandbox/logix-core/Root.js +7 -3
  222. package/public/sandbox/logix-core/Runtime.js +54 -40
  223. package/public/sandbox/logix-core/ScopeRegistry.js +6 -3
  224. package/public/sandbox/logix-core/StateTrait.js +17 -14
  225. package/public/sandbox/logix-core/TraitLifecycle.js +8 -8
  226. package/public/sandbox/logix-core/Workflow.js +332 -0
  227. package/public/sandbox/logix-core.js +11133 -6622
  228. package/public/sandbox/logix-core.manifest.json +4 -2
  229. package/public/sandbox/worker.js +3 -3
  230. package/public/sandbox/chunks/chunk-4LRLOTMA.js +0 -1698
  231. package/public/sandbox/chunks/chunk-CDLXJHXY.js +0 -120
  232. package/public/sandbox/chunks/chunk-CZRI7MHA.js +0 -46
  233. package/public/sandbox/chunks/chunk-EJDFUZ4B.js +0 -408
  234. package/public/sandbox/chunks/chunk-IP63FME6.js +0 -282
  235. package/public/sandbox/chunks/chunk-JIXTOQXJ.js +0 -1103
  236. package/public/sandbox/chunks/chunk-MPUSOFJ3.js +0 -1928
  237. package/public/sandbox/chunks/chunk-ON2LY6HJ.js +0 -135
  238. package/public/sandbox/chunks/chunk-POIBXAH5.js +0 -995
  239. package/public/sandbox/chunks/chunk-PQ652ULI.js +0 -6359
  240. package/public/sandbox/chunks/chunk-RJQ4PG2F.js +0 -77
  241. package/public/sandbox/chunks/chunk-S4EXG3OS.js +0 -533
  242. package/public/sandbox/chunks/chunk-SUXDGXVE.js +0 -390
  243. package/public/sandbox/chunks/chunk-TOQ6SJ6O.js +0 -244
  244. package/public/sandbox/chunks/chunk-UKYAF3NL.js +0 -1036
  245. package/public/sandbox/chunks/chunk-UMVN3AWO.js +0 -395
  246. package/public/sandbox/chunks/chunk-WFV5PPWJ.js +0 -194
  247. package/public/sandbox/chunks/chunk-YF6IO732.js +0 -206
  248. package/public/sandbox/chunks/chunk-ZUBABAAO.js +0 -86
@@ -1,1698 +0,0 @@
1
- // @logixjs/core subpath bundles for @logixjs/sandbox
2
-
3
- import {
4
- shouldNoopInSyncTransactionFiber
5
- } from "./chunk-WFV5PPWJ.js";
6
- import {
7
- getRuntimeInternals
8
- } from "./chunk-UCFEP3BH.js";
9
- import {
10
- isDevEnv
11
- } from "./chunk-CZRI7MHA.js";
12
- import {
13
- currentDiagnosticsLevel,
14
- record,
15
- toRuntimeDebugEventRef,
16
- toSerializableErrorSummary
17
- } from "./chunk-UKYAF3NL.js";
18
- import {
19
- makeEvidenceSink
20
- } from "./chunk-3LX3KIQQ.js";
21
- import {
22
- projectJsonValue
23
- } from "./chunk-TOQ6SJ6O.js";
24
-
25
- // ../logix-core/src/internal/runtime/core/process/meta.ts
26
- var PROCESS_META = /* @__PURE__ */ Symbol.for("@logixjs/core/processMeta");
27
- var defineHidden = (target, key, value) => {
28
- Object.defineProperty(target, key, {
29
- value,
30
- enumerable: false,
31
- configurable: true,
32
- writable: false
33
- });
34
- };
35
- var getMeta = (effect) => effect[PROCESS_META];
36
- var getDefinition = (effect) => getMeta(effect)?.definition;
37
- var attachMeta = (effect, meta) => {
38
- defineHidden(effect, PROCESS_META, meta);
39
- return effect;
40
- };
41
-
42
- // ../logix-core/src/internal/observability/evidenceCollector.ts
43
- import { Context, Effect, FiberRef, Layer } from "../effect.js";
44
- var EvidenceCollectorTagImpl = class extends Context.Tag("@logixjs/core/EvidenceCollector")() {
45
- };
46
- var EvidenceCollectorTag = EvidenceCollectorTagImpl;
47
- var evidenceCollectorLayer = (collector) => Layer.succeed(EvidenceCollectorTag, collector);
48
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
49
- var makeEvidenceCollector = (session) => {
50
- const sink = makeEvidenceSink(session);
51
- const convergeStaticIrByDigest = /* @__PURE__ */ new Map();
52
- let kernelImplementationRef;
53
- let runtimeServicesEvidence;
54
- const exportBudget = {
55
- dropped: 0,
56
- oversized: 0,
57
- nonSerializable: 0
58
- };
59
- const debugSink = {
60
- record: (event) => Effect.gen(function* () {
61
- const level = yield* FiberRef.get(currentDiagnosticsLevel);
62
- const instanceIdRaw = event.instanceId;
63
- const instanceId = typeof instanceIdRaw === "string" && instanceIdRaw.length > 0 ? instanceIdRaw : "unknown";
64
- const eventSeq = level === "off" ? void 0 : session.local.nextSeq("eventSeq", instanceId);
65
- const ref = toRuntimeDebugEventRef(event, {
66
- diagnosticsLevel: level,
67
- eventSeq,
68
- onMetaProjection: ({ stats }) => {
69
- exportBudget.dropped += stats.dropped;
70
- exportBudget.oversized += stats.oversized;
71
- }
72
- });
73
- if (!ref) return;
74
- const projected = projectJsonValue(ref);
75
- exportBudget.dropped += projected.stats.dropped;
76
- exportBudget.oversized += projected.stats.oversized;
77
- exportBudget.nonSerializable += projected.stats.nonSerializable;
78
- sink.record("debug:event", projected.value, {
79
- timestamp: ref.timestamp
80
- });
81
- })
82
- };
83
- const registerConvergeStaticIr = (staticIr) => {
84
- if (!isRecord(staticIr)) return;
85
- const digest = staticIr.staticIrDigest;
86
- if (typeof digest !== "string" || digest.length === 0) return;
87
- const projected = projectJsonValue(staticIr);
88
- exportBudget.dropped += projected.stats.dropped;
89
- exportBudget.oversized += projected.stats.oversized;
90
- exportBudget.nonSerializable += projected.stats.nonSerializable;
91
- convergeStaticIrByDigest.set(digest, projected.value);
92
- };
93
- const setKernelImplementationRef = (ref) => {
94
- const projected = projectJsonValue(ref);
95
- exportBudget.dropped += projected.stats.dropped;
96
- exportBudget.oversized += projected.stats.oversized;
97
- exportBudget.nonSerializable += projected.stats.nonSerializable;
98
- kernelImplementationRef = projected.value;
99
- };
100
- const setRuntimeServicesEvidence = (evidence) => {
101
- const projected = projectJsonValue(evidence);
102
- exportBudget.dropped += projected.stats.dropped;
103
- exportBudget.oversized += projected.stats.oversized;
104
- exportBudget.nonSerializable += projected.stats.nonSerializable;
105
- runtimeServicesEvidence = projected.value;
106
- };
107
- const exportEvidencePackage = (options) => {
108
- const convergeSummary = convergeStaticIrByDigest.size > 0 ? {
109
- staticIrByDigest: Object.fromEntries(convergeStaticIrByDigest)
110
- } : void 0;
111
- const runtimeSummary = kernelImplementationRef != null || runtimeServicesEvidence != null ? {
112
- ...kernelImplementationRef != null ? { kernelImplementationRef } : {},
113
- ...runtimeServicesEvidence != null ? { services: runtimeServicesEvidence } : {}
114
- } : void 0;
115
- const summary = convergeSummary != null || runtimeSummary != null ? {
116
- ...convergeSummary != null ? { converge: convergeSummary } : {},
117
- ...runtimeSummary != null ? { runtime: runtimeSummary } : {}
118
- } : void 0;
119
- return sink.export({
120
- maxEvents: options?.maxEvents,
121
- summary
122
- });
123
- };
124
- const clear = () => {
125
- sink.clear();
126
- convergeStaticIrByDigest.clear();
127
- kernelImplementationRef = void 0;
128
- runtimeServicesEvidence = void 0;
129
- exportBudget.dropped = 0;
130
- exportBudget.oversized = 0;
131
- exportBudget.nonSerializable = 0;
132
- };
133
- return {
134
- session,
135
- debugSink,
136
- registerConvergeStaticIr,
137
- setKernelImplementationRef,
138
- setRuntimeServicesEvidence,
139
- exportEvidencePackage,
140
- clear
141
- };
142
- };
143
-
144
- // ../logix-core/src/internal/runtime/core/process/ProcessRuntime.ts
145
- import {
146
- Cause,
147
- Context as Context2,
148
- Deferred,
149
- Duration,
150
- Effect as Effect3,
151
- Fiber as Fiber2,
152
- FiberRef as FiberRef2,
153
- Layer as Layer2,
154
- Option as Option2,
155
- PubSub,
156
- Queue,
157
- Ref as Ref2,
158
- Scope as Scope2,
159
- Stream as Stream2
160
- } from "../effect.js";
161
-
162
- // ../logix-core/src/internal/runtime/core/process/identity.ts
163
- var scopeKeyFromScope = (scope) => {
164
- switch (scope.type) {
165
- case "app":
166
- return `app:${scope.appId}`;
167
- case "moduleInstance":
168
- return `moduleInstance:${scope.moduleId}::${scope.instanceId}`;
169
- case "uiSubtree":
170
- return `uiSubtree:${scope.subtreeId}`;
171
- }
172
- };
173
- var installationKeyFromIdentity = (identity) => `${identity.processId}@@${scopeKeyFromScope(identity.scope)}`;
174
- var processInstanceIdFromIdentity = (identity) => {
175
- const scopeKey = scopeKeyFromScope(identity.identity.scope);
176
- return `process:${identity.identity.processId}::${scopeKey}::r${identity.runSeq}`;
177
- };
178
-
179
- // ../logix-core/src/internal/runtime/core/process/concurrency.ts
180
- import { Effect as Effect2, Fiber, Option, Ref, Stream } from "../effect.js";
181
- var DEFAULT_SERIAL_QUEUE_GUARD_LIMIT = 4096;
182
- var DEFAULT_PARALLEL_LIMIT = 16;
183
- var resolveQueueLimit = (maxQueue, options) => {
184
- const defaultGuard = options?.defaultGuard ?? DEFAULT_SERIAL_QUEUE_GUARD_LIMIT;
185
- const configured = typeof maxQueue === "number" && Number.isFinite(maxQueue) && maxQueue >= 0 ? Math.floor(maxQueue) : "unbounded";
186
- return {
187
- configured,
188
- guard: configured === "unbounded" ? defaultGuard : configured
189
- };
190
- };
191
- var runProcessTriggerStream = (args) => Effect2.gen(function* () {
192
- const policy = args.policy;
193
- const defaultQueueGuard = args.defaultQueueGuard ?? DEFAULT_SERIAL_QUEUE_GUARD_LIMIT;
194
- if (policy.mode === "latest") {
195
- const stateRef = yield* Ref.make({ fiber: void 0, runningId: 0, nextId: 0 });
196
- const onTrigger2 = (trigger0) => Effect2.gen(function* () {
197
- const trigger = args.assignTriggerSeq(trigger0);
198
- const [prevFiber, prevRunningId, runId] = yield* Ref.modify(stateRef, (s) => {
199
- const nextId = s.nextId + 1;
200
- return [[s.fiber, s.runningId, nextId], { ...s, nextId, runningId: nextId }];
201
- });
202
- if (prevFiber && prevRunningId !== 0) {
203
- const done = yield* Fiber.poll(prevFiber);
204
- if (Option.isNone(done)) {
205
- yield* Fiber.interruptFork(prevFiber);
206
- }
207
- }
208
- const fiber = yield* Effect2.forkScoped(
209
- args.run(trigger).pipe(Effect2.ensuring(Ref.update(stateRef, (s) => s.runningId === runId ? { ...s, runningId: 0 } : s)))
210
- );
211
- yield* Ref.update(stateRef, (s) => ({ ...s, fiber }));
212
- });
213
- return yield* Stream.runForEach(args.stream, onTrigger2);
214
- }
215
- const busyRef = yield* Ref.make(false);
216
- const serialStateRef = yield* Ref.make({
217
- running: false,
218
- queue: [],
219
- peak: 0
220
- });
221
- const parallelStateRef = yield* Ref.make({
222
- active: 0,
223
- queue: [],
224
- peak: 0
225
- });
226
- const serialQueueLimit = resolveQueueLimit(policy.maxQueue, { defaultGuard: defaultQueueGuard });
227
- const parallelQueueLimit = resolveQueueLimit(void 0, { defaultGuard: defaultQueueGuard });
228
- const parallelLimit = typeof policy.maxParallel === "number" && Number.isFinite(policy.maxParallel) && policy.maxParallel >= 1 ? Math.floor(policy.maxParallel) : args.defaultParallelLimit ?? DEFAULT_PARALLEL_LIMIT;
229
- const drainSerial = () => Effect2.suspend(
230
- () => Ref.modify(serialStateRef, (state) => {
231
- if (state.running || state.queue.length === 0) {
232
- return [Option.none(), state];
233
- }
234
- const [next, ...rest] = state.queue;
235
- return [Option.some(next), { ...state, running: true, queue: rest }];
236
- }).pipe(
237
- Effect2.flatMap(
238
- (next) => Option.match(next, {
239
- onNone: () => Effect2.void,
240
- onSome: (trigger) => Effect2.forkScoped(
241
- args.run(trigger).pipe(
242
- Effect2.ensuring(Ref.update(serialStateRef, (s) => ({ ...s, running: false }))),
243
- Effect2.zipRight(drainSerial())
244
- )
245
- ).pipe(Effect2.asVoid)
246
- })
247
- )
248
- )
249
- );
250
- const drainParallel = () => Effect2.suspend(
251
- () => Ref.modify(parallelStateRef, (state) => {
252
- if (state.active >= parallelLimit || state.queue.length === 0) {
253
- return [Option.none(), state];
254
- }
255
- const [next, ...rest] = state.queue;
256
- return [Option.some(next), { ...state, active: state.active + 1, queue: rest }];
257
- }).pipe(
258
- Effect2.flatMap(
259
- (next) => Option.match(next, {
260
- onNone: () => Effect2.void,
261
- onSome: (trigger) => Effect2.forkScoped(
262
- args.run(trigger).pipe(
263
- Effect2.ensuring(
264
- Ref.update(parallelStateRef, (s) => ({
265
- ...s,
266
- active: Math.max(0, s.active - 1)
267
- }))
268
- ),
269
- Effect2.zipRight(drainParallel())
270
- )
271
- ).pipe(Effect2.asVoid, Effect2.zipRight(drainParallel()))
272
- })
273
- )
274
- )
275
- );
276
- const onTrigger = (trigger0) => Effect2.gen(function* () {
277
- const trigger = args.assignTriggerSeq(trigger0);
278
- if (policy.mode === "drop") {
279
- const acquired = yield* Ref.modify(
280
- busyRef,
281
- (busy) => busy ? [false, busy] : [true, true]
282
- );
283
- if (!acquired) {
284
- yield* args.onDrop(trigger);
285
- return;
286
- }
287
- yield* Effect2.forkScoped(args.run(trigger).pipe(Effect2.ensuring(Ref.set(busyRef, false))));
288
- return;
289
- }
290
- if (policy.mode === "parallel") {
291
- const nextSize2 = yield* Ref.modify(parallelStateRef, (state) => {
292
- const queue = [...state.queue, trigger];
293
- return [queue.length, { ...state, queue, peak: Math.max(state.peak, queue.length) }];
294
- });
295
- if (nextSize2 > parallelQueueLimit.guard) {
296
- const state = yield* Ref.get(parallelStateRef);
297
- yield* args.onQueueOverflow({
298
- mode: "parallel",
299
- currentLength: nextSize2,
300
- peak: state.peak,
301
- limit: parallelQueueLimit,
302
- policy
303
- });
304
- return;
305
- }
306
- yield* drainParallel();
307
- return;
308
- }
309
- const nextSize = yield* Ref.modify(serialStateRef, (state) => {
310
- const queue = [...state.queue, trigger];
311
- return [queue.length, { ...state, queue, peak: Math.max(state.peak, queue.length) }];
312
- });
313
- if (nextSize > serialQueueLimit.guard) {
314
- const state = yield* Ref.get(serialStateRef);
315
- yield* args.onQueueOverflow({
316
- mode: "serial",
317
- currentLength: nextSize,
318
- peak: state.peak,
319
- limit: serialQueueLimit,
320
- policy
321
- });
322
- return;
323
- }
324
- yield* drainSerial();
325
- });
326
- return yield* Stream.runForEach(args.stream, onTrigger);
327
- });
328
-
329
- // ../logix-core/src/internal/runtime/core/process/events.ts
330
- var PROCESS_EVENT_MAX_BYTES = 4 * 1024;
331
- var PROCESS_EVENT_MAX_EVENTS_PER_RUN = 50;
332
- var PROCESS_EVENT_RESERVED_EVENTS_FOR_SUMMARY = 1;
333
- var makeProcessRunEventBudgetState = (options) => ({
334
- maxEvents: typeof options?.maxEvents === "number" && Number.isFinite(options.maxEvents) && options.maxEvents >= 0 ? Math.floor(options.maxEvents) : PROCESS_EVENT_MAX_EVENTS_PER_RUN,
335
- maxBytes: typeof options?.maxBytes === "number" && Number.isFinite(options.maxBytes) && options.maxBytes >= 0 ? Math.floor(options.maxBytes) : PROCESS_EVENT_MAX_BYTES,
336
- emitted: 0,
337
- dropped: 0,
338
- downgraded: 0,
339
- summaryEmitted: false
340
- });
341
- var makeBudgetSummaryEvent = (args) => ({
342
- type: "process:trigger",
343
- identity: args.sourceEvent.identity,
344
- trigger: args.sourceEvent.trigger,
345
- severity: "warning",
346
- eventSeq: args.sourceEvent.eventSeq,
347
- timestampMs: args.sourceEvent.timestampMs,
348
- error: {
349
- message: "Process run event budget exceeded; further trigger/dispatch events are suppressed.",
350
- code: "process::event_budget_exceeded",
351
- hint: `maxEvents=${args.maxEvents} maxBytes=${args.maxBytes} emitted=${args.emitted} dropped=${args.dropped} downgraded=${args.downgraded}`
352
- }
353
- });
354
- var applyProcessRunEventBudget = (state, event) => {
355
- const maxEvents = Math.max(0, state.maxEvents);
356
- const maxBytes = Math.max(0, state.maxBytes);
357
- if (state.summaryEmitted) {
358
- return [
359
- { _tag: "drop" },
360
- {
361
- ...state,
362
- dropped: state.dropped + 1
363
- }
364
- ];
365
- }
366
- const reserve = PROCESS_EVENT_RESERVED_EVENTS_FOR_SUMMARY;
367
- const allowedRegular = Math.max(0, maxEvents - reserve);
368
- if (state.emitted < allowedRegular) {
369
- const enforced = enforceProcessEventMaxBytes(event, { maxBytes });
370
- return [
371
- { _tag: "emit", event: enforced.event },
372
- {
373
- ...state,
374
- emitted: state.emitted + 1,
375
- downgraded: state.downgraded + (enforced.downgraded ? 1 : 0)
376
- }
377
- ];
378
- }
379
- const dropped = state.dropped + 1;
380
- const summary = makeBudgetSummaryEvent({
381
- sourceEvent: event,
382
- maxEvents,
383
- maxBytes,
384
- emitted: state.emitted,
385
- dropped,
386
- downgraded: state.downgraded
387
- });
388
- const enforcedSummary = enforceProcessEventMaxBytes(summary, { maxBytes });
389
- return [
390
- { _tag: "emitSummary", event: enforcedSummary.event },
391
- {
392
- ...state,
393
- emitted: Math.min(maxEvents, state.emitted + 1),
394
- dropped,
395
- downgraded: state.downgraded + (enforcedSummary.downgraded ? 1 : 0),
396
- summaryEmitted: true
397
- }
398
- ];
399
- };
400
- var estimateEventBytes = (event) => {
401
- const json = JSON.stringify(event);
402
- return typeof Buffer !== "undefined" ? Buffer.byteLength(json, "utf8") : new TextEncoder().encode(json).length;
403
- };
404
- var truncateChars = (value, maxLen) => value.length <= maxLen ? value : value.slice(0, maxLen);
405
- var normalizeErrorSummary = (error) => {
406
- const message = typeof error.message === "string" && error.message.length > 0 ? error.message : "Error";
407
- const hint = typeof error.hint === "string" && error.hint.length > 0 ? truncateChars(error.hint, 1024) : void 0;
408
- return {
409
- name: typeof error.name === "string" && error.name.length > 0 ? error.name : void 0,
410
- message: truncateChars(message, 256),
411
- code: typeof error.code === "string" && error.code.length > 0 ? error.code : void 0,
412
- hint
413
- };
414
- };
415
- var enforceProcessEventMaxBytes = (event, options) => {
416
- const maxBytes = options?.maxBytes ?? PROCESS_EVENT_MAX_BYTES;
417
- let downgraded = false;
418
- let next = event;
419
- if (event.error) {
420
- const normalized = normalizeErrorSummary(event.error);
421
- if (normalized.message !== event.error.message || normalized.hint !== event.error.hint || normalized.code !== event.error.code || normalized.name !== event.error.name) {
422
- downgraded = true;
423
- next = { ...event, error: normalized };
424
- }
425
- }
426
- if (estimateEventBytes(next) <= maxBytes) {
427
- return { event: next, downgraded };
428
- }
429
- if (!next.error?.hint) {
430
- return { event: next, downgraded: true };
431
- }
432
- const hint = next.error.hint;
433
- const steps = [512, 256, 128, 64, 32, 0];
434
- for (const maxLen of steps) {
435
- const trimmed = maxLen === 0 ? void 0 : truncateChars(hint, maxLen);
436
- const candidate = {
437
- ...next,
438
- error: {
439
- ...next.error,
440
- hint: trimmed
441
- }
442
- };
443
- if (estimateEventBytes(candidate) <= maxBytes) {
444
- return { event: candidate, downgraded: true };
445
- }
446
- }
447
- const fallback = next.error ? {
448
- ...next,
449
- error: {
450
- ...next.error,
451
- message: truncateChars(next.error.message, 96),
452
- hint: void 0
453
- }
454
- } : next;
455
- return { event: fallback, downgraded: true };
456
- };
457
-
458
- // ../logix-core/src/internal/runtime/core/process/selectorSchema.ts
459
- import * as SchemaAST from "../effect/SchemaAST.js";
460
- var isRecord2 = (value) => typeof value === "object" && value !== null;
461
- var resolveSchemaAst = (schema) => {
462
- if (!isRecord2(schema)) return void 0;
463
- const ast = schema.ast;
464
- if (!ast) return void 0;
465
- if (typeof ast !== "object" && typeof ast !== "function") return void 0;
466
- return ast;
467
- };
468
- var makeDotPathError = (path, message, hint) => {
469
- const err = new Error(message);
470
- err.code = "process::invalid_dot_path";
471
- err.hint = hint ?? [
472
- "Expected dot-path syntax: segments separated by '.', numeric segments represent array indices.",
473
- `path: ${path}`,
474
- "",
475
- "examples:",
476
- "- count",
477
- "- user.name",
478
- "- items.0.id"
479
- ].join("\n");
480
- return err;
481
- };
482
- var makeSchemaMismatchError = (path) => makeDotPathError(
483
- path,
484
- "Invalid dot-path: path does not match the state schema.",
485
- [
486
- "The module state schema does not contain the requested dot-path.",
487
- `path: ${path}`,
488
- "",
489
- "fix:",
490
- "- Ensure the path exists in the state schema.",
491
- "- Use numeric segments for array indices (e.g. items.0.id)."
492
- ].join("\n")
493
- );
494
- var parseDotPath = (path) => {
495
- if (typeof path !== "string" || path.length === 0) {
496
- return { ok: false, error: makeDotPathError(String(path), "dot-path must be a non-empty string") };
497
- }
498
- const raw = path.split(".");
499
- if (raw.length === 0) {
500
- return { ok: false, error: makeDotPathError(path, "dot-path must contain at least one segment") };
501
- }
502
- const segments = [];
503
- for (let i = 0; i < raw.length; i++) {
504
- const seg = raw[i];
505
- if (seg.length === 0) {
506
- return {
507
- ok: false,
508
- error: makeDotPathError(
509
- path,
510
- `Invalid dot-path: empty segment at index ${i}.`,
511
- [
512
- "Expected dot-path syntax: segments separated by '.', numeric segments represent array indices.",
513
- `path: ${path}`,
514
- "",
515
- "examples:",
516
- "- count",
517
- "- user.name",
518
- "- items.0.id",
519
- "",
520
- "fix:",
521
- "- Remove consecutive dots or trailing dots."
522
- ].join("\n")
523
- )
524
- };
525
- }
526
- if (/^[0-9]+$/.test(seg)) {
527
- const n = Number(seg);
528
- if (!Number.isFinite(n) || n < 0) {
529
- return {
530
- ok: false,
531
- error: makeDotPathError(path, `Invalid array index segment "${seg}" at index ${i}.`)
532
- };
533
- }
534
- segments.push(Math.floor(n));
535
- continue;
536
- }
537
- segments.push(seg);
538
- }
539
- return { ok: true, segments };
540
- };
541
- var resolveAstForPath = (ast, segments, seen) => {
542
- if (segments.length === 0) return ast;
543
- let current = ast;
544
- while (true) {
545
- if (SchemaAST.isSuspend(current)) {
546
- if (seen.has(current)) return void 0;
547
- seen.add(current);
548
- current = current.f();
549
- continue;
550
- }
551
- if (SchemaAST.isRefinement(current)) {
552
- current = current.from;
553
- continue;
554
- }
555
- break;
556
- }
557
- if (SchemaAST.isTransformation(current)) {
558
- const from = resolveAstForPath(current.from, segments, seen);
559
- if (from) return from;
560
- return resolveAstForPath(current.to, segments, seen);
561
- }
562
- if (SchemaAST.isUnion(current)) {
563
- for (const node of current.types) {
564
- const resolved = resolveAstForPath(node, segments, seen);
565
- if (resolved) return resolved;
566
- }
567
- return void 0;
568
- }
569
- if (SchemaAST.isTupleType(current)) {
570
- const [head, ...tail] = segments;
571
- if (typeof head !== "number") return void 0;
572
- const element = head < current.elements.length ? current.elements[head] : current.rest.length > 0 ? current.rest[0] : void 0;
573
- return element ? resolveAstForPath(element.type, tail, seen) : void 0;
574
- }
575
- if (SchemaAST.isTypeLiteral(current)) {
576
- const [head, ...tail] = segments;
577
- if (head === void 0) return void 0;
578
- if (typeof head === "string") {
579
- for (const ps of current.propertySignatures) {
580
- if (String(ps.name) !== head) continue;
581
- return resolveAstForPath(ps.type, tail, seen);
582
- }
583
- }
584
- for (const sig of current.indexSignatures) {
585
- let param = sig.parameter;
586
- while (SchemaAST.isRefinement(param)) {
587
- param = param.from;
588
- }
589
- const tag2 = param?._tag;
590
- const acceptsString = tag2 === "StringKeyword" || tag2 === "TemplateLiteral";
591
- const acceptsNumber = tag2 === "NumberKeyword";
592
- if (typeof head === "string" && acceptsString) {
593
- return resolveAstForPath(sig.type, tail, seen);
594
- }
595
- if (typeof head === "number" && acceptsNumber) {
596
- return resolveAstForPath(sig.type, tail, seen);
597
- }
598
- }
599
- }
600
- const tag = current?._tag;
601
- if (tag === "AnyKeyword" || tag === "UnknownKeyword" || tag === "ObjectKeyword" || tag === "Declaration") {
602
- return current;
603
- }
604
- return void 0;
605
- };
606
- var selectBySegments = (segments) => (state) => {
607
- let current = state;
608
- for (const seg of segments) {
609
- if (current == null) return void 0;
610
- if (typeof seg === "number") {
611
- if (Array.isArray(current)) {
612
- current = current[seg];
613
- continue;
614
- }
615
- if (isRecord2(current)) {
616
- current = current[String(seg)];
617
- continue;
618
- }
619
- return void 0;
620
- }
621
- if (isRecord2(current)) {
622
- current = current[seg];
623
- continue;
624
- }
625
- return void 0;
626
- }
627
- return current;
628
- };
629
- var makeSchemaSelector = (path, schemaAst) => {
630
- const parsed = parseDotPath(path);
631
- if (!parsed.ok) return { ok: false, error: parsed.error };
632
- if (schemaAst) {
633
- const resolved = resolveAstForPath(schemaAst, parsed.segments, /* @__PURE__ */ new Set());
634
- if (!resolved) {
635
- return { ok: false, error: makeSchemaMismatchError(path) };
636
- }
637
- }
638
- return {
639
- ok: true,
640
- selector: selectBySegments(parsed.segments),
641
- segments: parsed.segments
642
- };
643
- };
644
-
645
- // ../logix-core/src/internal/runtime/core/process/supervision.ts
646
- var initialState = () => ({ failureTimes: [] });
647
- var onFailure = (policy, state, nowMs) => {
648
- if (policy.mode === "failStop") {
649
- return {
650
- decision: "stop",
651
- nextState: state,
652
- withinWindowFailures: state.failureTimes.length,
653
- maxRestarts: 0,
654
- windowMs: policy.windowMs
655
- };
656
- }
657
- const maxRestartsRaw = policy.maxRestarts;
658
- const maxRestarts = typeof maxRestartsRaw === "number" && Number.isFinite(maxRestartsRaw) && maxRestartsRaw >= 0 ? Math.floor(maxRestartsRaw) : 0;
659
- if (maxRestarts <= 0) {
660
- return {
661
- decision: "stop",
662
- nextState: state,
663
- withinWindowFailures: state.failureTimes.length,
664
- maxRestarts,
665
- windowMs: policy.windowMs
666
- };
667
- }
668
- const windowMsRaw = policy.windowMs;
669
- const windowMs = typeof windowMsRaw === "number" && Number.isFinite(windowMsRaw) && windowMsRaw > 0 ? Math.floor(windowMsRaw) : void 0;
670
- const failureTimesRaw = [...state.failureTimes, nowMs];
671
- const failureTimes = windowMs ? failureTimesRaw.filter((t) => t >= nowMs - windowMs) : failureTimesRaw;
672
- const cap = maxRestarts + 1;
673
- const capped = failureTimes.length > cap ? failureTimes.slice(failureTimes.length - cap) : failureTimes;
674
- const withinWindowFailures = capped.length;
675
- const decision = withinWindowFailures <= maxRestarts ? "restart" : "stop";
676
- return {
677
- decision,
678
- nextState: { failureTimes: capped },
679
- withinWindowFailures,
680
- maxRestarts,
681
- windowMs
682
- };
683
- };
684
-
685
- // ../logix-core/src/internal/runtime/core/process/ProcessRuntime.ts
686
- var ProcessRuntimeTag = class extends Context2.Tag("@logixjs/core/ProcessRuntime")() {
687
- };
688
- var currentProcessTrigger = FiberRef2.unsafeMake(void 0);
689
- var currentProcessEventBudget = FiberRef2.unsafeMake(
690
- void 0
691
- );
692
- var RUNTIME_BOOT_EVENT = "runtime:boot";
693
- var deriveDebugModuleId = (processId) => `process:${processId}`;
694
- var deriveTxnAnchor = (event) => {
695
- const trigger = event.trigger;
696
- if (!trigger) return {};
697
- if ((trigger.kind === "moduleAction" || trigger.kind === "moduleStateChange") && typeof trigger.instanceId === "string" && typeof trigger.txnSeq === "number" && Number.isFinite(trigger.txnSeq) && trigger.txnSeq >= 1) {
698
- const txnSeq = Math.floor(trigger.txnSeq);
699
- return {
700
- txnSeq,
701
- txnId: `${trigger.instanceId}::t${txnSeq}`
702
- };
703
- }
704
- return {};
705
- };
706
- var shouldNoopDueToSyncTxn = (scope, kind) => {
707
- const moduleId = scope.type === "moduleInstance" ? scope.moduleId : void 0;
708
- const instanceId = scope.type === "moduleInstance" ? scope.instanceId : void 0;
709
- return shouldNoopInSyncTransactionFiber({
710
- moduleId,
711
- instanceId,
712
- code: "process::invalid_usage",
713
- severity: "error",
714
- message: "ProcessRuntime scheduling is not allowed inside a synchronous StateTransaction body (it may deadlock the txnQueue).",
715
- hint: "Trigger/schedule Process outside the transaction window (e.g. in a watcher's run section or a separate fiber); do not trigger Process directly inside a reducer / synchronous transaction body.",
716
- kind
717
- });
718
- };
719
- var resolveRuntimeStateSchemaAst = (runtime) => {
720
- try {
721
- const internals = getRuntimeInternals(runtime);
722
- return resolveSchemaAst(internals.stateSchema);
723
- } catch {
724
- return void 0;
725
- }
726
- };
727
- var withModuleHint = (error, moduleId) => {
728
- const hint = error.hint;
729
- if (typeof hint === "string" && hint.length > 0) {
730
- if (!hint.includes("moduleId=")) {
731
- ;
732
- error.hint = `moduleId=${moduleId}
733
- ${hint}`;
734
- }
735
- return error;
736
- }
737
- ;
738
- error.hint = `moduleId=${moduleId}`;
739
- return error;
740
- };
741
- var actionIdFromUnknown = (action) => {
742
- if (!action || typeof action !== "object") return void 0;
743
- const anyAction = action;
744
- if (typeof anyAction._tag === "string" && anyAction._tag.length > 0) return anyAction._tag;
745
- if (typeof anyAction.type === "string" && anyAction.type.length > 0) return anyAction.type;
746
- return void 0;
747
- };
748
- var make = (options) => Effect3.gen(function* () {
749
- const runtimeScope = yield* Effect3.scope;
750
- const maxEventHistory = typeof options?.maxEventHistory === "number" && Number.isFinite(options.maxEventHistory) && options.maxEventHistory >= 0 ? Math.floor(options.maxEventHistory) : 500;
751
- const installations = /* @__PURE__ */ new Map();
752
- const instances = /* @__PURE__ */ new Map();
753
- const eventsBuffer = [];
754
- const eventsHub = yield* PubSub.sliding(Math.max(1, Math.min(2048, maxEventHistory)));
755
- const trimEvents = () => {
756
- if (maxEventHistory <= 0) {
757
- eventsBuffer.length = 0;
758
- return;
759
- }
760
- if (eventsBuffer.length <= maxEventHistory) return;
761
- const excess = eventsBuffer.length - maxEventHistory;
762
- eventsBuffer.splice(0, excess);
763
- };
764
- const recordDebugEvent = (event) => Effect3.gen(function* () {
765
- const diagnosticsLevel = yield* FiberRef2.get(currentDiagnosticsLevel);
766
- if (diagnosticsLevel === "off") {
767
- return;
768
- }
769
- const processId = event.identity.identity.processId;
770
- const processInstanceId = processInstanceIdFromIdentity(event.identity);
771
- const moduleId = deriveDebugModuleId(processId);
772
- const { txnSeq, txnId } = deriveTxnAnchor(event);
773
- yield* record({
774
- type: event.type,
775
- moduleId,
776
- instanceId: processInstanceId,
777
- identity: event.identity,
778
- severity: event.severity,
779
- eventSeq: event.eventSeq,
780
- timestampMs: event.timestampMs,
781
- trigger: event.trigger,
782
- dispatch: event.dispatch,
783
- error: event.error,
784
- txnSeq,
785
- txnId
786
- });
787
- });
788
- const publishEvent = (event) => Effect3.gen(function* () {
789
- eventsBuffer.push(event);
790
- trimEvents();
791
- yield* PubSub.publish(eventsHub, event);
792
- yield* recordDebugEvent(event);
793
- });
794
- const emit = (event) => Effect3.gen(function* () {
795
- const budgetRef = yield* FiberRef2.get(currentProcessEventBudget);
796
- if (budgetRef) {
797
- const decision = yield* Ref2.modify(budgetRef, (state) => {
798
- const [nextDecision, nextState] = applyProcessRunEventBudget(state, event);
799
- return [nextDecision, nextState];
800
- });
801
- if (decision._tag === "emit" || decision._tag === "emitSummary") {
802
- yield* publishEvent(decision.event);
803
- }
804
- return;
805
- }
806
- const enforced = enforceProcessEventMaxBytes(event);
807
- yield* publishEvent(enforced.event);
808
- });
809
- const emitErrorDiagnostic = (scope, processId, code, message, hint) => {
810
- if (!isDevEnv()) {
811
- return Effect3.void;
812
- }
813
- const moduleId = scope.type === "moduleInstance" ? scope.moduleId : void 0;
814
- const instanceId = scope.type === "moduleInstance" ? scope.instanceId : void 0;
815
- return record({
816
- type: "diagnostic",
817
- moduleId,
818
- instanceId,
819
- code,
820
- severity: "error",
821
- message,
822
- hint,
823
- actionTag: processId,
824
- kind: "process_runtime"
825
- });
826
- };
827
- const resolveMissingDependencies = (installation) => {
828
- const declared = installation.definition.requires ?? [];
829
- const implicitFromTriggers = [];
830
- for (const trigger of installation.definition.triggers) {
831
- if (trigger.kind === "moduleAction" || trigger.kind === "moduleStateChange") {
832
- implicitFromTriggers.push(trigger.moduleId);
833
- }
834
- }
835
- const requires = Array.from(/* @__PURE__ */ new Set([...declared, ...implicitFromTriggers]));
836
- if (requires.length === 0) return [];
837
- const missing = [];
838
- for (const dep of requires) {
839
- if (typeof dep !== "string" || dep.length === 0) continue;
840
- const tag = Context2.Tag(`@logixjs/Module/${dep}`)();
841
- const found = Context2.getOption(installation.env, tag);
842
- if (Option2.isNone(found)) {
843
- missing.push(dep);
844
- }
845
- }
846
- return missing;
847
- };
848
- const stopInstance = (instance, reason) => Effect3.gen(function* () {
849
- if (instance.status.status === "stopped" || instance.status.status === "failed" || instance.status.status === "stopping") {
850
- return;
851
- }
852
- const fiber = instance.fiber;
853
- instance.status = {
854
- ...instance.status,
855
- status: "stopping",
856
- stoppedReason: reason
857
- };
858
- if (fiber) {
859
- yield* Fiber2.interrupt(fiber);
860
- }
861
- yield* Queue.shutdown(instance.platformTriggersQueue);
862
- instance.status = {
863
- ...instance.status,
864
- status: "stopped",
865
- stoppedReason: reason
866
- };
867
- instance.fiber = void 0;
868
- const evt = {
869
- type: "process:stop",
870
- identity: instance.identity,
871
- severity: "info",
872
- eventSeq: instance.nextEventSeq++,
873
- timestampMs: Date.now()
874
- };
875
- yield* emit(evt);
876
- const installation = installations.get(instance.installationKey);
877
- if (installation?.pendingStart) {
878
- installation.pendingStart = void 0;
879
- yield* startInstallation(instance.installationKey);
880
- }
881
- });
882
- const startInstallation = (installationKey) => Effect3.gen(function* () {
883
- const installation = installations.get(installationKey);
884
- if (!installation) return;
885
- installation.pendingStart = void 0;
886
- const noop = yield* shouldNoopDueToSyncTxn(installation.identity.scope, "process_start_in_transaction");
887
- if (noop) return;
888
- const currentId = installation.currentInstanceId;
889
- if (currentId) {
890
- const current = instances.get(currentId);
891
- if (current && (current.status.status === "running" || current.status.status === "starting")) {
892
- return;
893
- }
894
- }
895
- const runSeq = installation.nextRunSeq++;
896
- const identity = {
897
- identity: installation.identity,
898
- runSeq
899
- };
900
- const processInstanceId = processInstanceIdFromIdentity(identity);
901
- const platformTriggersQueue = yield* Queue.sliding(64);
902
- const instanceState = {
903
- installationKey,
904
- processInstanceId,
905
- identity,
906
- processId: installation.identity.processId,
907
- scope: installation.identity.scope,
908
- forkScope: installation.forkScope,
909
- platformTriggersQueue,
910
- status: {
911
- identity,
912
- status: "starting"
913
- },
914
- nextEventSeq: 1,
915
- nextTriggerSeq: 1
916
- };
917
- instances.set(processInstanceId, instanceState);
918
- installation.currentInstanceId = processInstanceId;
919
- if (installation.forkScope !== runtimeScope) {
920
- yield* Scope2.addFinalizer(
921
- installation.forkScope,
922
- Effect3.suspend(() => {
923
- const status = instanceState.status.status;
924
- if (status === "stopped" || status === "failed" || status === "stopping") {
925
- return Effect3.void;
926
- }
927
- return stopInstance(instanceState, "scopeDisposed");
928
- }).pipe(Effect3.catchAllCause(() => Effect3.void))
929
- );
930
- }
931
- yield* emit({
932
- type: "process:start",
933
- identity,
934
- severity: "info",
935
- eventSeq: instanceState.nextEventSeq++,
936
- timestampMs: Date.now()
937
- });
938
- const missing = resolveMissingDependencies(installation);
939
- if (missing.length > 0) {
940
- const hint = isDevEnv() ? [
941
- "Strict scope dependency resolution: missing required modules in the current scope.",
942
- `missing: ${missing.join(", ")}`,
943
- "",
944
- "fix:",
945
- "- Provide the missing module implementation(s) in the same scope via imports.",
946
- ` Example: RootModule.implement({ imports: [${missing[0]}.implement(...).impl], processes: [...] })`,
947
- "- Do not rely on cross-scope fallbacks / guessing instances."
948
- ].join("\n") : void 0;
949
- const error = {
950
- message: `Missing dependencies in scope: ${missing.join(", ")}`,
951
- code: "process::missing_dependency",
952
- hint
953
- };
954
- instanceState.status = {
955
- ...instanceState.status,
956
- status: "failed",
957
- stoppedReason: "failed",
958
- lastError: error
959
- };
960
- yield* emit({
961
- type: "process:error",
962
- identity,
963
- severity: "error",
964
- eventSeq: instanceState.nextEventSeq++,
965
- timestampMs: Date.now(),
966
- error
967
- });
968
- yield* emitErrorDiagnostic(
969
- installation.identity.scope,
970
- installation.identity.processId,
971
- "process::missing_dependency",
972
- error.message,
973
- hint
974
- );
975
- return;
976
- }
977
- const shouldRecordChainEvents = installation.definition.diagnosticsLevel !== "off";
978
- const baseEnv = installation.env;
979
- const makeWrappedEnv = () => {
980
- if (!shouldRecordChainEvents) {
981
- return baseEnv;
982
- }
983
- const requires = installation.definition.requires ?? [];
984
- if (requires.length === 0) {
985
- return baseEnv;
986
- }
987
- const ids = Array.from(new Set(requires));
988
- let nextEnv = baseEnv;
989
- for (const moduleId of ids) {
990
- if (typeof moduleId !== "string" || moduleId.length === 0) continue;
991
- const tag = Context2.Tag(`@logixjs/Module/${moduleId}`)();
992
- const found = Context2.getOption(baseEnv, tag);
993
- if (Option2.isNone(found)) continue;
994
- const runtime = found.value;
995
- const recordDispatch = (action) => Effect3.gen(function* () {
996
- const trigger = yield* FiberRef2.get(currentProcessTrigger);
997
- if (!trigger) return;
998
- const actionId = actionIdFromUnknown(action) ?? "unknown";
999
- const dispatchModuleId = typeof runtime.moduleId === "string" ? runtime.moduleId : moduleId;
1000
- const dispatchInstanceId = typeof runtime.instanceId === "string" ? runtime.instanceId : "unknown";
1001
- const evt = {
1002
- type: "process:dispatch",
1003
- identity,
1004
- trigger,
1005
- dispatch: {
1006
- moduleId: dispatchModuleId,
1007
- instanceId: dispatchInstanceId,
1008
- actionId
1009
- },
1010
- severity: "info",
1011
- eventSeq: instanceState.nextEventSeq++,
1012
- timestampMs: Date.now()
1013
- };
1014
- yield* emit(evt);
1015
- });
1016
- const wrapped = {
1017
- ...runtime,
1018
- dispatch: (action) => runtime.dispatch(action).pipe(Effect3.tap(() => recordDispatch(action))),
1019
- dispatchLowPriority: (action) => runtime.dispatchLowPriority(action).pipe(Effect3.tap(() => recordDispatch(action))),
1020
- dispatchBatch: (actions) => runtime.dispatchBatch(actions).pipe(Effect3.tap(() => Effect3.forEach(actions, recordDispatch, { discard: true })))
1021
- };
1022
- nextEnv = Context2.add(tag, wrapped)(nextEnv);
1023
- }
1024
- return nextEnv;
1025
- };
1026
- const wrappedEnv = makeWrappedEnv();
1027
- const providedProcess = Effect3.provide(installation.process, wrappedEnv);
1028
- const makeTriggerStream = (spec) => Effect3.gen(function* () {
1029
- if (spec.kind === "timer") {
1030
- const interval = Duration.decodeUnknown(spec.timerId);
1031
- if (Option2.isNone(interval)) {
1032
- const err = new Error(`[ProcessRuntime] invalid timerId (expected DurationInput): ${spec.timerId}`);
1033
- err.code = "process::invalid_timer_id";
1034
- err.hint = "timerId must be a valid DurationInput string, e.g. '10 millis', '1 seconds', '5 minutes'.";
1035
- return yield* Effect3.fail(err);
1036
- }
1037
- return Stream2.tick(interval.value).pipe(
1038
- Stream2.map(
1039
- () => ({
1040
- kind: "timer",
1041
- name: spec.name,
1042
- timerId: spec.timerId
1043
- })
1044
- )
1045
- );
1046
- }
1047
- if (spec.kind === "moduleAction") {
1048
- const tag2 = Context2.Tag(`@logixjs/Module/${spec.moduleId}`)();
1049
- const found2 = Context2.getOption(baseEnv, tag2);
1050
- if (Option2.isNone(found2)) {
1051
- return yield* Effect3.fail(new Error(`Missing module runtime in scope: ${spec.moduleId}`));
1052
- }
1053
- const runtime2 = found2.value;
1054
- if (!shouldRecordChainEvents) {
1055
- const stream2 = runtime2.actions$;
1056
- if (!stream2) {
1057
- const err = new Error("ModuleRuntime does not provide actions$ (required for moduleAction trigger).");
1058
- err.code = "process::missing_action_stream";
1059
- err.hint = `moduleId=${spec.moduleId}`;
1060
- return yield* Effect3.fail(err);
1061
- }
1062
- return stream2.pipe(
1063
- Stream2.filter((action) => actionIdFromUnknown(action) === spec.actionId),
1064
- Stream2.map(
1065
- () => ({
1066
- kind: "moduleAction",
1067
- name: spec.name,
1068
- moduleId: spec.moduleId,
1069
- instanceId: runtime2.instanceId,
1070
- actionId: spec.actionId,
1071
- txnSeq: 1
1072
- })
1073
- )
1074
- );
1075
- }
1076
- const stream = runtime2.actionsWithMeta$;
1077
- if (!stream) {
1078
- const err = new Error(
1079
- "ModuleRuntime does not provide actionsWithMeta$ (required for moduleAction trigger)."
1080
- );
1081
- err.code = "process::missing_action_meta_stream";
1082
- err.hint = `moduleId=${spec.moduleId}`;
1083
- return yield* Effect3.fail(err);
1084
- }
1085
- return stream.pipe(
1086
- Stream2.filter((evt) => actionIdFromUnknown(evt.value) === spec.actionId),
1087
- Stream2.map((evt) => {
1088
- const txnSeq = evt?.meta?.txnSeq;
1089
- return {
1090
- kind: "moduleAction",
1091
- name: spec.name,
1092
- moduleId: spec.moduleId,
1093
- instanceId: runtime2.instanceId,
1094
- actionId: spec.actionId,
1095
- txnSeq: typeof txnSeq === "number" ? txnSeq : 1
1096
- };
1097
- })
1098
- );
1099
- }
1100
- const tag = Context2.Tag(`@logixjs/Module/${spec.moduleId}`)();
1101
- const found = Context2.getOption(baseEnv, tag);
1102
- if (Option2.isNone(found)) {
1103
- return yield* Effect3.fail(new Error(`Missing module runtime in scope: ${spec.moduleId}`));
1104
- }
1105
- const runtime = found.value;
1106
- const schemaAst = resolveRuntimeStateSchemaAst(runtime);
1107
- const selectorResult = makeSchemaSelector(spec.path, schemaAst);
1108
- if (!selectorResult.ok) {
1109
- return yield* Effect3.fail(withModuleHint(selectorResult.error, spec.moduleId));
1110
- }
1111
- const selectorBase = selectorResult.selector;
1112
- const prevRef = yield* Ref2.make(Option2.none());
1113
- const enableSelectorDiagnostics = shouldRecordChainEvents;
1114
- const selectorDiagnosticsRef = enableSelectorDiagnostics ? yield* Ref2.make({
1115
- windowStartedMs: Date.now(),
1116
- triggersInWindow: 0,
1117
- lastWarningAtMs: 0
1118
- }) : void 0;
1119
- const sampleEveryMask = 127;
1120
- const slowSampleThresholdMs = 4;
1121
- const triggerWindowMs = 1e3;
1122
- const triggerWarningThreshold = isDevEnv() ? 20 : 200;
1123
- const warningCooldownMs = 3e4;
1124
- let selectorCalls = 0;
1125
- let selectorSamples = 0;
1126
- let selectorSlowSamples = 0;
1127
- let selectorMaxSampleMs = 0;
1128
- const nowMs = () => {
1129
- if (typeof performance !== "undefined" && typeof performance.now === "function") {
1130
- return performance.now();
1131
- }
1132
- return Date.now();
1133
- };
1134
- const selector = enableSelectorDiagnostics ? (state) => {
1135
- selectorCalls += 1;
1136
- if ((selectorCalls & sampleEveryMask) !== 0) {
1137
- return selectorBase(state);
1138
- }
1139
- const t0 = nowMs();
1140
- const value = selectorBase(state);
1141
- const dt = nowMs() - t0;
1142
- selectorSamples += 1;
1143
- if (dt >= slowSampleThresholdMs) {
1144
- selectorSlowSamples += 1;
1145
- }
1146
- if (dt > selectorMaxSampleMs) {
1147
- selectorMaxSampleMs = dt;
1148
- }
1149
- return value;
1150
- } : selectorBase;
1151
- const maybeWarnSelector = (trigger) => {
1152
- if (!selectorDiagnosticsRef) {
1153
- return Effect3.void;
1154
- }
1155
- return Effect3.gen(function* () {
1156
- const now = Date.now();
1157
- const decision = yield* Ref2.modify(selectorDiagnosticsRef, (s) => {
1158
- const windowExpired = now - s.windowStartedMs >= triggerWindowMs;
1159
- const windowStartedMs = windowExpired ? now : s.windowStartedMs;
1160
- const triggersInWindow = windowExpired ? 1 : s.triggersInWindow + 1;
1161
- const shouldCooldown = now - s.lastWarningAtMs < warningCooldownMs;
1162
- const tooFrequent = triggersInWindow >= triggerWarningThreshold;
1163
- const tooSlow = selectorMaxSampleMs >= slowSampleThresholdMs && selectorSamples > 0;
1164
- const shouldWarn = !shouldCooldown && (tooFrequent || tooSlow);
1165
- const next = shouldWarn ? {
1166
- windowStartedMs: now,
1167
- triggersInWindow: 0,
1168
- lastWarningAtMs: now
1169
- } : {
1170
- ...s,
1171
- windowStartedMs,
1172
- triggersInWindow
1173
- };
1174
- return [
1175
- {
1176
- shouldWarn,
1177
- tooFrequent,
1178
- tooSlow,
1179
- triggersInWindow
1180
- },
1181
- next
1182
- ];
1183
- });
1184
- if (!decision.shouldWarn) {
1185
- return;
1186
- }
1187
- const code = decision.tooFrequent ? "process::selector_high_frequency" : "process::selector_slow";
1188
- const hint = [
1189
- `moduleId=${spec.moduleId}`,
1190
- `path=${spec.path}`,
1191
- `windowMs=${triggerWindowMs}`,
1192
- `triggersInWindow=${decision.triggersInWindow}`,
1193
- `threshold=${triggerWarningThreshold}`,
1194
- `cooldownMs=${warningCooldownMs}`,
1195
- "",
1196
- "selector sampling:",
1197
- `calls=${selectorCalls}`,
1198
- `sampled=${selectorSamples}`,
1199
- `slowSamples(>=${slowSampleThresholdMs}ms)=${selectorSlowSamples}`,
1200
- `maxSampleMs=${selectorMaxSampleMs.toFixed(2)}`,
1201
- "",
1202
- "notes:",
1203
- "- Ensure the selected value is stable (prefer primitive/tuple; avoid returning fresh objects).",
1204
- "- Narrow the path to reduce change frequency; avoid selecting large objects."
1205
- ].join("\n");
1206
- selectorSamples = 0;
1207
- selectorSlowSamples = 0;
1208
- selectorMaxSampleMs = 0;
1209
- yield* emit({
1210
- type: "process:trigger",
1211
- identity,
1212
- trigger,
1213
- severity: "warning",
1214
- eventSeq: instanceState.nextEventSeq++,
1215
- timestampMs: Date.now(),
1216
- error: {
1217
- message: "moduleStateChange selector diagnostics warning",
1218
- code,
1219
- hint
1220
- }
1221
- });
1222
- });
1223
- };
1224
- const baseStream = runtime.changesWithMeta(selector).pipe(
1225
- Stream2.mapEffect(
1226
- (evt) => Ref2.get(prevRef).pipe(
1227
- Effect3.flatMap((prev) => {
1228
- if (Option2.isSome(prev) && Object.is(prev.value, evt.value)) {
1229
- return Effect3.succeed(Option2.none());
1230
- }
1231
- return Ref2.set(prevRef, Option2.some(evt.value)).pipe(Effect3.as(Option2.some(evt)));
1232
- })
1233
- )
1234
- ),
1235
- Stream2.filterMap((opt) => opt),
1236
- Stream2.map((evt) => {
1237
- const txnSeq = evt?.meta?.txnSeq;
1238
- return {
1239
- kind: "moduleStateChange",
1240
- name: spec.name,
1241
- moduleId: spec.moduleId,
1242
- instanceId: runtime.instanceId,
1243
- path: spec.path,
1244
- txnSeq: typeof txnSeq === "number" ? txnSeq : 1
1245
- };
1246
- })
1247
- );
1248
- return enableSelectorDiagnostics ? baseStream.pipe(Stream2.tap(maybeWarnSelector)) : baseStream;
1249
- });
1250
- const makeRun = (trigger, fatal) => Effect3.locally(
1251
- currentProcessTrigger,
1252
- trigger
1253
- )(
1254
- providedProcess.pipe(
1255
- Effect3.catchAllCause((cause) => {
1256
- if (Cause.isInterruptedOnly(cause)) {
1257
- return Effect3.void;
1258
- }
1259
- return Deferred.succeed(fatal, cause).pipe(
1260
- Effect3.asVoid,
1261
- Effect3.catchAll(() => Effect3.void)
1262
- );
1263
- })
1264
- )
1265
- );
1266
- const makeChainRun = (trigger, fatal) => {
1267
- if (!shouldRecordChainEvents) {
1268
- return makeRun(trigger, fatal);
1269
- }
1270
- return Effect3.gen(function* () {
1271
- const budgetRef = yield* Ref2.make(makeProcessRunEventBudgetState());
1272
- return yield* Effect3.locally(
1273
- currentProcessEventBudget,
1274
- budgetRef
1275
- )(emitTriggerEvent(trigger, "info").pipe(Effect3.zipRight(makeRun(trigger, fatal))));
1276
- });
1277
- };
1278
- const assignTriggerSeq = (trigger) => {
1279
- if (!shouldRecordChainEvents) {
1280
- return trigger;
1281
- }
1282
- return {
1283
- ...trigger,
1284
- triggerSeq: instanceState.nextTriggerSeq++
1285
- };
1286
- };
1287
- const emitTriggerEvent = (trigger, severity) => {
1288
- if (!shouldRecordChainEvents) {
1289
- return Effect3.void;
1290
- }
1291
- const evt = {
1292
- type: "process:trigger",
1293
- identity,
1294
- trigger,
1295
- severity,
1296
- eventSeq: instanceState.nextEventSeq++,
1297
- timestampMs: Date.now()
1298
- };
1299
- return emit(evt);
1300
- };
1301
- const policy = installation.definition.concurrency;
1302
- const autoStart = installation.definition.triggers.some(
1303
- (t) => t.kind === "platformEvent" && t.platformEvent === RUNTIME_BOOT_EVENT
1304
- );
1305
- const bootTriggerSpec = installation.definition.triggers.find(
1306
- (t) => t.kind === "platformEvent" && t.platformEvent === RUNTIME_BOOT_EVENT
1307
- );
1308
- const instanceProgram = Effect3.gen(function* () {
1309
- const fatal = yield* Deferred.make();
1310
- const platformEventStream = Stream2.fromQueue(
1311
- instanceState.platformTriggersQueue
1312
- );
1313
- const nonPlatformTriggers = installation.definition.triggers.filter(
1314
- (t) => t.kind !== "platformEvent"
1315
- );
1316
- const streams = yield* Effect3.forEach(nonPlatformTriggers, makeTriggerStream);
1317
- const triggerStream = Stream2.mergeAll([platformEventStream, ...streams], {
1318
- concurrency: "unbounded"
1319
- });
1320
- const reportQueueOverflow = (info) => {
1321
- const err = new Error("Process trigger queue overflow (serial maxQueue guard).");
1322
- err.code = "process::serial_queue_overflow";
1323
- err.hint = [
1324
- `mode=${info.mode}`,
1325
- `queue: current=${info.currentLength} peak=${info.peak}`,
1326
- `maxQueue: configured=${info.limit.configured} guard=${info.limit.guard}`,
1327
- `policy: ${JSON.stringify(info.policy)}`,
1328
- "",
1329
- "fix:",
1330
- "- Configure concurrency.maxQueue (serial) to a finite value, or switch to mode=latest/drop to avoid unbounded backlog."
1331
- ].join("\n");
1332
- return Deferred.succeed(fatal, Cause.fail(err)).pipe(
1333
- Effect3.asVoid,
1334
- Effect3.catchAll(() => Effect3.void)
1335
- );
1336
- };
1337
- const runnerFiber = yield* Effect3.forkScoped(
1338
- runProcessTriggerStream({
1339
- stream: triggerStream,
1340
- policy,
1341
- assignTriggerSeq,
1342
- run: (trigger) => makeChainRun(trigger, fatal),
1343
- onDrop: (trigger) => emitTriggerEvent(trigger, "warning"),
1344
- onQueueOverflow: reportQueueOverflow
1345
- })
1346
- );
1347
- if (autoStart) {
1348
- yield* Queue.offer(instanceState.platformTriggersQueue, {
1349
- kind: "platformEvent",
1350
- name: bootTriggerSpec?.name,
1351
- platformEvent: RUNTIME_BOOT_EVENT
1352
- });
1353
- }
1354
- const cause = yield* Deferred.await(fatal);
1355
- yield* Fiber2.interrupt(runnerFiber);
1356
- return yield* Effect3.failCause(cause);
1357
- });
1358
- const fiber = yield* Effect3.forkIn(installation.forkScope)(
1359
- Effect3.scoped(instanceProgram).pipe(
1360
- Effect3.catchAllCause(
1361
- (cause) => Effect3.gen(function* () {
1362
- if (Cause.isInterruptedOnly(cause)) {
1363
- if (instanceState.status.status === "stopping") {
1364
- return;
1365
- }
1366
- instanceState.status = {
1367
- ...instanceState.status,
1368
- status: "stopped",
1369
- stoppedReason: "scopeDisposed"
1370
- };
1371
- instanceState.fiber = void 0;
1372
- yield* Effect3.uninterruptible(
1373
- emit({
1374
- type: "process:stop",
1375
- identity,
1376
- severity: "info",
1377
- eventSeq: instanceState.nextEventSeq++,
1378
- timestampMs: Date.now()
1379
- })
1380
- );
1381
- const installation2 = installations.get(installationKey);
1382
- if (installation2?.pendingStart) {
1383
- installation2.pendingStart = void 0;
1384
- yield* startInstallation(installationKey);
1385
- }
1386
- return;
1387
- }
1388
- const primary = Option2.getOrElse(
1389
- Cause.failureOption(cause),
1390
- () => Option2.getOrElse(Cause.dieOption(cause), () => cause)
1391
- );
1392
- const summary = toSerializableErrorSummary(primary);
1393
- const error = summary.errorSummary;
1394
- instanceState.status = {
1395
- ...instanceState.status,
1396
- status: "failed",
1397
- stoppedReason: "failed",
1398
- lastError: error
1399
- };
1400
- yield* emit({
1401
- type: "process:error",
1402
- identity,
1403
- severity: "error",
1404
- eventSeq: instanceState.nextEventSeq++,
1405
- timestampMs: Date.now(),
1406
- error
1407
- });
1408
- const decision = onFailure(
1409
- installation.definition.errorPolicy,
1410
- installation.supervision,
1411
- Date.now()
1412
- );
1413
- installation.supervision = decision.nextState;
1414
- if (decision.decision === "restart") {
1415
- yield* emit({
1416
- type: "process:restart",
1417
- identity,
1418
- severity: "warning",
1419
- eventSeq: instanceState.nextEventSeq++,
1420
- timestampMs: Date.now(),
1421
- error
1422
- });
1423
- yield* startInstallation(installationKey);
1424
- } else {
1425
- yield* emitErrorDiagnostic(
1426
- installation.identity.scope,
1427
- installation.identity.processId,
1428
- "process::failed_stop",
1429
- "Process failed and stopped (failStop / restart limit reached).",
1430
- `processId=${installation.identity.processId} scopeKey=${installation.scopeKey} failures=${decision.withinWindowFailures} maxRestarts=${decision.maxRestarts}`
1431
- );
1432
- }
1433
- })
1434
- )
1435
- )
1436
- );
1437
- instanceState.fiber = fiber;
1438
- instanceState.status = {
1439
- ...instanceState.status,
1440
- status: "running"
1441
- };
1442
- yield* Effect3.yieldNow();
1443
- });
1444
- const install = (process, options2) => Effect3.gen(function* () {
1445
- const meta = getMeta(process);
1446
- if (!meta) {
1447
- return void 0;
1448
- }
1449
- const env = yield* Effect3.context();
1450
- const forkScopeOpt = yield* Effect3.serviceOption(Scope2.Scope);
1451
- const forkScope = Option2.isSome(forkScopeOpt) ? forkScopeOpt.value : runtimeScope;
1452
- const scopeKey = scopeKeyFromScope(options2.scope);
1453
- const identity = {
1454
- processId: meta.definition.processId,
1455
- scope: options2.scope
1456
- };
1457
- const installationKey = installationKeyFromIdentity(identity);
1458
- const existing = installations.get(installationKey);
1459
- if (existing) {
1460
- existing.env = env;
1461
- existing.forkScope = forkScope;
1462
- existing.enabled = options2.enabled ?? true;
1463
- existing.installedAt = options2.installedAt ?? existing.installedAt;
1464
- if (!existing.enabled) {
1465
- existing.pendingStart = void 0;
1466
- return {
1467
- identity,
1468
- enabled: existing.enabled,
1469
- installedAt: existing.installedAt
1470
- };
1471
- }
1472
- const currentId = existing.currentInstanceId;
1473
- const current = currentId ? instances.get(currentId) : void 0;
1474
- const status = current?.status.status;
1475
- if (status === "running" || status === "starting") {
1476
- const mode = options2.mode ?? "switch";
1477
- if (mode === "switch" && current && current.forkScope !== forkScope) {
1478
- existing.pendingStart = { forkScope };
1479
- yield* Scope2.addFinalizer(
1480
- forkScope,
1481
- Effect3.sync(() => {
1482
- const installation2 = installations.get(installationKey);
1483
- if (!installation2) return;
1484
- if (installation2.pendingStart?.forkScope === forkScope) {
1485
- installation2.pendingStart = void 0;
1486
- }
1487
- })
1488
- );
1489
- } else {
1490
- existing.pendingStart = void 0;
1491
- }
1492
- return {
1493
- identity,
1494
- enabled: existing.enabled,
1495
- installedAt: existing.installedAt
1496
- };
1497
- }
1498
- if (status === "stopping") {
1499
- const mode = options2.mode ?? "switch";
1500
- if (mode === "switch") {
1501
- existing.pendingStart = { forkScope };
1502
- yield* Scope2.addFinalizer(
1503
- forkScope,
1504
- Effect3.sync(() => {
1505
- const installation2 = installations.get(installationKey);
1506
- if (!installation2) return;
1507
- if (installation2.pendingStart?.forkScope === forkScope) {
1508
- installation2.pendingStart = void 0;
1509
- }
1510
- })
1511
- );
1512
- } else {
1513
- existing.pendingStart = void 0;
1514
- }
1515
- return {
1516
- identity,
1517
- enabled: existing.enabled,
1518
- installedAt: existing.installedAt
1519
- };
1520
- }
1521
- existing.pendingStart = void 0;
1522
- yield* startInstallation(installationKey);
1523
- return {
1524
- identity,
1525
- enabled: existing.enabled,
1526
- installedAt: existing.installedAt
1527
- };
1528
- }
1529
- const derived = Effect3.suspend(() => process);
1530
- attachMeta(derived, {
1531
- ...meta,
1532
- installationScope: options2.scope
1533
- });
1534
- const installation = {
1535
- identity,
1536
- scopeKey,
1537
- definition: meta.definition,
1538
- env,
1539
- forkScope,
1540
- process: derived,
1541
- kind: meta.kind ?? "process",
1542
- enabled: options2.enabled ?? true,
1543
- installedAt: options2.installedAt,
1544
- nextRunSeq: 1,
1545
- supervision: initialState(),
1546
- pendingStart: void 0
1547
- };
1548
- installations.set(installationKey, installation);
1549
- if (installation.enabled) {
1550
- yield* startInstallation(installationKey);
1551
- }
1552
- return {
1553
- identity,
1554
- enabled: installation.enabled,
1555
- installedAt: installation.installedAt
1556
- };
1557
- });
1558
- const listInstallations = (filter) => Effect3.sync(() => {
1559
- const scopeType = filter?.scopeType;
1560
- const scopeKey = filter?.scopeKey;
1561
- const out = [];
1562
- for (const installation of installations.values()) {
1563
- if (scopeType && installation.identity.scope.type !== scopeType) continue;
1564
- if (scopeKey && installation.scopeKey !== scopeKey) continue;
1565
- out.push({
1566
- identity: installation.identity,
1567
- enabled: installation.enabled,
1568
- installedAt: installation.installedAt
1569
- });
1570
- }
1571
- return out;
1572
- });
1573
- const getInstanceStatus = (processInstanceId) => Effect3.sync(() => instances.get(processInstanceId)?.status);
1574
- const controlInstance = (processInstanceId, request) => Effect3.suspend(() => {
1575
- const instance = instances.get(processInstanceId);
1576
- if (!instance) {
1577
- return Effect3.void;
1578
- }
1579
- return shouldNoopDueToSyncTxn(instance.scope, "process_control_in_transaction").pipe(
1580
- Effect3.flatMap((noop) => {
1581
- if (noop) {
1582
- return Effect3.void;
1583
- }
1584
- if (request.action === "stop") {
1585
- return stopInstance(instance, "manualStop");
1586
- }
1587
- if (request.action === "restart") {
1588
- return stopInstance(instance, "manualStop").pipe(
1589
- Effect3.flatMap(() => {
1590
- const installation = installations.get(instance.installationKey);
1591
- if (!installation) {
1592
- return Effect3.void;
1593
- }
1594
- installation.currentInstanceId = void 0;
1595
- return startInstallation(instance.installationKey);
1596
- })
1597
- );
1598
- }
1599
- if (request.action === "start") {
1600
- if (instance.status.status === "running" || instance.status.status === "starting") {
1601
- return Effect3.void;
1602
- }
1603
- const installation = installations.get(instance.installationKey);
1604
- if (!installation) {
1605
- return Effect3.void;
1606
- }
1607
- installation.currentInstanceId = void 0;
1608
- return startInstallation(instance.installationKey);
1609
- }
1610
- return Effect3.void;
1611
- })
1612
- );
1613
- });
1614
- const deliverPlatformEvent = (event) => Effect3.gen(function* () {
1615
- const noop = yield* shouldNoopInSyncTransactionFiber({
1616
- code: "process::invalid_usage",
1617
- severity: "error",
1618
- message: "ProcessRuntime platform events are not allowed inside a synchronous StateTransaction body (it may deadlock the txnQueue).",
1619
- hint: "Deliver platformEvent outside the transaction window.",
1620
- kind: "process_platform_event_in_transaction"
1621
- });
1622
- if (noop) return;
1623
- const targets = Array.from(instances.values());
1624
- const eventName = event.eventName;
1625
- yield* Effect3.forEach(
1626
- targets,
1627
- (instance) => Effect3.suspend(() => {
1628
- if (instance.status.status !== "starting" && instance.status.status !== "running") {
1629
- return Effect3.void;
1630
- }
1631
- const installation = installations.get(instance.installationKey);
1632
- if (!installation) {
1633
- return Effect3.void;
1634
- }
1635
- const specs = installation.definition.triggers.filter(
1636
- (t) => t.kind === "platformEvent" && t.platformEvent === eventName
1637
- );
1638
- if (specs.length === 0) {
1639
- return Effect3.void;
1640
- }
1641
- return Effect3.forEach(
1642
- specs,
1643
- (spec) => Queue.offer(instance.platformTriggersQueue, {
1644
- kind: "platformEvent",
1645
- name: spec.name,
1646
- platformEvent: spec.platformEvent
1647
- }),
1648
- { discard: true }
1649
- );
1650
- }),
1651
- { discard: true }
1652
- );
1653
- });
1654
- const eventsStream = Stream2.fromPubSub(eventsHub);
1655
- const getEventsSnapshot = () => Effect3.sync(() => eventsBuffer.slice());
1656
- yield* Effect3.addFinalizer(
1657
- () => Effect3.gen(function* () {
1658
- for (const installation of installations.values()) {
1659
- installation.pendingStart = void 0;
1660
- }
1661
- for (const instance of instances.values()) {
1662
- if (instance.fiber) {
1663
- yield* stopInstance(instance, "scopeDisposed");
1664
- }
1665
- }
1666
- }).pipe(
1667
- Effect3.catchAllCause(
1668
- (cause) => Effect3.sync(() => {
1669
- if (isDevEnv()) {
1670
- console.warn("[ProcessRuntime] finalizer failed", Cause.pretty(cause));
1671
- }
1672
- })
1673
- )
1674
- )
1675
- );
1676
- return {
1677
- install,
1678
- listInstallations,
1679
- getInstanceStatus,
1680
- controlInstance,
1681
- deliverPlatformEvent,
1682
- events: eventsStream,
1683
- getEventsSnapshot
1684
- };
1685
- });
1686
- var layer = (options) => Layer2.scoped(ProcessRuntimeTag, make(options));
1687
-
1688
- export {
1689
- EvidenceCollectorTag,
1690
- evidenceCollectorLayer,
1691
- makeEvidenceCollector,
1692
- getMeta,
1693
- getDefinition,
1694
- attachMeta,
1695
- ProcessRuntimeTag,
1696
- layer
1697
- };
1698
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL3Byb2Nlc3MvbWV0YS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9vYnNlcnZhYmlsaXR5L2V2aWRlbmNlQ29sbGVjdG9yLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL1Byb2Nlc3NSdW50aW1lLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL2lkZW50aXR5LnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL2NvbmN1cnJlbmN5LnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL2V2ZW50cy50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvcHJvY2Vzcy9zZWxlY3RvclNjaGVtYS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvcHJvY2Vzcy9zdXBlcnZpc2lvbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHR5cGUgeyBFZmZlY3QgfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgdHlwZSB7IFByb2Nlc3NEZWZpbml0aW9uLCBQcm9jZXNzU2NvcGUgfSBmcm9tICcuL3Byb3RvY29sLmpzJ1xuXG5leHBvcnQgdHlwZSBQcm9jZXNzTWV0YSA9IHtcbiAgcmVhZG9ubHkgZGVmaW5pdGlvbjogUHJvY2Vzc0RlZmluaXRpb25cbiAgLyoqXG4gICAqIGluc3RhbGxhdGlvblNjb3BlOiBwYXJ0IG9mIFN0YXRpYyBJUi5cbiAgICogLSBGb3IgaW5zdGFuY2Utc2NvcGUgLyBzdWJ0cmVlLXNjb3BlIHNjZW5hcmlvcywgdGhlIHJ1bnRpbWUgb3ZlcndyaXRlcyB0aGlzIGZpZWxkIGR1cmluZyBpbnN0YWxsYXRpb24gd2l0aCBhIGRlcml2ZWQgZWZmZWN0LlxuICAgKiAtIFRoaXMgZmllbGQgaXMgZm9yIGV4cG9ydC9kaWFnbm9zdGljcyBvbmx5OyBpdCBkb2VzIG5vdCBwYXJ0aWNpcGF0ZSBpbiBzdGFibGUgaWRlbnRpdHkgZGVyaXZhdGlvbiAoc2VlIGlkZW50aXR5LnRzKS5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbGxhdGlvblNjb3BlPzogUHJvY2Vzc1Njb3BlXG4gIHJlYWRvbmx5IGtpbmQ/OiAncHJvY2VzcycgfCAnbGluaydcbn1cblxuZXhwb3J0IGNvbnN0IFBST0NFU1NfTUVUQSA9IFN5bWJvbC5mb3IoJ0Bsb2dpeGpzL2NvcmUvcHJvY2Vzc01ldGEnKVxuXG5leHBvcnQgdHlwZSBQcm9jZXNzRWZmZWN0PEUgPSBuZXZlciwgUiA9IG5ldmVyPiA9IEVmZmVjdC5FZmZlY3Q8dm9pZCwgRSwgUj4gJiB7XG4gIHJlYWRvbmx5IFtQUk9DRVNTX01FVEFdPzogUHJvY2Vzc01ldGFcbn1cblxuY29uc3QgZGVmaW5lSGlkZGVuID0gKHRhcmdldDogb2JqZWN0LCBrZXk6IHN5bWJvbCwgdmFsdWU6IHVua25vd24pOiB2b2lkID0+IHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCB7XG4gICAgdmFsdWUsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgfSlcbn1cblxuZXhwb3J0IGNvbnN0IGdldE1ldGEgPSAoZWZmZWN0OiBFZmZlY3QuRWZmZWN0PHZvaWQsIGFueSwgYW55Pik6IFByb2Nlc3NNZXRhIHwgdW5kZWZpbmVkID0+XG4gIChlZmZlY3QgYXMgUHJvY2Vzc0VmZmVjdClbUFJPQ0VTU19NRVRBXVxuXG5leHBvcnQgY29uc3QgZ2V0RGVmaW5pdGlvbiA9IChlZmZlY3Q6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgYW55LCBhbnk+KTogUHJvY2Vzc0RlZmluaXRpb24gfCB1bmRlZmluZWQgPT5cbiAgZ2V0TWV0YShlZmZlY3QpPy5kZWZpbml0aW9uXG5cbmV4cG9ydCBjb25zdCBhdHRhY2hNZXRhID0gPEUsIFI+KGVmZmVjdDogRWZmZWN0LkVmZmVjdDx2b2lkLCBFLCBSPiwgbWV0YTogUHJvY2Vzc01ldGEpOiBQcm9jZXNzRWZmZWN0PEUsIFI+ID0+IHtcbiAgZGVmaW5lSGlkZGVuKGVmZmVjdCBhcyBhbnksIFBST0NFU1NfTUVUQSwgbWV0YSlcbiAgcmV0dXJuIGVmZmVjdCBhcyBQcm9jZXNzRWZmZWN0PEUsIFI+XG59XG4iLCAiaW1wb3J0IHsgQ29udGV4dCwgRWZmZWN0LCBGaWJlclJlZiwgTGF5ZXIgfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgdHlwZSB7IEpzb25WYWx1ZSB9IGZyb20gJy4vanNvblZhbHVlLmpzJ1xuaW1wb3J0IHsgcHJvamVjdEpzb25WYWx1ZSB9IGZyb20gJy4vanNvblZhbHVlLmpzJ1xuaW1wb3J0IHR5cGUgeyBFdmlkZW5jZVBhY2thZ2UgfSBmcm9tICcuL2V2aWRlbmNlLmpzJ1xuaW1wb3J0IHR5cGUgeyBSdW5TZXNzaW9uIH0gZnJvbSAnLi9ydW5TZXNzaW9uLmpzJ1xuaW1wb3J0IHsgbWFrZUV2aWRlbmNlU2luayB9IGZyb20gJy4vcnVuU2Vzc2lvbi5qcydcbmltcG9ydCB7XG4gIGN1cnJlbnREaWFnbm9zdGljc0xldmVsLFxuICB0b1J1bnRpbWVEZWJ1Z0V2ZW50UmVmLFxuICB0eXBlIEV2ZW50IGFzIERlYnVnRXZlbnQsXG4gIHR5cGUgU2luayBhcyBEZWJ1Z1NpbmssXG59IGZyb20gJy4uL3J1bnRpbWUvY29yZS9EZWJ1Z1NpbmsuanMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgRXZpZGVuY2VDb2xsZWN0b3Ige1xuICByZWFkb25seSBzZXNzaW9uOiBSdW5TZXNzaW9uXG4gIHJlYWRvbmx5IGRlYnVnU2luazogRGVidWdTaW5rXG4gIHJlYWRvbmx5IHJlZ2lzdGVyQ29udmVyZ2VTdGF0aWNJcjogKHN0YXRpY0lyOiB1bmtub3duKSA9PiB2b2lkXG4gIHJlYWRvbmx5IHNldEtlcm5lbEltcGxlbWVudGF0aW9uUmVmOiAocmVmOiB1bmtub3duKSA9PiB2b2lkXG4gIHJlYWRvbmx5IHNldFJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlOiAoZXZpZGVuY2U6IHVua25vd24pID0+IHZvaWRcbiAgcmVhZG9ubHkgZXhwb3J0RXZpZGVuY2VQYWNrYWdlOiAob3B0aW9ucz86IHsgcmVhZG9ubHkgbWF4RXZlbnRzPzogbnVtYmVyIH0pID0+IEV2aWRlbmNlUGFja2FnZVxuICByZWFkb25seSBjbGVhcjogKCkgPT4gdm9pZFxufVxuXG5jbGFzcyBFdmlkZW5jZUNvbGxlY3RvclRhZ0ltcGwgZXh0ZW5kcyBDb250ZXh0LlRhZygnQGxvZ2l4anMvY29yZS9FdmlkZW5jZUNvbGxlY3RvcicpPFxuICBFdmlkZW5jZUNvbGxlY3RvclRhZ0ltcGwsXG4gIEV2aWRlbmNlQ29sbGVjdG9yXG4+KCkge31cblxuZXhwb3J0IGNvbnN0IEV2aWRlbmNlQ29sbGVjdG9yVGFnID0gRXZpZGVuY2VDb2xsZWN0b3JUYWdJbXBsXG5cbmV4cG9ydCBjb25zdCBldmlkZW5jZUNvbGxlY3RvckxheWVyID0gKFxuICBjb2xsZWN0b3I6IEV2aWRlbmNlQ29sbGVjdG9yLFxuKTogTGF5ZXIuTGF5ZXI8RXZpZGVuY2VDb2xsZWN0b3JUYWdJbXBsLCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLnN1Y2NlZWQoRXZpZGVuY2VDb2xsZWN0b3JUYWcsIGNvbGxlY3RvcikgYXMgTGF5ZXIuTGF5ZXI8RXZpZGVuY2VDb2xsZWN0b3JUYWdJbXBsLCBuZXZlciwgbmV2ZXI+XG5cbmNvbnN0IGlzUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT5cbiAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSlcblxuZXhwb3J0IGNvbnN0IG1ha2VFdmlkZW5jZUNvbGxlY3RvciA9IChzZXNzaW9uOiBSdW5TZXNzaW9uKTogRXZpZGVuY2VDb2xsZWN0b3IgPT4ge1xuICBjb25zdCBzaW5rID0gbWFrZUV2aWRlbmNlU2luayhzZXNzaW9uKVxuXG4gIGNvbnN0IGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdCA9IG5ldyBNYXA8c3RyaW5nLCBKc29uVmFsdWU+KClcbiAgbGV0IGtlcm5lbEltcGxlbWVudGF0aW9uUmVmOiBKc29uVmFsdWUgfCB1bmRlZmluZWRcbiAgbGV0IHJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlOiBKc29uVmFsdWUgfCB1bmRlZmluZWRcblxuICBjb25zdCBleHBvcnRCdWRnZXQgPSB7XG4gICAgZHJvcHBlZDogMCxcbiAgICBvdmVyc2l6ZWQ6IDAsXG4gICAgbm9uU2VyaWFsaXphYmxlOiAwLFxuICB9XG5cbiAgY29uc3QgZGVidWdTaW5rOiBEZWJ1Z1NpbmsgPSB7XG4gICAgcmVjb3JkOiAoZXZlbnQ6IERlYnVnRXZlbnQpID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGxldmVsID0geWllbGQqIEZpYmVyUmVmLmdldChjdXJyZW50RGlhZ25vc3RpY3NMZXZlbClcbiAgICAgICAgY29uc3QgaW5zdGFuY2VJZFJhdyA9IChldmVudCBhcyBhbnkpLmluc3RhbmNlSWRcbiAgICAgICAgY29uc3QgaW5zdGFuY2VJZCA9IHR5cGVvZiBpbnN0YW5jZUlkUmF3ID09PSAnc3RyaW5nJyAmJiBpbnN0YW5jZUlkUmF3Lmxlbmd0aCA+IDAgPyBpbnN0YW5jZUlkUmF3IDogJ3Vua25vd24nXG4gICAgICAgIGNvbnN0IGV2ZW50U2VxID0gbGV2ZWwgPT09ICdvZmYnID8gdW5kZWZpbmVkIDogc2Vzc2lvbi5sb2NhbC5uZXh0U2VxKCdldmVudFNlcScsIGluc3RhbmNlSWQpXG4gICAgICAgIGNvbnN0IHJlZiA9IHRvUnVudGltZURlYnVnRXZlbnRSZWYoZXZlbnQsIHtcbiAgICAgICAgICBkaWFnbm9zdGljc0xldmVsOiBsZXZlbCxcbiAgICAgICAgICBldmVudFNlcSxcbiAgICAgICAgICBvbk1ldGFQcm9qZWN0aW9uOiAoeyBzdGF0cyB9KSA9PiB7XG4gICAgICAgICAgICBleHBvcnRCdWRnZXQuZHJvcHBlZCArPSBzdGF0cy5kcm9wcGVkXG4gICAgICAgICAgICBleHBvcnRCdWRnZXQub3ZlcnNpemVkICs9IHN0YXRzLm92ZXJzaXplZFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIGlmICghcmVmKSByZXR1cm5cblxuICAgICAgICBjb25zdCBwcm9qZWN0ZWQgPSBwcm9qZWN0SnNvblZhbHVlKHJlZilcbiAgICAgICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgKz0gcHJvamVjdGVkLnN0YXRzLmRyb3BwZWRcbiAgICAgICAgZXhwb3J0QnVkZ2V0Lm92ZXJzaXplZCArPSBwcm9qZWN0ZWQuc3RhdHMub3ZlcnNpemVkXG4gICAgICAgIGV4cG9ydEJ1ZGdldC5ub25TZXJpYWxpemFibGUgKz0gcHJvamVjdGVkLnN0YXRzLm5vblNlcmlhbGl6YWJsZVxuXG4gICAgICAgIHNpbmsucmVjb3JkKCdkZWJ1ZzpldmVudCcsIHByb2plY3RlZC52YWx1ZSwge1xuICAgICAgICAgIHRpbWVzdGFtcDogcmVmLnRpbWVzdGFtcCxcbiAgICAgICAgfSlcbiAgICAgIH0pLFxuICB9XG5cbiAgY29uc3QgcmVnaXN0ZXJDb252ZXJnZVN0YXRpY0lyID0gKHN0YXRpY0lyOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgaWYgKCFpc1JlY29yZChzdGF0aWNJcikpIHJldHVyblxuICAgIGNvbnN0IGRpZ2VzdCA9IHN0YXRpY0lyLnN0YXRpY0lyRGlnZXN0XG4gICAgaWYgKHR5cGVvZiBkaWdlc3QgIT09ICdzdHJpbmcnIHx8IGRpZ2VzdC5sZW5ndGggPT09IDApIHJldHVyblxuICAgIGNvbnN0IHByb2plY3RlZCA9IHByb2plY3RKc29uVmFsdWUoc3RhdGljSXIpXG4gICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgKz0gcHJvamVjdGVkLnN0YXRzLmRyb3BwZWRcbiAgICBleHBvcnRCdWRnZXQub3ZlcnNpemVkICs9IHByb2plY3RlZC5zdGF0cy5vdmVyc2l6ZWRcbiAgICBleHBvcnRCdWRnZXQubm9uU2VyaWFsaXphYmxlICs9IHByb2plY3RlZC5zdGF0cy5ub25TZXJpYWxpemFibGVcbiAgICBjb252ZXJnZVN0YXRpY0lyQnlEaWdlc3Quc2V0KGRpZ2VzdCwgcHJvamVjdGVkLnZhbHVlKVxuICB9XG5cbiAgY29uc3Qgc2V0S2VybmVsSW1wbGVtZW50YXRpb25SZWYgPSAocmVmOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgY29uc3QgcHJvamVjdGVkID0gcHJvamVjdEpzb25WYWx1ZShyZWYpXG4gICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgKz0gcHJvamVjdGVkLnN0YXRzLmRyb3BwZWRcbiAgICBleHBvcnRCdWRnZXQub3ZlcnNpemVkICs9IHByb2plY3RlZC5zdGF0cy5vdmVyc2l6ZWRcbiAgICBleHBvcnRCdWRnZXQubm9uU2VyaWFsaXphYmxlICs9IHByb2plY3RlZC5zdGF0cy5ub25TZXJpYWxpemFibGVcbiAgICBrZXJuZWxJbXBsZW1lbnRhdGlvblJlZiA9IHByb2plY3RlZC52YWx1ZVxuICB9XG5cbiAgY29uc3Qgc2V0UnVudGltZVNlcnZpY2VzRXZpZGVuY2UgPSAoZXZpZGVuY2U6IHVua25vd24pOiB2b2lkID0+IHtcbiAgICBjb25zdCBwcm9qZWN0ZWQgPSBwcm9qZWN0SnNvblZhbHVlKGV2aWRlbmNlKVxuICAgIGV4cG9ydEJ1ZGdldC5kcm9wcGVkICs9IHByb2plY3RlZC5zdGF0cy5kcm9wcGVkXG4gICAgZXhwb3J0QnVkZ2V0Lm92ZXJzaXplZCArPSBwcm9qZWN0ZWQuc3RhdHMub3ZlcnNpemVkXG4gICAgZXhwb3J0QnVkZ2V0Lm5vblNlcmlhbGl6YWJsZSArPSBwcm9qZWN0ZWQuc3RhdHMubm9uU2VyaWFsaXphYmxlXG4gICAgcnVudGltZVNlcnZpY2VzRXZpZGVuY2UgPSBwcm9qZWN0ZWQudmFsdWVcbiAgfVxuXG4gIGNvbnN0IGV4cG9ydEV2aWRlbmNlUGFja2FnZSA9IChvcHRpb25zPzogeyByZWFkb25seSBtYXhFdmVudHM/OiBudW1iZXIgfSk6IEV2aWRlbmNlUGFja2FnZSA9PiB7XG4gICAgY29uc3QgY29udmVyZ2VTdW1tYXJ5ID1cbiAgICAgIGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdC5zaXplID4gMFxuICAgICAgICA/ICh7XG4gICAgICAgICAgICBzdGF0aWNJckJ5RGlnZXN0OiBPYmplY3QuZnJvbUVudHJpZXMoY29udmVyZ2VTdGF0aWNJckJ5RGlnZXN0KSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgSnNvblZhbHVlKVxuICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgY29uc3QgcnVudGltZVN1bW1hcnkgPVxuICAgICAga2VybmVsSW1wbGVtZW50YXRpb25SZWYgIT0gbnVsbCB8fCBydW50aW1lU2VydmljZXNFdmlkZW5jZSAhPSBudWxsXG4gICAgICAgID8gKHtcbiAgICAgICAgICAgIC4uLihrZXJuZWxJbXBsZW1lbnRhdGlvblJlZiAhPSBudWxsID8geyBrZXJuZWxJbXBsZW1lbnRhdGlvblJlZiB9IDoge30pLFxuICAgICAgICAgICAgLi4uKHJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlICE9IG51bGwgPyB7IHNlcnZpY2VzOiBydW50aW1lU2VydmljZXNFdmlkZW5jZSB9IDoge30pLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBKc29uVmFsdWUpXG4gICAgICAgIDogdW5kZWZpbmVkXG5cbiAgICBjb25zdCBzdW1tYXJ5ID1cbiAgICAgIGNvbnZlcmdlU3VtbWFyeSAhPSBudWxsIHx8IHJ1bnRpbWVTdW1tYXJ5ICE9IG51bGxcbiAgICAgICAgPyAoe1xuICAgICAgICAgICAgLi4uKGNvbnZlcmdlU3VtbWFyeSAhPSBudWxsID8geyBjb252ZXJnZTogY29udmVyZ2VTdW1tYXJ5IH0gOiB7fSksXG4gICAgICAgICAgICAuLi4ocnVudGltZVN1bW1hcnkgIT0gbnVsbCA/IHsgcnVudGltZTogcnVudGltZVN1bW1hcnkgfSA6IHt9KSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgSnNvblZhbHVlKVxuICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgcmV0dXJuIHNpbmsuZXhwb3J0KHtcbiAgICAgIG1heEV2ZW50czogb3B0aW9ucz8ubWF4RXZlbnRzLFxuICAgICAgc3VtbWFyeSxcbiAgICB9KVxuICB9XG5cbiAgY29uc3QgY2xlYXIgPSAoKTogdm9pZCA9PiB7XG4gICAgc2luay5jbGVhcigpXG4gICAgY29udmVyZ2VTdGF0aWNJckJ5RGlnZXN0LmNsZWFyKClcbiAgICBrZXJuZWxJbXBsZW1lbnRhdGlvblJlZiA9IHVuZGVmaW5lZFxuICAgIHJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlID0gdW5kZWZpbmVkXG4gICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgPSAwXG4gICAgZXhwb3J0QnVkZ2V0Lm92ZXJzaXplZCA9IDBcbiAgICBleHBvcnRCdWRnZXQubm9uU2VyaWFsaXphYmxlID0gMFxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzZXNzaW9uLFxuICAgIGRlYnVnU2luayxcbiAgICByZWdpc3RlckNvbnZlcmdlU3RhdGljSXIsXG4gICAgc2V0S2VybmVsSW1wbGVtZW50YXRpb25SZWYsXG4gICAgc2V0UnVudGltZVNlcnZpY2VzRXZpZGVuY2UsXG4gICAgZXhwb3J0RXZpZGVuY2VQYWNrYWdlLFxuICAgIGNsZWFyLFxuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgQ2F1c2UsXG4gIENvbnRleHQsXG4gIERlZmVycmVkLFxuICBEdXJhdGlvbixcbiAgRWZmZWN0LFxuICBGaWJlcixcbiAgRmliZXJSZWYsXG4gIExheWVyLFxuICBPcHRpb24sXG4gIFB1YlN1YixcbiAgUXVldWUsXG4gIFJlZixcbiAgU2NvcGUsXG4gIFN0cmVhbSxcbn0gZnJvbSAnZWZmZWN0J1xuaW1wb3J0ICogYXMgRGVidWcgZnJvbSAnLi4vRGVidWdTaW5rLmpzJ1xuaW1wb3J0IHsgdG9TZXJpYWxpemFibGVFcnJvclN1bW1hcnkgfSBmcm9tICcuLi9lcnJvclN1bW1hcnkuanMnXG5pbXBvcnQgKiBhcyBUYXNrUnVubmVyIGZyb20gJy4uL1Rhc2tSdW5uZXIuanMnXG5pbXBvcnQgeyBpc0RldkVudiB9IGZyb20gJy4uL2Vudi5qcydcbmltcG9ydCB7IGdldFJ1bnRpbWVJbnRlcm5hbHMgfSBmcm9tICcuLi9ydW50aW1lSW50ZXJuYWxzQWNjZXNzb3IuanMnXG5pbXBvcnQgKiBhcyBJZGVudGl0eSBmcm9tICcuL2lkZW50aXR5LmpzJ1xuaW1wb3J0ICogYXMgUHJvY2Vzc0NvbmN1cnJlbmN5IGZyb20gJy4vY29uY3VycmVuY3kuanMnXG5pbXBvcnQgKiBhcyBQcm9jZXNzRXZlbnRzIGZyb20gJy4vZXZlbnRzLmpzJ1xuaW1wb3J0ICogYXMgTWV0YSBmcm9tICcuL21ldGEuanMnXG5pbXBvcnQgeyBtYWtlU2NoZW1hU2VsZWN0b3IsIHJlc29sdmVTY2hlbWFBc3QgfSBmcm9tICcuL3NlbGVjdG9yU2NoZW1hLmpzJ1xuaW1wb3J0IHR5cGUge1xuICBQcm9jZXNzQ29udHJvbFJlcXVlc3QsXG4gIFByb2Nlc3NEZWZpbml0aW9uLFxuICBQcm9jZXNzRXZlbnQsXG4gIFByb2Nlc3NJbnN0YWxsYXRpb24sXG4gIFByb2Nlc3NJbnN0YW5jZUlkZW50aXR5LFxuICBQcm9jZXNzSW5zdGFuY2VTdGF0dXMsXG4gIFByb2Nlc3NQbGF0Zm9ybUV2ZW50LFxuICBQcm9jZXNzU2NvcGUsXG4gIFByb2Nlc3NUcmlnZ2VyLFxuICBQcm9jZXNzVHJpZ2dlclNwZWMsXG4gIFNlcmlhbGl6YWJsZUVycm9yU3VtbWFyeSxcbn0gZnJvbSAnLi9wcm90b2NvbC5qcydcbmltcG9ydCAqIGFzIFN1cGVydmlzaW9uIGZyb20gJy4vc3VwZXJ2aXNpb24uanMnXG5cbnR5cGUgSW5zdGFsbGF0aW9uS2V5ID0gc3RyaW5nXG50eXBlIFByb2Nlc3NJbnN0YW5jZUlkID0gc3RyaW5nXG5cbnR5cGUgUHJvY2Vzc0luc3RhbGxNb2RlID0gJ3N3aXRjaCcgfCAnZXhoYXVzdCdcblxudHlwZSBJbnN0YWxsYXRpb25TdGF0ZSA9IHtcbiAgcmVhZG9ubHkgaWRlbnRpdHk6IHtcbiAgICByZWFkb25seSBwcm9jZXNzSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IHNjb3BlOiBQcm9jZXNzU2NvcGVcbiAgfVxuICByZWFkb25seSBzY29wZUtleTogc3RyaW5nXG4gIHJlYWRvbmx5IGRlZmluaXRpb246IFByb2Nlc3NEZWZpbml0aW9uXG4gIGVudjogQ29udGV4dC5Db250ZXh0PGFueT5cbiAgZm9ya1Njb3BlOiBTY29wZS5TY29wZVxuICByZWFkb25seSBwcm9jZXNzOiBFZmZlY3QuRWZmZWN0PHZvaWQsIGFueSwgdW5rbm93bj5cbiAgcmVhZG9ubHkga2luZDogTWV0YS5Qcm9jZXNzTWV0YVsna2luZCddXG4gIGVuYWJsZWQ6IGJvb2xlYW5cbiAgaW5zdGFsbGVkQXQ/OiBzdHJpbmdcbiAgbmV4dFJ1blNlcTogbnVtYmVyXG4gIHN1cGVydmlzaW9uOiBTdXBlcnZpc2lvbi5TdXBlcnZpc2lvblN0YXRlXG4gIGN1cnJlbnRJbnN0YW5jZUlkPzogUHJvY2Vzc0luc3RhbmNlSWRcbiAgcGVuZGluZ1N0YXJ0PzogeyByZWFkb25seSBmb3JrU2NvcGU6IFNjb3BlLlNjb3BlIH1cbn1cblxudHlwZSBJbnN0YW5jZVN0YXRlID0ge1xuICByZWFkb25seSBpbnN0YWxsYXRpb25LZXk6IEluc3RhbGxhdGlvbktleVxuICByZWFkb25seSBwcm9jZXNzSW5zdGFuY2VJZDogUHJvY2Vzc0luc3RhbmNlSWRcbiAgcmVhZG9ubHkgaWRlbnRpdHk6IFByb2Nlc3NJbnN0YW5jZUlkZW50aXR5XG4gIHJlYWRvbmx5IHByb2Nlc3NJZDogc3RyaW5nXG4gIHJlYWRvbmx5IHNjb3BlOiBQcm9jZXNzU2NvcGVcbiAgcmVhZG9ubHkgZm9ya1Njb3BlOiBTY29wZS5TY29wZVxuICByZWFkb25seSBwbGF0Zm9ybVRyaWdnZXJzUXVldWU6IFF1ZXVlLlF1ZXVlPFByb2Nlc3NUcmlnZ2VyPlxuICBzdGF0dXM6IFByb2Nlc3NJbnN0YW5jZVN0YXR1c1xuICBuZXh0RXZlbnRTZXE6IG51bWJlclxuICBuZXh0VHJpZ2dlclNlcTogbnVtYmVyXG4gIGZpYmVyPzogRmliZXIuUnVudGltZUZpYmVyPHVua25vd24sIHVua25vd24+XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvY2Vzc1J1bnRpbWUge1xuICByZWFkb25seSBpbnN0YWxsOiA8RSwgUj4oXG4gICAgcHJvY2VzczogRWZmZWN0LkVmZmVjdDx2b2lkLCBFLCBSPixcbiAgICBvcHRpb25zOiB7XG4gICAgICByZWFkb25seSBzY29wZTogUHJvY2Vzc1Njb3BlXG4gICAgICByZWFkb25seSBlbmFibGVkPzogYm9vbGVhblxuICAgICAgcmVhZG9ubHkgaW5zdGFsbGVkQXQ/OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IG1vZGU/OiBQcm9jZXNzSW5zdGFsbE1vZGVcbiAgICB9LFxuICApID0+IEVmZmVjdC5FZmZlY3Q8UHJvY2Vzc0luc3RhbGxhdGlvbiB8IHVuZGVmaW5lZCwgbmV2ZXIsIFI+XG4gIHJlYWRvbmx5IGxpc3RJbnN0YWxsYXRpb25zOiAoZmlsdGVyPzoge1xuICAgIHJlYWRvbmx5IHNjb3BlVHlwZT86IFByb2Nlc3NTY29wZVsndHlwZSddXG4gICAgcmVhZG9ubHkgc2NvcGVLZXk/OiBzdHJpbmdcbiAgfSkgPT4gRWZmZWN0LkVmZmVjdDxSZWFkb25seUFycmF5PFByb2Nlc3NJbnN0YWxsYXRpb24+PlxuICByZWFkb25seSBnZXRJbnN0YW5jZVN0YXR1czogKHByb2Nlc3NJbnN0YW5jZUlkOiBzdHJpbmcpID0+IEVmZmVjdC5FZmZlY3Q8UHJvY2Vzc0luc3RhbmNlU3RhdHVzIHwgdW5kZWZpbmVkPlxuICByZWFkb25seSBjb250cm9sSW5zdGFuY2U6IChwcm9jZXNzSW5zdGFuY2VJZDogc3RyaW5nLCByZXF1ZXN0OiBQcm9jZXNzQ29udHJvbFJlcXVlc3QpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZD5cbiAgcmVhZG9ubHkgZGVsaXZlclBsYXRmb3JtRXZlbnQ6IChldmVudDogUHJvY2Vzc1BsYXRmb3JtRXZlbnQpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZD5cbiAgcmVhZG9ubHkgZXZlbnRzOiBTdHJlYW0uU3RyZWFtPFByb2Nlc3NFdmVudD5cbiAgcmVhZG9ubHkgZ2V0RXZlbnRzU25hcHNob3Q6ICgpID0+IEVmZmVjdC5FZmZlY3Q8UmVhZG9ubHlBcnJheTxQcm9jZXNzRXZlbnQ+PlxufVxuXG5leHBvcnQgY2xhc3MgUHJvY2Vzc1J1bnRpbWVUYWcgZXh0ZW5kcyBDb250ZXh0LlRhZygnQGxvZ2l4anMvY29yZS9Qcm9jZXNzUnVudGltZScpPFByb2Nlc3NSdW50aW1lVGFnLCBQcm9jZXNzUnVudGltZT4oKSB7fVxuXG5jb25zdCBjdXJyZW50UHJvY2Vzc1RyaWdnZXIgPSBGaWJlclJlZi51bnNhZmVNYWtlPFByb2Nlc3NUcmlnZ2VyIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpXG5jb25zdCBjdXJyZW50UHJvY2Vzc0V2ZW50QnVkZ2V0ID0gRmliZXJSZWYudW5zYWZlTWFrZTxSZWYuUmVmPFByb2Nlc3NFdmVudHMuUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0U3RhdGU+IHwgdW5kZWZpbmVkPihcbiAgdW5kZWZpbmVkLFxuKVxuY29uc3QgUlVOVElNRV9CT09UX0VWRU5UID0gJ3J1bnRpbWU6Ym9vdCcgYXMgY29uc3RcblxuY29uc3QgZGVyaXZlRGVidWdNb2R1bGVJZCA9IChwcm9jZXNzSWQ6IHN0cmluZyk6IHN0cmluZyA9PiBgcHJvY2Vzczoke3Byb2Nlc3NJZH1gXG5cbnR5cGUgTm9uUGxhdGZvcm1UcmlnZ2VyU3BlYyA9IEV4Y2x1ZGU8UHJvY2Vzc1RyaWdnZXJTcGVjLCB7IHJlYWRvbmx5IGtpbmQ6ICdwbGF0Zm9ybUV2ZW50JyB9PlxuXG5jb25zdCBkZXJpdmVUeG5BbmNob3IgPSAoZXZlbnQ6IFByb2Nlc3NFdmVudCk6IHsgcmVhZG9ubHkgdHhuU2VxPzogbnVtYmVyOyByZWFkb25seSB0eG5JZD86IHN0cmluZyB9ID0+IHtcbiAgY29uc3QgdHJpZ2dlcjogYW55ID0gZXZlbnQudHJpZ2dlclxuICBpZiAoIXRyaWdnZXIpIHJldHVybiB7fVxuICBpZiAoXG4gICAgKHRyaWdnZXIua2luZCA9PT0gJ21vZHVsZUFjdGlvbicgfHwgdHJpZ2dlci5raW5kID09PSAnbW9kdWxlU3RhdGVDaGFuZ2UnKSAmJlxuICAgIHR5cGVvZiB0cmlnZ2VyLmluc3RhbmNlSWQgPT09ICdzdHJpbmcnICYmXG4gICAgdHlwZW9mIHRyaWdnZXIudHhuU2VxID09PSAnbnVtYmVyJyAmJlxuICAgIE51bWJlci5pc0Zpbml0ZSh0cmlnZ2VyLnR4blNlcSkgJiZcbiAgICB0cmlnZ2VyLnR4blNlcSA+PSAxXG4gICkge1xuICAgIGNvbnN0IHR4blNlcSA9IE1hdGguZmxvb3IodHJpZ2dlci50eG5TZXEpXG4gICAgcmV0dXJuIHtcbiAgICAgIHR4blNlcSxcbiAgICAgIHR4bklkOiBgJHt0cmlnZ2VyLmluc3RhbmNlSWR9Ojp0JHt0eG5TZXF9YCxcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHt9XG59XG5cbmNvbnN0IHNob3VsZE5vb3BEdWVUb1N5bmNUeG4gPSAoc2NvcGU6IFByb2Nlc3NTY29wZSwga2luZDogc3RyaW5nKTogRWZmZWN0LkVmZmVjdDxib29sZWFuPiA9PiB7XG4gIGNvbnN0IG1vZHVsZUlkID0gc2NvcGUudHlwZSA9PT0gJ21vZHVsZUluc3RhbmNlJyA/IHNjb3BlLm1vZHVsZUlkIDogdW5kZWZpbmVkXG4gIGNvbnN0IGluc3RhbmNlSWQgPSBzY29wZS50eXBlID09PSAnbW9kdWxlSW5zdGFuY2UnID8gc2NvcGUuaW5zdGFuY2VJZCA6IHVuZGVmaW5lZFxuICByZXR1cm4gVGFza1J1bm5lci5zaG91bGROb29wSW5TeW5jVHJhbnNhY3Rpb25GaWJlcih7XG4gICAgbW9kdWxlSWQsXG4gICAgaW5zdGFuY2VJZCxcbiAgICBjb2RlOiAncHJvY2Vzczo6aW52YWxpZF91c2FnZScsXG4gICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgbWVzc2FnZTpcbiAgICAgICdQcm9jZXNzUnVudGltZSBzY2hlZHVsaW5nIGlzIG5vdCBhbGxvd2VkIGluc2lkZSBhIHN5bmNocm9ub3VzIFN0YXRlVHJhbnNhY3Rpb24gYm9keSAoaXQgbWF5IGRlYWRsb2NrIHRoZSB0eG5RdWV1ZSkuJyxcbiAgICBoaW50OlxuICAgICAgXCJUcmlnZ2VyL3NjaGVkdWxlIFByb2Nlc3Mgb3V0c2lkZSB0aGUgdHJhbnNhY3Rpb24gd2luZG93IChlLmcuIGluIGEgd2F0Y2hlcidzIHJ1biBzZWN0aW9uIG9yIGEgc2VwYXJhdGUgZmliZXIpOyBcIiArXG4gICAgICAnZG8gbm90IHRyaWdnZXIgUHJvY2VzcyBkaXJlY3RseSBpbnNpZGUgYSByZWR1Y2VyIC8gc3luY2hyb25vdXMgdHJhbnNhY3Rpb24gYm9keS4nLFxuICAgIGtpbmQsXG4gIH0pXG59XG5cbmNvbnN0IHJlc29sdmVSdW50aW1lU3RhdGVTY2hlbWFBc3QgPSAocnVudGltZTogdW5rbm93bik6IFJldHVyblR5cGU8dHlwZW9mIHJlc29sdmVTY2hlbWFBc3Q+ID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBpbnRlcm5hbHMgPSBnZXRSdW50aW1lSW50ZXJuYWxzKHJ1bnRpbWUgYXMgYW55KVxuICAgIHJldHVybiByZXNvbHZlU2NoZW1hQXN0KGludGVybmFscy5zdGF0ZVNjaGVtYSlcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG59XG5cbmNvbnN0IHdpdGhNb2R1bGVIaW50ID0gKGVycm9yOiBFcnJvciwgbW9kdWxlSWQ6IHN0cmluZyk6IEVycm9yID0+IHtcbiAgY29uc3QgaGludCA9IChlcnJvciBhcyBhbnkpLmhpbnRcbiAgaWYgKHR5cGVvZiBoaW50ID09PSAnc3RyaW5nJyAmJiBoaW50Lmxlbmd0aCA+IDApIHtcbiAgICBpZiAoIWhpbnQuaW5jbHVkZXMoJ21vZHVsZUlkPScpKSB7XG4gICAgICA7KGVycm9yIGFzIGFueSkuaGludCA9IGBtb2R1bGVJZD0ke21vZHVsZUlkfVxcbiR7aGludH1gXG4gICAgfVxuICAgIHJldHVybiBlcnJvclxuICB9XG4gIDsoZXJyb3IgYXMgYW55KS5oaW50ID0gYG1vZHVsZUlkPSR7bW9kdWxlSWR9YFxuICByZXR1cm4gZXJyb3Jcbn1cblxuY29uc3QgYWN0aW9uSWRGcm9tVW5rbm93biA9IChhY3Rpb246IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoIWFjdGlvbiB8fCB0eXBlb2YgYWN0aW9uICE9PSAnb2JqZWN0JykgcmV0dXJuIHVuZGVmaW5lZFxuICBjb25zdCBhbnlBY3Rpb24gPSBhY3Rpb24gYXMgYW55XG4gIGlmICh0eXBlb2YgYW55QWN0aW9uLl90YWcgPT09ICdzdHJpbmcnICYmIGFueUFjdGlvbi5fdGFnLmxlbmd0aCA+IDApIHJldHVybiBhbnlBY3Rpb24uX3RhZ1xuICBpZiAodHlwZW9mIGFueUFjdGlvbi50eXBlID09PSAnc3RyaW5nJyAmJiBhbnlBY3Rpb24udHlwZS5sZW5ndGggPiAwKSByZXR1cm4gYW55QWN0aW9uLnR5cGVcbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5leHBvcnQgY29uc3QgbWFrZSA9IChvcHRpb25zPzoge1xuICByZWFkb25seSBtYXhFdmVudEhpc3Rvcnk/OiBudW1iZXJcbn0pOiBFZmZlY3QuRWZmZWN0PFByb2Nlc3NSdW50aW1lLCBuZXZlciwgU2NvcGUuU2NvcGU+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBydW50aW1lU2NvcGUgPSB5aWVsZCogRWZmZWN0LnNjb3BlXG4gICAgY29uc3QgbWF4RXZlbnRIaXN0b3J5ID1cbiAgICAgIHR5cGVvZiBvcHRpb25zPy5tYXhFdmVudEhpc3RvcnkgPT09ICdudW1iZXInICYmXG4gICAgICBOdW1iZXIuaXNGaW5pdGUob3B0aW9ucy5tYXhFdmVudEhpc3RvcnkpICYmXG4gICAgICBvcHRpb25zLm1heEV2ZW50SGlzdG9yeSA+PSAwXG4gICAgICAgID8gTWF0aC5mbG9vcihvcHRpb25zLm1heEV2ZW50SGlzdG9yeSlcbiAgICAgICAgOiA1MDBcblxuICAgIGNvbnN0IGluc3RhbGxhdGlvbnMgPSBuZXcgTWFwPEluc3RhbGxhdGlvbktleSwgSW5zdGFsbGF0aW9uU3RhdGU+KClcbiAgICBjb25zdCBpbnN0YW5jZXMgPSBuZXcgTWFwPFByb2Nlc3NJbnN0YW5jZUlkLCBJbnN0YW5jZVN0YXRlPigpXG5cbiAgICBjb25zdCBldmVudHNCdWZmZXI6IFByb2Nlc3NFdmVudFtdID0gW11cbiAgICBjb25zdCBldmVudHNIdWIgPSB5aWVsZCogUHViU3ViLnNsaWRpbmc8UHJvY2Vzc0V2ZW50PihNYXRoLm1heCgxLCBNYXRoLm1pbigyMDQ4LCBtYXhFdmVudEhpc3RvcnkpKSlcblxuICAgIGNvbnN0IHRyaW1FdmVudHMgPSAoKSA9PiB7XG4gICAgICBpZiAobWF4RXZlbnRIaXN0b3J5IDw9IDApIHtcbiAgICAgICAgZXZlbnRzQnVmZmVyLmxlbmd0aCA9IDBcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBpZiAoZXZlbnRzQnVmZmVyLmxlbmd0aCA8PSBtYXhFdmVudEhpc3RvcnkpIHJldHVyblxuICAgICAgY29uc3QgZXhjZXNzID0gZXZlbnRzQnVmZmVyLmxlbmd0aCAtIG1heEV2ZW50SGlzdG9yeVxuICAgICAgZXZlbnRzQnVmZmVyLnNwbGljZSgwLCBleGNlc3MpXG4gICAgfVxuXG4gICAgY29uc3QgcmVjb3JkRGVidWdFdmVudCA9IChldmVudDogUHJvY2Vzc0V2ZW50KTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBkaWFnbm9zdGljc0xldmVsID0geWllbGQqIEZpYmVyUmVmLmdldChEZWJ1Zy5jdXJyZW50RGlhZ25vc3RpY3NMZXZlbClcblxuICAgICAgICAvLyBkaWFnbm9zdGljcz1vZmY6IGF2b2lkIGVudGVyaW5nIERlYnVnIHNpbmtzIChuZWFyLXplcm8gY29zdCk7IGVycm9yIGNhc2VzIGFyZSBleHBvc2VkIHZpYSBkaWFnbm9zdGljIGV2ZW50cy5cbiAgICAgICAgaWYgKGRpYWdub3N0aWNzTGV2ZWwgPT09ICdvZmYnKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcm9jZXNzSWQgPSBldmVudC5pZGVudGl0eS5pZGVudGl0eS5wcm9jZXNzSWRcbiAgICAgICAgY29uc3QgcHJvY2Vzc0luc3RhbmNlSWQgPSBJZGVudGl0eS5wcm9jZXNzSW5zdGFuY2VJZEZyb21JZGVudGl0eShldmVudC5pZGVudGl0eSlcbiAgICAgICAgY29uc3QgbW9kdWxlSWQgPSBkZXJpdmVEZWJ1Z01vZHVsZUlkKHByb2Nlc3NJZClcbiAgICAgICAgY29uc3QgeyB0eG5TZXEsIHR4bklkIH0gPSBkZXJpdmVUeG5BbmNob3IoZXZlbnQpXG5cbiAgICAgICAgeWllbGQqIERlYnVnLnJlY29yZCh7XG4gICAgICAgICAgdHlwZTogZXZlbnQudHlwZSxcbiAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICBpbnN0YW5jZUlkOiBwcm9jZXNzSW5zdGFuY2VJZCxcbiAgICAgICAgICBpZGVudGl0eTogZXZlbnQuaWRlbnRpdHksXG4gICAgICAgICAgc2V2ZXJpdHk6IGV2ZW50LnNldmVyaXR5LFxuICAgICAgICAgIGV2ZW50U2VxOiBldmVudC5ldmVudFNlcSxcbiAgICAgICAgICB0aW1lc3RhbXBNczogZXZlbnQudGltZXN0YW1wTXMsXG4gICAgICAgICAgdHJpZ2dlcjogZXZlbnQudHJpZ2dlcixcbiAgICAgICAgICBkaXNwYXRjaDogZXZlbnQuZGlzcGF0Y2gsXG4gICAgICAgICAgZXJyb3I6IGV2ZW50LmVycm9yLFxuICAgICAgICAgIHR4blNlcSxcbiAgICAgICAgICB0eG5JZCxcbiAgICAgICAgfSBhcyBhbnkpXG4gICAgICB9KVxuXG4gICAgY29uc3QgcHVibGlzaEV2ZW50ID0gKGV2ZW50OiBQcm9jZXNzRXZlbnQpOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGV2ZW50c0J1ZmZlci5wdXNoKGV2ZW50KVxuICAgICAgICB0cmltRXZlbnRzKClcbiAgICAgICAgeWllbGQqIFB1YlN1Yi5wdWJsaXNoKGV2ZW50c0h1YiwgZXZlbnQpXG4gICAgICAgIHlpZWxkKiByZWNvcmREZWJ1Z0V2ZW50KGV2ZW50KVxuICAgICAgfSlcblxuICAgIGNvbnN0IGVtaXQgPSAoZXZlbnQ6IFByb2Nlc3NFdmVudCk6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgYnVkZ2V0UmVmID0geWllbGQqIEZpYmVyUmVmLmdldChjdXJyZW50UHJvY2Vzc0V2ZW50QnVkZ2V0KVxuICAgICAgICBpZiAoYnVkZ2V0UmVmKSB7XG4gICAgICAgICAgY29uc3QgZGVjaXNpb24gPSB5aWVsZCogUmVmLm1vZGlmeShidWRnZXRSZWYsIChzdGF0ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgW25leHREZWNpc2lvbiwgbmV4dFN0YXRlXSA9IFByb2Nlc3NFdmVudHMuYXBwbHlQcm9jZXNzUnVuRXZlbnRCdWRnZXQoc3RhdGUsIGV2ZW50KVxuICAgICAgICAgICAgcmV0dXJuIFtuZXh0RGVjaXNpb24sIG5leHRTdGF0ZV0gYXMgY29uc3RcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgaWYgKGRlY2lzaW9uLl90YWcgPT09ICdlbWl0JyB8fCBkZWNpc2lvbi5fdGFnID09PSAnZW1pdFN1bW1hcnknKSB7XG4gICAgICAgICAgICB5aWVsZCogcHVibGlzaEV2ZW50KGRlY2lzaW9uLmV2ZW50KVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVuZm9yY2VkID0gUHJvY2Vzc0V2ZW50cy5lbmZvcmNlUHJvY2Vzc0V2ZW50TWF4Qnl0ZXMoZXZlbnQpXG4gICAgICAgIHlpZWxkKiBwdWJsaXNoRXZlbnQoZW5mb3JjZWQuZXZlbnQpXG4gICAgICB9KVxuXG4gICAgY29uc3QgZW1pdEVycm9yRGlhZ25vc3RpYyA9IChcbiAgICAgIHNjb3BlOiBQcm9jZXNzU2NvcGUsXG4gICAgICBwcm9jZXNzSWQ6IHN0cmluZyxcbiAgICAgIGNvZGU6IHN0cmluZyxcbiAgICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICAgIGhpbnQ/OiBzdHJpbmcsXG4gICAgKTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PiB7XG4gICAgICBpZiAoIWlzRGV2RW52KCkpIHtcbiAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICB9XG4gICAgICBjb25zdCBtb2R1bGVJZCA9IHNjb3BlLnR5cGUgPT09ICdtb2R1bGVJbnN0YW5jZScgPyBzY29wZS5tb2R1bGVJZCA6IHVuZGVmaW5lZFxuICAgICAgY29uc3QgaW5zdGFuY2VJZCA9IHNjb3BlLnR5cGUgPT09ICdtb2R1bGVJbnN0YW5jZScgPyBzY29wZS5pbnN0YW5jZUlkIDogdW5kZWZpbmVkXG4gICAgICByZXR1cm4gRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogJ2RpYWdub3N0aWMnLFxuICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgY29kZSxcbiAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICAgIG1lc3NhZ2UsXG4gICAgICAgIGhpbnQsXG4gICAgICAgIGFjdGlvblRhZzogcHJvY2Vzc0lkLFxuICAgICAgICBraW5kOiAncHJvY2Vzc19ydW50aW1lJyxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZU1pc3NpbmdEZXBlbmRlbmNpZXMgPSAoaW5zdGFsbGF0aW9uOiBJbnN0YWxsYXRpb25TdGF0ZSk6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiA9PiB7XG4gICAgICBjb25zdCBkZWNsYXJlZCA9IGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLnJlcXVpcmVzID8/IFtdXG4gICAgICBjb25zdCBpbXBsaWNpdEZyb21UcmlnZ2Vyczogc3RyaW5nW10gPSBbXVxuICAgICAgZm9yIChjb25zdCB0cmlnZ2VyIG9mIGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLnRyaWdnZXJzKSB7XG4gICAgICAgIGlmICh0cmlnZ2VyLmtpbmQgPT09ICdtb2R1bGVBY3Rpb24nIHx8IHRyaWdnZXIua2luZCA9PT0gJ21vZHVsZVN0YXRlQ2hhbmdlJykge1xuICAgICAgICAgIGltcGxpY2l0RnJvbVRyaWdnZXJzLnB1c2godHJpZ2dlci5tb2R1bGVJZClcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZXF1aXJlcyA9IEFycmF5LmZyb20obmV3IFNldChbLi4uZGVjbGFyZWQsIC4uLmltcGxpY2l0RnJvbVRyaWdnZXJzXSkpXG4gICAgICBpZiAocmVxdWlyZXMubGVuZ3RoID09PSAwKSByZXR1cm4gW11cblxuICAgICAgY29uc3QgbWlzc2luZzogc3RyaW5nW10gPSBbXVxuICAgICAgZm9yIChjb25zdCBkZXAgb2YgcmVxdWlyZXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBkZXAgIT09ICdzdHJpbmcnIHx8IGRlcC5sZW5ndGggPT09IDApIGNvbnRpbnVlXG5cbiAgICAgICAgLy8gTW9kdWxlVGFnIGtleSBjb252ZW50aW9uOiBgQGxvZ2l4anMvTW9kdWxlLyR7aWR9YDsgVGFnIGlkZW50aXR5IGlzIGRlcml2ZWQgZnJvbSB0aGUga2V5LCBzbyB3ZSBjYW4gY29uc3RydWN0IGl0IG9uIGRlbWFuZC5cbiAgICAgICAgY29uc3QgdGFnID0gQ29udGV4dC5UYWcoYEBsb2dpeGpzL01vZHVsZS8ke2RlcH1gKSgpIGFzIENvbnRleHQuVGFnPGFueSwgYW55PlxuICAgICAgICBjb25zdCBmb3VuZCA9IENvbnRleHQuZ2V0T3B0aW9uKGluc3RhbGxhdGlvbi5lbnYsIHRhZylcbiAgICAgICAgaWYgKE9wdGlvbi5pc05vbmUoZm91bmQpKSB7XG4gICAgICAgICAgbWlzc2luZy5wdXNoKGRlcClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1pc3NpbmdcbiAgICB9XG5cbiAgICBjb25zdCBzdG9wSW5zdGFuY2UgPSAoXG4gICAgICBpbnN0YW5jZTogSW5zdGFuY2VTdGF0ZSxcbiAgICAgIHJlYXNvbjogUHJvY2Vzc0luc3RhbmNlU3RhdHVzWydzdG9wcGVkUmVhc29uJ10sXG4gICAgKTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaW5zdGFuY2Uuc3RhdHVzLnN0YXR1cyA9PT0gJ3N0b3BwZWQnIHx8XG4gICAgICAgICAgaW5zdGFuY2Uuc3RhdHVzLnN0YXR1cyA9PT0gJ2ZhaWxlZCcgfHxcbiAgICAgICAgICBpbnN0YW5jZS5zdGF0dXMuc3RhdHVzID09PSAnc3RvcHBpbmcnXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmliZXIgPSBpbnN0YW5jZS5maWJlclxuICAgICAgICBpbnN0YW5jZS5zdGF0dXMgPSB7XG4gICAgICAgICAgLi4uaW5zdGFuY2Uuc3RhdHVzLFxuICAgICAgICAgIHN0YXR1czogJ3N0b3BwaW5nJyxcbiAgICAgICAgICBzdG9wcGVkUmVhc29uOiByZWFzb24sXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmliZXIpIHtcbiAgICAgICAgICB5aWVsZCogRmliZXIuaW50ZXJydXB0KGZpYmVyKVxuICAgICAgICB9XG5cbiAgICAgICAgeWllbGQqIFF1ZXVlLnNodXRkb3duKGluc3RhbmNlLnBsYXRmb3JtVHJpZ2dlcnNRdWV1ZSlcblxuICAgICAgICBpbnN0YW5jZS5zdGF0dXMgPSB7XG4gICAgICAgICAgLi4uaW5zdGFuY2Uuc3RhdHVzLFxuICAgICAgICAgIHN0YXR1czogJ3N0b3BwZWQnLFxuICAgICAgICAgIHN0b3BwZWRSZWFzb246IHJlYXNvbixcbiAgICAgICAgfVxuICAgICAgICBpbnN0YW5jZS5maWJlciA9IHVuZGVmaW5lZFxuXG4gICAgICAgIGNvbnN0IGV2dDogUHJvY2Vzc0V2ZW50ID0ge1xuICAgICAgICAgIHR5cGU6ICdwcm9jZXNzOnN0b3AnLFxuICAgICAgICAgIGlkZW50aXR5OiBpbnN0YW5jZS5pZGVudGl0eSxcbiAgICAgICAgICBzZXZlcml0eTogJ2luZm8nLFxuICAgICAgICAgIGV2ZW50U2VxOiBpbnN0YW5jZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgfVxuICAgICAgICB5aWVsZCogZW1pdChldnQpXG5cbiAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uID0gaW5zdGFsbGF0aW9ucy5nZXQoaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICBpZiAoaW5zdGFsbGF0aW9uPy5wZW5kaW5nU3RhcnQpIHtcbiAgICAgICAgICBpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgICAgeWllbGQqIHN0YXJ0SW5zdGFsbGF0aW9uKGluc3RhbmNlLmluc3RhbGxhdGlvbktleSlcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgIGNvbnN0IHN0YXJ0SW5zdGFsbGF0aW9uOiAoaW5zdGFsbGF0aW9uS2V5OiBJbnN0YWxsYXRpb25LZXkpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPSAoaW5zdGFsbGF0aW9uS2V5KSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBpbnN0YWxsYXRpb24gPSBpbnN0YWxsYXRpb25zLmdldChpbnN0YWxsYXRpb25LZXkpXG4gICAgICAgIGlmICghaW5zdGFsbGF0aW9uKSByZXR1cm5cbiAgICAgICAgaW5zdGFsbGF0aW9uLnBlbmRpbmdTdGFydCA9IHVuZGVmaW5lZFxuXG4gICAgICAgIGNvbnN0IG5vb3AgPSB5aWVsZCogc2hvdWxkTm9vcER1ZVRvU3luY1R4bihpbnN0YWxsYXRpb24uaWRlbnRpdHkuc2NvcGUsICdwcm9jZXNzX3N0YXJ0X2luX3RyYW5zYWN0aW9uJylcbiAgICAgICAgaWYgKG5vb3ApIHJldHVyblxuXG4gICAgICAgIC8vIERvIG5vdCBzdGFydCBhZ2FpbiBpZiBhbiBhY3RpdmUgaW5zdGFuY2UgYWxyZWFkeSBleGlzdHMuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRJZCA9IGluc3RhbGxhdGlvbi5jdXJyZW50SW5zdGFuY2VJZFxuICAgICAgICBpZiAoY3VycmVudElkKSB7XG4gICAgICAgICAgY29uc3QgY3VycmVudCA9IGluc3RhbmNlcy5nZXQoY3VycmVudElkKVxuICAgICAgICAgIGlmIChjdXJyZW50ICYmIChjdXJyZW50LnN0YXR1cy5zdGF0dXMgPT09ICdydW5uaW5nJyB8fCBjdXJyZW50LnN0YXR1cy5zdGF0dXMgPT09ICdzdGFydGluZycpKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBydW5TZXEgPSBpbnN0YWxsYXRpb24ubmV4dFJ1blNlcSsrXG4gICAgICAgIGNvbnN0IGlkZW50aXR5OiBQcm9jZXNzSW5zdGFuY2VJZGVudGl0eSA9IHtcbiAgICAgICAgICBpZGVudGl0eTogaW5zdGFsbGF0aW9uLmlkZW50aXR5LFxuICAgICAgICAgIHJ1blNlcSxcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9jZXNzSW5zdGFuY2VJZCA9IElkZW50aXR5LnByb2Nlc3NJbnN0YW5jZUlkRnJvbUlkZW50aXR5KGlkZW50aXR5KVxuXG4gICAgICAgIGNvbnN0IHBsYXRmb3JtVHJpZ2dlcnNRdWV1ZSA9IHlpZWxkKiBRdWV1ZS5zbGlkaW5nPFByb2Nlc3NUcmlnZ2VyPig2NClcblxuICAgICAgICBjb25zdCBpbnN0YW5jZVN0YXRlOiBJbnN0YW5jZVN0YXRlID0ge1xuICAgICAgICAgIGluc3RhbGxhdGlvbktleSxcbiAgICAgICAgICBwcm9jZXNzSW5zdGFuY2VJZCxcbiAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICBwcm9jZXNzSWQ6IGluc3RhbGxhdGlvbi5pZGVudGl0eS5wcm9jZXNzSWQsXG4gICAgICAgICAgc2NvcGU6IGluc3RhbGxhdGlvbi5pZGVudGl0eS5zY29wZSxcbiAgICAgICAgICBmb3JrU2NvcGU6IGluc3RhbGxhdGlvbi5mb3JrU2NvcGUsXG4gICAgICAgICAgcGxhdGZvcm1UcmlnZ2Vyc1F1ZXVlLFxuICAgICAgICAgIHN0YXR1czoge1xuICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICBzdGF0dXM6ICdzdGFydGluZycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBuZXh0RXZlbnRTZXE6IDEsXG4gICAgICAgICAgbmV4dFRyaWdnZXJTZXE6IDEsXG4gICAgICAgIH1cblxuICAgICAgICBpbnN0YW5jZXMuc2V0KHByb2Nlc3NJbnN0YW5jZUlkLCBpbnN0YW5jZVN0YXRlKVxuICAgICAgICBpbnN0YWxsYXRpb24uY3VycmVudEluc3RhbmNlSWQgPSBwcm9jZXNzSW5zdGFuY2VJZFxuXG4gICAgICAgIC8vIFdoZW4gZm9ya1Njb3BlIGlzIGRpc3Bvc2VkIChlLmcuIHVpU3VidHJlZSB1bm1vdW50KSwgZW5zdXJlIHRoZSBpbnN0YW5jZSB0cmFuc2l0aW9ucyB0byBzdG9wcGVkIGFuZCBlbWl0cyBhIHN0b3AgZXZlbnQuXG4gICAgICAgIC8vIC0gRG8gbm90IHJlbHkgb24gdW5zdGFibGUgXCJ3aGV0aGVyIGludGVycnVwdGlvbiByZWFjaGVzIGNhdGNoQWxsQ2F1c2VcIiBiZWhhdmlvci5cbiAgICAgICAgLy8gLSBEbyBub3QgZG91YmxlLXJlZ2lzdGVyIG9uIHJ1bnRpbWVTY29wZTsgdGhlIHJ1bnRpbWUgZmluYWxpemVyIGFscmVhZHkgc3RvcHMgYWxsIGluc3RhbmNlcy5cbiAgICAgICAgaWYgKGluc3RhbGxhdGlvbi5mb3JrU2NvcGUgIT09IHJ1bnRpbWVTY29wZSkge1xuICAgICAgICAgIHlpZWxkKiBTY29wZS5hZGRGaW5hbGl6ZXIoXG4gICAgICAgICAgICBpbnN0YWxsYXRpb24uZm9ya1Njb3BlIGFzIFNjb3BlLkNsb3NlYWJsZVNjb3BlLFxuICAgICAgICAgICAgRWZmZWN0LnN1c3BlbmQoKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBzdGF0dXMgPSBpbnN0YW5jZVN0YXRlLnN0YXR1cy5zdGF0dXNcbiAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gJ3N0b3BwZWQnIHx8IHN0YXR1cyA9PT0gJ2ZhaWxlZCcgfHwgc3RhdHVzID09PSAnc3RvcHBpbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHN0b3BJbnN0YW5jZShpbnN0YW5jZVN0YXRlLCAnc2NvcGVEaXNwb3NlZCcpXG4gICAgICAgICAgICB9KS5waXBlKEVmZmVjdC5jYXRjaEFsbENhdXNlKCgpID0+IEVmZmVjdC52b2lkKSksXG4gICAgICAgICAgKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gc3RhcnQgZXZlbnQ6IGluZGljYXRlcyB0aGUgaW5zdGFuY2UgaGFzIGVudGVyZWQgdGhlIHN0YXJ0IGZsb3cgKGZpYmVyIGhhcyBiZWVuIGZvcmtlZCkuXG4gICAgICAgIHlpZWxkKiBlbWl0KHtcbiAgICAgICAgICB0eXBlOiAncHJvY2VzczpzdGFydCcsXG4gICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgc2V2ZXJpdHk6ICdpbmZvJyxcbiAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgfSlcblxuICAgICAgICBjb25zdCBtaXNzaW5nID0gcmVzb2x2ZU1pc3NpbmdEZXBlbmRlbmNpZXMoaW5zdGFsbGF0aW9uKVxuICAgICAgICBpZiAobWlzc2luZy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgaGludCA9IGlzRGV2RW52KClcbiAgICAgICAgICAgID8gW1xuICAgICAgICAgICAgICAgICdTdHJpY3Qgc2NvcGUgZGVwZW5kZW5jeSByZXNvbHV0aW9uOiBtaXNzaW5nIHJlcXVpcmVkIG1vZHVsZXMgaW4gdGhlIGN1cnJlbnQgc2NvcGUuJyxcbiAgICAgICAgICAgICAgICBgbWlzc2luZzogJHttaXNzaW5nLmpvaW4oJywgJyl9YCxcbiAgICAgICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICAgICAnZml4OicsXG4gICAgICAgICAgICAgICAgJy0gUHJvdmlkZSB0aGUgbWlzc2luZyBtb2R1bGUgaW1wbGVtZW50YXRpb24ocykgaW4gdGhlIHNhbWUgc2NvcGUgdmlhIGltcG9ydHMuJyxcbiAgICAgICAgICAgICAgICBgICBFeGFtcGxlOiBSb290TW9kdWxlLmltcGxlbWVudCh7IGltcG9ydHM6IFske21pc3NpbmdbMF19LmltcGxlbWVudCguLi4pLmltcGxdLCBwcm9jZXNzZXM6IFsuLi5dIH0pYCxcbiAgICAgICAgICAgICAgICAnLSBEbyBub3QgcmVseSBvbiBjcm9zcy1zY29wZSBmYWxsYmFja3MgLyBndWVzc2luZyBpbnN0YW5jZXMuJyxcbiAgICAgICAgICAgICAgXS5qb2luKCdcXG4nKVxuICAgICAgICAgICAgOiB1bmRlZmluZWRcblxuICAgICAgICAgIGNvbnN0IGVycm9yOiBTZXJpYWxpemFibGVFcnJvclN1bW1hcnkgPSB7XG4gICAgICAgICAgICBtZXNzYWdlOiBgTWlzc2luZyBkZXBlbmRlbmNpZXMgaW4gc2NvcGU6ICR7bWlzc2luZy5qb2luKCcsICcpfWAsXG4gICAgICAgICAgICBjb2RlOiAncHJvY2Vzczo6bWlzc2luZ19kZXBlbmRlbmN5JyxcbiAgICAgICAgICAgIGhpbnQsXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaW5zdGFuY2VTdGF0ZS5zdGF0dXMgPSB7XG4gICAgICAgICAgICAuLi5pbnN0YW5jZVN0YXRlLnN0YXR1cyxcbiAgICAgICAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXG4gICAgICAgICAgICBzdG9wcGVkUmVhc29uOiAnZmFpbGVkJyxcbiAgICAgICAgICAgIGxhc3RFcnJvcjogZXJyb3IsXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgeWllbGQqIGVtaXQoe1xuICAgICAgICAgICAgdHlwZTogJ3Byb2Nlc3M6ZXJyb3InLFxuICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgICAgIGV2ZW50U2VxOiBpbnN0YW5jZVN0YXRlLm5leHRFdmVudFNlcSsrLFxuICAgICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgeWllbGQqIGVtaXRFcnJvckRpYWdub3N0aWMoXG4gICAgICAgICAgICBpbnN0YWxsYXRpb24uaWRlbnRpdHkuc2NvcGUsXG4gICAgICAgICAgICBpbnN0YWxsYXRpb24uaWRlbnRpdHkucHJvY2Vzc0lkLFxuICAgICAgICAgICAgJ3Byb2Nlc3M6Om1pc3NpbmdfZGVwZW5kZW5jeScsXG4gICAgICAgICAgICBlcnJvci5tZXNzYWdlLFxuICAgICAgICAgICAgaGludCxcbiAgICAgICAgICApXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzaG91bGRSZWNvcmRDaGFpbkV2ZW50cyA9IGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLmRpYWdub3N0aWNzTGV2ZWwgIT09ICdvZmYnXG5cbiAgICAgICAgY29uc3QgYmFzZUVudiA9IGluc3RhbGxhdGlvbi5lbnZcblxuICAgICAgICBjb25zdCBtYWtlV3JhcHBlZEVudiA9ICgpOiBDb250ZXh0LkNvbnRleHQ8YW55PiA9PiB7XG4gICAgICAgICAgaWYgKCFzaG91bGRSZWNvcmRDaGFpbkV2ZW50cykge1xuICAgICAgICAgICAgcmV0dXJuIGJhc2VFbnZcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCByZXF1aXJlcyA9IGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLnJlcXVpcmVzID8/IFtdXG4gICAgICAgICAgaWYgKHJlcXVpcmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGJhc2VFbnZcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBpZHMgPSBBcnJheS5mcm9tKG5ldyBTZXQocmVxdWlyZXMpKVxuICAgICAgICAgIGxldCBuZXh0RW52ID0gYmFzZUVudlxuXG4gICAgICAgICAgZm9yIChjb25zdCBtb2R1bGVJZCBvZiBpZHMpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbW9kdWxlSWQgIT09ICdzdHJpbmcnIHx8IG1vZHVsZUlkLmxlbmd0aCA9PT0gMCkgY29udGludWVcbiAgICAgICAgICAgIGNvbnN0IHRhZyA9IENvbnRleHQuVGFnKGBAbG9naXhqcy9Nb2R1bGUvJHttb2R1bGVJZH1gKSgpIGFzIENvbnRleHQuVGFnPGFueSwgYW55PlxuICAgICAgICAgICAgY29uc3QgZm91bmQgPSBDb250ZXh0LmdldE9wdGlvbihiYXNlRW52LCB0YWcpXG4gICAgICAgICAgICBpZiAoT3B0aW9uLmlzTm9uZShmb3VuZCkpIGNvbnRpbnVlXG4gICAgICAgICAgICBjb25zdCBydW50aW1lID0gZm91bmQudmFsdWUgYXMgYW55XG5cbiAgICAgICAgICAgIGNvbnN0IHJlY29yZERpc3BhdGNoID0gKGFjdGlvbjogdW5rbm93bikgPT5cbiAgICAgICAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRyaWdnZXIgPSB5aWVsZCogRmliZXJSZWYuZ2V0KGN1cnJlbnRQcm9jZXNzVHJpZ2dlcilcbiAgICAgICAgICAgICAgICBpZiAoIXRyaWdnZXIpIHJldHVyblxuXG4gICAgICAgICAgICAgICAgY29uc3QgYWN0aW9uSWQgPSBhY3Rpb25JZEZyb21Vbmtub3duKGFjdGlvbikgPz8gJ3Vua25vd24nXG4gICAgICAgICAgICAgICAgY29uc3QgZGlzcGF0Y2hNb2R1bGVJZCA9IHR5cGVvZiBydW50aW1lLm1vZHVsZUlkID09PSAnc3RyaW5nJyA/IHJ1bnRpbWUubW9kdWxlSWQgOiBtb2R1bGVJZFxuICAgICAgICAgICAgICAgIGNvbnN0IGRpc3BhdGNoSW5zdGFuY2VJZCA9IHR5cGVvZiBydW50aW1lLmluc3RhbmNlSWQgPT09ICdzdHJpbmcnID8gcnVudGltZS5pbnN0YW5jZUlkIDogJ3Vua25vd24nXG5cbiAgICAgICAgICAgICAgICBjb25zdCBldnQ6IFByb2Nlc3NFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdwcm9jZXNzOmRpc3BhdGNoJyxcbiAgICAgICAgICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgICAgICAgICAgdHJpZ2dlcixcbiAgICAgICAgICAgICAgICAgIGRpc3BhdGNoOiB7XG4gICAgICAgICAgICAgICAgICAgIG1vZHVsZUlkOiBkaXNwYXRjaE1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBkaXNwYXRjaEluc3RhbmNlSWQsXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbklkLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHNldmVyaXR5OiAnaW5mbycsXG4gICAgICAgICAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcE1zOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHlpZWxkKiBlbWl0KGV2dClcbiAgICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZCA9IHtcbiAgICAgICAgICAgICAgLi4ucnVudGltZSxcbiAgICAgICAgICAgICAgZGlzcGF0Y2g6IChhY3Rpb246IHVua25vd24pID0+IHJ1bnRpbWUuZGlzcGF0Y2goYWN0aW9uKS5waXBlKEVmZmVjdC50YXAoKCkgPT4gcmVjb3JkRGlzcGF0Y2goYWN0aW9uKSkpLFxuICAgICAgICAgICAgICBkaXNwYXRjaExvd1ByaW9yaXR5OiAoYWN0aW9uOiB1bmtub3duKSA9PlxuICAgICAgICAgICAgICAgIHJ1bnRpbWUuZGlzcGF0Y2hMb3dQcmlvcml0eShhY3Rpb24pLnBpcGUoRWZmZWN0LnRhcCgoKSA9PiByZWNvcmREaXNwYXRjaChhY3Rpb24pKSksXG4gICAgICAgICAgICAgIGRpc3BhdGNoQmF0Y2g6IChhY3Rpb25zOiBSZWFkb25seUFycmF5PHVua25vd24+KSA9PlxuICAgICAgICAgICAgICAgIHJ1bnRpbWVcbiAgICAgICAgICAgICAgICAgIC5kaXNwYXRjaEJhdGNoKGFjdGlvbnMpXG4gICAgICAgICAgICAgICAgICAucGlwZShFZmZlY3QudGFwKCgpID0+IEVmZmVjdC5mb3JFYWNoKGFjdGlvbnMsIHJlY29yZERpc3BhdGNoLCB7IGRpc2NhcmQ6IHRydWUgfSkpKSxcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV4dEVudiA9IENvbnRleHQuYWRkKHRhZywgd3JhcHBlZCkobmV4dEVudilcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbmV4dEVudlxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgd3JhcHBlZEVudiA9IG1ha2VXcmFwcGVkRW52KClcbiAgICAgICAgY29uc3QgcHJvdmlkZWRQcm9jZXNzID0gRWZmZWN0LnByb3ZpZGUoaW5zdGFsbGF0aW9uLnByb2Nlc3MsIHdyYXBwZWRFbnYpXG5cbiAgICAgICAgY29uc3QgbWFrZVRyaWdnZXJTdHJlYW0gPSAoc3BlYzogTm9uUGxhdGZvcm1UcmlnZ2VyU3BlYyk6IEVmZmVjdC5FZmZlY3Q8U3RyZWFtLlN0cmVhbTxQcm9jZXNzVHJpZ2dlcj4sIEVycm9yPiA9PlxuICAgICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGlmIChzcGVjLmtpbmQgPT09ICd0aW1lcicpIHtcbiAgICAgICAgICAgICAgY29uc3QgaW50ZXJ2YWwgPSBEdXJhdGlvbi5kZWNvZGVVbmtub3duKHNwZWMudGltZXJJZClcbiAgICAgICAgICAgICAgaWYgKE9wdGlvbi5pc05vbmUoaW50ZXJ2YWwpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKGBbUHJvY2Vzc1J1bnRpbWVdIGludmFsaWQgdGltZXJJZCAoZXhwZWN0ZWQgRHVyYXRpb25JbnB1dCk6ICR7c3BlYy50aW1lcklkfWApXG4gICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5jb2RlID0gJ3Byb2Nlc3M6OmludmFsaWRfdGltZXJfaWQnXG4gICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5oaW50ID1cbiAgICAgICAgICAgICAgICAgIFwidGltZXJJZCBtdXN0IGJlIGEgdmFsaWQgRHVyYXRpb25JbnB1dCBzdHJpbmcsIGUuZy4gJzEwIG1pbGxpcycsICcxIHNlY29uZHMnLCAnNSBtaW51dGVzJy5cIlxuICAgICAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwoZXJyKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIFN0cmVhbS50aWNrKGludGVydmFsLnZhbHVlKS5waXBlKFxuICAgICAgICAgICAgICAgIFN0cmVhbS5tYXAoXG4gICAgICAgICAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAoe1xuICAgICAgICAgICAgICAgICAgICAgIGtpbmQ6ICd0aW1lcicsXG4gICAgICAgICAgICAgICAgICAgICAgbmFtZTogc3BlYy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICAgIHRpbWVySWQ6IHNwZWMudGltZXJJZCxcbiAgICAgICAgICAgICAgICAgICAgfSkgc2F0aXNmaWVzIFByb2Nlc3NUcmlnZ2VyLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNwZWMua2luZCA9PT0gJ21vZHVsZUFjdGlvbicpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGFnID0gQ29udGV4dC5UYWcoYEBsb2dpeGpzL01vZHVsZS8ke3NwZWMubW9kdWxlSWR9YCkoKSBhcyBDb250ZXh0LlRhZzxhbnksIGFueT5cbiAgICAgICAgICAgICAgY29uc3QgZm91bmQgPSBDb250ZXh0LmdldE9wdGlvbihiYXNlRW52LCB0YWcpXG4gICAgICAgICAgICAgIGlmIChPcHRpb24uaXNOb25lKGZvdW5kKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwobmV3IEVycm9yKGBNaXNzaW5nIG1vZHVsZSBydW50aW1lIGluIHNjb3BlOiAke3NwZWMubW9kdWxlSWR9YCkpXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjb25zdCBydW50aW1lID0gZm91bmQudmFsdWUgYXMgYW55XG5cbiAgICAgICAgICAgICAgLy8gcGVyZjogd2hlbiBkaWFnbm9zdGljcz1vZmYsIGF2b2lkIHN1YnNjcmliaW5nIHRvIGFjdGlvbnNXaXRoTWV0YSQgKHB1Ymxpc2hlZCBpbnNpZGUgdHhuczsgbW9yZSBzdWJzY3JpYmVycyBodXJ0IGhvdCBwYXRocykuXG4gICAgICAgICAgICAgIC8vIGRpYWdub3N0aWNzPWxpZ2h0L2Z1bGwgbmVlZHMgdHhuU2VxL3R4bklkIGFuY2hvcnMsIHNvIG9ubHkgdXNlIGFjdGlvbnNXaXRoTWV0YSQgd2hlbiBjaGFpbiBldmVudHMgYXJlIGVuYWJsZWQuXG4gICAgICAgICAgICAgIGlmICghc2hvdWxkUmVjb3JkQ2hhaW5FdmVudHMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBydW50aW1lLmFjdGlvbnMkIGFzIFN0cmVhbS5TdHJlYW08YW55PiB8IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIGlmICghc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgRXJyb3IoJ01vZHVsZVJ1bnRpbWUgZG9lcyBub3QgcHJvdmlkZSBhY3Rpb25zJCAocmVxdWlyZWQgZm9yIG1vZHVsZUFjdGlvbiB0cmlnZ2VyKS4nKVxuICAgICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5jb2RlID0gJ3Byb2Nlc3M6Om1pc3NpbmdfYWN0aW9uX3N0cmVhbSdcbiAgICAgICAgICAgICAgICAgIDsoZXJyIGFzIGFueSkuaGludCA9IGBtb2R1bGVJZD0ke3NwZWMubW9kdWxlSWR9YFxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbChlcnIpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0cmVhbS5waXBlKFxuICAgICAgICAgICAgICAgICAgU3RyZWFtLmZpbHRlcigoYWN0aW9uOiBhbnkpID0+IGFjdGlvbklkRnJvbVVua25vd24oYWN0aW9uKSA9PT0gc3BlYy5hY3Rpb25JZCksXG4gICAgICAgICAgICAgICAgICBTdHJlYW0ubWFwKFxuICAgICAgICAgICAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICh7XG4gICAgICAgICAgICAgICAgICAgICAgICBraW5kOiAnbW9kdWxlQWN0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IHNwZWMubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZUlkOiBzcGVjLm1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkIGFzIHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbklkOiBzcGVjLmFjdGlvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHhuU2VxOiAxLFxuICAgICAgICAgICAgICAgICAgICAgIH0pIHNhdGlzZmllcyBQcm9jZXNzVHJpZ2dlcixcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0gcnVudGltZS5hY3Rpb25zV2l0aE1ldGEkIGFzIFN0cmVhbS5TdHJlYW08YW55PiB8IHVuZGVmaW5lZFxuICAgICAgICAgICAgICBpZiAoIXN0cmVhbSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICdNb2R1bGVSdW50aW1lIGRvZXMgbm90IHByb3ZpZGUgYWN0aW9uc1dpdGhNZXRhJCAocmVxdWlyZWQgZm9yIG1vZHVsZUFjdGlvbiB0cmlnZ2VyKS4nLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICA7KGVyciBhcyBhbnkpLmNvZGUgPSAncHJvY2Vzczo6bWlzc2luZ19hY3Rpb25fbWV0YV9zdHJlYW0nXG4gICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5oaW50ID0gYG1vZHVsZUlkPSR7c3BlYy5tb2R1bGVJZH1gXG4gICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbChlcnIpXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZXR1cm4gc3RyZWFtLnBpcGUoXG4gICAgICAgICAgICAgICAgU3RyZWFtLmZpbHRlcigoZXZ0OiBhbnkpID0+IGFjdGlvbklkRnJvbVVua25vd24oZXZ0LnZhbHVlKSA9PT0gc3BlYy5hY3Rpb25JZCksXG4gICAgICAgICAgICAgICAgU3RyZWFtLm1hcCgoZXZ0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHR4blNlcSA9IGV2dD8ubWV0YT8udHhuU2VxXG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBraW5kOiAnbW9kdWxlQWN0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogc3BlYy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICBtb2R1bGVJZDogc3BlYy5tb2R1bGVJZCxcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkIGFzIHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uSWQ6IHNwZWMuYWN0aW9uSWQsXG4gICAgICAgICAgICAgICAgICAgIHR4blNlcTogdHlwZW9mIHR4blNlcSA9PT0gJ251bWJlcicgPyB0eG5TZXEgOiAxLFxuICAgICAgICAgICAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc1RyaWdnZXJcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBtb2R1bGVTdGF0ZUNoYW5nZVxuICAgICAgICAgICAgY29uc3QgdGFnID0gQ29udGV4dC5UYWcoYEBsb2dpeGpzL01vZHVsZS8ke3NwZWMubW9kdWxlSWR9YCkoKSBhcyBDb250ZXh0LlRhZzxhbnksIGFueT5cbiAgICAgICAgICAgIGNvbnN0IGZvdW5kID0gQ29udGV4dC5nZXRPcHRpb24oYmFzZUVudiwgdGFnKVxuICAgICAgICAgICAgaWYgKE9wdGlvbi5pc05vbmUoZm91bmQpKSB7XG4gICAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwobmV3IEVycm9yKGBNaXNzaW5nIG1vZHVsZSBydW50aW1lIGluIHNjb3BlOiAke3NwZWMubW9kdWxlSWR9YCkpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHJ1bnRpbWUgPSBmb3VuZC52YWx1ZSBhcyBhbnlcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYUFzdCA9IHJlc29sdmVSdW50aW1lU3RhdGVTY2hlbWFBc3QocnVudGltZSlcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdG9yUmVzdWx0ID0gbWFrZVNjaGVtYVNlbGVjdG9yKHNwZWMucGF0aCwgc2NoZW1hQXN0KVxuICAgICAgICAgICAgaWYgKCFzZWxlY3RvclJlc3VsdC5vaykge1xuICAgICAgICAgICAgICByZXR1cm4geWllbGQqIEVmZmVjdC5mYWlsKHdpdGhNb2R1bGVIaW50KHNlbGVjdG9yUmVzdWx0LmVycm9yLCBzcGVjLm1vZHVsZUlkKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdG9yQmFzZSA9IHNlbGVjdG9yUmVzdWx0LnNlbGVjdG9yXG4gICAgICAgICAgICBjb25zdCBwcmV2UmVmID0geWllbGQqIFJlZi5tYWtlPE9wdGlvbi5PcHRpb248dW5rbm93bj4+KE9wdGlvbi5ub25lKCkpXG5cbiAgICAgICAgICAgIGNvbnN0IGVuYWJsZVNlbGVjdG9yRGlhZ25vc3RpY3MgPSBzaG91bGRSZWNvcmRDaGFpbkV2ZW50c1xuXG4gICAgICAgICAgICBjb25zdCBzZWxlY3RvckRpYWdub3N0aWNzUmVmID0gZW5hYmxlU2VsZWN0b3JEaWFnbm9zdGljc1xuICAgICAgICAgICAgICA/IHlpZWxkKiBSZWYubWFrZSh7XG4gICAgICAgICAgICAgICAgICB3aW5kb3dTdGFydGVkTXM6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICB0cmlnZ2Vyc0luV2luZG93OiAwLFxuICAgICAgICAgICAgICAgICAgbGFzdFdhcm5pbmdBdE1zOiAwLFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIDogdW5kZWZpbmVkXG5cbiAgICAgICAgICAgIGNvbnN0IHNhbXBsZUV2ZXJ5TWFzayA9IDB4N2YgLy8gc2FtcGxlIGV2ZXJ5IDEyOCBjYWxsc1xuICAgICAgICAgICAgY29uc3Qgc2xvd1NhbXBsZVRocmVzaG9sZE1zID0gNFxuICAgICAgICAgICAgY29uc3QgdHJpZ2dlcldpbmRvd01zID0gMTAwMFxuICAgICAgICAgICAgY29uc3QgdHJpZ2dlcldhcm5pbmdUaHJlc2hvbGQgPSBpc0RldkVudigpID8gMjAgOiAyMDBcbiAgICAgICAgICAgIGNvbnN0IHdhcm5pbmdDb29sZG93bk1zID0gMzBfMDAwXG5cbiAgICAgICAgICAgIGxldCBzZWxlY3RvckNhbGxzID0gMFxuICAgICAgICAgICAgbGV0IHNlbGVjdG9yU2FtcGxlcyA9IDBcbiAgICAgICAgICAgIGxldCBzZWxlY3RvclNsb3dTYW1wbGVzID0gMFxuICAgICAgICAgICAgbGV0IHNlbGVjdG9yTWF4U2FtcGxlTXMgPSAwXG5cbiAgICAgICAgICAgIGNvbnN0IG5vd01zID0gKCk6IG51bWJlciA9PiB7XG4gICAgICAgICAgICAgIGlmICh0eXBlb2YgcGVyZm9ybWFuY2UgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBwZXJmb3JtYW5jZS5ub3cgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGVyZm9ybWFuY2Uubm93KClcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gRGF0ZS5ub3coKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzZWxlY3RvciA9IGVuYWJsZVNlbGVjdG9yRGlhZ25vc3RpY3NcbiAgICAgICAgICAgICAgPyAoc3RhdGU6IHVua25vd24pOiB1bmtub3duID0+IHtcbiAgICAgICAgICAgICAgICAgIHNlbGVjdG9yQ2FsbHMgKz0gMVxuICAgICAgICAgICAgICAgICAgaWYgKChzZWxlY3RvckNhbGxzICYgc2FtcGxlRXZlcnlNYXNrKSAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0b3JCYXNlKHN0YXRlKVxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBjb25zdCB0MCA9IG5vd01zKClcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc2VsZWN0b3JCYXNlKHN0YXRlKVxuICAgICAgICAgICAgICAgICAgY29uc3QgZHQgPSBub3dNcygpIC0gdDBcblxuICAgICAgICAgICAgICAgICAgc2VsZWN0b3JTYW1wbGVzICs9IDFcbiAgICAgICAgICAgICAgICAgIGlmIChkdCA+PSBzbG93U2FtcGxlVGhyZXNob2xkTXMpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JTbG93U2FtcGxlcyArPSAxXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBpZiAoZHQgPiBzZWxlY3Rvck1heFNhbXBsZU1zKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yTWF4U2FtcGxlTXMgPSBkdFxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDogc2VsZWN0b3JCYXNlXG5cbiAgICAgICAgICAgIGNvbnN0IG1heWJlV2FyblNlbGVjdG9yID0gKHRyaWdnZXI6IFByb2Nlc3NUcmlnZ2VyKTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PiB7XG4gICAgICAgICAgICAgIGlmICghc2VsZWN0b3JEaWFnbm9zdGljc1JlZikge1xuICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpXG5cbiAgICAgICAgICAgICAgICBjb25zdCBkZWNpc2lvbiA9IHlpZWxkKiBSZWYubW9kaWZ5KHNlbGVjdG9yRGlhZ25vc3RpY3NSZWYsIChzKSA9PiB7XG4gICAgICAgICAgICAgICAgICBjb25zdCB3aW5kb3dFeHBpcmVkID0gbm93IC0gcy53aW5kb3dTdGFydGVkTXMgPj0gdHJpZ2dlcldpbmRvd01zXG4gICAgICAgICAgICAgICAgICBjb25zdCB3aW5kb3dTdGFydGVkTXMgPSB3aW5kb3dFeHBpcmVkID8gbm93IDogcy53aW5kb3dTdGFydGVkTXNcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRyaWdnZXJzSW5XaW5kb3cgPSB3aW5kb3dFeHBpcmVkID8gMSA6IHMudHJpZ2dlcnNJbldpbmRvdyArIDFcblxuICAgICAgICAgICAgICAgICAgY29uc3Qgc2hvdWxkQ29vbGRvd24gPSBub3cgLSBzLmxhc3RXYXJuaW5nQXRNcyA8IHdhcm5pbmdDb29sZG93bk1zXG4gICAgICAgICAgICAgICAgICBjb25zdCB0b29GcmVxdWVudCA9IHRyaWdnZXJzSW5XaW5kb3cgPj0gdHJpZ2dlcldhcm5pbmdUaHJlc2hvbGRcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb1Nsb3cgPSBzZWxlY3Rvck1heFNhbXBsZU1zID49IHNsb3dTYW1wbGVUaHJlc2hvbGRNcyAmJiBzZWxlY3RvclNhbXBsZXMgPiAwXG4gICAgICAgICAgICAgICAgICBjb25zdCBzaG91bGRXYXJuID0gIXNob3VsZENvb2xkb3duICYmICh0b29GcmVxdWVudCB8fCB0b29TbG93KVxuXG4gICAgICAgICAgICAgICAgICBjb25zdCBuZXh0ID0gc2hvdWxkV2FyblxuICAgICAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd1N0YXJ0ZWRNczogbm93LFxuICAgICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcnNJbldpbmRvdzogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RXYXJuaW5nQXRNczogbm93LFxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5zLFxuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93U3RhcnRlZE1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcnNJbldpbmRvdyxcbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICBzaG91bGRXYXJuLFxuICAgICAgICAgICAgICAgICAgICAgIHRvb0ZyZXF1ZW50LFxuICAgICAgICAgICAgICAgICAgICAgIHRvb1Nsb3csXG4gICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcnNJbldpbmRvdyxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgbmV4dCxcbiAgICAgICAgICAgICAgICAgIF0gYXMgY29uc3RcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgaWYgKCFkZWNpc2lvbi5zaG91bGRXYXJuKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBjb2RlID0gZGVjaXNpb24udG9vRnJlcXVlbnQgPyAncHJvY2Vzczo6c2VsZWN0b3JfaGlnaF9mcmVxdWVuY3knIDogJ3Byb2Nlc3M6OnNlbGVjdG9yX3Nsb3cnXG5cbiAgICAgICAgICAgICAgICBjb25zdCBoaW50ID0gW1xuICAgICAgICAgICAgICAgICAgYG1vZHVsZUlkPSR7c3BlYy5tb2R1bGVJZH1gLFxuICAgICAgICAgICAgICAgICAgYHBhdGg9JHtzcGVjLnBhdGh9YCxcbiAgICAgICAgICAgICAgICAgIGB3aW5kb3dNcz0ke3RyaWdnZXJXaW5kb3dNc31gLFxuICAgICAgICAgICAgICAgICAgYHRyaWdnZXJzSW5XaW5kb3c9JHtkZWNpc2lvbi50cmlnZ2Vyc0luV2luZG93fWAsXG4gICAgICAgICAgICAgICAgICBgdGhyZXNob2xkPSR7dHJpZ2dlcldhcm5pbmdUaHJlc2hvbGR9YCxcbiAgICAgICAgICAgICAgICAgIGBjb29sZG93bk1zPSR7d2FybmluZ0Nvb2xkb3duTXN9YCxcbiAgICAgICAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgICAgICAgJ3NlbGVjdG9yIHNhbXBsaW5nOicsXG4gICAgICAgICAgICAgICAgICBgY2FsbHM9JHtzZWxlY3RvckNhbGxzfWAsXG4gICAgICAgICAgICAgICAgICBgc2FtcGxlZD0ke3NlbGVjdG9yU2FtcGxlc31gLFxuICAgICAgICAgICAgICAgICAgYHNsb3dTYW1wbGVzKD49JHtzbG93U2FtcGxlVGhyZXNob2xkTXN9bXMpPSR7c2VsZWN0b3JTbG93U2FtcGxlc31gLFxuICAgICAgICAgICAgICAgICAgYG1heFNhbXBsZU1zPSR7c2VsZWN0b3JNYXhTYW1wbGVNcy50b0ZpeGVkKDIpfWAsXG4gICAgICAgICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICAgICAgICdub3RlczonLFxuICAgICAgICAgICAgICAgICAgJy0gRW5zdXJlIHRoZSBzZWxlY3RlZCB2YWx1ZSBpcyBzdGFibGUgKHByZWZlciBwcmltaXRpdmUvdHVwbGU7IGF2b2lkIHJldHVybmluZyBmcmVzaCBvYmplY3RzKS4nLFxuICAgICAgICAgICAgICAgICAgJy0gTmFycm93IHRoZSBwYXRoIHRvIHJlZHVjZSBjaGFuZ2UgZnJlcXVlbmN5OyBhdm9pZCBzZWxlY3RpbmcgbGFyZ2Ugb2JqZWN0cy4nLFxuICAgICAgICAgICAgICAgIF0uam9pbignXFxuJylcblxuICAgICAgICAgICAgICAgIHNlbGVjdG9yU2FtcGxlcyA9IDBcbiAgICAgICAgICAgICAgICBzZWxlY3RvclNsb3dTYW1wbGVzID0gMFxuICAgICAgICAgICAgICAgIHNlbGVjdG9yTWF4U2FtcGxlTXMgPSAwXG5cbiAgICAgICAgICAgICAgICB5aWVsZCogZW1pdCh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAncHJvY2Vzczp0cmlnZ2VyJyxcbiAgICAgICAgICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgICAgICAgICAgdHJpZ2dlcixcbiAgICAgICAgICAgICAgICAgIHNldmVyaXR5OiAnd2FybmluZycsXG4gICAgICAgICAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcE1zOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ21vZHVsZVN0YXRlQ2hhbmdlIHNlbGVjdG9yIGRpYWdub3N0aWNzIHdhcm5pbmcnLFxuICAgICAgICAgICAgICAgICAgICBjb2RlLFxuICAgICAgICAgICAgICAgICAgICBoaW50LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9IHNhdGlzZmllcyBQcm9jZXNzRXZlbnQpXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGJhc2VTdHJlYW0gPSAocnVudGltZS5jaGFuZ2VzV2l0aE1ldGEoc2VsZWN0b3IpIGFzIFN0cmVhbS5TdHJlYW08YW55PikucGlwZShcbiAgICAgICAgICAgICAgU3RyZWFtLm1hcEVmZmVjdCgoZXZ0OiBhbnkpID0+XG4gICAgICAgICAgICAgICAgUmVmLmdldChwcmV2UmVmKS5waXBlKFxuICAgICAgICAgICAgICAgICAgRWZmZWN0LmZsYXRNYXAoKHByZXYpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9wdGlvbi5pc1NvbWUocHJldikgJiYgT2JqZWN0LmlzKHByZXYudmFsdWUsIGV2dC52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnN1Y2NlZWQoT3B0aW9uLm5vbmUoKSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUmVmLnNldChwcmV2UmVmLCBPcHRpb24uc29tZShldnQudmFsdWUpKS5waXBlKEVmZmVjdC5hcyhPcHRpb24uc29tZShldnQpKSlcbiAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIFN0cmVhbS5maWx0ZXJNYXAoKG9wdCkgPT4gb3B0KSxcbiAgICAgICAgICAgICAgU3RyZWFtLm1hcCgoZXZ0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0eG5TZXEgPSBldnQ/Lm1ldGE/LnR4blNlcVxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBraW5kOiAnbW9kdWxlU3RhdGVDaGFuZ2UnLFxuICAgICAgICAgICAgICAgICAgbmFtZTogc3BlYy5uYW1lLFxuICAgICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHNwZWMubW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQgYXMgc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgcGF0aDogc3BlYy5wYXRoLFxuICAgICAgICAgICAgICAgICAgdHhuU2VxOiB0eXBlb2YgdHhuU2VxID09PSAnbnVtYmVyJyA/IHR4blNlcSA6IDEsXG4gICAgICAgICAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc1RyaWdnZXJcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApXG5cbiAgICAgICAgICAgIHJldHVybiBlbmFibGVTZWxlY3RvckRpYWdub3N0aWNzID8gYmFzZVN0cmVhbS5waXBlKFN0cmVhbS50YXAobWF5YmVXYXJuU2VsZWN0b3IpKSA6IGJhc2VTdHJlYW1cbiAgICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IG1ha2VSdW4gPSAodHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIsIGZhdGFsOiBEZWZlcnJlZC5EZWZlcnJlZDxDYXVzZS5DYXVzZTxhbnk+Pik6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT5cbiAgICAgICAgICBFZmZlY3QubG9jYWxseShcbiAgICAgICAgICAgIGN1cnJlbnRQcm9jZXNzVHJpZ2dlcixcbiAgICAgICAgICAgIHRyaWdnZXIsXG4gICAgICAgICAgKShcbiAgICAgICAgICAgIHByb3ZpZGVkUHJvY2Vzcy5waXBlKFxuICAgICAgICAgICAgICBFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoY2F1c2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoQ2F1c2UuaXNJbnRlcnJ1cHRlZE9ubHkoY2F1c2UpKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIERlZmVycmVkLnN1Y2NlZWQoZmF0YWwsIGNhdXNlKS5waXBlKFxuICAgICAgICAgICAgICAgICAgRWZmZWN0LmFzVm9pZCxcbiAgICAgICAgICAgICAgICAgIEVmZmVjdC5jYXRjaEFsbCgoKSA9PiBFZmZlY3Qudm9pZCksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKVxuXG4gICAgICAgIGNvbnN0IG1ha2VDaGFpblJ1biA9IChcbiAgICAgICAgICB0cmlnZ2VyOiBQcm9jZXNzVHJpZ2dlcixcbiAgICAgICAgICBmYXRhbDogRGVmZXJyZWQuRGVmZXJyZWQ8Q2F1c2UuQ2F1c2U8YW55Pj4sXG4gICAgICAgICk6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT4ge1xuICAgICAgICAgIGlmICghc2hvdWxkUmVjb3JkQ2hhaW5FdmVudHMpIHtcbiAgICAgICAgICAgIHJldHVybiBtYWtlUnVuKHRyaWdnZXIsIGZhdGFsKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBidWRnZXRSZWYgPSB5aWVsZCogUmVmLm1ha2UoUHJvY2Vzc0V2ZW50cy5tYWtlUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0U3RhdGUoKSlcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmxvY2FsbHkoXG4gICAgICAgICAgICAgIGN1cnJlbnRQcm9jZXNzRXZlbnRCdWRnZXQsXG4gICAgICAgICAgICAgIGJ1ZGdldFJlZixcbiAgICAgICAgICAgICkoZW1pdFRyaWdnZXJFdmVudCh0cmlnZ2VyLCAnaW5mbycpLnBpcGUoRWZmZWN0LnppcFJpZ2h0KG1ha2VSdW4odHJpZ2dlciwgZmF0YWwpKSkpXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFzc2lnblRyaWdnZXJTZXEgPSAodHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIpOiBQcm9jZXNzVHJpZ2dlciA9PiB7XG4gICAgICAgICAgaWYgKCFzaG91bGRSZWNvcmRDaGFpbkV2ZW50cykge1xuICAgICAgICAgICAgcmV0dXJuIHRyaWdnZXJcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4udHJpZ2dlcixcbiAgICAgICAgICAgIHRyaWdnZXJTZXE6IGluc3RhbmNlU3RhdGUubmV4dFRyaWdnZXJTZXErKyxcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBlbWl0VHJpZ2dlckV2ZW50ID0gKHRyaWdnZXI6IFByb2Nlc3NUcmlnZ2VyLCBzZXZlcml0eTogUHJvY2Vzc0V2ZW50WydzZXZlcml0eSddKTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PiB7XG4gICAgICAgICAgaWYgKCFzaG91bGRSZWNvcmRDaGFpbkV2ZW50cykge1xuICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZXZ0OiBQcm9jZXNzRXZlbnQgPSB7XG4gICAgICAgICAgICB0eXBlOiAncHJvY2Vzczp0cmlnZ2VyJyxcbiAgICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgICAgdHJpZ2dlcixcbiAgICAgICAgICAgIHNldmVyaXR5LFxuICAgICAgICAgICAgZXZlbnRTZXE6IGluc3RhbmNlU3RhdGUubmV4dEV2ZW50U2VxKyssXG4gICAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGVtaXQoZXZ0KVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcG9saWN5ID0gaW5zdGFsbGF0aW9uLmRlZmluaXRpb24uY29uY3VycmVuY3lcbiAgICAgICAgY29uc3QgYXV0b1N0YXJ0ID0gaW5zdGFsbGF0aW9uLmRlZmluaXRpb24udHJpZ2dlcnMuc29tZShcbiAgICAgICAgICAodCkgPT4gdC5raW5kID09PSAncGxhdGZvcm1FdmVudCcgJiYgdC5wbGF0Zm9ybUV2ZW50ID09PSBSVU5USU1FX0JPT1RfRVZFTlQsXG4gICAgICAgIClcbiAgICAgICAgY29uc3QgYm9vdFRyaWdnZXJTcGVjID0gaW5zdGFsbGF0aW9uLmRlZmluaXRpb24udHJpZ2dlcnMuZmluZChcbiAgICAgICAgICAodCk6IHQgaXMgRXh0cmFjdDxQcm9jZXNzVHJpZ2dlclNwZWMsIHsgcmVhZG9ubHkga2luZDogJ3BsYXRmb3JtRXZlbnQnIH0+ID0+XG4gICAgICAgICAgICB0LmtpbmQgPT09ICdwbGF0Zm9ybUV2ZW50JyAmJiB0LnBsYXRmb3JtRXZlbnQgPT09IFJVTlRJTUVfQk9PVF9FVkVOVCxcbiAgICAgICAgKVxuXG4gICAgICAgIGNvbnN0IGluc3RhbmNlUHJvZ3JhbSA9IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICBjb25zdCBmYXRhbCA9IHlpZWxkKiBEZWZlcnJlZC5tYWtlPENhdXNlLkNhdXNlPGFueT4+KClcblxuICAgICAgICAgIGNvbnN0IHBsYXRmb3JtRXZlbnRTdHJlYW06IFN0cmVhbS5TdHJlYW08UHJvY2Vzc1RyaWdnZXI+ID0gU3RyZWFtLmZyb21RdWV1ZShcbiAgICAgICAgICAgIGluc3RhbmNlU3RhdGUucGxhdGZvcm1UcmlnZ2Vyc1F1ZXVlLFxuICAgICAgICAgIClcblxuICAgICAgICAgIGNvbnN0IG5vblBsYXRmb3JtVHJpZ2dlcnMgPSBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi50cmlnZ2Vycy5maWx0ZXIoXG4gICAgICAgICAgICAodCk6IHQgaXMgTm9uUGxhdGZvcm1UcmlnZ2VyU3BlYyA9PiB0LmtpbmQgIT09ICdwbGF0Zm9ybUV2ZW50JyxcbiAgICAgICAgICApXG5cbiAgICAgICAgICBjb25zdCBzdHJlYW1zID0geWllbGQqIEVmZmVjdC5mb3JFYWNoKG5vblBsYXRmb3JtVHJpZ2dlcnMsIG1ha2VUcmlnZ2VyU3RyZWFtKVxuXG4gICAgICAgICAgY29uc3QgdHJpZ2dlclN0cmVhbSA9IFN0cmVhbS5tZXJnZUFsbChbcGxhdGZvcm1FdmVudFN0cmVhbSwgLi4uc3RyZWFtc10sIHtcbiAgICAgICAgICAgIGNvbmN1cnJlbmN5OiAndW5ib3VuZGVkJyxcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgY29uc3QgcmVwb3J0UXVldWVPdmVyZmxvdyA9IChcbiAgICAgICAgICAgIGluZm86IFByb2Nlc3NDb25jdXJyZW5jeS5Qcm9jZXNzVHJpZ2dlclF1ZXVlT3ZlcmZsb3dJbmZvLFxuICAgICAgICAgICk6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT4ge1xuICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKCdQcm9jZXNzIHRyaWdnZXIgcXVldWUgb3ZlcmZsb3cgKHNlcmlhbCBtYXhRdWV1ZSBndWFyZCkuJylcbiAgICAgICAgICAgIDsoZXJyIGFzIGFueSkuY29kZSA9ICdwcm9jZXNzOjpzZXJpYWxfcXVldWVfb3ZlcmZsb3cnXG4gICAgICAgICAgICA7KGVyciBhcyBhbnkpLmhpbnQgPSBbXG4gICAgICAgICAgICAgIGBtb2RlPSR7aW5mby5tb2RlfWAsXG4gICAgICAgICAgICAgIGBxdWV1ZTogY3VycmVudD0ke2luZm8uY3VycmVudExlbmd0aH0gcGVhaz0ke2luZm8ucGVha31gLFxuICAgICAgICAgICAgICBgbWF4UXVldWU6IGNvbmZpZ3VyZWQ9JHtpbmZvLmxpbWl0LmNvbmZpZ3VyZWR9IGd1YXJkPSR7aW5mby5saW1pdC5ndWFyZH1gLFxuICAgICAgICAgICAgICBgcG9saWN5OiAke0pTT04uc3RyaW5naWZ5KGluZm8ucG9saWN5KX1gLFxuICAgICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICAgJ2ZpeDonLFxuICAgICAgICAgICAgICAnLSBDb25maWd1cmUgY29uY3VycmVuY3kubWF4UXVldWUgKHNlcmlhbCkgdG8gYSBmaW5pdGUgdmFsdWUsIG9yIHN3aXRjaCB0byBtb2RlPWxhdGVzdC9kcm9wIHRvIGF2b2lkIHVuYm91bmRlZCBiYWNrbG9nLicsXG4gICAgICAgICAgICBdLmpvaW4oJ1xcbicpXG4gICAgICAgICAgICByZXR1cm4gRGVmZXJyZWQuc3VjY2VlZChmYXRhbCwgQ2F1c2UuZmFpbChlcnIpKS5waXBlKFxuICAgICAgICAgICAgICBFZmZlY3QuYXNWb2lkLFxuICAgICAgICAgICAgICBFZmZlY3QuY2F0Y2hBbGwoKCkgPT4gRWZmZWN0LnZvaWQpLFxuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHJ1bm5lckZpYmVyID0geWllbGQqIEVmZmVjdC5mb3JrU2NvcGVkKFxuICAgICAgICAgICAgUHJvY2Vzc0NvbmN1cnJlbmN5LnJ1blByb2Nlc3NUcmlnZ2VyU3RyZWFtKHtcbiAgICAgICAgICAgICAgc3RyZWFtOiB0cmlnZ2VyU3RyZWFtLFxuICAgICAgICAgICAgICBwb2xpY3ksXG4gICAgICAgICAgICAgIGFzc2lnblRyaWdnZXJTZXEsXG4gICAgICAgICAgICAgIHJ1bjogKHRyaWdnZXIpID0+IG1ha2VDaGFpblJ1bih0cmlnZ2VyLCBmYXRhbCksXG4gICAgICAgICAgICAgIG9uRHJvcDogKHRyaWdnZXIpID0+IGVtaXRUcmlnZ2VyRXZlbnQodHJpZ2dlciwgJ3dhcm5pbmcnKSxcbiAgICAgICAgICAgICAgb25RdWV1ZU92ZXJmbG93OiByZXBvcnRRdWV1ZU92ZXJmbG93LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKVxuXG4gICAgICAgICAgaWYgKGF1dG9TdGFydCkge1xuICAgICAgICAgICAgeWllbGQqIFF1ZXVlLm9mZmVyKGluc3RhbmNlU3RhdGUucGxhdGZvcm1UcmlnZ2Vyc1F1ZXVlLCB7XG4gICAgICAgICAgICAgIGtpbmQ6ICdwbGF0Zm9ybUV2ZW50JyxcbiAgICAgICAgICAgICAgbmFtZTogYm9vdFRyaWdnZXJTcGVjPy5uYW1lLFxuICAgICAgICAgICAgICBwbGF0Zm9ybUV2ZW50OiBSVU5USU1FX0JPT1RfRVZFTlQsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGNhdXNlID0geWllbGQqIERlZmVycmVkLmF3YWl0KGZhdGFsKVxuICAgICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHQocnVubmVyRmliZXIpXG4gICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbENhdXNlKGNhdXNlKVxuICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IGZpYmVyID0geWllbGQqIEVmZmVjdC5mb3JrSW4oaW5zdGFsbGF0aW9uLmZvcmtTY29wZSkoXG4gICAgICAgICAgRWZmZWN0LnNjb3BlZChpbnN0YW5jZVByb2dyYW0pLnBpcGUoXG4gICAgICAgICAgICBFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoY2F1c2UpID0+XG4gICAgICAgICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgICAgICAvLyBJbnRlcnJ1cHRpb25zICh0eXBpY2FsbHkgZnJvbSBzY29wZSBkaXNwb3NlIC8gbWFudWFsIHN0b3ApIHNob3VsZCBub3QgYmUgdHJlYXRlZCBhcyBwcm9jZXNzIGZhaWx1cmVzLlxuICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSB3ZSBlbWl0IHByb2Nlc3M6ZXJyb3IvZGlhZ25vc3RpYyBkdXJpbmcgc2NvcGUgc2h1dGRvd24gYW5kIG1heSBkZWFkbG9jayBkaXNwb3NhbC5cbiAgICAgICAgICAgICAgICBpZiAoQ2F1c2UuaXNJbnRlcnJ1cHRlZE9ubHkoY2F1c2UpKSB7XG4gICAgICAgICAgICAgICAgICAvLyBJZiBzdG9wSW5zdGFuY2UgYWxyZWFkeSBhZHZhbmNlZCB0aGUgc3RhdHVzIHRvIHN0b3BwaW5nLCBzdG9wSW5zdGFuY2Ugb3ducyB0aGUgc3RvcCBldmVudCBhbmQgZmluYWwgc3RhdGUuXG4gICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VTdGF0ZS5zdGF0dXMuc3RhdHVzID09PSAnc3RvcHBpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgdHJlYXQgYXMgYSBuYXR1cmFsIHN0b3AgZHVlIHRvIHNjb3BlIGRpc3Bvc2FsIChlLmcuIG1vZHVsZUluc3RhbmNlIHNjb3BlIGNsb3NpbmcpLlxuICAgICAgICAgICAgICAgICAgaW5zdGFuY2VTdGF0ZS5zdGF0dXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmluc3RhbmNlU3RhdGUuc3RhdHVzLFxuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6ICdzdG9wcGVkJyxcbiAgICAgICAgICAgICAgICAgICAgc3RvcHBlZFJlYXNvbjogJ3Njb3BlRGlzcG9zZWQnLFxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgaW5zdGFuY2VTdGF0ZS5maWJlciA9IHVuZGVmaW5lZFxuXG4gICAgICAgICAgICAgICAgICB5aWVsZCogRWZmZWN0LnVuaW50ZXJydXB0aWJsZShcbiAgICAgICAgICAgICAgICAgICAgZW1pdCh7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3Byb2Nlc3M6c3RvcCcsXG4gICAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgICAgICAgc2V2ZXJpdHk6ICdpbmZvJyxcbiAgICAgICAgICAgICAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICApXG5cbiAgICAgICAgICAgICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbiA9IGluc3RhbGxhdGlvbnMuZ2V0KGluc3RhbGxhdGlvbktleSlcbiAgICAgICAgICAgICAgICAgIGlmIChpbnN0YWxsYXRpb24/LnBlbmRpbmdTdGFydCkge1xuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIHlpZWxkKiBzdGFydEluc3RhbGxhdGlvbihpbnN0YWxsYXRpb25LZXkpXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwcmltYXJ5ID0gT3B0aW9uLmdldE9yRWxzZShDYXVzZS5mYWlsdXJlT3B0aW9uKGNhdXNlKSwgKCkgPT5cbiAgICAgICAgICAgICAgICAgIE9wdGlvbi5nZXRPckVsc2UoQ2F1c2UuZGllT3B0aW9uKGNhdXNlKSwgKCkgPT4gY2F1c2UpLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICBjb25zdCBzdW1tYXJ5ID0gdG9TZXJpYWxpemFibGVFcnJvclN1bW1hcnkocHJpbWFyeSlcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvcjogU2VyaWFsaXphYmxlRXJyb3JTdW1tYXJ5ID0gc3VtbWFyeS5lcnJvclN1bW1hcnkgYXMgYW55XG5cbiAgICAgICAgICAgICAgICBpbnN0YW5jZVN0YXRlLnN0YXR1cyA9IHtcbiAgICAgICAgICAgICAgICAgIC4uLmluc3RhbmNlU3RhdGUuc3RhdHVzLFxuICAgICAgICAgICAgICAgICAgc3RhdHVzOiAnZmFpbGVkJyxcbiAgICAgICAgICAgICAgICAgIHN0b3BwZWRSZWFzb246ICdmYWlsZWQnLFxuICAgICAgICAgICAgICAgICAgbGFzdEVycm9yOiBlcnJvcixcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB5aWVsZCogZW1pdCh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAncHJvY2VzczplcnJvcicsXG4gICAgICAgICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgICAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgZXZlbnRTZXE6IGluc3RhbmNlU3RhdGUubmV4dEV2ZW50U2VxKyssXG4gICAgICAgICAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICBjb25zdCBkZWNpc2lvbiA9IFN1cGVydmlzaW9uLm9uRmFpbHVyZShcbiAgICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLmVycm9yUG9saWN5LFxuICAgICAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uLnN1cGVydmlzaW9uLFxuICAgICAgICAgICAgICAgICAgRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uLnN1cGVydmlzaW9uID0gZGVjaXNpb24ubmV4dFN0YXRlXG5cbiAgICAgICAgICAgICAgICBpZiAoZGVjaXNpb24uZGVjaXNpb24gPT09ICdyZXN0YXJ0Jykge1xuICAgICAgICAgICAgICAgICAgLy8gc3VwZXJ2aXNlOiBjb250cm9sbGVkIHJlc3RhcnQgKHJ1blNlcSBpbmNyZW1lbnRzKSBhbmQgZW1pdCBhIHJlc3RhcnQgZXZlbnQuXG4gICAgICAgICAgICAgICAgICB5aWVsZCogZW1pdCh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdwcm9jZXNzOnJlc3RhcnQnLFxuICAgICAgICAgICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgICAgICAgICAgc2V2ZXJpdHk6ICd3YXJuaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRTZXE6IGluc3RhbmNlU3RhdGUubmV4dEV2ZW50U2VxKyssXG4gICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcE1zOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICB5aWVsZCogc3RhcnRJbnN0YWxsYXRpb24oaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB5aWVsZCogZW1pdEVycm9yRGlhZ25vc3RpYyhcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uLmlkZW50aXR5LnNjb3BlLFxuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24uaWRlbnRpdHkucHJvY2Vzc0lkLFxuICAgICAgICAgICAgICAgICAgICAncHJvY2Vzczo6ZmFpbGVkX3N0b3AnLFxuICAgICAgICAgICAgICAgICAgICAnUHJvY2VzcyBmYWlsZWQgYW5kIHN0b3BwZWQgKGZhaWxTdG9wIC8gcmVzdGFydCBsaW1pdCByZWFjaGVkKS4nLFxuICAgICAgICAgICAgICAgICAgICBgcHJvY2Vzc0lkPSR7aW5zdGFsbGF0aW9uLmlkZW50aXR5LnByb2Nlc3NJZH0gc2NvcGVLZXk9JHtpbnN0YWxsYXRpb24uc2NvcGVLZXl9IGZhaWx1cmVzPSR7ZGVjaXNpb24ud2l0aGluV2luZG93RmFpbHVyZXN9IG1heFJlc3RhcnRzPSR7ZGVjaXNpb24ubWF4UmVzdGFydHN9YCxcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApLFxuICAgICAgICApXG5cbiAgICAgICAgaW5zdGFuY2VTdGF0ZS5maWJlciA9IGZpYmVyIGFzIEZpYmVyLlJ1bnRpbWVGaWJlcjx1bmtub3duLCB1bmtub3duPlxuICAgICAgICBpbnN0YW5jZVN0YXRlLnN0YXR1cyA9IHtcbiAgICAgICAgICAuLi5pbnN0YW5jZVN0YXRlLnN0YXR1cyxcbiAgICAgICAgICBzdGF0dXM6ICdydW5uaW5nJyxcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJlc3QtZWZmb3J0OiBlbnN1cmUgdGhlIGluc3RhbmNlIGZpYmVyIHN0YXJ0cyBzdWJzY3JpYmluZyB0byB0cmlnZ2VyIHN0cmVhbXMgYmVmb3JlIGluc3RhbGwvc3RhcnQgcmV0dXJucyxcbiAgICAgICAgLy8gYXZvaWRpbmcgbG9zdCBtb2R1bGVBY3Rpb24vbW9kdWxlU3RhdGVDaGFuZ2UgdHJpZ2dlcnMgcmlnaHQgYWZ0ZXIgZW52IGlzIGJ1aWx0IGFuZCBkaXNwYXRjaCBoYXBwZW5zLlxuICAgICAgICB5aWVsZCogRWZmZWN0LnlpZWxkTm93KClcbiAgICAgIH0pXG5cbiAgICBjb25zdCBpbnN0YWxsID0gPEUsIFI+KFxuICAgICAgcHJvY2VzczogRWZmZWN0LkVmZmVjdDx2b2lkLCBFLCBSPixcbiAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgcmVhZG9ubHkgc2NvcGU6IFByb2Nlc3NTY29wZVxuICAgICAgICByZWFkb25seSBlbmFibGVkPzogYm9vbGVhblxuICAgICAgICByZWFkb25seSBpbnN0YWxsZWRBdD86IHN0cmluZ1xuICAgICAgICByZWFkb25seSBtb2RlPzogUHJvY2Vzc0luc3RhbGxNb2RlXG4gICAgICB9LFxuICAgICk6IEVmZmVjdC5FZmZlY3Q8UHJvY2Vzc0luc3RhbGxhdGlvbiB8IHVuZGVmaW5lZCwgbmV2ZXIsIFI+ID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSBNZXRhLmdldE1ldGEocHJvY2VzcylcbiAgICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW52ID0geWllbGQqIEVmZmVjdC5jb250ZXh0PFI+KClcbiAgICAgICAgY29uc3QgZm9ya1Njb3BlT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKFNjb3BlLlNjb3BlKVxuICAgICAgICBjb25zdCBmb3JrU2NvcGUgPSBPcHRpb24uaXNTb21lKGZvcmtTY29wZU9wdCkgPyBmb3JrU2NvcGVPcHQudmFsdWUgOiBydW50aW1lU2NvcGVcblxuICAgICAgICBjb25zdCBzY29wZUtleSA9IElkZW50aXR5LnNjb3BlS2V5RnJvbVNjb3BlKG9wdGlvbnMuc2NvcGUpXG4gICAgICAgIGNvbnN0IGlkZW50aXR5ID0ge1xuICAgICAgICAgIHByb2Nlc3NJZDogbWV0YS5kZWZpbml0aW9uLnByb2Nlc3NJZCxcbiAgICAgICAgICBzY29wZTogb3B0aW9ucy5zY29wZSxcbiAgICAgICAgfSBhcyBjb25zdFxuXG4gICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbktleSA9IElkZW50aXR5Lmluc3RhbGxhdGlvbktleUZyb21JZGVudGl0eShpZGVudGl0eSlcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBpbnN0YWxsYXRpb25zLmdldChpbnN0YWxsYXRpb25LZXkpXG4gICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgIGV4aXN0aW5nLmVudiA9IGVudiBhcyBDb250ZXh0LkNvbnRleHQ8YW55PlxuICAgICAgICAgIGV4aXN0aW5nLmZvcmtTY29wZSA9IGZvcmtTY29wZVxuICAgICAgICAgIGV4aXN0aW5nLmVuYWJsZWQgPSBvcHRpb25zLmVuYWJsZWQgPz8gdHJ1ZVxuICAgICAgICAgIGV4aXN0aW5nLmluc3RhbGxlZEF0ID0gb3B0aW9ucy5pbnN0YWxsZWRBdCA/PyBleGlzdGluZy5pbnN0YWxsZWRBdFxuICAgICAgICAgIGlmICghZXhpc3RpbmcuZW5hYmxlZCkge1xuICAgICAgICAgICAgZXhpc3RpbmcucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgICAgZW5hYmxlZDogZXhpc3RpbmcuZW5hYmxlZCxcbiAgICAgICAgICAgICAgaW5zdGFsbGVkQXQ6IGV4aXN0aW5nLmluc3RhbGxlZEF0LFxuICAgICAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc0luc3RhbGxhdGlvblxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGN1cnJlbnRJZCA9IGV4aXN0aW5nLmN1cnJlbnRJbnN0YW5jZUlkXG4gICAgICAgICAgY29uc3QgY3VycmVudCA9IGN1cnJlbnRJZCA/IGluc3RhbmNlcy5nZXQoY3VycmVudElkKSA6IHVuZGVmaW5lZFxuICAgICAgICAgIGNvbnN0IHN0YXR1cyA9IGN1cnJlbnQ/LnN0YXR1cy5zdGF0dXNcblxuICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdydW5uaW5nJyB8fCBzdGF0dXMgPT09ICdzdGFydGluZycpIHtcbiAgICAgICAgICAgIGNvbnN0IG1vZGU6IFByb2Nlc3NJbnN0YWxsTW9kZSA9IG9wdGlvbnMubW9kZSA/PyAnc3dpdGNoJ1xuICAgICAgICAgICAgaWYgKG1vZGUgPT09ICdzd2l0Y2gnICYmIGN1cnJlbnQgJiYgY3VycmVudC5mb3JrU2NvcGUgIT09IGZvcmtTY29wZSkge1xuICAgICAgICAgICAgICBleGlzdGluZy5wZW5kaW5nU3RhcnQgPSB7IGZvcmtTY29wZSB9XG4gICAgICAgICAgICAgIHlpZWxkKiBTY29wZS5hZGRGaW5hbGl6ZXIoXG4gICAgICAgICAgICAgICAgZm9ya1Njb3BlLFxuICAgICAgICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbiA9IGluc3RhbGxhdGlvbnMuZ2V0KGluc3RhbGxhdGlvbktleSlcbiAgICAgICAgICAgICAgICAgIGlmICghaW5zdGFsbGF0aW9uKSByZXR1cm5cbiAgICAgICAgICAgICAgICAgIGlmIChpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0Py5mb3JrU2NvcGUgPT09IGZvcmtTY29wZSkge1xuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGV4aXN0aW5nLnBlbmRpbmdTdGFydCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICAgIGVuYWJsZWQ6IGV4aXN0aW5nLmVuYWJsZWQsXG4gICAgICAgICAgICAgIGluc3RhbGxlZEF0OiBleGlzdGluZy5pbnN0YWxsZWRBdCxcbiAgICAgICAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NJbnN0YWxsYXRpb25cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc3RhdHVzID09PSAnc3RvcHBpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBtb2RlOiBQcm9jZXNzSW5zdGFsbE1vZGUgPSBvcHRpb25zLm1vZGUgPz8gJ3N3aXRjaCdcbiAgICAgICAgICAgIGlmIChtb2RlID09PSAnc3dpdGNoJykge1xuICAgICAgICAgICAgICBleGlzdGluZy5wZW5kaW5nU3RhcnQgPSB7IGZvcmtTY29wZSB9XG4gICAgICAgICAgICAgIHlpZWxkKiBTY29wZS5hZGRGaW5hbGl6ZXIoXG4gICAgICAgICAgICAgICAgZm9ya1Njb3BlLFxuICAgICAgICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbiA9IGluc3RhbGxhdGlvbnMuZ2V0KGluc3RhbGxhdGlvbktleSlcbiAgICAgICAgICAgICAgICAgIGlmICghaW5zdGFsbGF0aW9uKSByZXR1cm5cbiAgICAgICAgICAgICAgICAgIGlmIChpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0Py5mb3JrU2NvcGUgPT09IGZvcmtTY29wZSkge1xuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGV4aXN0aW5nLnBlbmRpbmdTdGFydCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICAgIGVuYWJsZWQ6IGV4aXN0aW5nLmVuYWJsZWQsXG4gICAgICAgICAgICAgIGluc3RhbGxlZEF0OiBleGlzdGluZy5pbnN0YWxsZWRBdCxcbiAgICAgICAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NJbnN0YWxsYXRpb25cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBleGlzdGluZy5wZW5kaW5nU3RhcnQgPSB1bmRlZmluZWRcbiAgICAgICAgICB5aWVsZCogc3RhcnRJbnN0YWxsYXRpb24oaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgIGVuYWJsZWQ6IGV4aXN0aW5nLmVuYWJsZWQsXG4gICAgICAgICAgICBpbnN0YWxsZWRBdDogZXhpc3RpbmcuaW5zdGFsbGVkQXQsXG4gICAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc0luc3RhbGxhdGlvblxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVyaXZlIGFuIGVmZmVjdCBmb3IgdGhpcyBpbnN0YWxsYXRpb24gdG8gYXZvaWQgb3ZlcndyaXRpbmcgbWV0YSBvbiB0aGUgb3JpZ2luYWwgRWZmZWN0IChyZXVzZWQgYWNyb3NzIHNjb3BlcykuXG4gICAgICAgIC8vIE5vdGU6IGRvIG5vdCBwcm92aWRlIGVudiBlYWdlcmx5OyB3ZSBtYXkgbmVlZCB0byBsYXllciBhZGRpdGlvbmFsIGNvbnRleHQgcGVyLXRyaWdnZXIgZXhlY3V0aW9uIChlLmcuIGRpc3BhdGNoIGNoYWluIGRpYWdub3N0aWNzKS5cbiAgICAgICAgY29uc3QgZGVyaXZlZCA9IEVmZmVjdC5zdXNwZW5kKCgpID0+IHByb2Nlc3MpXG4gICAgICAgIE1ldGEuYXR0YWNoTWV0YShkZXJpdmVkLCB7XG4gICAgICAgICAgLi4ubWV0YSxcbiAgICAgICAgICBpbnN0YWxsYXRpb25TY29wZTogb3B0aW9ucy5zY29wZSxcbiAgICAgICAgfSlcblxuICAgICAgICBjb25zdCBpbnN0YWxsYXRpb246IEluc3RhbGxhdGlvblN0YXRlID0ge1xuICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgIHNjb3BlS2V5LFxuICAgICAgICAgIGRlZmluaXRpb246IG1ldGEuZGVmaW5pdGlvbixcbiAgICAgICAgICBlbnY6IGVudiBhcyBDb250ZXh0LkNvbnRleHQ8YW55PixcbiAgICAgICAgICBmb3JrU2NvcGUsXG4gICAgICAgICAgcHJvY2VzczogZGVyaXZlZCBhcyB1bmtub3duIGFzIEVmZmVjdC5FZmZlY3Q8dm9pZCwgYW55LCB1bmtub3duPixcbiAgICAgICAgICBraW5kOiBtZXRhLmtpbmQgPz8gJ3Byb2Nlc3MnLFxuICAgICAgICAgIGVuYWJsZWQ6IG9wdGlvbnMuZW5hYmxlZCA/PyB0cnVlLFxuICAgICAgICAgIGluc3RhbGxlZEF0OiBvcHRpb25zLmluc3RhbGxlZEF0LFxuICAgICAgICAgIG5leHRSdW5TZXE6IDEsXG4gICAgICAgICAgc3VwZXJ2aXNpb246IFN1cGVydmlzaW9uLmluaXRpYWxTdGF0ZSgpLFxuICAgICAgICAgIHBlbmRpbmdTdGFydDogdW5kZWZpbmVkLFxuICAgICAgICB9XG5cbiAgICAgICAgaW5zdGFsbGF0aW9ucy5zZXQoaW5zdGFsbGF0aW9uS2V5LCBpbnN0YWxsYXRpb24pXG5cbiAgICAgICAgaWYgKGluc3RhbGxhdGlvbi5lbmFibGVkKSB7XG4gICAgICAgICAgeWllbGQqIHN0YXJ0SW5zdGFsbGF0aW9uKGluc3RhbGxhdGlvbktleSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgZW5hYmxlZDogaW5zdGFsbGF0aW9uLmVuYWJsZWQsXG4gICAgICAgICAgaW5zdGFsbGVkQXQ6IGluc3RhbGxhdGlvbi5pbnN0YWxsZWRBdCxcbiAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc0luc3RhbGxhdGlvblxuICAgICAgfSlcblxuICAgIGNvbnN0IGxpc3RJbnN0YWxsYXRpb25zOiBQcm9jZXNzUnVudGltZVsnbGlzdEluc3RhbGxhdGlvbnMnXSA9IChmaWx0ZXIpID0+XG4gICAgICBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNjb3BlVHlwZSA9IGZpbHRlcj8uc2NvcGVUeXBlXG4gICAgICAgIGNvbnN0IHNjb3BlS2V5ID0gZmlsdGVyPy5zY29wZUtleVxuICAgICAgICBjb25zdCBvdXQ6IFByb2Nlc3NJbnN0YWxsYXRpb25bXSA9IFtdXG4gICAgICAgIGZvciAoY29uc3QgaW5zdGFsbGF0aW9uIG9mIGluc3RhbGxhdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgICAgICBpZiAoc2NvcGVUeXBlICYmIGluc3RhbGxhdGlvbi5pZGVudGl0eS5zY29wZS50eXBlICE9PSBzY29wZVR5cGUpIGNvbnRpbnVlXG4gICAgICAgICAgaWYgKHNjb3BlS2V5ICYmIGluc3RhbGxhdGlvbi5zY29wZUtleSAhPT0gc2NvcGVLZXkpIGNvbnRpbnVlXG4gICAgICAgICAgb3V0LnB1c2goe1xuICAgICAgICAgICAgaWRlbnRpdHk6IGluc3RhbGxhdGlvbi5pZGVudGl0eSxcbiAgICAgICAgICAgIGVuYWJsZWQ6IGluc3RhbGxhdGlvbi5lbmFibGVkLFxuICAgICAgICAgICAgaW5zdGFsbGVkQXQ6IGluc3RhbGxhdGlvbi5pbnN0YWxsZWRBdCxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXRcbiAgICAgIH0pXG5cbiAgICBjb25zdCBnZXRJbnN0YW5jZVN0YXR1czogUHJvY2Vzc1J1bnRpbWVbJ2dldEluc3RhbmNlU3RhdHVzJ10gPSAocHJvY2Vzc0luc3RhbmNlSWQpID0+XG4gICAgICBFZmZlY3Quc3luYygoKSA9PiBpbnN0YW5jZXMuZ2V0KHByb2Nlc3NJbnN0YW5jZUlkKT8uc3RhdHVzKVxuXG4gICAgY29uc3QgY29udHJvbEluc3RhbmNlOiBQcm9jZXNzUnVudGltZVsnY29udHJvbEluc3RhbmNlJ10gPSAocHJvY2Vzc0luc3RhbmNlSWQsIHJlcXVlc3QpID0+XG4gICAgICBFZmZlY3Quc3VzcGVuZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluc3RhbmNlID0gaW5zdGFuY2VzLmdldChwcm9jZXNzSW5zdGFuY2VJZClcbiAgICAgICAgaWYgKCFpbnN0YW5jZSkge1xuICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNob3VsZE5vb3BEdWVUb1N5bmNUeG4oaW5zdGFuY2Uuc2NvcGUsICdwcm9jZXNzX2NvbnRyb2xfaW5fdHJhbnNhY3Rpb24nKS5waXBlKFxuICAgICAgICAgIEVmZmVjdC5mbGF0TWFwKChub29wKSA9PiB7XG4gICAgICAgICAgICBpZiAobm9vcCkge1xuICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlcXVlc3QuYWN0aW9uID09PSAnc3RvcCcpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHN0b3BJbnN0YW5jZShpbnN0YW5jZSwgJ21hbnVhbFN0b3AnKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVxdWVzdC5hY3Rpb24gPT09ICdyZXN0YXJ0Jykge1xuICAgICAgICAgICAgICByZXR1cm4gc3RvcEluc3RhbmNlKGluc3RhbmNlLCAnbWFudWFsU3RvcCcpLnBpcGUoXG4gICAgICAgICAgICAgICAgRWZmZWN0LmZsYXRNYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uID0gaW5zdGFsbGF0aW9ucy5nZXQoaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgICAgICAgaWYgKCFpbnN0YWxsYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24uY3VycmVudEluc3RhbmNlSWQgPSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgIHJldHVybiBzdGFydEluc3RhbGxhdGlvbihpbnN0YW5jZS5pbnN0YWxsYXRpb25LZXkpXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gc3RhcnQ6IG9ubHkgYXBwbGllcyB0byBzdG9wcGVkIGluc3RhbmNlczsgcmV1c2VzIGN1cnJlbnQgcnVuU2VxIHdpdGhvdXQgaW5jcmVtZW50aW5nLlxuICAgICAgICAgICAgaWYgKHJlcXVlc3QuYWN0aW9uID09PSAnc3RhcnQnKSB7XG4gICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5zdGF0dXMuc3RhdHVzID09PSAncnVubmluZycgfHwgaW5zdGFuY2Uuc3RhdHVzLnN0YXR1cyA9PT0gJ3N0YXJ0aW5nJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uID0gaW5zdGFsbGF0aW9ucy5nZXQoaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgICBpZiAoIWluc3RhbGxhdGlvbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGluc3RhbGxhdGlvbi5jdXJyZW50SW5zdGFuY2VJZCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgICByZXR1cm4gc3RhcnRJbnN0YWxsYXRpb24oaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgfSlcblxuICAgIGNvbnN0IGRlbGl2ZXJQbGF0Zm9ybUV2ZW50OiBQcm9jZXNzUnVudGltZVsnZGVsaXZlclBsYXRmb3JtRXZlbnQnXSA9IChldmVudCkgPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3Qgbm9vcCA9IHlpZWxkKiBUYXNrUnVubmVyLnNob3VsZE5vb3BJblN5bmNUcmFuc2FjdGlvbkZpYmVyKHtcbiAgICAgICAgICBjb2RlOiAncHJvY2Vzczo6aW52YWxpZF91c2FnZScsXG4gICAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICdQcm9jZXNzUnVudGltZSBwbGF0Zm9ybSBldmVudHMgYXJlIG5vdCBhbGxvd2VkIGluc2lkZSBhIHN5bmNocm9ub3VzIFN0YXRlVHJhbnNhY3Rpb24gYm9keSAoaXQgbWF5IGRlYWRsb2NrIHRoZSB0eG5RdWV1ZSkuJyxcbiAgICAgICAgICBoaW50OiAnRGVsaXZlciBwbGF0Zm9ybUV2ZW50IG91dHNpZGUgdGhlIHRyYW5zYWN0aW9uIHdpbmRvdy4nLFxuICAgICAgICAgIGtpbmQ6ICdwcm9jZXNzX3BsYXRmb3JtX2V2ZW50X2luX3RyYW5zYWN0aW9uJyxcbiAgICAgICAgfSlcbiAgICAgICAgaWYgKG5vb3ApIHJldHVyblxuXG4gICAgICAgIGNvbnN0IHRhcmdldHMgPSBBcnJheS5mcm9tKGluc3RhbmNlcy52YWx1ZXMoKSlcbiAgICAgICAgY29uc3QgZXZlbnROYW1lID0gZXZlbnQuZXZlbnROYW1lXG5cbiAgICAgICAgeWllbGQqIEVmZmVjdC5mb3JFYWNoKFxuICAgICAgICAgIHRhcmdldHMsXG4gICAgICAgICAgKGluc3RhbmNlKSA9PlxuICAgICAgICAgICAgRWZmZWN0LnN1c3BlbmQoKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoaW5zdGFuY2Uuc3RhdHVzLnN0YXR1cyAhPT0gJ3N0YXJ0aW5nJyAmJiBpbnN0YW5jZS5zdGF0dXMuc3RhdHVzICE9PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbiA9IGluc3RhbGxhdGlvbnMuZ2V0KGluc3RhbmNlLmluc3RhbGxhdGlvbktleSlcbiAgICAgICAgICAgICAgaWYgKCFpbnN0YWxsYXRpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNvbnN0IHNwZWNzID0gaW5zdGFsbGF0aW9uLmRlZmluaXRpb24udHJpZ2dlcnMuZmlsdGVyKFxuICAgICAgICAgICAgICAgICh0KTogdCBpcyBFeHRyYWN0PFByb2Nlc3NUcmlnZ2VyU3BlYywgeyByZWFkb25seSBraW5kOiAncGxhdGZvcm1FdmVudCcgfT4gPT5cbiAgICAgICAgICAgICAgICAgIHQua2luZCA9PT0gJ3BsYXRmb3JtRXZlbnQnICYmIHQucGxhdGZvcm1FdmVudCA9PT0gZXZlbnROYW1lLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIGlmIChzcGVjcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHJldHVybiBFZmZlY3QuZm9yRWFjaChcbiAgICAgICAgICAgICAgICBzcGVjcyxcbiAgICAgICAgICAgICAgICAoc3BlYykgPT5cbiAgICAgICAgICAgICAgICAgIFF1ZXVlLm9mZmVyKGluc3RhbmNlLnBsYXRmb3JtVHJpZ2dlcnNRdWV1ZSwge1xuICAgICAgICAgICAgICAgICAgICBraW5kOiAncGxhdGZvcm1FdmVudCcsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IHNwZWMubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm1FdmVudDogc3BlYy5wbGF0Zm9ybUV2ZW50LFxuICAgICAgICAgICAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc1RyaWdnZXIpLFxuICAgICAgICAgICAgICAgIHsgZGlzY2FyZDogdHJ1ZSB9LFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB7IGRpc2NhcmQ6IHRydWUgfSxcbiAgICAgICAgKVxuICAgICAgfSlcblxuICAgIGNvbnN0IGV2ZW50c1N0cmVhbTogUHJvY2Vzc1J1bnRpbWVbJ2V2ZW50cyddID0gU3RyZWFtLmZyb21QdWJTdWIoZXZlbnRzSHViKVxuXG4gICAgY29uc3QgZ2V0RXZlbnRzU25hcHNob3Q6IFByb2Nlc3NSdW50aW1lWydnZXRFdmVudHNTbmFwc2hvdCddID0gKCkgPT4gRWZmZWN0LnN5bmMoKCkgPT4gZXZlbnRzQnVmZmVyLnNsaWNlKCkpXG5cbiAgICB5aWVsZCogRWZmZWN0LmFkZEZpbmFsaXplcigoKSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGluc3RhbGxhdGlvbiBvZiBpbnN0YWxsYXRpb25zLnZhbHVlcygpKSB7XG4gICAgICAgICAgaW5zdGFsbGF0aW9uLnBlbmRpbmdTdGFydCA9IHVuZGVmaW5lZFxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgaW5zdGFuY2Ugb2YgaW5zdGFuY2VzLnZhbHVlcygpKSB7XG4gICAgICAgICAgaWYgKGluc3RhbmNlLmZpYmVyKSB7XG4gICAgICAgICAgICB5aWVsZCogc3RvcEluc3RhbmNlKGluc3RhbmNlLCAnc2NvcGVEaXNwb3NlZCcpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KS5waXBlKFxuICAgICAgICBFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoY2F1c2UpID0+XG4gICAgICAgICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgLy8gRmluYWxpemVycyBtdXN0IG5vdCB0aHJvdzsgYmVzdC1lZmZvcnQgbG9nZ2luZyBvbmx5LlxuICAgICAgICAgICAgaWYgKGlzRGV2RW52KCkpIHtcbiAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdbUHJvY2Vzc1J1bnRpbWVdIGZpbmFsaXplciBmYWlsZWQnLCBDYXVzZS5wcmV0dHkoY2F1c2UpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApXG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5zdGFsbCxcbiAgICAgIGxpc3RJbnN0YWxsYXRpb25zLFxuICAgICAgZ2V0SW5zdGFuY2VTdGF0dXMsXG4gICAgICBjb250cm9sSW5zdGFuY2UsXG4gICAgICBkZWxpdmVyUGxhdGZvcm1FdmVudCxcbiAgICAgIGV2ZW50czogZXZlbnRzU3RyZWFtLFxuICAgICAgZ2V0RXZlbnRzU25hcHNob3QsXG4gICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc1J1bnRpbWVcbiAgfSlcblxuZXhwb3J0IGNvbnN0IGxheWVyID0gKG9wdGlvbnM/OiB7IHJlYWRvbmx5IG1heEV2ZW50SGlzdG9yeT86IG51bWJlciB9KTogTGF5ZXIuTGF5ZXI8UHJvY2Vzc1J1bnRpbWVUYWcsIG5ldmVyLCBuZXZlcj4gPT5cbiAgTGF5ZXIuc2NvcGVkKFByb2Nlc3NSdW50aW1lVGFnLCBtYWtlKG9wdGlvbnMpKVxuIiwgImltcG9ydCB0eXBlIHsgUHJvY2Vzc0lkZW50aXR5LCBQcm9jZXNzSW5zdGFuY2VJZGVudGl0eSwgUHJvY2Vzc1Njb3BlIH0gZnJvbSAnLi9wcm90b2NvbC5qcydcblxuZXhwb3J0IHR5cGUgUHJvY2Vzc1Njb3BlS2V5ID0gc3RyaW5nXG5cbmV4cG9ydCBjb25zdCBzY29wZUtleUZyb21TY29wZSA9IChzY29wZTogUHJvY2Vzc1Njb3BlKTogUHJvY2Vzc1Njb3BlS2V5ID0+IHtcbiAgc3dpdGNoIChzY29wZS50eXBlKSB7XG4gICAgY2FzZSAnYXBwJzpcbiAgICAgIHJldHVybiBgYXBwOiR7c2NvcGUuYXBwSWR9YFxuICAgIGNhc2UgJ21vZHVsZUluc3RhbmNlJzpcbiAgICAgIHJldHVybiBgbW9kdWxlSW5zdGFuY2U6JHtzY29wZS5tb2R1bGVJZH06OiR7c2NvcGUuaW5zdGFuY2VJZH1gXG4gICAgY2FzZSAndWlTdWJ0cmVlJzpcbiAgICAgIHJldHVybiBgdWlTdWJ0cmVlOiR7c2NvcGUuc3VidHJlZUlkfWBcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgaW5zdGFsbGF0aW9uS2V5RnJvbUlkZW50aXR5ID0gKGlkZW50aXR5OiBQcm9jZXNzSWRlbnRpdHkpOiBzdHJpbmcgPT5cbiAgYCR7aWRlbnRpdHkucHJvY2Vzc0lkfUBAJHtzY29wZUtleUZyb21TY29wZShpZGVudGl0eS5zY29wZSl9YFxuXG5leHBvcnQgY29uc3QgcHJvY2Vzc0luc3RhbmNlSWRGcm9tSWRlbnRpdHkgPSAoaWRlbnRpdHk6IFByb2Nlc3NJbnN0YW5jZUlkZW50aXR5KTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc2NvcGVLZXkgPSBzY29wZUtleUZyb21TY29wZShpZGVudGl0eS5pZGVudGl0eS5zY29wZSlcbiAgcmV0dXJuIGBwcm9jZXNzOiR7aWRlbnRpdHkuaWRlbnRpdHkucHJvY2Vzc0lkfTo6JHtzY29wZUtleX06OnIke2lkZW50aXR5LnJ1blNlcX1gXG59XG4iLCAiaW1wb3J0IHsgRWZmZWN0LCBGaWJlciwgT3B0aW9uLCBSZWYsIFNjb3BlLCBTdHJlYW0gfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgdHlwZSB7IFRhc2tSdW5uZXJNb2RlIH0gZnJvbSAnLi4vVGFza1J1bm5lci5qcydcbmltcG9ydCB0eXBlIHsgUHJvY2Vzc0NvbmN1cnJlbmN5UG9saWN5LCBQcm9jZXNzVHJpZ2dlciB9IGZyb20gJy4vcHJvdG9jb2wuanMnXG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NFUklBTF9RVUVVRV9HVUFSRF9MSU1JVCA9IDQwOTZcbmV4cG9ydCBjb25zdCBERUZBVUxUX1BBUkFMTEVMX0xJTUlUID0gMTZcblxuZXhwb3J0IGNvbnN0IHRvVGFza1J1bm5lck1vZGUgPSAocG9saWN5OiBQcm9jZXNzQ29uY3VycmVuY3lQb2xpY3kpOiBUYXNrUnVubmVyTW9kZSA9PiB7XG4gIHN3aXRjaCAocG9saWN5Lm1vZGUpIHtcbiAgICBjYXNlICdsYXRlc3QnOlxuICAgICAgcmV0dXJuICdsYXRlc3QnXG4gICAgY2FzZSAnc2VyaWFsJzpcbiAgICAgIHJldHVybiAndGFzaydcbiAgICBjYXNlICdkcm9wJzpcbiAgICAgIHJldHVybiAnZXhoYXVzdCdcbiAgICBjYXNlICdwYXJhbGxlbCc6XG4gICAgICByZXR1cm4gJ3BhcmFsbGVsJ1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIFJlc29sdmVkUXVldWVMaW1pdCA9IHtcbiAgLyoqIFVzZXItY29uZmlndXJlZCBsaW1pdDsgdHJlYXRlZCBhcyB1bmxpbWl0ZWQgd2hlbiBvbWl0dGVkIChzdGlsbCBib3VuZGVkIGJ5IHRoZSBndWFyZCkuICovXG4gIHJlYWRvbmx5IGNvbmZpZ3VyZWQ6IG51bWJlciB8ICd1bmJvdW5kZWQnXG4gIC8qKiBSdW50aW1lLWVuZm9yY2VkIGd1YXJkIGxpbWl0IChwcmV2ZW50cyB1bmJvdW5kZWQgbWVtb3J5IGdyb3d0aCkuICovXG4gIHJlYWRvbmx5IGd1YXJkOiBudW1iZXJcbn1cblxuZXhwb3J0IGNvbnN0IHJlc29sdmVRdWV1ZUxpbWl0ID0gKFxuICBtYXhRdWV1ZTogdW5rbm93bixcbiAgb3B0aW9ucz86IHtcbiAgICByZWFkb25seSBkZWZhdWx0R3VhcmQ/OiBudW1iZXJcbiAgfSxcbik6IFJlc29sdmVkUXVldWVMaW1pdCA9PiB7XG4gIGNvbnN0IGRlZmF1bHRHdWFyZCA9IG9wdGlvbnM/LmRlZmF1bHRHdWFyZCA/PyBERUZBVUxUX1NFUklBTF9RVUVVRV9HVUFSRF9MSU1JVFxuXG4gIGNvbnN0IGNvbmZpZ3VyZWQgPVxuICAgIHR5cGVvZiBtYXhRdWV1ZSA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKG1heFF1ZXVlKSAmJiBtYXhRdWV1ZSA+PSAwID8gTWF0aC5mbG9vcihtYXhRdWV1ZSkgOiAndW5ib3VuZGVkJ1xuXG4gIHJldHVybiB7XG4gICAgY29uZmlndXJlZCxcbiAgICBndWFyZDogY29uZmlndXJlZCA9PT0gJ3VuYm91bmRlZCcgPyBkZWZhdWx0R3VhcmQgOiBjb25maWd1cmVkLFxuICB9XG59XG5cbmV4cG9ydCB0eXBlIFByb2Nlc3NUcmlnZ2VyUXVldWVPdmVyZmxvd0luZm8gPSB7XG4gIHJlYWRvbmx5IG1vZGU6ICdzZXJpYWwnIHwgJ3BhcmFsbGVsJ1xuICByZWFkb25seSBjdXJyZW50TGVuZ3RoOiBudW1iZXJcbiAgcmVhZG9ubHkgcGVhazogbnVtYmVyXG4gIHJlYWRvbmx5IGxpbWl0OiBSZXNvbHZlZFF1ZXVlTGltaXRcbiAgcmVhZG9ubHkgcG9saWN5OiBQcm9jZXNzQ29uY3VycmVuY3lQb2xpY3lcbn1cblxuZXhwb3J0IGNvbnN0IHJ1blByb2Nlc3NUcmlnZ2VyU3RyZWFtID0gKGFyZ3M6IHtcbiAgcmVhZG9ubHkgc3RyZWFtOiBTdHJlYW0uU3RyZWFtPFByb2Nlc3NUcmlnZ2VyPlxuICByZWFkb25seSBwb2xpY3k6IFByb2Nlc3NDb25jdXJyZW5jeVBvbGljeVxuICByZWFkb25seSBhc3NpZ25UcmlnZ2VyU2VxOiAodHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIpID0+IFByb2Nlc3NUcmlnZ2VyXG4gIC8qKiBydW4gYSB0cmlnZ2VyIHRvIGNvbXBsZXRpb24gKHRoZSBjYWxsZXIgZGVjaWRlcyB3aGF0IGEgXFxcInJ1blxcXCIgbWVhbnMpLiAqL1xuICByZWFkb25seSBydW46ICh0cmlnZ2VyOiBQcm9jZXNzVHJpZ2dlcikgPT4gRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgU2NvcGUuU2NvcGU+XG4gIC8qKiBpbnZva2VkIHdoZW4gYSB0cmlnZ2VyIGlzIGRyb3BwZWQgKG9ubHkgZm9yIG1vZGU9ZHJvcCkuICovXG4gIHJlYWRvbmx5IG9uRHJvcDogKHRyaWdnZXI6IFByb2Nlc3NUcmlnZ2VyKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQ+XG4gIC8qKiBpbnZva2VkIHdoZW4gaW50ZXJuYWwgcXVldWUgZ3VhcmQgaXMgZXhjZWVkZWQgKGZhaWwtc3RvcCBieSBkZWZhdWx0KS4gKi9cbiAgcmVhZG9ubHkgb25RdWV1ZU92ZXJmbG93OiAoaW5mbzogUHJvY2Vzc1RyaWdnZXJRdWV1ZU92ZXJmbG93SW5mbykgPT4gRWZmZWN0LkVmZmVjdDx2b2lkPlxuICByZWFkb25seSBkZWZhdWx0UGFyYWxsZWxMaW1pdD86IG51bWJlclxuICByZWFkb25seSBkZWZhdWx0UXVldWVHdWFyZD86IG51bWJlclxufSk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIFNjb3BlLlNjb3BlPiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3QgcG9saWN5ID0gYXJncy5wb2xpY3lcbiAgICBjb25zdCBkZWZhdWx0UXVldWVHdWFyZCA9IGFyZ3MuZGVmYXVsdFF1ZXVlR3VhcmQgPz8gREVGQVVMVF9TRVJJQUxfUVVFVUVfR1VBUkRfTElNSVRcblxuICAgIGlmIChwb2xpY3kubW9kZSA9PT0gJ2xhdGVzdCcpIHtcbiAgICAgIGNvbnN0IHN0YXRlUmVmID0geWllbGQqIFJlZi5tYWtlPHtcbiAgICAgICAgcmVhZG9ubHkgZmliZXI/OiBGaWJlci5SdW50aW1lRmliZXI8dm9pZCwgbmV2ZXI+XG4gICAgICAgIHJlYWRvbmx5IHJ1bm5pbmdJZDogbnVtYmVyXG4gICAgICAgIHJlYWRvbmx5IG5leHRJZDogbnVtYmVyXG4gICAgICB9Pih7IGZpYmVyOiB1bmRlZmluZWQsIHJ1bm5pbmdJZDogMCwgbmV4dElkOiAwIH0pXG5cbiAgICAgIGNvbnN0IG9uVHJpZ2dlciA9ICh0cmlnZ2VyMDogUHJvY2Vzc1RyaWdnZXIpOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBTY29wZS5TY29wZT4gPT5cbiAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgIGNvbnN0IHRyaWdnZXIgPSBhcmdzLmFzc2lnblRyaWdnZXJTZXEodHJpZ2dlcjApXG5cbiAgICAgICAgICBjb25zdCBbcHJldkZpYmVyLCBwcmV2UnVubmluZ0lkLCBydW5JZF0gPSB5aWVsZCogUmVmLm1vZGlmeShzdGF0ZVJlZiwgKHMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5leHRJZCA9IHMubmV4dElkICsgMVxuICAgICAgICAgICAgcmV0dXJuIFtbcy5maWJlciwgcy5ydW5uaW5nSWQsIG5leHRJZF0gYXMgY29uc3QsIHsgLi4ucywgbmV4dElkLCBydW5uaW5nSWQ6IG5leHRJZCB9XSBhcyBjb25zdFxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBpZiAocHJldkZpYmVyICYmIHByZXZSdW5uaW5nSWQgIT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGRvbmUgPSB5aWVsZCogRmliZXIucG9sbChwcmV2RmliZXIpXG4gICAgICAgICAgICBpZiAoT3B0aW9uLmlzTm9uZShkb25lKSkge1xuICAgICAgICAgICAgICB5aWVsZCogRmliZXIuaW50ZXJydXB0Rm9yayhwcmV2RmliZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZmliZXIgPSB5aWVsZCogRWZmZWN0LmZvcmtTY29wZWQoXG4gICAgICAgICAgICBhcmdzXG4gICAgICAgICAgICAgIC5ydW4odHJpZ2dlcilcbiAgICAgICAgICAgICAgLnBpcGUoRWZmZWN0LmVuc3VyaW5nKFJlZi51cGRhdGUoc3RhdGVSZWYsIChzKSA9PiAocy5ydW5uaW5nSWQgPT09IHJ1bklkID8geyAuLi5zLCBydW5uaW5nSWQ6IDAgfSA6IHMpKSkpLFxuICAgICAgICAgIClcblxuICAgICAgICAgIHlpZWxkKiBSZWYudXBkYXRlKHN0YXRlUmVmLCAocykgPT4gKHsgLi4ucywgZmliZXIgfSkpXG4gICAgICAgIH0pXG5cbiAgICAgIHJldHVybiB5aWVsZCogU3RyZWFtLnJ1bkZvckVhY2goYXJncy5zdHJlYW0sIG9uVHJpZ2dlcilcbiAgICB9XG5cbiAgICBjb25zdCBidXN5UmVmID0geWllbGQqIFJlZi5tYWtlKGZhbHNlKVxuICAgIGNvbnN0IHNlcmlhbFN0YXRlUmVmID0geWllbGQqIFJlZi5tYWtlKHtcbiAgICAgIHJ1bm5pbmc6IGZhbHNlLFxuICAgICAgcXVldWU6IFtdIGFzIFByb2Nlc3NUcmlnZ2VyW10sXG4gICAgICBwZWFrOiAwLFxuICAgIH0pXG4gICAgY29uc3QgcGFyYWxsZWxTdGF0ZVJlZiA9IHlpZWxkKiBSZWYubWFrZSh7XG4gICAgICBhY3RpdmU6IDAsXG4gICAgICBxdWV1ZTogW10gYXMgUHJvY2Vzc1RyaWdnZXJbXSxcbiAgICAgIHBlYWs6IDAsXG4gICAgfSlcblxuICAgIGNvbnN0IHNlcmlhbFF1ZXVlTGltaXQgPSByZXNvbHZlUXVldWVMaW1pdChwb2xpY3kubWF4UXVldWUsIHsgZGVmYXVsdEd1YXJkOiBkZWZhdWx0UXVldWVHdWFyZCB9KVxuICAgIGNvbnN0IHBhcmFsbGVsUXVldWVMaW1pdCA9IHJlc29sdmVRdWV1ZUxpbWl0KHVuZGVmaW5lZCwgeyBkZWZhdWx0R3VhcmQ6IGRlZmF1bHRRdWV1ZUd1YXJkIH0pXG4gICAgY29uc3QgcGFyYWxsZWxMaW1pdCA9XG4gICAgICB0eXBlb2YgcG9saWN5Lm1heFBhcmFsbGVsID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUocG9saWN5Lm1heFBhcmFsbGVsKSAmJiBwb2xpY3kubWF4UGFyYWxsZWwgPj0gMVxuICAgICAgICA/IE1hdGguZmxvb3IocG9saWN5Lm1heFBhcmFsbGVsKVxuICAgICAgICA6IChhcmdzLmRlZmF1bHRQYXJhbGxlbExpbWl0ID8/IERFRkFVTFRfUEFSQUxMRUxfTElNSVQpXG5cbiAgICBjb25zdCBkcmFpblNlcmlhbCA9ICgpOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBTY29wZS5TY29wZT4gPT5cbiAgICAgIEVmZmVjdC5zdXNwZW5kKCgpID0+XG4gICAgICAgIFJlZi5tb2RpZnkoc2VyaWFsU3RhdGVSZWYsIChzdGF0ZSkgPT4ge1xuICAgICAgICAgIGlmIChzdGF0ZS5ydW5uaW5nIHx8IHN0YXRlLnF1ZXVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIFtPcHRpb24ubm9uZSgpLCBzdGF0ZV0gYXMgY29uc3RcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgW25leHQsIC4uLnJlc3RdID0gc3RhdGUucXVldWVcbiAgICAgICAgICByZXR1cm4gW09wdGlvbi5zb21lKG5leHQpLCB7IC4uLnN0YXRlLCBydW5uaW5nOiB0cnVlLCBxdWV1ZTogcmVzdCB9XSBhcyBjb25zdFxuICAgICAgICB9KS5waXBlKFxuICAgICAgICAgIEVmZmVjdC5mbGF0TWFwKChuZXh0KSA9PlxuICAgICAgICAgICAgT3B0aW9uLm1hdGNoKG5leHQsIHtcbiAgICAgICAgICAgICAgb25Ob25lOiAoKSA9PiBFZmZlY3Qudm9pZCxcbiAgICAgICAgICAgICAgb25Tb21lOiAodHJpZ2dlcikgPT5cbiAgICAgICAgICAgICAgICBFZmZlY3QuZm9ya1Njb3BlZChcbiAgICAgICAgICAgICAgICAgIGFyZ3NcbiAgICAgICAgICAgICAgICAgICAgLnJ1bih0cmlnZ2VyKVxuICAgICAgICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICBFZmZlY3QuZW5zdXJpbmcoUmVmLnVwZGF0ZShzZXJpYWxTdGF0ZVJlZiwgKHMpID0+ICh7IC4uLnMsIHJ1bm5pbmc6IGZhbHNlIH0pKSksXG4gICAgICAgICAgICAgICAgICAgICAgRWZmZWN0LnppcFJpZ2h0KGRyYWluU2VyaWFsKCkpLFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICkucGlwZShFZmZlY3QuYXNWb2lkKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApXG5cbiAgICBjb25zdCBkcmFpblBhcmFsbGVsID0gKCk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIFNjb3BlLlNjb3BlPiA9PlxuICAgICAgRWZmZWN0LnN1c3BlbmQoKCkgPT5cbiAgICAgICAgUmVmLm1vZGlmeShwYXJhbGxlbFN0YXRlUmVmLCAoc3RhdGUpID0+IHtcbiAgICAgICAgICBpZiAoc3RhdGUuYWN0aXZlID49IHBhcmFsbGVsTGltaXQgfHwgc3RhdGUucXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gW09wdGlvbi5ub25lKCksIHN0YXRlXSBhcyBjb25zdFxuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBbbmV4dCwgLi4ucmVzdF0gPSBzdGF0ZS5xdWV1ZVxuICAgICAgICAgIHJldHVybiBbT3B0aW9uLnNvbWUobmV4dCksIHsgLi4uc3RhdGUsIGFjdGl2ZTogc3RhdGUuYWN0aXZlICsgMSwgcXVldWU6IHJlc3QgfV0gYXMgY29uc3RcbiAgICAgICAgfSkucGlwZShcbiAgICAgICAgICBFZmZlY3QuZmxhdE1hcCgobmV4dCkgPT5cbiAgICAgICAgICAgIE9wdGlvbi5tYXRjaChuZXh0LCB7XG4gICAgICAgICAgICAgIG9uTm9uZTogKCkgPT4gRWZmZWN0LnZvaWQsXG4gICAgICAgICAgICAgIG9uU29tZTogKHRyaWdnZXIpID0+XG4gICAgICAgICAgICAgICAgRWZmZWN0LmZvcmtTY29wZWQoXG4gICAgICAgICAgICAgICAgICBhcmdzLnJ1bih0cmlnZ2VyKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICBFZmZlY3QuZW5zdXJpbmcoXG4gICAgICAgICAgICAgICAgICAgICAgUmVmLnVwZGF0ZShwYXJhbGxlbFN0YXRlUmVmLCAocykgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLnMsXG4gICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IE1hdGgubWF4KDAsIHMuYWN0aXZlIC0gMSksXG4gICAgICAgICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQoZHJhaW5QYXJhbGxlbCgpKSxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKS5waXBlKEVmZmVjdC5hc1ZvaWQsIEVmZmVjdC56aXBSaWdodChkcmFpblBhcmFsbGVsKCkpKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApXG5cbiAgICBjb25zdCBvblRyaWdnZXIgPSAodHJpZ2dlcjA6IFByb2Nlc3NUcmlnZ2VyKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgU2NvcGUuU2NvcGU+ID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IHRyaWdnZXIgPSBhcmdzLmFzc2lnblRyaWdnZXJTZXEodHJpZ2dlcjApXG5cbiAgICAgICAgaWYgKHBvbGljeS5tb2RlID09PSAnZHJvcCcpIHtcbiAgICAgICAgICBjb25zdCBhY3F1aXJlZCA9IHlpZWxkKiBSZWYubW9kaWZ5KGJ1c3lSZWYsIChidXN5KSA9PlxuICAgICAgICAgICAgYnVzeSA/IChbZmFsc2UsIGJ1c3ldIGFzIGNvbnN0KSA6IChbdHJ1ZSwgdHJ1ZV0gYXMgY29uc3QpLFxuICAgICAgICAgIClcbiAgICAgICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgICAgICB5aWVsZCogYXJncy5vbkRyb3AodHJpZ2dlcilcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cblxuICAgICAgICAgIHlpZWxkKiBFZmZlY3QuZm9ya1Njb3BlZChhcmdzLnJ1bih0cmlnZ2VyKS5waXBlKEVmZmVjdC5lbnN1cmluZyhSZWYuc2V0KGJ1c3lSZWYsIGZhbHNlKSkpKVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvbGljeS5tb2RlID09PSAncGFyYWxsZWwnKSB7XG4gICAgICAgICAgY29uc3QgbmV4dFNpemUgPSB5aWVsZCogUmVmLm1vZGlmeShwYXJhbGxlbFN0YXRlUmVmLCAoc3RhdGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHF1ZXVlID0gWy4uLnN0YXRlLnF1ZXVlLCB0cmlnZ2VyXVxuICAgICAgICAgICAgcmV0dXJuIFtxdWV1ZS5sZW5ndGgsIHsgLi4uc3RhdGUsIHF1ZXVlLCBwZWFrOiBNYXRoLm1heChzdGF0ZS5wZWFrLCBxdWV1ZS5sZW5ndGgpIH1dIGFzIGNvbnN0XG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGlmIChuZXh0U2l6ZSA+IHBhcmFsbGVsUXVldWVMaW1pdC5ndWFyZCkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSB5aWVsZCogUmVmLmdldChwYXJhbGxlbFN0YXRlUmVmKVxuICAgICAgICAgICAgeWllbGQqIGFyZ3Mub25RdWV1ZU92ZXJmbG93KHtcbiAgICAgICAgICAgICAgbW9kZTogJ3BhcmFsbGVsJyxcbiAgICAgICAgICAgICAgY3VycmVudExlbmd0aDogbmV4dFNpemUsXG4gICAgICAgICAgICAgIHBlYWs6IHN0YXRlLnBlYWssXG4gICAgICAgICAgICAgIGxpbWl0OiBwYXJhbGxlbFF1ZXVlTGltaXQsXG4gICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB5aWVsZCogZHJhaW5QYXJhbGxlbCgpXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXJpYWxcbiAgICAgICAgY29uc3QgbmV4dFNpemUgPSB5aWVsZCogUmVmLm1vZGlmeShzZXJpYWxTdGF0ZVJlZiwgKHN0YXRlKSA9PiB7XG4gICAgICAgICAgY29uc3QgcXVldWUgPSBbLi4uc3RhdGUucXVldWUsIHRyaWdnZXJdXG4gICAgICAgICAgcmV0dXJuIFtxdWV1ZS5sZW5ndGgsIHsgLi4uc3RhdGUsIHF1ZXVlLCBwZWFrOiBNYXRoLm1heChzdGF0ZS5wZWFrLCBxdWV1ZS5sZW5ndGgpIH1dIGFzIGNvbnN0XG4gICAgICAgIH0pXG5cbiAgICAgICAgaWYgKG5leHRTaXplID4gc2VyaWFsUXVldWVMaW1pdC5ndWFyZCkge1xuICAgICAgICAgIGNvbnN0IHN0YXRlID0geWllbGQqIFJlZi5nZXQoc2VyaWFsU3RhdGVSZWYpXG4gICAgICAgICAgeWllbGQqIGFyZ3Mub25RdWV1ZU92ZXJmbG93KHtcbiAgICAgICAgICAgIG1vZGU6ICdzZXJpYWwnLFxuICAgICAgICAgICAgY3VycmVudExlbmd0aDogbmV4dFNpemUsXG4gICAgICAgICAgICBwZWFrOiBzdGF0ZS5wZWFrLFxuICAgICAgICAgICAgbGltaXQ6IHNlcmlhbFF1ZXVlTGltaXQsXG4gICAgICAgICAgICBwb2xpY3ksXG4gICAgICAgICAgfSlcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIHlpZWxkKiBkcmFpblNlcmlhbCgpXG4gICAgICB9KVxuXG4gICAgcmV0dXJuIHlpZWxkKiBTdHJlYW0ucnVuRm9yRWFjaChhcmdzLnN0cmVhbSwgb25UcmlnZ2VyKVxuICB9KVxuIiwgImltcG9ydCB0eXBlIHsgUHJvY2Vzc0V2ZW50IH0gZnJvbSAnLi9wcm90b2NvbC5qcydcblxuZXhwb3J0IGNvbnN0IFBST0NFU1NfRVZFTlRfTUFYX0JZVEVTID0gNCAqIDEwMjRcbmV4cG9ydCBjb25zdCBQUk9DRVNTX0VWRU5UX01BWF9FVkVOVFNfUEVSX1JVTiA9IDUwXG5leHBvcnQgY29uc3QgUFJPQ0VTU19FVkVOVF9SRVNFUlZFRF9FVkVOVFNfRk9SX1NVTU1BUlkgPSAxXG5cbmV4cG9ydCB0eXBlIFByb2Nlc3NSdW5FdmVudEJ1ZGdldFN0YXRlID0ge1xuICByZWFkb25seSBtYXhFdmVudHM6IG51bWJlclxuICByZWFkb25seSBtYXhCeXRlczogbnVtYmVyXG4gIHJlYWRvbmx5IGVtaXR0ZWQ6IG51bWJlclxuICByZWFkb25seSBkcm9wcGVkOiBudW1iZXJcbiAgcmVhZG9ubHkgZG93bmdyYWRlZDogbnVtYmVyXG4gIHJlYWRvbmx5IHN1bW1hcnlFbWl0dGVkOiBib29sZWFuXG59XG5cbmV4cG9ydCBjb25zdCBtYWtlUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0U3RhdGUgPSAob3B0aW9ucz86IHtcbiAgcmVhZG9ubHkgbWF4RXZlbnRzPzogbnVtYmVyXG4gIHJlYWRvbmx5IG1heEJ5dGVzPzogbnVtYmVyXG59KTogUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0U3RhdGUgPT4gKHtcbiAgbWF4RXZlbnRzOlxuICAgIHR5cGVvZiBvcHRpb25zPy5tYXhFdmVudHMgPT09ICdudW1iZXInICYmIE51bWJlci5pc0Zpbml0ZShvcHRpb25zLm1heEV2ZW50cykgJiYgb3B0aW9ucy5tYXhFdmVudHMgPj0gMFxuICAgICAgPyBNYXRoLmZsb29yKG9wdGlvbnMubWF4RXZlbnRzKVxuICAgICAgOiBQUk9DRVNTX0VWRU5UX01BWF9FVkVOVFNfUEVSX1JVTixcbiAgbWF4Qnl0ZXM6XG4gICAgdHlwZW9mIG9wdGlvbnM/Lm1heEJ5dGVzID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUob3B0aW9ucy5tYXhCeXRlcykgJiYgb3B0aW9ucy5tYXhCeXRlcyA+PSAwXG4gICAgICA/IE1hdGguZmxvb3Iob3B0aW9ucy5tYXhCeXRlcylcbiAgICAgIDogUFJPQ0VTU19FVkVOVF9NQVhfQllURVMsXG4gIGVtaXR0ZWQ6IDAsXG4gIGRyb3BwZWQ6IDAsXG4gIGRvd25ncmFkZWQ6IDAsXG4gIHN1bW1hcnlFbWl0dGVkOiBmYWxzZSxcbn0pXG5cbmV4cG9ydCB0eXBlIFByb2Nlc3NSdW5FdmVudEJ1ZGdldERlY2lzaW9uID1cbiAgfCB7XG4gICAgICByZWFkb25seSBfdGFnOiAnZW1pdCdcbiAgICAgIHJlYWRvbmx5IGV2ZW50OiBQcm9jZXNzRXZlbnRcbiAgICB9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgX3RhZzogJ2VtaXRTdW1tYXJ5J1xuICAgICAgcmVhZG9ubHkgZXZlbnQ6IFByb2Nlc3NFdmVudFxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBfdGFnOiAnZHJvcCdcbiAgICB9XG5cbmNvbnN0IG1ha2VCdWRnZXRTdW1tYXJ5RXZlbnQgPSAoYXJnczoge1xuICByZWFkb25seSBzb3VyY2VFdmVudDogUHJvY2Vzc0V2ZW50XG4gIHJlYWRvbmx5IG1heEV2ZW50czogbnVtYmVyXG4gIHJlYWRvbmx5IG1heEJ5dGVzOiBudW1iZXJcbiAgcmVhZG9ubHkgZW1pdHRlZDogbnVtYmVyXG4gIHJlYWRvbmx5IGRyb3BwZWQ6IG51bWJlclxuICByZWFkb25seSBkb3duZ3JhZGVkOiBudW1iZXJcbn0pOiBQcm9jZXNzRXZlbnQgPT4gKHtcbiAgdHlwZTogJ3Byb2Nlc3M6dHJpZ2dlcicsXG4gIGlkZW50aXR5OiBhcmdzLnNvdXJjZUV2ZW50LmlkZW50aXR5LFxuICB0cmlnZ2VyOiBhcmdzLnNvdXJjZUV2ZW50LnRyaWdnZXIsXG4gIHNldmVyaXR5OiAnd2FybmluZycsXG4gIGV2ZW50U2VxOiBhcmdzLnNvdXJjZUV2ZW50LmV2ZW50U2VxLFxuICB0aW1lc3RhbXBNczogYXJncy5zb3VyY2VFdmVudC50aW1lc3RhbXBNcyxcbiAgZXJyb3I6IHtcbiAgICBtZXNzYWdlOiAnUHJvY2VzcyBydW4gZXZlbnQgYnVkZ2V0IGV4Y2VlZGVkOyBmdXJ0aGVyIHRyaWdnZXIvZGlzcGF0Y2ggZXZlbnRzIGFyZSBzdXBwcmVzc2VkLicsXG4gICAgY29kZTogJ3Byb2Nlc3M6OmV2ZW50X2J1ZGdldF9leGNlZWRlZCcsXG4gICAgaGludDogYG1heEV2ZW50cz0ke2FyZ3MubWF4RXZlbnRzfSBtYXhCeXRlcz0ke2FyZ3MubWF4Qnl0ZXN9IGVtaXR0ZWQ9JHthcmdzLmVtaXR0ZWR9IGRyb3BwZWQ9JHthcmdzLmRyb3BwZWR9IGRvd25ncmFkZWQ9JHthcmdzLmRvd25ncmFkZWR9YCxcbiAgfSxcbn0pXG5cbmV4cG9ydCBjb25zdCBhcHBseVByb2Nlc3NSdW5FdmVudEJ1ZGdldCA9IChcbiAgc3RhdGU6IFByb2Nlc3NSdW5FdmVudEJ1ZGdldFN0YXRlLFxuICBldmVudDogUHJvY2Vzc0V2ZW50LFxuKTogcmVhZG9ubHkgW1Byb2Nlc3NSdW5FdmVudEJ1ZGdldERlY2lzaW9uLCBQcm9jZXNzUnVuRXZlbnRCdWRnZXRTdGF0ZV0gPT4ge1xuICBjb25zdCBtYXhFdmVudHMgPSBNYXRoLm1heCgwLCBzdGF0ZS5tYXhFdmVudHMpXG4gIGNvbnN0IG1heEJ5dGVzID0gTWF0aC5tYXgoMCwgc3RhdGUubWF4Qnl0ZXMpXG5cbiAgaWYgKHN0YXRlLnN1bW1hcnlFbWl0dGVkKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHsgX3RhZzogJ2Ryb3AnIH0sXG4gICAgICB7XG4gICAgICAgIC4uLnN0YXRlLFxuICAgICAgICBkcm9wcGVkOiBzdGF0ZS5kcm9wcGVkICsgMSxcbiAgICAgIH0sXG4gICAgXVxuICB9XG5cbiAgY29uc3QgcmVzZXJ2ZSA9IFBST0NFU1NfRVZFTlRfUkVTRVJWRURfRVZFTlRTX0ZPUl9TVU1NQVJZXG4gIGNvbnN0IGFsbG93ZWRSZWd1bGFyID0gTWF0aC5tYXgoMCwgbWF4RXZlbnRzIC0gcmVzZXJ2ZSlcblxuICBpZiAoc3RhdGUuZW1pdHRlZCA8IGFsbG93ZWRSZWd1bGFyKSB7XG4gICAgY29uc3QgZW5mb3JjZWQgPSBlbmZvcmNlUHJvY2Vzc0V2ZW50TWF4Qnl0ZXMoZXZlbnQsIHsgbWF4Qnl0ZXMgfSlcbiAgICByZXR1cm4gW1xuICAgICAgeyBfdGFnOiAnZW1pdCcsIGV2ZW50OiBlbmZvcmNlZC5ldmVudCB9LFxuICAgICAge1xuICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgZW1pdHRlZDogc3RhdGUuZW1pdHRlZCArIDEsXG4gICAgICAgIGRvd25ncmFkZWQ6IHN0YXRlLmRvd25ncmFkZWQgKyAoZW5mb3JjZWQuZG93bmdyYWRlZCA/IDEgOiAwKSxcbiAgICAgIH0sXG4gICAgXVxuICB9XG5cbiAgY29uc3QgZHJvcHBlZCA9IHN0YXRlLmRyb3BwZWQgKyAxXG4gIGNvbnN0IHN1bW1hcnkgPSBtYWtlQnVkZ2V0U3VtbWFyeUV2ZW50KHtcbiAgICBzb3VyY2VFdmVudDogZXZlbnQsXG4gICAgbWF4RXZlbnRzLFxuICAgIG1heEJ5dGVzLFxuICAgIGVtaXR0ZWQ6IHN0YXRlLmVtaXR0ZWQsXG4gICAgZHJvcHBlZCxcbiAgICBkb3duZ3JhZGVkOiBzdGF0ZS5kb3duZ3JhZGVkLFxuICB9KVxuICBjb25zdCBlbmZvcmNlZFN1bW1hcnkgPSBlbmZvcmNlUHJvY2Vzc0V2ZW50TWF4Qnl0ZXMoc3VtbWFyeSwgeyBtYXhCeXRlcyB9KVxuXG4gIHJldHVybiBbXG4gICAgeyBfdGFnOiAnZW1pdFN1bW1hcnknLCBldmVudDogZW5mb3JjZWRTdW1tYXJ5LmV2ZW50IH0sXG4gICAge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICBlbWl0dGVkOiBNYXRoLm1pbihtYXhFdmVudHMsIHN0YXRlLmVtaXR0ZWQgKyAxKSxcbiAgICAgIGRyb3BwZWQsXG4gICAgICBkb3duZ3JhZGVkOiBzdGF0ZS5kb3duZ3JhZGVkICsgKGVuZm9yY2VkU3VtbWFyeS5kb3duZ3JhZGVkID8gMSA6IDApLFxuICAgICAgc3VtbWFyeUVtaXR0ZWQ6IHRydWUsXG4gICAgfSxcbiAgXVxufVxuXG5leHBvcnQgY29uc3QgZXN0aW1hdGVFdmVudEJ5dGVzID0gKGV2ZW50OiBQcm9jZXNzRXZlbnQpOiBudW1iZXIgPT4ge1xuICBjb25zdCBqc29uID0gSlNPTi5zdHJpbmdpZnkoZXZlbnQpXG4gIHJldHVybiB0eXBlb2YgQnVmZmVyICE9PSAndW5kZWZpbmVkJyA/IEJ1ZmZlci5ieXRlTGVuZ3RoKGpzb24sICd1dGY4JykgOiBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoanNvbikubGVuZ3RoXG59XG5cbmNvbnN0IHRydW5jYXRlQ2hhcnMgPSAodmFsdWU6IHN0cmluZywgbWF4TGVuOiBudW1iZXIpOiBzdHJpbmcgPT5cbiAgdmFsdWUubGVuZ3RoIDw9IG1heExlbiA/IHZhbHVlIDogdmFsdWUuc2xpY2UoMCwgbWF4TGVuKVxuXG5jb25zdCBub3JtYWxpemVFcnJvclN1bW1hcnkgPSAoZXJyb3I6IE5vbk51bGxhYmxlPFByb2Nlc3NFdmVudFsnZXJyb3InXT4pOiBOb25OdWxsYWJsZTxQcm9jZXNzRXZlbnRbJ2Vycm9yJ10+ID0+IHtcbiAgY29uc3QgbWVzc2FnZSA9IHR5cGVvZiBlcnJvci5tZXNzYWdlID09PSAnc3RyaW5nJyAmJiBlcnJvci5tZXNzYWdlLmxlbmd0aCA+IDAgPyBlcnJvci5tZXNzYWdlIDogJ0Vycm9yJ1xuXG4gIGNvbnN0IGhpbnQgPSB0eXBlb2YgZXJyb3IuaGludCA9PT0gJ3N0cmluZycgJiYgZXJyb3IuaGludC5sZW5ndGggPiAwID8gdHJ1bmNhdGVDaGFycyhlcnJvci5oaW50LCAxMDI0KSA6IHVuZGVmaW5lZFxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogdHlwZW9mIGVycm9yLm5hbWUgPT09ICdzdHJpbmcnICYmIGVycm9yLm5hbWUubGVuZ3RoID4gMCA/IGVycm9yLm5hbWUgOiB1bmRlZmluZWQsXG4gICAgbWVzc2FnZTogdHJ1bmNhdGVDaGFycyhtZXNzYWdlLCAyNTYpLFxuICAgIGNvZGU6IHR5cGVvZiBlcnJvci5jb2RlID09PSAnc3RyaW5nJyAmJiBlcnJvci5jb2RlLmxlbmd0aCA+IDAgPyBlcnJvci5jb2RlIDogdW5kZWZpbmVkLFxuICAgIGhpbnQsXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGVuZm9yY2VQcm9jZXNzRXZlbnRNYXhCeXRlcyA9IChcbiAgZXZlbnQ6IFByb2Nlc3NFdmVudCxcbiAgb3B0aW9ucz86IHtcbiAgICByZWFkb25seSBtYXhCeXRlcz86IG51bWJlclxuICB9LFxuKTogeyByZWFkb25seSBldmVudDogUHJvY2Vzc0V2ZW50OyByZWFkb25seSBkb3duZ3JhZGVkOiBib29sZWFuIH0gPT4ge1xuICBjb25zdCBtYXhCeXRlcyA9IG9wdGlvbnM/Lm1heEJ5dGVzID8/IFBST0NFU1NfRVZFTlRfTUFYX0JZVEVTXG5cbiAgbGV0IGRvd25ncmFkZWQgPSBmYWxzZVxuICBsZXQgbmV4dDogUHJvY2Vzc0V2ZW50ID0gZXZlbnRcblxuICBpZiAoZXZlbnQuZXJyb3IpIHtcbiAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplRXJyb3JTdW1tYXJ5KGV2ZW50LmVycm9yKVxuICAgIGlmIChcbiAgICAgIG5vcm1hbGl6ZWQubWVzc2FnZSAhPT0gZXZlbnQuZXJyb3IubWVzc2FnZSB8fFxuICAgICAgbm9ybWFsaXplZC5oaW50ICE9PSBldmVudC5lcnJvci5oaW50IHx8XG4gICAgICBub3JtYWxpemVkLmNvZGUgIT09IGV2ZW50LmVycm9yLmNvZGUgfHxcbiAgICAgIG5vcm1hbGl6ZWQubmFtZSAhPT0gZXZlbnQuZXJyb3IubmFtZVxuICAgICkge1xuICAgICAgZG93bmdyYWRlZCA9IHRydWVcbiAgICAgIG5leHQgPSB7IC4uLmV2ZW50LCBlcnJvcjogbm9ybWFsaXplZCB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGVzdGltYXRlRXZlbnRCeXRlcyhuZXh0KSA8PSBtYXhCeXRlcykge1xuICAgIHJldHVybiB7IGV2ZW50OiBuZXh0LCBkb3duZ3JhZGVkIH1cbiAgfVxuXG4gIC8vIEZ1cnRoZXIgdHJpbW1pbmcgaXMgYXBwbGllZCB0byBlcnJvci5oaW50IG9ubHkgKGNvbW1vbiB0cmlnZ2VyOiBtdWx0aS1saW5lIGhpbnRzKS5cbiAgaWYgKCFuZXh0LmVycm9yPy5oaW50KSB7XG4gICAgLy8gTm90aGluZyBsZWZ0IHRvIHRyaW07IGJlc3QtZWZmb3J0IHJldHVybi5cbiAgICByZXR1cm4geyBldmVudDogbmV4dCwgZG93bmdyYWRlZDogdHJ1ZSB9XG4gIH1cblxuICBjb25zdCBoaW50ID0gbmV4dC5lcnJvci5oaW50XG4gIGNvbnN0IHN0ZXBzID0gWzUxMiwgMjU2LCAxMjgsIDY0LCAzMiwgMF1cblxuICBmb3IgKGNvbnN0IG1heExlbiBvZiBzdGVwcykge1xuICAgIGNvbnN0IHRyaW1tZWQgPSBtYXhMZW4gPT09IDAgPyB1bmRlZmluZWQgOiB0cnVuY2F0ZUNoYXJzKGhpbnQsIG1heExlbilcbiAgICBjb25zdCBjYW5kaWRhdGU6IFByb2Nlc3NFdmVudCA9IHtcbiAgICAgIC4uLm5leHQsXG4gICAgICBlcnJvcjoge1xuICAgICAgICAuLi5uZXh0LmVycm9yLFxuICAgICAgICBoaW50OiB0cmltbWVkLFxuICAgICAgfSxcbiAgICB9XG4gICAgaWYgKGVzdGltYXRlRXZlbnRCeXRlcyhjYW5kaWRhdGUpIDw9IG1heEJ5dGVzKSB7XG4gICAgICByZXR1cm4geyBldmVudDogY2FuZGlkYXRlLCBkb3duZ3JhZGVkOiB0cnVlIH1cbiAgICB9XG4gIH1cblxuICAvLyBGYWxsYmFjazogcmVtb3ZlIGhpbnQgYW5kIHNob3J0ZW4gbWVzc2FnZSAocHJvY2VzczplcnJvciBtdXN0IHN0aWxsIGhhdmUgYSBtZXNzYWdlKS5cbiAgY29uc3QgZmFsbGJhY2s6IFByb2Nlc3NFdmVudCA9IG5leHQuZXJyb3JcbiAgICA/ICh7XG4gICAgICAgIC4uLm5leHQsXG4gICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgLi4ubmV4dC5lcnJvcixcbiAgICAgICAgICBtZXNzYWdlOiB0cnVuY2F0ZUNoYXJzKG5leHQuZXJyb3IubWVzc2FnZSwgOTYpLFxuICAgICAgICAgIGhpbnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgfSxcbiAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NFdmVudClcbiAgICA6IG5leHRcblxuICByZXR1cm4geyBldmVudDogZmFsbGJhY2ssIGRvd25ncmFkZWQ6IHRydWUgfVxufVxuIiwgImltcG9ydCAqIGFzIFNjaGVtYUFTVCBmcm9tICdlZmZlY3QvU2NoZW1hQVNUJ1xuXG5leHBvcnQgdHlwZSBEb3RQYXRoU2VnbWVudCA9IHN0cmluZyB8IG51bWJlclxuXG50eXBlIERvdFBhdGhQYXJzZVJlc3VsdCA9XG4gIHwgeyByZWFkb25seSBvazogdHJ1ZTsgcmVhZG9ubHkgc2VnbWVudHM6IFJlYWRvbmx5QXJyYXk8RG90UGF0aFNlZ21lbnQ+IH1cbiAgfCB7IHJlYWRvbmx5IG9rOiBmYWxzZTsgcmVhZG9ubHkgZXJyb3I6IEVycm9yIH1cblxuZXhwb3J0IHR5cGUgRG90UGF0aFNlbGVjdG9yUmVzdWx0ID1cbiAgfCB7XG4gICAgICByZWFkb25seSBvazogdHJ1ZVxuICAgICAgcmVhZG9ubHkgc2VsZWN0b3I6IChzdGF0ZTogdW5rbm93bikgPT4gdW5rbm93blxuICAgICAgcmVhZG9ubHkgc2VnbWVudHM6IFJlYWRvbmx5QXJyYXk8RG90UGF0aFNlZ21lbnQ+XG4gICAgfVxuICB8IHsgcmVhZG9ubHkgb2s6IGZhbHNlOyByZWFkb25seSBlcnJvcjogRXJyb3IgfVxuXG5jb25zdCBpc1JlY29yZCA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGxcblxuZXhwb3J0IGNvbnN0IHJlc29sdmVTY2hlbWFBc3QgPSAoc2NoZW1hOiB1bmtub3duKTogU2NoZW1hQVNULkFTVCB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmICghaXNSZWNvcmQoc2NoZW1hKSkgcmV0dXJuIHVuZGVmaW5lZFxuICBjb25zdCBhc3QgPSAoc2NoZW1hIGFzIGFueSkuYXN0IGFzIFNjaGVtYUFTVC5BU1QgfCB1bmRlZmluZWRcbiAgaWYgKCFhc3QpIHJldHVybiB1bmRlZmluZWRcbiAgaWYgKHR5cGVvZiBhc3QgIT09ICdvYmplY3QnICYmIHR5cGVvZiBhc3QgIT09ICdmdW5jdGlvbicpIHJldHVybiB1bmRlZmluZWRcbiAgcmV0dXJuIGFzdFxufVxuXG5jb25zdCBtYWtlRG90UGF0aEVycm9yID0gKHBhdGg6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBoaW50Pzogc3RyaW5nKTogRXJyb3IgPT4ge1xuICBjb25zdCBlcnIgPSBuZXcgRXJyb3IobWVzc2FnZSlcbiAgOyhlcnIgYXMgYW55KS5jb2RlID0gJ3Byb2Nlc3M6OmludmFsaWRfZG90X3BhdGgnXG4gIDsoZXJyIGFzIGFueSkuaGludCA9XG4gICAgaGludCA/P1xuICAgIFtcbiAgICAgIFwiRXhwZWN0ZWQgZG90LXBhdGggc3ludGF4OiBzZWdtZW50cyBzZXBhcmF0ZWQgYnkgJy4nLCBudW1lcmljIHNlZ21lbnRzIHJlcHJlc2VudCBhcnJheSBpbmRpY2VzLlwiLFxuICAgICAgYHBhdGg6ICR7cGF0aH1gLFxuICAgICAgJycsXG4gICAgICAnZXhhbXBsZXM6JyxcbiAgICAgICctIGNvdW50JyxcbiAgICAgICctIHVzZXIubmFtZScsXG4gICAgICAnLSBpdGVtcy4wLmlkJyxcbiAgICBdLmpvaW4oJ1xcbicpXG4gIHJldHVybiBlcnJcbn1cblxuY29uc3QgbWFrZVNjaGVtYU1pc21hdGNoRXJyb3IgPSAocGF0aDogc3RyaW5nKTogRXJyb3IgPT5cbiAgbWFrZURvdFBhdGhFcnJvcihcbiAgICBwYXRoLFxuICAgICdJbnZhbGlkIGRvdC1wYXRoOiBwYXRoIGRvZXMgbm90IG1hdGNoIHRoZSBzdGF0ZSBzY2hlbWEuJyxcbiAgICBbXG4gICAgICAnVGhlIG1vZHVsZSBzdGF0ZSBzY2hlbWEgZG9lcyBub3QgY29udGFpbiB0aGUgcmVxdWVzdGVkIGRvdC1wYXRoLicsXG4gICAgICBgcGF0aDogJHtwYXRofWAsXG4gICAgICAnJyxcbiAgICAgICdmaXg6JyxcbiAgICAgICctIEVuc3VyZSB0aGUgcGF0aCBleGlzdHMgaW4gdGhlIHN0YXRlIHNjaGVtYS4nLFxuICAgICAgJy0gVXNlIG51bWVyaWMgc2VnbWVudHMgZm9yIGFycmF5IGluZGljZXMgKGUuZy4gaXRlbXMuMC5pZCkuJyxcbiAgICBdLmpvaW4oJ1xcbicpLFxuICApXG5cbmNvbnN0IHBhcnNlRG90UGF0aCA9IChwYXRoOiBzdHJpbmcpOiBEb3RQYXRoUGFyc2VSZXN1bHQgPT4ge1xuICBpZiAodHlwZW9mIHBhdGggIT09ICdzdHJpbmcnIHx8IHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHsgb2s6IGZhbHNlLCBlcnJvcjogbWFrZURvdFBhdGhFcnJvcihTdHJpbmcocGF0aCksICdkb3QtcGF0aCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpIH1cbiAgfVxuXG4gIGNvbnN0IHJhdyA9IHBhdGguc3BsaXQoJy4nKVxuICBpZiAocmF3Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IG1ha2VEb3RQYXRoRXJyb3IocGF0aCwgJ2RvdC1wYXRoIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgc2VnbWVudCcpIH1cbiAgfVxuXG4gIGNvbnN0IHNlZ21lbnRzOiBEb3RQYXRoU2VnbWVudFtdID0gW11cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYXcubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzZWcgPSByYXdbaV0hXG4gICAgaWYgKHNlZy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgZXJyb3I6IG1ha2VEb3RQYXRoRXJyb3IoXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICBgSW52YWxpZCBkb3QtcGF0aDogZW1wdHkgc2VnbWVudCBhdCBpbmRleCAke2l9LmAsXG4gICAgICAgICAgW1xuICAgICAgICAgICAgXCJFeHBlY3RlZCBkb3QtcGF0aCBzeW50YXg6IHNlZ21lbnRzIHNlcGFyYXRlZCBieSAnLicsIG51bWVyaWMgc2VnbWVudHMgcmVwcmVzZW50IGFycmF5IGluZGljZXMuXCIsXG4gICAgICAgICAgICBgcGF0aDogJHtwYXRofWAsXG4gICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICdleGFtcGxlczonLFxuICAgICAgICAgICAgJy0gY291bnQnLFxuICAgICAgICAgICAgJy0gdXNlci5uYW1lJyxcbiAgICAgICAgICAgICctIGl0ZW1zLjAuaWQnLFxuICAgICAgICAgICAgJycsXG4gICAgICAgICAgICAnZml4OicsXG4gICAgICAgICAgICAnLSBSZW1vdmUgY29uc2VjdXRpdmUgZG90cyBvciB0cmFpbGluZyBkb3RzLicsXG4gICAgICAgICAgXS5qb2luKCdcXG4nKSxcbiAgICAgICAgKSxcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoL15bMC05XSskLy50ZXN0KHNlZykpIHtcbiAgICAgIGNvbnN0IG4gPSBOdW1iZXIoc2VnKVxuICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobikgfHwgbiA8IDApIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvazogZmFsc2UsXG4gICAgICAgICAgZXJyb3I6IG1ha2VEb3RQYXRoRXJyb3IocGF0aCwgYEludmFsaWQgYXJyYXkgaW5kZXggc2VnbWVudCBcIiR7c2VnfVwiIGF0IGluZGV4ICR7aX0uYCksXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNlZ21lbnRzLnB1c2goTWF0aC5mbG9vcihuKSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgc2VnbWVudHMucHVzaChzZWcpXG4gIH1cblxuICByZXR1cm4geyBvazogdHJ1ZSwgc2VnbWVudHMgfVxufVxuXG5jb25zdCByZXNvbHZlQXN0Rm9yUGF0aCA9IChcbiAgYXN0OiBTY2hlbWFBU1QuQVNULFxuICBzZWdtZW50czogUmVhZG9ubHlBcnJheTxEb3RQYXRoU2VnbWVudD4sXG4gIHNlZW46IFNldDxTY2hlbWFBU1QuQVNUPixcbik6IFNjaGVtYUFTVC5BU1QgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoc2VnbWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gYXN0XG5cbiAgbGV0IGN1cnJlbnQgPSBhc3RcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoU2NoZW1hQVNULmlzU3VzcGVuZChjdXJyZW50KSkge1xuICAgICAgaWYgKHNlZW4uaGFzKGN1cnJlbnQpKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgICBzZWVuLmFkZChjdXJyZW50KVxuICAgICAgY3VycmVudCA9IGN1cnJlbnQuZigpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoU2NoZW1hQVNULmlzUmVmaW5lbWVudChjdXJyZW50KSkge1xuICAgICAgY3VycmVudCA9IGN1cnJlbnQuZnJvbVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgYnJlYWtcbiAgfVxuXG4gIGlmIChTY2hlbWFBU1QuaXNUcmFuc2Zvcm1hdGlvbihjdXJyZW50KSkge1xuICAgIGNvbnN0IGZyb20gPSByZXNvbHZlQXN0Rm9yUGF0aChjdXJyZW50LmZyb20sIHNlZ21lbnRzLCBzZWVuKVxuICAgIGlmIChmcm9tKSByZXR1cm4gZnJvbVxuICAgIHJldHVybiByZXNvbHZlQXN0Rm9yUGF0aChjdXJyZW50LnRvLCBzZWdtZW50cywgc2VlbilcbiAgfVxuXG4gIGlmIChTY2hlbWFBU1QuaXNVbmlvbihjdXJyZW50KSkge1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBjdXJyZW50LnR5cGVzKSB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVBc3RGb3JQYXRoKG5vZGUsIHNlZ21lbnRzLCBzZWVuKVxuICAgICAgaWYgKHJlc29sdmVkKSByZXR1cm4gcmVzb2x2ZWRcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG5cbiAgaWYgKFNjaGVtYUFTVC5pc1R1cGxlVHlwZShjdXJyZW50KSkge1xuICAgIGNvbnN0IFtoZWFkLCAuLi50YWlsXSA9IHNlZ21lbnRzXG4gICAgaWYgKHR5cGVvZiBoZWFkICE9PSAnbnVtYmVyJykgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGNvbnN0IGVsZW1lbnQgPVxuICAgICAgaGVhZCA8IGN1cnJlbnQuZWxlbWVudHMubGVuZ3RoID8gY3VycmVudC5lbGVtZW50c1toZWFkXSA6IGN1cnJlbnQucmVzdC5sZW5ndGggPiAwID8gY3VycmVudC5yZXN0WzBdIDogdW5kZWZpbmVkXG4gICAgcmV0dXJuIGVsZW1lbnQgPyByZXNvbHZlQXN0Rm9yUGF0aChlbGVtZW50LnR5cGUsIHRhaWwsIHNlZW4pIDogdW5kZWZpbmVkXG4gIH1cblxuICBpZiAoU2NoZW1hQVNULmlzVHlwZUxpdGVyYWwoY3VycmVudCkpIHtcbiAgICBjb25zdCBbaGVhZCwgLi4udGFpbF0gPSBzZWdtZW50c1xuICAgIGlmIChoZWFkID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWRcblxuICAgIGlmICh0eXBlb2YgaGVhZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGZvciAoY29uc3QgcHMgb2YgY3VycmVudC5wcm9wZXJ0eVNpZ25hdHVyZXMpIHtcbiAgICAgICAgaWYgKFN0cmluZyhwcy5uYW1lKSAhPT0gaGVhZCkgY29udGludWVcbiAgICAgICAgcmV0dXJuIHJlc29sdmVBc3RGb3JQYXRoKHBzLnR5cGUsIHRhaWwsIHNlZW4pXG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzaWcgb2YgY3VycmVudC5pbmRleFNpZ25hdHVyZXMpIHtcbiAgICAgIGxldCBwYXJhbTogU2NoZW1hQVNULkFTVCA9IHNpZy5wYXJhbWV0ZXIgYXMgdW5rbm93biBhcyBTY2hlbWFBU1QuQVNUXG4gICAgICB3aGlsZSAoU2NoZW1hQVNULmlzUmVmaW5lbWVudChwYXJhbSkpIHtcbiAgICAgICAgcGFyYW0gPSBwYXJhbS5mcm9tXG4gICAgICB9XG4gICAgICBjb25zdCB0YWcgPSAocGFyYW0gYXMgYW55KT8uX3RhZ1xuICAgICAgY29uc3QgYWNjZXB0c1N0cmluZyA9IHRhZyA9PT0gJ1N0cmluZ0tleXdvcmQnIHx8IHRhZyA9PT0gJ1RlbXBsYXRlTGl0ZXJhbCdcbiAgICAgIGNvbnN0IGFjY2VwdHNOdW1iZXIgPSB0YWcgPT09ICdOdW1iZXJLZXl3b3JkJ1xuICAgICAgaWYgKHR5cGVvZiBoZWFkID09PSAnc3RyaW5nJyAmJiBhY2NlcHRzU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlQXN0Rm9yUGF0aChzaWcudHlwZSwgdGFpbCwgc2VlbilcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgaGVhZCA9PT0gJ251bWJlcicgJiYgYWNjZXB0c051bWJlcikge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZUFzdEZvclBhdGgoc2lnLnR5cGUsIHRhaWwsIHNlZW4pXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgdGFnID0gKGN1cnJlbnQgYXMgYW55KT8uX3RhZ1xuICBpZiAodGFnID09PSAnQW55S2V5d29yZCcgfHwgdGFnID09PSAnVW5rbm93bktleXdvcmQnIHx8IHRhZyA9PT0gJ09iamVjdEtleXdvcmQnIHx8IHRhZyA9PT0gJ0RlY2xhcmF0aW9uJykge1xuICAgIHJldHVybiBjdXJyZW50XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmNvbnN0IHNlbGVjdEJ5U2VnbWVudHMgPVxuICAoc2VnbWVudHM6IFJlYWRvbmx5QXJyYXk8RG90UGF0aFNlZ21lbnQ+KSA9PlxuICAoc3RhdGU6IHVua25vd24pOiB1bmtub3duID0+IHtcbiAgICBsZXQgY3VycmVudDogdW5rbm93biA9IHN0YXRlXG4gICAgZm9yIChjb25zdCBzZWcgb2Ygc2VnbWVudHMpIHtcbiAgICAgIGlmIChjdXJyZW50ID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcbiAgICAgIGlmICh0eXBlb2Ygc2VnID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShjdXJyZW50KSkge1xuICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W3NlZ11cbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc1JlY29yZChjdXJyZW50KSkge1xuICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W1N0cmluZyhzZWcpXVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgfVxuICAgICAgaWYgKGlzUmVjb3JkKGN1cnJlbnQpKSB7XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W3NlZ11cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG4gICAgcmV0dXJuIGN1cnJlbnRcbiAgfVxuXG5leHBvcnQgY29uc3QgbWFrZVNjaGVtYVNlbGVjdG9yID0gKHBhdGg6IHN0cmluZywgc2NoZW1hQXN0PzogU2NoZW1hQVNULkFTVCk6IERvdFBhdGhTZWxlY3RvclJlc3VsdCA9PiB7XG4gIGNvbnN0IHBhcnNlZCA9IHBhcnNlRG90UGF0aChwYXRoKVxuICBpZiAoIXBhcnNlZC5vaykgcmV0dXJuIHsgb2s6IGZhbHNlLCBlcnJvcjogcGFyc2VkLmVycm9yIH1cblxuICBpZiAoc2NoZW1hQXN0KSB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlQXN0Rm9yUGF0aChzY2hlbWFBc3QsIHBhcnNlZC5zZWdtZW50cywgbmV3IFNldCgpKVxuICAgIGlmICghcmVzb2x2ZWQpIHtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IG1ha2VTY2hlbWFNaXNtYXRjaEVycm9yKHBhdGgpIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG9rOiB0cnVlLFxuICAgIHNlbGVjdG9yOiBzZWxlY3RCeVNlZ21lbnRzKHBhcnNlZC5zZWdtZW50cyksXG4gICAgc2VnbWVudHM6IHBhcnNlZC5zZWdtZW50cyxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgUHJvY2Vzc0Vycm9yUG9saWN5IH0gZnJvbSAnLi9wcm90b2NvbC5qcydcblxuZXhwb3J0IHR5cGUgU3VwZXJ2aXNpb25EZWNpc2lvbiA9ICdzdG9wJyB8ICdyZXN0YXJ0J1xuXG5leHBvcnQgdHlwZSBTdXBlcnZpc2lvblN0YXRlID0ge1xuICByZWFkb25seSBmYWlsdXJlVGltZXM6IFJlYWRvbmx5QXJyYXk8bnVtYmVyPlxufVxuXG5leHBvcnQgY29uc3QgaW5pdGlhbFN0YXRlID0gKCk6IFN1cGVydmlzaW9uU3RhdGUgPT4gKHsgZmFpbHVyZVRpbWVzOiBbXSB9KVxuXG5leHBvcnQgdHlwZSBGYWlsdXJlRGVjaXNpb24gPSB7XG4gIHJlYWRvbmx5IGRlY2lzaW9uOiBTdXBlcnZpc2lvbkRlY2lzaW9uXG4gIHJlYWRvbmx5IG5leHRTdGF0ZTogU3VwZXJ2aXNpb25TdGF0ZVxuICByZWFkb25seSB3aXRoaW5XaW5kb3dGYWlsdXJlczogbnVtYmVyXG4gIHJlYWRvbmx5IG1heFJlc3RhcnRzOiBudW1iZXJcbiAgcmVhZG9ubHkgd2luZG93TXM/OiBudW1iZXJcbn1cblxuZXhwb3J0IGNvbnN0IG9uRmFpbHVyZSA9IChwb2xpY3k6IFByb2Nlc3NFcnJvclBvbGljeSwgc3RhdGU6IFN1cGVydmlzaW9uU3RhdGUsIG5vd01zOiBudW1iZXIpOiBGYWlsdXJlRGVjaXNpb24gPT4ge1xuICBpZiAocG9saWN5Lm1vZGUgPT09ICdmYWlsU3RvcCcpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZGVjaXNpb246ICdzdG9wJyxcbiAgICAgIG5leHRTdGF0ZTogc3RhdGUsXG4gICAgICB3aXRoaW5XaW5kb3dGYWlsdXJlczogc3RhdGUuZmFpbHVyZVRpbWVzLmxlbmd0aCxcbiAgICAgIG1heFJlc3RhcnRzOiAwLFxuICAgICAgd2luZG93TXM6IHBvbGljeS53aW5kb3dNcyxcbiAgICB9XG4gIH1cblxuICBjb25zdCBtYXhSZXN0YXJ0c1JhdyA9IHBvbGljeS5tYXhSZXN0YXJ0c1xuICBjb25zdCBtYXhSZXN0YXJ0cyA9XG4gICAgdHlwZW9mIG1heFJlc3RhcnRzUmF3ID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUobWF4UmVzdGFydHNSYXcpICYmIG1heFJlc3RhcnRzUmF3ID49IDBcbiAgICAgID8gTWF0aC5mbG9vcihtYXhSZXN0YXJ0c1JhdylcbiAgICAgIDogMFxuXG4gIGlmIChtYXhSZXN0YXJ0cyA8PSAwKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRlY2lzaW9uOiAnc3RvcCcsXG4gICAgICBuZXh0U3RhdGU6IHN0YXRlLFxuICAgICAgd2l0aGluV2luZG93RmFpbHVyZXM6IHN0YXRlLmZhaWx1cmVUaW1lcy5sZW5ndGgsXG4gICAgICBtYXhSZXN0YXJ0cyxcbiAgICAgIHdpbmRvd01zOiBwb2xpY3kud2luZG93TXMsXG4gICAgfVxuICB9XG5cbiAgY29uc3Qgd2luZG93TXNSYXcgPSBwb2xpY3kud2luZG93TXNcbiAgY29uc3Qgd2luZG93TXMgPVxuICAgIHR5cGVvZiB3aW5kb3dNc1JhdyA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKHdpbmRvd01zUmF3KSAmJiB3aW5kb3dNc1JhdyA+IDBcbiAgICAgID8gTWF0aC5mbG9vcih3aW5kb3dNc1JhdylcbiAgICAgIDogdW5kZWZpbmVkXG5cbiAgY29uc3QgZmFpbHVyZVRpbWVzUmF3ID0gWy4uLnN0YXRlLmZhaWx1cmVUaW1lcywgbm93TXNdXG4gIGNvbnN0IGZhaWx1cmVUaW1lcyA9IHdpbmRvd01zID8gZmFpbHVyZVRpbWVzUmF3LmZpbHRlcigodCkgPT4gdCA+PSBub3dNcyAtIHdpbmRvd01zKSA6IGZhaWx1cmVUaW1lc1Jhd1xuXG4gIC8vIEtlZXAgYXQgbW9zdCBtYXhSZXN0YXJ0cysxIHRpbWVzdGFtcHMgdG8gYXZvaWQgdW5ib3VuZGVkIGdyb3d0aC5cbiAgY29uc3QgY2FwID0gbWF4UmVzdGFydHMgKyAxXG4gIGNvbnN0IGNhcHBlZCA9IGZhaWx1cmVUaW1lcy5sZW5ndGggPiBjYXAgPyBmYWlsdXJlVGltZXMuc2xpY2UoZmFpbHVyZVRpbWVzLmxlbmd0aCAtIGNhcCkgOiBmYWlsdXJlVGltZXNcblxuICBjb25zdCB3aXRoaW5XaW5kb3dGYWlsdXJlcyA9IGNhcHBlZC5sZW5ndGhcbiAgY29uc3QgZGVjaXNpb246IFN1cGVydmlzaW9uRGVjaXNpb24gPSB3aXRoaW5XaW5kb3dGYWlsdXJlcyA8PSBtYXhSZXN0YXJ0cyA/ICdyZXN0YXJ0JyA6ICdzdG9wJ1xuXG4gIHJldHVybiB7XG4gICAgZGVjaXNpb24sXG4gICAgbmV4dFN0YXRlOiB7IGZhaWx1cmVUaW1lczogY2FwcGVkIH0sXG4gICAgd2l0aGluV2luZG93RmFpbHVyZXMsXG4gICAgbWF4UmVzdGFydHMsXG4gICAgd2luZG93TXMsXG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFjTyxJQUFNLGVBQWUsdUJBQU8sSUFBSSwyQkFBMkI7QUFNbEUsSUFBTSxlQUFlLENBQUMsUUFBZ0IsS0FBYSxVQUF5QjtBQUMxRSxTQUFPLGVBQWUsUUFBUSxLQUFLO0FBQUEsSUFDakM7QUFBQSxJQUNBLFlBQVk7QUFBQSxJQUNaLGNBQWM7QUFBQSxJQUNkLFVBQVU7QUFBQSxFQUNaLENBQUM7QUFDSDtBQUVPLElBQU0sVUFBVSxDQUFDLFdBQ3JCLE9BQXlCLFlBQVk7QUFFakMsSUFBTSxnQkFBZ0IsQ0FBQyxXQUM1QixRQUFRLE1BQU0sR0FBRztBQUVaLElBQU0sYUFBYSxDQUFPLFFBQW1DLFNBQTJD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QVMsT0FBTztBQUNsQixpQkFBTyxhQUFhLFVBQVUsZUFBZTtBQUFBLFFBQy9DO0FBQUEsTUFDRjtBQUFBLElBQ0YsQ0FBQyxFQUFFO0FBQUEsTUFDREEsUUFBTztBQUFBLFFBQWMsQ0FBQyxVQUNwQkEsUUFBTyxLQUFLLE1BQU07QUFFaEIsY0FBSSxTQUFTLEdBQUc7QUFFZCxvQkFBUSxLQUFLLHFDQUFxQyxNQUFNLE9BQU8sS0FBSyxDQUFDO0FBQUEsVUFDdkU7QUFBQSxRQUNGLENBQUM7QUFBQSxNQUNIO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBLFFBQVE7QUFBQSxJQUNSO0FBQUEsRUFDRjtBQUNGLENBQUM7QUFFSSxJQUFNLFFBQVEsQ0FBQyxZQUNwQlksT0FBTSxPQUFPLG1CQUFtQixLQUFLLE9BQU8sQ0FBQzsiLAogICJuYW1lcyI6IFsiQ29udGV4dCIsICJFZmZlY3QiLCAiRmliZXIiLCAiRmliZXJSZWYiLCAiTGF5ZXIiLCAiT3B0aW9uIiwgIlJlZiIsICJTY29wZSIsICJTdHJlYW0iLCAiRWZmZWN0IiwgIkVmZmVjdCIsICJvblRyaWdnZXIiLCAibmV4dFNpemUiLCAiaXNSZWNvcmQiLCAidGFnIiwgIkNvbnRleHQiLCAiRmliZXJSZWYiLCAiRWZmZWN0IiwgIlJlZiIsICJPcHRpb24iLCAiRmliZXIiLCAiU2NvcGUiLCAiU3RyZWFtIiwgInRhZyIsICJmb3VuZCIsICJydW50aW1lIiwgInN0cmVhbSIsICJpbnN0YWxsYXRpb24iLCAib3B0aW9ucyIsICJMYXllciJdCn0K