@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
@@ -0,0 +1,1698 @@
1
+ // @logix/core subpath bundles for @logix/sandbox
2
+
3
+ import {
4
+ shouldNoopInSyncTransactionFiber
5
+ } from "./chunk-QUMEVT2F.js";
6
+ import {
7
+ getRuntimeInternals
8
+ } from "./chunk-F743SKYD.js";
9
+ import {
10
+ currentDiagnosticsLevel,
11
+ record,
12
+ toRuntimeDebugEventRef,
13
+ toSerializableErrorSummary
14
+ } from "./chunk-X74KU74D.js";
15
+ import {
16
+ makeEvidenceSink
17
+ } from "./chunk-GZ2NSE6A.js";
18
+ import {
19
+ projectJsonValue
20
+ } from "./chunk-S6ZZHV6G.js";
21
+ import {
22
+ isDevEnv
23
+ } from "./chunk-LTFCYZQ6.js";
24
+
25
+ // ../logix-core/src/internal/runtime/core/process/meta.ts
26
+ var PROCESS_META = /* @__PURE__ */ Symbol.for("@logix/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("@logix/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("@logix/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(`@logix/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(`@logix/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(`@logix/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(`@logix/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,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL3Byb2Nlc3MvbWV0YS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9vYnNlcnZhYmlsaXR5L2V2aWRlbmNlQ29sbGVjdG9yLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL1Byb2Nlc3NSdW50aW1lLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL2lkZW50aXR5LnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL2NvbmN1cnJlbmN5LnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL2V2ZW50cy50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvcHJvY2Vzcy9zZWxlY3RvclNjaGVtYS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvcHJvY2Vzcy9zdXBlcnZpc2lvbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHR5cGUgeyBFZmZlY3QgfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgdHlwZSB7IFByb2Nlc3NEZWZpbml0aW9uLCBQcm9jZXNzU2NvcGUgfSBmcm9tICcuL3Byb3RvY29sLmpzJ1xuXG5leHBvcnQgdHlwZSBQcm9jZXNzTWV0YSA9IHtcbiAgcmVhZG9ubHkgZGVmaW5pdGlvbjogUHJvY2Vzc0RlZmluaXRpb25cbiAgLyoqXG4gICAqIGluc3RhbGxhdGlvblNjb3BlXHVGRjFBU3RhdGljIElSIFx1NzY4NFx1NEUwMFx1OTBFOFx1NTIwNlx1MzAwMlxuICAgKiAtIFx1NUJGOVx1NEU4RSBpbnN0YW5jZS1zY29wZSAvIHN1YnRyZWUtc2NvcGUgXHU3QjQ5XHU1NzNBXHU2NjZGXHVGRjBDXHU4RkQwXHU4ODRDXHU2NUY2XHU0RjFBXHU1NzI4XHU1Qjg5XHU4OEM1XHU2NUY2XHU3NTI4XHUyMDFDXHU2RDNFXHU3NTFGIGVmZmVjdFx1MjAxRFx1ODk4Nlx1NzZENlx1OEJFNVx1NUI1N1x1NkJCNVx1RkYxQlxuICAgKiAtIFx1OEJFNVx1NUI1N1x1NkJCNVx1NEVDNVx1NzUyOFx1NEU4RVx1NUJGQ1x1NTFGQS9cdThCQ0FcdTY1QURcdUZGMENcdTRFMERcdTUzQzJcdTRFMEVcdTdBMzNcdTVCOUFcdThFQUJcdTRFRkRcdTZEM0VcdTc1MUZcdUZGMDhcdThFQUJcdTRFRkRcdTZEM0VcdTc1MUZcdTU3MjggaWRlbnRpdHkudHMgXHU1QjhDXHU2MjEwXHVGRjA5XHUzMDAyXG4gICAqL1xuICByZWFkb25seSBpbnN0YWxsYXRpb25TY29wZT86IFByb2Nlc3NTY29wZVxuICByZWFkb25seSBraW5kPzogJ3Byb2Nlc3MnIHwgJ2xpbmsnXG59XG5cbmV4cG9ydCBjb25zdCBQUk9DRVNTX01FVEEgPSBTeW1ib2wuZm9yKCdAbG9naXgvY29yZS9wcm9jZXNzTWV0YScpXG5cbmV4cG9ydCB0eXBlIFByb2Nlc3NFZmZlY3Q8RSA9IG5ldmVyLCBSID0gbmV2ZXI+ID0gRWZmZWN0LkVmZmVjdDx2b2lkLCBFLCBSPiAmIHtcbiAgcmVhZG9ubHkgW1BST0NFU1NfTUVUQV0/OiBQcm9jZXNzTWV0YVxufVxuXG5jb25zdCBkZWZpbmVIaWRkZW4gPSAodGFyZ2V0OiBvYmplY3QsIGtleTogc3ltYm9sLCB2YWx1ZTogdW5rbm93bik6IHZvaWQgPT4ge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHtcbiAgICB2YWx1ZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICB9KVxufVxuXG5leHBvcnQgY29uc3QgZ2V0TWV0YSA9IChlZmZlY3Q6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgYW55LCBhbnk+KTogUHJvY2Vzc01ldGEgfCB1bmRlZmluZWQgPT5cbiAgKGVmZmVjdCBhcyBQcm9jZXNzRWZmZWN0KVtQUk9DRVNTX01FVEFdXG5cbmV4cG9ydCBjb25zdCBnZXREZWZpbml0aW9uID0gKGVmZmVjdDogRWZmZWN0LkVmZmVjdDx2b2lkLCBhbnksIGFueT4pOiBQcm9jZXNzRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCA9PlxuICBnZXRNZXRhKGVmZmVjdCk/LmRlZmluaXRpb25cblxuZXhwb3J0IGNvbnN0IGF0dGFjaE1ldGEgPSA8RSwgUj4oZWZmZWN0OiBFZmZlY3QuRWZmZWN0PHZvaWQsIEUsIFI+LCBtZXRhOiBQcm9jZXNzTWV0YSk6IFByb2Nlc3NFZmZlY3Q8RSwgUj4gPT4ge1xuICBkZWZpbmVIaWRkZW4oZWZmZWN0IGFzIGFueSwgUFJPQ0VTU19NRVRBLCBtZXRhKVxuICByZXR1cm4gZWZmZWN0IGFzIFByb2Nlc3NFZmZlY3Q8RSwgUj5cbn1cbiIsICJpbXBvcnQgeyBDb250ZXh0LCBFZmZlY3QsIEZpYmVyUmVmLCBMYXllciB9IGZyb20gJ2VmZmVjdCdcbmltcG9ydCB0eXBlIHsgSnNvblZhbHVlIH0gZnJvbSAnLi9qc29uVmFsdWUuanMnXG5pbXBvcnQgeyBwcm9qZWN0SnNvblZhbHVlIH0gZnJvbSAnLi9qc29uVmFsdWUuanMnXG5pbXBvcnQgdHlwZSB7IEV2aWRlbmNlUGFja2FnZSB9IGZyb20gJy4vZXZpZGVuY2UuanMnXG5pbXBvcnQgdHlwZSB7IFJ1blNlc3Npb24gfSBmcm9tICcuL3J1blNlc3Npb24uanMnXG5pbXBvcnQgeyBtYWtlRXZpZGVuY2VTaW5rIH0gZnJvbSAnLi9ydW5TZXNzaW9uLmpzJ1xuaW1wb3J0IHtcbiAgY3VycmVudERpYWdub3N0aWNzTGV2ZWwsXG4gIHRvUnVudGltZURlYnVnRXZlbnRSZWYsXG4gIHR5cGUgRXZlbnQgYXMgRGVidWdFdmVudCxcbiAgdHlwZSBTaW5rIGFzIERlYnVnU2luayxcbn0gZnJvbSAnLi4vcnVudGltZS9jb3JlL0RlYnVnU2luay5qcydcblxuZXhwb3J0IGludGVyZmFjZSBFdmlkZW5jZUNvbGxlY3RvciB7XG4gIHJlYWRvbmx5IHNlc3Npb246IFJ1blNlc3Npb25cbiAgcmVhZG9ubHkgZGVidWdTaW5rOiBEZWJ1Z1NpbmtcbiAgcmVhZG9ubHkgcmVnaXN0ZXJDb252ZXJnZVN0YXRpY0lyOiAoc3RhdGljSXI6IHVua25vd24pID0+IHZvaWRcbiAgcmVhZG9ubHkgc2V0S2VybmVsSW1wbGVtZW50YXRpb25SZWY6IChyZWY6IHVua25vd24pID0+IHZvaWRcbiAgcmVhZG9ubHkgc2V0UnVudGltZVNlcnZpY2VzRXZpZGVuY2U6IChldmlkZW5jZTogdW5rbm93bikgPT4gdm9pZFxuICByZWFkb25seSBleHBvcnRFdmlkZW5jZVBhY2thZ2U6IChvcHRpb25zPzogeyByZWFkb25seSBtYXhFdmVudHM/OiBudW1iZXIgfSkgPT4gRXZpZGVuY2VQYWNrYWdlXG4gIHJlYWRvbmx5IGNsZWFyOiAoKSA9PiB2b2lkXG59XG5cbmNsYXNzIEV2aWRlbmNlQ29sbGVjdG9yVGFnSW1wbCBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXgvY29yZS9FdmlkZW5jZUNvbGxlY3RvcicpPFxuICBFdmlkZW5jZUNvbGxlY3RvclRhZ0ltcGwsXG4gIEV2aWRlbmNlQ29sbGVjdG9yXG4+KCkge31cblxuZXhwb3J0IGNvbnN0IEV2aWRlbmNlQ29sbGVjdG9yVGFnID0gRXZpZGVuY2VDb2xsZWN0b3JUYWdJbXBsXG5cbmV4cG9ydCBjb25zdCBldmlkZW5jZUNvbGxlY3RvckxheWVyID0gKFxuICBjb2xsZWN0b3I6IEV2aWRlbmNlQ29sbGVjdG9yLFxuKTogTGF5ZXIuTGF5ZXI8RXZpZGVuY2VDb2xsZWN0b3JUYWdJbXBsLCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLnN1Y2NlZWQoRXZpZGVuY2VDb2xsZWN0b3JUYWcsIGNvbGxlY3RvcikgYXMgTGF5ZXIuTGF5ZXI8RXZpZGVuY2VDb2xsZWN0b3JUYWdJbXBsLCBuZXZlciwgbmV2ZXI+XG5cbmNvbnN0IGlzUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT5cbiAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSlcblxuZXhwb3J0IGNvbnN0IG1ha2VFdmlkZW5jZUNvbGxlY3RvciA9IChzZXNzaW9uOiBSdW5TZXNzaW9uKTogRXZpZGVuY2VDb2xsZWN0b3IgPT4ge1xuICBjb25zdCBzaW5rID0gbWFrZUV2aWRlbmNlU2luayhzZXNzaW9uKVxuXG4gIGNvbnN0IGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdCA9IG5ldyBNYXA8c3RyaW5nLCBKc29uVmFsdWU+KClcbiAgbGV0IGtlcm5lbEltcGxlbWVudGF0aW9uUmVmOiBKc29uVmFsdWUgfCB1bmRlZmluZWRcbiAgbGV0IHJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlOiBKc29uVmFsdWUgfCB1bmRlZmluZWRcblxuICBjb25zdCBleHBvcnRCdWRnZXQgPSB7XG4gICAgZHJvcHBlZDogMCxcbiAgICBvdmVyc2l6ZWQ6IDAsXG4gICAgbm9uU2VyaWFsaXphYmxlOiAwLFxuICB9XG5cbiAgY29uc3QgZGVidWdTaW5rOiBEZWJ1Z1NpbmsgPSB7XG4gICAgcmVjb3JkOiAoZXZlbnQ6IERlYnVnRXZlbnQpID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGxldmVsID0geWllbGQqIEZpYmVyUmVmLmdldChjdXJyZW50RGlhZ25vc3RpY3NMZXZlbClcbiAgICAgICAgY29uc3QgaW5zdGFuY2VJZFJhdyA9IChldmVudCBhcyBhbnkpLmluc3RhbmNlSWRcbiAgICAgICAgY29uc3QgaW5zdGFuY2VJZCA9IHR5cGVvZiBpbnN0YW5jZUlkUmF3ID09PSAnc3RyaW5nJyAmJiBpbnN0YW5jZUlkUmF3Lmxlbmd0aCA+IDAgPyBpbnN0YW5jZUlkUmF3IDogJ3Vua25vd24nXG4gICAgICAgIGNvbnN0IGV2ZW50U2VxID0gbGV2ZWwgPT09ICdvZmYnID8gdW5kZWZpbmVkIDogc2Vzc2lvbi5sb2NhbC5uZXh0U2VxKCdldmVudFNlcScsIGluc3RhbmNlSWQpXG4gICAgICAgIGNvbnN0IHJlZiA9IHRvUnVudGltZURlYnVnRXZlbnRSZWYoZXZlbnQsIHtcbiAgICAgICAgICBkaWFnbm9zdGljc0xldmVsOiBsZXZlbCxcbiAgICAgICAgICBldmVudFNlcSxcbiAgICAgICAgICBvbk1ldGFQcm9qZWN0aW9uOiAoeyBzdGF0cyB9KSA9PiB7XG4gICAgICAgICAgICBleHBvcnRCdWRnZXQuZHJvcHBlZCArPSBzdGF0cy5kcm9wcGVkXG4gICAgICAgICAgICBleHBvcnRCdWRnZXQub3ZlcnNpemVkICs9IHN0YXRzLm92ZXJzaXplZFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIGlmICghcmVmKSByZXR1cm5cblxuICAgICAgICBjb25zdCBwcm9qZWN0ZWQgPSBwcm9qZWN0SnNvblZhbHVlKHJlZilcbiAgICAgICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgKz0gcHJvamVjdGVkLnN0YXRzLmRyb3BwZWRcbiAgICAgICAgZXhwb3J0QnVkZ2V0Lm92ZXJzaXplZCArPSBwcm9qZWN0ZWQuc3RhdHMub3ZlcnNpemVkXG4gICAgICAgIGV4cG9ydEJ1ZGdldC5ub25TZXJpYWxpemFibGUgKz0gcHJvamVjdGVkLnN0YXRzLm5vblNlcmlhbGl6YWJsZVxuXG4gICAgICAgIHNpbmsucmVjb3JkKCdkZWJ1ZzpldmVudCcsIHByb2plY3RlZC52YWx1ZSwge1xuICAgICAgICAgIHRpbWVzdGFtcDogcmVmLnRpbWVzdGFtcCxcbiAgICAgICAgfSlcbiAgICAgIH0pLFxuICB9XG5cbiAgY29uc3QgcmVnaXN0ZXJDb252ZXJnZVN0YXRpY0lyID0gKHN0YXRpY0lyOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgaWYgKCFpc1JlY29yZChzdGF0aWNJcikpIHJldHVyblxuICAgIGNvbnN0IGRpZ2VzdCA9IHN0YXRpY0lyLnN0YXRpY0lyRGlnZXN0XG4gICAgaWYgKHR5cGVvZiBkaWdlc3QgIT09ICdzdHJpbmcnIHx8IGRpZ2VzdC5sZW5ndGggPT09IDApIHJldHVyblxuICAgIGNvbnN0IHByb2plY3RlZCA9IHByb2plY3RKc29uVmFsdWUoc3RhdGljSXIpXG4gICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgKz0gcHJvamVjdGVkLnN0YXRzLmRyb3BwZWRcbiAgICBleHBvcnRCdWRnZXQub3ZlcnNpemVkICs9IHByb2plY3RlZC5zdGF0cy5vdmVyc2l6ZWRcbiAgICBleHBvcnRCdWRnZXQubm9uU2VyaWFsaXphYmxlICs9IHByb2plY3RlZC5zdGF0cy5ub25TZXJpYWxpemFibGVcbiAgICBjb252ZXJnZVN0YXRpY0lyQnlEaWdlc3Quc2V0KGRpZ2VzdCwgcHJvamVjdGVkLnZhbHVlKVxuICB9XG5cbiAgY29uc3Qgc2V0S2VybmVsSW1wbGVtZW50YXRpb25SZWYgPSAocmVmOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgY29uc3QgcHJvamVjdGVkID0gcHJvamVjdEpzb25WYWx1ZShyZWYpXG4gICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgKz0gcHJvamVjdGVkLnN0YXRzLmRyb3BwZWRcbiAgICBleHBvcnRCdWRnZXQub3ZlcnNpemVkICs9IHByb2plY3RlZC5zdGF0cy5vdmVyc2l6ZWRcbiAgICBleHBvcnRCdWRnZXQubm9uU2VyaWFsaXphYmxlICs9IHByb2plY3RlZC5zdGF0cy5ub25TZXJpYWxpemFibGVcbiAgICBrZXJuZWxJbXBsZW1lbnRhdGlvblJlZiA9IHByb2plY3RlZC52YWx1ZVxuICB9XG5cbiAgY29uc3Qgc2V0UnVudGltZVNlcnZpY2VzRXZpZGVuY2UgPSAoZXZpZGVuY2U6IHVua25vd24pOiB2b2lkID0+IHtcbiAgICBjb25zdCBwcm9qZWN0ZWQgPSBwcm9qZWN0SnNvblZhbHVlKGV2aWRlbmNlKVxuICAgIGV4cG9ydEJ1ZGdldC5kcm9wcGVkICs9IHByb2plY3RlZC5zdGF0cy5kcm9wcGVkXG4gICAgZXhwb3J0QnVkZ2V0Lm92ZXJzaXplZCArPSBwcm9qZWN0ZWQuc3RhdHMub3ZlcnNpemVkXG4gICAgZXhwb3J0QnVkZ2V0Lm5vblNlcmlhbGl6YWJsZSArPSBwcm9qZWN0ZWQuc3RhdHMubm9uU2VyaWFsaXphYmxlXG4gICAgcnVudGltZVNlcnZpY2VzRXZpZGVuY2UgPSBwcm9qZWN0ZWQudmFsdWVcbiAgfVxuXG4gIGNvbnN0IGV4cG9ydEV2aWRlbmNlUGFja2FnZSA9IChvcHRpb25zPzogeyByZWFkb25seSBtYXhFdmVudHM/OiBudW1iZXIgfSk6IEV2aWRlbmNlUGFja2FnZSA9PiB7XG4gICAgY29uc3QgY29udmVyZ2VTdW1tYXJ5ID1cbiAgICAgIGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdC5zaXplID4gMFxuICAgICAgICA/ICh7XG4gICAgICAgICAgICBzdGF0aWNJckJ5RGlnZXN0OiBPYmplY3QuZnJvbUVudHJpZXMoY29udmVyZ2VTdGF0aWNJckJ5RGlnZXN0KSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgSnNvblZhbHVlKVxuICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgY29uc3QgcnVudGltZVN1bW1hcnkgPVxuICAgICAga2VybmVsSW1wbGVtZW50YXRpb25SZWYgIT0gbnVsbCB8fCBydW50aW1lU2VydmljZXNFdmlkZW5jZSAhPSBudWxsXG4gICAgICAgID8gKHtcbiAgICAgICAgICAgIC4uLihrZXJuZWxJbXBsZW1lbnRhdGlvblJlZiAhPSBudWxsID8geyBrZXJuZWxJbXBsZW1lbnRhdGlvblJlZiB9IDoge30pLFxuICAgICAgICAgICAgLi4uKHJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlICE9IG51bGwgPyB7IHNlcnZpY2VzOiBydW50aW1lU2VydmljZXNFdmlkZW5jZSB9IDoge30pLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBKc29uVmFsdWUpXG4gICAgICAgIDogdW5kZWZpbmVkXG5cbiAgICBjb25zdCBzdW1tYXJ5ID1cbiAgICAgIGNvbnZlcmdlU3VtbWFyeSAhPSBudWxsIHx8IHJ1bnRpbWVTdW1tYXJ5ICE9IG51bGxcbiAgICAgICAgPyAoe1xuICAgICAgICAgICAgLi4uKGNvbnZlcmdlU3VtbWFyeSAhPSBudWxsID8geyBjb252ZXJnZTogY29udmVyZ2VTdW1tYXJ5IH0gOiB7fSksXG4gICAgICAgICAgICAuLi4ocnVudGltZVN1bW1hcnkgIT0gbnVsbCA/IHsgcnVudGltZTogcnVudGltZVN1bW1hcnkgfSA6IHt9KSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgSnNvblZhbHVlKVxuICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgcmV0dXJuIHNpbmsuZXhwb3J0KHtcbiAgICAgIG1heEV2ZW50czogb3B0aW9ucz8ubWF4RXZlbnRzLFxuICAgICAgc3VtbWFyeSxcbiAgICB9KVxuICB9XG5cbiAgY29uc3QgY2xlYXIgPSAoKTogdm9pZCA9PiB7XG4gICAgc2luay5jbGVhcigpXG4gICAgY29udmVyZ2VTdGF0aWNJckJ5RGlnZXN0LmNsZWFyKClcbiAgICBrZXJuZWxJbXBsZW1lbnRhdGlvblJlZiA9IHVuZGVmaW5lZFxuICAgIHJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlID0gdW5kZWZpbmVkXG4gICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgPSAwXG4gICAgZXhwb3J0QnVkZ2V0Lm92ZXJzaXplZCA9IDBcbiAgICBleHBvcnRCdWRnZXQubm9uU2VyaWFsaXphYmxlID0gMFxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzZXNzaW9uLFxuICAgIGRlYnVnU2luayxcbiAgICByZWdpc3RlckNvbnZlcmdlU3RhdGljSXIsXG4gICAgc2V0S2VybmVsSW1wbGVtZW50YXRpb25SZWYsXG4gICAgc2V0UnVudGltZVNlcnZpY2VzRXZpZGVuY2UsXG4gICAgZXhwb3J0RXZpZGVuY2VQYWNrYWdlLFxuICAgIGNsZWFyLFxuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgQ2F1c2UsXG4gIENvbnRleHQsXG4gIERlZmVycmVkLFxuICBEdXJhdGlvbixcbiAgRWZmZWN0LFxuICBGaWJlcixcbiAgRmliZXJSZWYsXG4gIExheWVyLFxuICBPcHRpb24sXG4gIFB1YlN1YixcbiAgUXVldWUsXG4gIFJlZixcbiAgU2NvcGUsXG4gIFN0cmVhbSxcbn0gZnJvbSAnZWZmZWN0J1xuaW1wb3J0ICogYXMgRGVidWcgZnJvbSAnLi4vRGVidWdTaW5rLmpzJ1xuaW1wb3J0IHsgdG9TZXJpYWxpemFibGVFcnJvclN1bW1hcnkgfSBmcm9tICcuLi9lcnJvclN1bW1hcnkuanMnXG5pbXBvcnQgKiBhcyBUYXNrUnVubmVyIGZyb20gJy4uL1Rhc2tSdW5uZXIuanMnXG5pbXBvcnQgeyBpc0RldkVudiB9IGZyb20gJy4uL2Vudi5qcydcbmltcG9ydCB7IGdldFJ1bnRpbWVJbnRlcm5hbHMgfSBmcm9tICcuLi9ydW50aW1lSW50ZXJuYWxzQWNjZXNzb3IuanMnXG5pbXBvcnQgKiBhcyBJZGVudGl0eSBmcm9tICcuL2lkZW50aXR5LmpzJ1xuaW1wb3J0ICogYXMgUHJvY2Vzc0NvbmN1cnJlbmN5IGZyb20gJy4vY29uY3VycmVuY3kuanMnXG5pbXBvcnQgKiBhcyBQcm9jZXNzRXZlbnRzIGZyb20gJy4vZXZlbnRzLmpzJ1xuaW1wb3J0ICogYXMgTWV0YSBmcm9tICcuL21ldGEuanMnXG5pbXBvcnQgeyBtYWtlU2NoZW1hU2VsZWN0b3IsIHJlc29sdmVTY2hlbWFBc3QgfSBmcm9tICcuL3NlbGVjdG9yU2NoZW1hLmpzJ1xuaW1wb3J0IHR5cGUge1xuICBQcm9jZXNzQ29udHJvbFJlcXVlc3QsXG4gIFByb2Nlc3NEZWZpbml0aW9uLFxuICBQcm9jZXNzRXZlbnQsXG4gIFByb2Nlc3NJbnN0YWxsYXRpb24sXG4gIFByb2Nlc3NJbnN0YW5jZUlkZW50aXR5LFxuICBQcm9jZXNzSW5zdGFuY2VTdGF0dXMsXG4gIFByb2Nlc3NQbGF0Zm9ybUV2ZW50LFxuICBQcm9jZXNzU2NvcGUsXG4gIFByb2Nlc3NUcmlnZ2VyLFxuICBQcm9jZXNzVHJpZ2dlclNwZWMsXG4gIFNlcmlhbGl6YWJsZUVycm9yU3VtbWFyeSxcbn0gZnJvbSAnLi9wcm90b2NvbC5qcydcbmltcG9ydCAqIGFzIFN1cGVydmlzaW9uIGZyb20gJy4vc3VwZXJ2aXNpb24uanMnXG5cbnR5cGUgSW5zdGFsbGF0aW9uS2V5ID0gc3RyaW5nXG50eXBlIFByb2Nlc3NJbnN0YW5jZUlkID0gc3RyaW5nXG5cbnR5cGUgUHJvY2Vzc0luc3RhbGxNb2RlID0gJ3N3aXRjaCcgfCAnZXhoYXVzdCdcblxudHlwZSBJbnN0YWxsYXRpb25TdGF0ZSA9IHtcbiAgcmVhZG9ubHkgaWRlbnRpdHk6IHtcbiAgICByZWFkb25seSBwcm9jZXNzSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IHNjb3BlOiBQcm9jZXNzU2NvcGVcbiAgfVxuICByZWFkb25seSBzY29wZUtleTogc3RyaW5nXG4gIHJlYWRvbmx5IGRlZmluaXRpb246IFByb2Nlc3NEZWZpbml0aW9uXG4gIGVudjogQ29udGV4dC5Db250ZXh0PGFueT5cbiAgZm9ya1Njb3BlOiBTY29wZS5TY29wZVxuICByZWFkb25seSBwcm9jZXNzOiBFZmZlY3QuRWZmZWN0PHZvaWQsIGFueSwgdW5rbm93bj5cbiAgcmVhZG9ubHkga2luZDogTWV0YS5Qcm9jZXNzTWV0YVsna2luZCddXG4gIGVuYWJsZWQ6IGJvb2xlYW5cbiAgaW5zdGFsbGVkQXQ/OiBzdHJpbmdcbiAgbmV4dFJ1blNlcTogbnVtYmVyXG4gIHN1cGVydmlzaW9uOiBTdXBlcnZpc2lvbi5TdXBlcnZpc2lvblN0YXRlXG4gIGN1cnJlbnRJbnN0YW5jZUlkPzogUHJvY2Vzc0luc3RhbmNlSWRcbiAgcGVuZGluZ1N0YXJ0PzogeyByZWFkb25seSBmb3JrU2NvcGU6IFNjb3BlLlNjb3BlIH1cbn1cblxudHlwZSBJbnN0YW5jZVN0YXRlID0ge1xuICByZWFkb25seSBpbnN0YWxsYXRpb25LZXk6IEluc3RhbGxhdGlvbktleVxuICByZWFkb25seSBwcm9jZXNzSW5zdGFuY2VJZDogUHJvY2Vzc0luc3RhbmNlSWRcbiAgcmVhZG9ubHkgaWRlbnRpdHk6IFByb2Nlc3NJbnN0YW5jZUlkZW50aXR5XG4gIHJlYWRvbmx5IHByb2Nlc3NJZDogc3RyaW5nXG4gIHJlYWRvbmx5IHNjb3BlOiBQcm9jZXNzU2NvcGVcbiAgcmVhZG9ubHkgZm9ya1Njb3BlOiBTY29wZS5TY29wZVxuICByZWFkb25seSBwbGF0Zm9ybVRyaWdnZXJzUXVldWU6IFF1ZXVlLlF1ZXVlPFByb2Nlc3NUcmlnZ2VyPlxuICBzdGF0dXM6IFByb2Nlc3NJbnN0YW5jZVN0YXR1c1xuICBuZXh0RXZlbnRTZXE6IG51bWJlclxuICBuZXh0VHJpZ2dlclNlcTogbnVtYmVyXG4gIGZpYmVyPzogRmliZXIuUnVudGltZUZpYmVyPHVua25vd24sIHVua25vd24+XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvY2Vzc1J1bnRpbWUge1xuICByZWFkb25seSBpbnN0YWxsOiA8RSwgUj4oXG4gICAgcHJvY2VzczogRWZmZWN0LkVmZmVjdDx2b2lkLCBFLCBSPixcbiAgICBvcHRpb25zOiB7XG4gICAgICByZWFkb25seSBzY29wZTogUHJvY2Vzc1Njb3BlXG4gICAgICByZWFkb25seSBlbmFibGVkPzogYm9vbGVhblxuICAgICAgcmVhZG9ubHkgaW5zdGFsbGVkQXQ/OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IG1vZGU/OiBQcm9jZXNzSW5zdGFsbE1vZGVcbiAgICB9LFxuICApID0+IEVmZmVjdC5FZmZlY3Q8UHJvY2Vzc0luc3RhbGxhdGlvbiB8IHVuZGVmaW5lZCwgbmV2ZXIsIFI+XG4gIHJlYWRvbmx5IGxpc3RJbnN0YWxsYXRpb25zOiAoZmlsdGVyPzoge1xuICAgIHJlYWRvbmx5IHNjb3BlVHlwZT86IFByb2Nlc3NTY29wZVsndHlwZSddXG4gICAgcmVhZG9ubHkgc2NvcGVLZXk/OiBzdHJpbmdcbiAgfSkgPT4gRWZmZWN0LkVmZmVjdDxSZWFkb25seUFycmF5PFByb2Nlc3NJbnN0YWxsYXRpb24+PlxuICByZWFkb25seSBnZXRJbnN0YW5jZVN0YXR1czogKHByb2Nlc3NJbnN0YW5jZUlkOiBzdHJpbmcpID0+IEVmZmVjdC5FZmZlY3Q8UHJvY2Vzc0luc3RhbmNlU3RhdHVzIHwgdW5kZWZpbmVkPlxuICByZWFkb25seSBjb250cm9sSW5zdGFuY2U6IChwcm9jZXNzSW5zdGFuY2VJZDogc3RyaW5nLCByZXF1ZXN0OiBQcm9jZXNzQ29udHJvbFJlcXVlc3QpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZD5cbiAgcmVhZG9ubHkgZGVsaXZlclBsYXRmb3JtRXZlbnQ6IChldmVudDogUHJvY2Vzc1BsYXRmb3JtRXZlbnQpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZD5cbiAgcmVhZG9ubHkgZXZlbnRzOiBTdHJlYW0uU3RyZWFtPFByb2Nlc3NFdmVudD5cbiAgcmVhZG9ubHkgZ2V0RXZlbnRzU25hcHNob3Q6ICgpID0+IEVmZmVjdC5FZmZlY3Q8UmVhZG9ubHlBcnJheTxQcm9jZXNzRXZlbnQ+PlxufVxuXG5leHBvcnQgY2xhc3MgUHJvY2Vzc1J1bnRpbWVUYWcgZXh0ZW5kcyBDb250ZXh0LlRhZygnQGxvZ2l4L2NvcmUvUHJvY2Vzc1J1bnRpbWUnKTxQcm9jZXNzUnVudGltZVRhZywgUHJvY2Vzc1J1bnRpbWU+KCkge31cblxuY29uc3QgY3VycmVudFByb2Nlc3NUcmlnZ2VyID0gRmliZXJSZWYudW5zYWZlTWFrZTxQcm9jZXNzVHJpZ2dlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKVxuY29uc3QgY3VycmVudFByb2Nlc3NFdmVudEJ1ZGdldCA9IEZpYmVyUmVmLnVuc2FmZU1ha2U8UmVmLlJlZjxQcm9jZXNzRXZlbnRzLlByb2Nlc3NSdW5FdmVudEJ1ZGdldFN0YXRlPiB8IHVuZGVmaW5lZD4oXG4gIHVuZGVmaW5lZCxcbilcbmNvbnN0IFJVTlRJTUVfQk9PVF9FVkVOVCA9ICdydW50aW1lOmJvb3QnIGFzIGNvbnN0XG5cbmNvbnN0IGRlcml2ZURlYnVnTW9kdWxlSWQgPSAocHJvY2Vzc0lkOiBzdHJpbmcpOiBzdHJpbmcgPT4gYHByb2Nlc3M6JHtwcm9jZXNzSWR9YFxuXG50eXBlIE5vblBsYXRmb3JtVHJpZ2dlclNwZWMgPSBFeGNsdWRlPFByb2Nlc3NUcmlnZ2VyU3BlYywgeyByZWFkb25seSBraW5kOiAncGxhdGZvcm1FdmVudCcgfT5cblxuY29uc3QgZGVyaXZlVHhuQW5jaG9yID0gKGV2ZW50OiBQcm9jZXNzRXZlbnQpOiB7IHJlYWRvbmx5IHR4blNlcT86IG51bWJlcjsgcmVhZG9ubHkgdHhuSWQ/OiBzdHJpbmcgfSA9PiB7XG4gIGNvbnN0IHRyaWdnZXI6IGFueSA9IGV2ZW50LnRyaWdnZXJcbiAgaWYgKCF0cmlnZ2VyKSByZXR1cm4ge31cbiAgaWYgKFxuICAgICh0cmlnZ2VyLmtpbmQgPT09ICdtb2R1bGVBY3Rpb24nIHx8IHRyaWdnZXIua2luZCA9PT0gJ21vZHVsZVN0YXRlQ2hhbmdlJykgJiZcbiAgICB0eXBlb2YgdHJpZ2dlci5pbnN0YW5jZUlkID09PSAnc3RyaW5nJyAmJlxuICAgIHR5cGVvZiB0cmlnZ2VyLnR4blNlcSA9PT0gJ251bWJlcicgJiZcbiAgICBOdW1iZXIuaXNGaW5pdGUodHJpZ2dlci50eG5TZXEpICYmXG4gICAgdHJpZ2dlci50eG5TZXEgPj0gMVxuICApIHtcbiAgICBjb25zdCB0eG5TZXEgPSBNYXRoLmZsb29yKHRyaWdnZXIudHhuU2VxKVxuICAgIHJldHVybiB7XG4gICAgICB0eG5TZXEsXG4gICAgICB0eG5JZDogYCR7dHJpZ2dlci5pbnN0YW5jZUlkfTo6dCR7dHhuU2VxfWAsXG4gICAgfVxuICB9XG4gIHJldHVybiB7fVxufVxuXG5jb25zdCBzaG91bGROb29wRHVlVG9TeW5jVHhuID0gKHNjb3BlOiBQcm9jZXNzU2NvcGUsIGtpbmQ6IHN0cmluZyk6IEVmZmVjdC5FZmZlY3Q8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBtb2R1bGVJZCA9IHNjb3BlLnR5cGUgPT09ICdtb2R1bGVJbnN0YW5jZScgPyBzY29wZS5tb2R1bGVJZCA6IHVuZGVmaW5lZFxuICBjb25zdCBpbnN0YW5jZUlkID0gc2NvcGUudHlwZSA9PT0gJ21vZHVsZUluc3RhbmNlJyA/IHNjb3BlLmluc3RhbmNlSWQgOiB1bmRlZmluZWRcbiAgcmV0dXJuIFRhc2tSdW5uZXIuc2hvdWxkTm9vcEluU3luY1RyYW5zYWN0aW9uRmliZXIoe1xuICAgIG1vZHVsZUlkLFxuICAgIGluc3RhbmNlSWQsXG4gICAgY29kZTogJ3Byb2Nlc3M6OmludmFsaWRfdXNhZ2UnLFxuICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgIG1lc3NhZ2U6XG4gICAgICAnUHJvY2Vzc1J1bnRpbWUgc2NoZWR1bGluZyBpcyBub3QgYWxsb3dlZCBpbnNpZGUgYSBzeW5jaHJvbm91cyBTdGF0ZVRyYW5zYWN0aW9uIGJvZHkgKGl0IG1heSBkZWFkbG9jayB0aGUgdHhuUXVldWUpLicsXG4gICAgaGludDpcbiAgICAgIFwiVHJpZ2dlci9zY2hlZHVsZSBQcm9jZXNzIG91dHNpZGUgdGhlIHRyYW5zYWN0aW9uIHdpbmRvdyAoZS5nLiBpbiBhIHdhdGNoZXIncyBydW4gc2VjdGlvbiBvciBhIHNlcGFyYXRlIGZpYmVyKTsgXCIgK1xuICAgICAgJ2RvIG5vdCB0cmlnZ2VyIFByb2Nlc3MgZGlyZWN0bHkgaW5zaWRlIGEgcmVkdWNlciAvIHN5bmNocm9ub3VzIHRyYW5zYWN0aW9uIGJvZHkuJyxcbiAgICBraW5kLFxuICB9KVxufVxuXG5jb25zdCByZXNvbHZlUnVudGltZVN0YXRlU2NoZW1hQXN0ID0gKHJ1bnRpbWU6IHVua25vd24pOiBSZXR1cm5UeXBlPHR5cGVvZiByZXNvbHZlU2NoZW1hQXN0PiA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgaW50ZXJuYWxzID0gZ2V0UnVudGltZUludGVybmFscyhydW50aW1lIGFzIGFueSlcbiAgICByZXR1cm4gcmVzb2x2ZVNjaGVtYUFzdChpbnRlcm5hbHMuc3RhdGVTY2hlbWEpXG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxufVxuXG5jb25zdCB3aXRoTW9kdWxlSGludCA9IChlcnJvcjogRXJyb3IsIG1vZHVsZUlkOiBzdHJpbmcpOiBFcnJvciA9PiB7XG4gIGNvbnN0IGhpbnQgPSAoZXJyb3IgYXMgYW55KS5oaW50XG4gIGlmICh0eXBlb2YgaGludCA9PT0gJ3N0cmluZycgJiYgaGludC5sZW5ndGggPiAwKSB7XG4gICAgaWYgKCFoaW50LmluY2x1ZGVzKCdtb2R1bGVJZD0nKSkge1xuICAgICAgOyhlcnJvciBhcyBhbnkpLmhpbnQgPSBgbW9kdWxlSWQ9JHttb2R1bGVJZH1cXG4ke2hpbnR9YFxuICAgIH1cbiAgICByZXR1cm4gZXJyb3JcbiAgfVxuICA7KGVycm9yIGFzIGFueSkuaGludCA9IGBtb2R1bGVJZD0ke21vZHVsZUlkfWBcbiAgcmV0dXJuIGVycm9yXG59XG5cbmNvbnN0IGFjdGlvbklkRnJvbVVua25vd24gPSAoYWN0aW9uOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgaWYgKCFhY3Rpb24gfHwgdHlwZW9mIGFjdGlvbiAhPT0gJ29iamVjdCcpIHJldHVybiB1bmRlZmluZWRcbiAgY29uc3QgYW55QWN0aW9uID0gYWN0aW9uIGFzIGFueVxuICBpZiAodHlwZW9mIGFueUFjdGlvbi5fdGFnID09PSAnc3RyaW5nJyAmJiBhbnlBY3Rpb24uX3RhZy5sZW5ndGggPiAwKSByZXR1cm4gYW55QWN0aW9uLl90YWdcbiAgaWYgKHR5cGVvZiBhbnlBY3Rpb24udHlwZSA9PT0gJ3N0cmluZycgJiYgYW55QWN0aW9uLnR5cGUubGVuZ3RoID4gMCkgcmV0dXJuIGFueUFjdGlvbi50eXBlXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuZXhwb3J0IGNvbnN0IG1ha2UgPSAob3B0aW9ucz86IHtcbiAgcmVhZG9ubHkgbWF4RXZlbnRIaXN0b3J5PzogbnVtYmVyXG59KTogRWZmZWN0LkVmZmVjdDxQcm9jZXNzUnVudGltZSwgbmV2ZXIsIFNjb3BlLlNjb3BlPiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3QgcnVudGltZVNjb3BlID0geWllbGQqIEVmZmVjdC5zY29wZVxuICAgIGNvbnN0IG1heEV2ZW50SGlzdG9yeSA9XG4gICAgICB0eXBlb2Ygb3B0aW9ucz8ubWF4RXZlbnRIaXN0b3J5ID09PSAnbnVtYmVyJyAmJlxuICAgICAgTnVtYmVyLmlzRmluaXRlKG9wdGlvbnMubWF4RXZlbnRIaXN0b3J5KSAmJlxuICAgICAgb3B0aW9ucy5tYXhFdmVudEhpc3RvcnkgPj0gMFxuICAgICAgICA/IE1hdGguZmxvb3Iob3B0aW9ucy5tYXhFdmVudEhpc3RvcnkpXG4gICAgICAgIDogNTAwXG5cbiAgICBjb25zdCBpbnN0YWxsYXRpb25zID0gbmV3IE1hcDxJbnN0YWxsYXRpb25LZXksIEluc3RhbGxhdGlvblN0YXRlPigpXG4gICAgY29uc3QgaW5zdGFuY2VzID0gbmV3IE1hcDxQcm9jZXNzSW5zdGFuY2VJZCwgSW5zdGFuY2VTdGF0ZT4oKVxuXG4gICAgY29uc3QgZXZlbnRzQnVmZmVyOiBQcm9jZXNzRXZlbnRbXSA9IFtdXG4gICAgY29uc3QgZXZlbnRzSHViID0geWllbGQqIFB1YlN1Yi5zbGlkaW5nPFByb2Nlc3NFdmVudD4oTWF0aC5tYXgoMSwgTWF0aC5taW4oMjA0OCwgbWF4RXZlbnRIaXN0b3J5KSkpXG5cbiAgICBjb25zdCB0cmltRXZlbnRzID0gKCkgPT4ge1xuICAgICAgaWYgKG1heEV2ZW50SGlzdG9yeSA8PSAwKSB7XG4gICAgICAgIGV2ZW50c0J1ZmZlci5sZW5ndGggPSAwXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgaWYgKGV2ZW50c0J1ZmZlci5sZW5ndGggPD0gbWF4RXZlbnRIaXN0b3J5KSByZXR1cm5cbiAgICAgIGNvbnN0IGV4Y2VzcyA9IGV2ZW50c0J1ZmZlci5sZW5ndGggLSBtYXhFdmVudEhpc3RvcnlcbiAgICAgIGV2ZW50c0J1ZmZlci5zcGxpY2UoMCwgZXhjZXNzKVxuICAgIH1cblxuICAgIGNvbnN0IHJlY29yZERlYnVnRXZlbnQgPSAoZXZlbnQ6IFByb2Nlc3NFdmVudCk6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgZGlhZ25vc3RpY3NMZXZlbCA9IHlpZWxkKiBGaWJlclJlZi5nZXQoRGVidWcuY3VycmVudERpYWdub3N0aWNzTGV2ZWwpXG5cbiAgICAgICAgLy8gZGlhZ25vc3RpY3M9b2ZmXHVGRjFBXHU1QzNEXHU5MUNGXHU0RTBEXHU4RkRCXHU1MTY1IERlYnVnIHNpbmtzXHVGRjA4XHU4RkQxXHU5NkY2XHU2MjEwXHU2NzJDXHVGRjA5XHVGRjFCXHU5NTE5XHU4QkVGXHU1NzNBXHU2NjZGXHU1M0U2XHU4ODRDXHU5MDFBXHU4RkM3IGRpYWdub3N0aWMgXHU0RThCXHU0RUY2XHU2NkI0XHU5NzMyXHUzMDAyXG4gICAgICAgIGlmIChkaWFnbm9zdGljc0xldmVsID09PSAnb2ZmJykge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJvY2Vzc0lkID0gZXZlbnQuaWRlbnRpdHkuaWRlbnRpdHkucHJvY2Vzc0lkXG4gICAgICAgIGNvbnN0IHByb2Nlc3NJbnN0YW5jZUlkID0gSWRlbnRpdHkucHJvY2Vzc0luc3RhbmNlSWRGcm9tSWRlbnRpdHkoZXZlbnQuaWRlbnRpdHkpXG4gICAgICAgIGNvbnN0IG1vZHVsZUlkID0gZGVyaXZlRGVidWdNb2R1bGVJZChwcm9jZXNzSWQpXG4gICAgICAgIGNvbnN0IHsgdHhuU2VxLCB0eG5JZCB9ID0gZGVyaXZlVHhuQW5jaG9yKGV2ZW50KVxuXG4gICAgICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICAgIHR5cGU6IGV2ZW50LnR5cGUsXG4gICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgaW5zdGFuY2VJZDogcHJvY2Vzc0luc3RhbmNlSWQsXG4gICAgICAgICAgaWRlbnRpdHk6IGV2ZW50LmlkZW50aXR5LFxuICAgICAgICAgIHNldmVyaXR5OiBldmVudC5zZXZlcml0eSxcbiAgICAgICAgICBldmVudFNlcTogZXZlbnQuZXZlbnRTZXEsXG4gICAgICAgICAgdGltZXN0YW1wTXM6IGV2ZW50LnRpbWVzdGFtcE1zLFxuICAgICAgICAgIHRyaWdnZXI6IGV2ZW50LnRyaWdnZXIsXG4gICAgICAgICAgZGlzcGF0Y2g6IGV2ZW50LmRpc3BhdGNoLFxuICAgICAgICAgIGVycm9yOiBldmVudC5lcnJvcixcbiAgICAgICAgICB0eG5TZXEsXG4gICAgICAgICAgdHhuSWQsXG4gICAgICAgIH0gYXMgYW55KVxuICAgICAgfSlcblxuICAgIGNvbnN0IHB1Ymxpc2hFdmVudCA9IChldmVudDogUHJvY2Vzc0V2ZW50KTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBldmVudHNCdWZmZXIucHVzaChldmVudClcbiAgICAgICAgdHJpbUV2ZW50cygpXG4gICAgICAgIHlpZWxkKiBQdWJTdWIucHVibGlzaChldmVudHNIdWIsIGV2ZW50KVxuICAgICAgICB5aWVsZCogcmVjb3JkRGVidWdFdmVudChldmVudClcbiAgICAgIH0pXG5cbiAgICBjb25zdCBlbWl0ID0gKGV2ZW50OiBQcm9jZXNzRXZlbnQpOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGJ1ZGdldFJlZiA9IHlpZWxkKiBGaWJlclJlZi5nZXQoY3VycmVudFByb2Nlc3NFdmVudEJ1ZGdldClcbiAgICAgICAgaWYgKGJ1ZGdldFJlZikge1xuICAgICAgICAgIGNvbnN0IGRlY2lzaW9uID0geWllbGQqIFJlZi5tb2RpZnkoYnVkZ2V0UmVmLCAoc3RhdGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IFtuZXh0RGVjaXNpb24sIG5leHRTdGF0ZV0gPSBQcm9jZXNzRXZlbnRzLmFwcGx5UHJvY2Vzc1J1bkV2ZW50QnVkZ2V0KHN0YXRlLCBldmVudClcbiAgICAgICAgICAgIHJldHVybiBbbmV4dERlY2lzaW9uLCBuZXh0U3RhdGVdIGFzIGNvbnN0XG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGlmIChkZWNpc2lvbi5fdGFnID09PSAnZW1pdCcgfHwgZGVjaXNpb24uX3RhZyA9PT0gJ2VtaXRTdW1tYXJ5Jykge1xuICAgICAgICAgICAgeWllbGQqIHB1Ymxpc2hFdmVudChkZWNpc2lvbi5ldmVudClcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBlbmZvcmNlZCA9IFByb2Nlc3NFdmVudHMuZW5mb3JjZVByb2Nlc3NFdmVudE1heEJ5dGVzKGV2ZW50KVxuICAgICAgICB5aWVsZCogcHVibGlzaEV2ZW50KGVuZm9yY2VkLmV2ZW50KVxuICAgICAgfSlcblxuICAgIGNvbnN0IGVtaXRFcnJvckRpYWdub3N0aWMgPSAoXG4gICAgICBzY29wZTogUHJvY2Vzc1Njb3BlLFxuICAgICAgcHJvY2Vzc0lkOiBzdHJpbmcsXG4gICAgICBjb2RlOiBzdHJpbmcsXG4gICAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgICBoaW50Pzogc3RyaW5nLFxuICAgICk6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT4ge1xuICAgICAgaWYgKCFpc0RldkVudigpKSB7XG4gICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgfVxuICAgICAgY29uc3QgbW9kdWxlSWQgPSBzY29wZS50eXBlID09PSAnbW9kdWxlSW5zdGFuY2UnID8gc2NvcGUubW9kdWxlSWQgOiB1bmRlZmluZWRcbiAgICAgIGNvbnN0IGluc3RhbmNlSWQgPSBzY29wZS50eXBlID09PSAnbW9kdWxlSW5zdGFuY2UnID8gc2NvcGUuaW5zdGFuY2VJZCA6IHVuZGVmaW5lZFxuICAgICAgcmV0dXJuIERlYnVnLnJlY29yZCh7XG4gICAgICAgIHR5cGU6ICdkaWFnbm9zdGljJyxcbiAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgIGNvZGUsXG4gICAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgICAgICBtZXNzYWdlLFxuICAgICAgICBoaW50LFxuICAgICAgICBhY3Rpb25UYWc6IHByb2Nlc3NJZCxcbiAgICAgICAga2luZDogJ3Byb2Nlc3NfcnVudGltZScsXG4gICAgICB9KVxuICAgIH1cblxuICAgIGNvbnN0IHJlc29sdmVNaXNzaW5nRGVwZW5kZW5jaWVzID0gKGluc3RhbGxhdGlvbjogSW5zdGFsbGF0aW9uU3RhdGUpOiBSZWFkb25seUFycmF5PHN0cmluZz4gPT4ge1xuICAgICAgY29uc3QgZGVjbGFyZWQgPSBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi5yZXF1aXJlcyA/PyBbXVxuICAgICAgY29uc3QgaW1wbGljaXRGcm9tVHJpZ2dlcnM6IHN0cmluZ1tdID0gW11cbiAgICAgIGZvciAoY29uc3QgdHJpZ2dlciBvZiBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi50cmlnZ2Vycykge1xuICAgICAgICBpZiAodHJpZ2dlci5raW5kID09PSAnbW9kdWxlQWN0aW9uJyB8fCB0cmlnZ2VyLmtpbmQgPT09ICdtb2R1bGVTdGF0ZUNoYW5nZScpIHtcbiAgICAgICAgICBpbXBsaWNpdEZyb21UcmlnZ2Vycy5wdXNoKHRyaWdnZXIubW9kdWxlSWQpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVxdWlyZXMgPSBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLmRlY2xhcmVkLCAuLi5pbXBsaWNpdEZyb21UcmlnZ2Vyc10pKVxuICAgICAgaWYgKHJlcXVpcmVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdXG5cbiAgICAgIGNvbnN0IG1pc3Npbmc6IHN0cmluZ1tdID0gW11cbiAgICAgIGZvciAoY29uc3QgZGVwIG9mIHJlcXVpcmVzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZGVwICE9PSAnc3RyaW5nJyB8fCBkZXAubGVuZ3RoID09PSAwKSBjb250aW51ZVxuXG4gICAgICAgIC8vIE1vZHVsZVRhZyBcdTc2ODQga2V5IFx1N0VBNlx1NUI5QVx1NEUzQSBgQGxvZ2l4L01vZHVsZS8ke2lkfWBcdUZGMUJUYWcgaWRlbnRpdHkgXHU1N0ZBXHU0RThFIGtleVx1RkYwQ1x1NTZFMFx1NkI2NFx1NTNFRlx1NEVFNVx1NjMwOVx1OTcwMFx1Njc4NFx1OTAyMFx1MzAwMlxuICAgICAgICBjb25zdCB0YWcgPSBDb250ZXh0LlRhZyhgQGxvZ2l4L01vZHVsZS8ke2RlcH1gKSgpIGFzIENvbnRleHQuVGFnPGFueSwgYW55PlxuICAgICAgICBjb25zdCBmb3VuZCA9IENvbnRleHQuZ2V0T3B0aW9uKGluc3RhbGxhdGlvbi5lbnYsIHRhZylcbiAgICAgICAgaWYgKE9wdGlvbi5pc05vbmUoZm91bmQpKSB7XG4gICAgICAgICAgbWlzc2luZy5wdXNoKGRlcClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG1pc3NpbmdcbiAgICB9XG5cbiAgICBjb25zdCBzdG9wSW5zdGFuY2UgPSAoXG4gICAgICBpbnN0YW5jZTogSW5zdGFuY2VTdGF0ZSxcbiAgICAgIHJlYXNvbjogUHJvY2Vzc0luc3RhbmNlU3RhdHVzWydzdG9wcGVkUmVhc29uJ10sXG4gICAgKTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaW5zdGFuY2Uuc3RhdHVzLnN0YXR1cyA9PT0gJ3N0b3BwZWQnIHx8XG4gICAgICAgICAgaW5zdGFuY2Uuc3RhdHVzLnN0YXR1cyA9PT0gJ2ZhaWxlZCcgfHxcbiAgICAgICAgICBpbnN0YW5jZS5zdGF0dXMuc3RhdHVzID09PSAnc3RvcHBpbmcnXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmliZXIgPSBpbnN0YW5jZS5maWJlclxuICAgICAgICBpbnN0YW5jZS5zdGF0dXMgPSB7XG4gICAgICAgICAgLi4uaW5zdGFuY2Uuc3RhdHVzLFxuICAgICAgICAgIHN0YXR1czogJ3N0b3BwaW5nJyxcbiAgICAgICAgICBzdG9wcGVkUmVhc29uOiByZWFzb24sXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmliZXIpIHtcbiAgICAgICAgICB5aWVsZCogRmliZXIuaW50ZXJydXB0KGZpYmVyKVxuICAgICAgICB9XG5cbiAgICAgICAgeWllbGQqIFF1ZXVlLnNodXRkb3duKGluc3RhbmNlLnBsYXRmb3JtVHJpZ2dlcnNRdWV1ZSlcblxuICAgICAgICBpbnN0YW5jZS5zdGF0dXMgPSB7XG4gICAgICAgICAgLi4uaW5zdGFuY2Uuc3RhdHVzLFxuICAgICAgICAgIHN0YXR1czogJ3N0b3BwZWQnLFxuICAgICAgICAgIHN0b3BwZWRSZWFzb246IHJlYXNvbixcbiAgICAgICAgfVxuICAgICAgICBpbnN0YW5jZS5maWJlciA9IHVuZGVmaW5lZFxuXG4gICAgICAgIGNvbnN0IGV2dDogUHJvY2Vzc0V2ZW50ID0ge1xuICAgICAgICAgIHR5cGU6ICdwcm9jZXNzOnN0b3AnLFxuICAgICAgICAgIGlkZW50aXR5OiBpbnN0YW5jZS5pZGVudGl0eSxcbiAgICAgICAgICBzZXZlcml0eTogJ2luZm8nLFxuICAgICAgICAgIGV2ZW50U2VxOiBpbnN0YW5jZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgfVxuICAgICAgICB5aWVsZCogZW1pdChldnQpXG5cbiAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uID0gaW5zdGFsbGF0aW9ucy5nZXQoaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICBpZiAoaW5zdGFsbGF0aW9uPy5wZW5kaW5nU3RhcnQpIHtcbiAgICAgICAgICBpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgICAgeWllbGQqIHN0YXJ0SW5zdGFsbGF0aW9uKGluc3RhbmNlLmluc3RhbGxhdGlvbktleSlcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgIGNvbnN0IHN0YXJ0SW5zdGFsbGF0aW9uOiAoaW5zdGFsbGF0aW9uS2V5OiBJbnN0YWxsYXRpb25LZXkpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPSAoaW5zdGFsbGF0aW9uS2V5KSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBpbnN0YWxsYXRpb24gPSBpbnN0YWxsYXRpb25zLmdldChpbnN0YWxsYXRpb25LZXkpXG4gICAgICAgIGlmICghaW5zdGFsbGF0aW9uKSByZXR1cm5cbiAgICAgICAgaW5zdGFsbGF0aW9uLnBlbmRpbmdTdGFydCA9IHVuZGVmaW5lZFxuXG4gICAgICAgIGNvbnN0IG5vb3AgPSB5aWVsZCogc2hvdWxkTm9vcER1ZVRvU3luY1R4bihpbnN0YWxsYXRpb24uaWRlbnRpdHkuc2NvcGUsICdwcm9jZXNzX3N0YXJ0X2luX3RyYW5zYWN0aW9uJylcbiAgICAgICAgaWYgKG5vb3ApIHJldHVyblxuXG4gICAgICAgIC8vIFx1ODJFNVx1NURGMlx1NjcwOVx1NkQzQlx1OERDM1x1NUI5RVx1NEY4Qlx1RkYwQ1x1NTIxOVx1NEUwRFx1OTFDRFx1NTkwRFx1NTQyRlx1NTJBOFx1MzAwMlxuICAgICAgICBjb25zdCBjdXJyZW50SWQgPSBpbnN0YWxsYXRpb24uY3VycmVudEluc3RhbmNlSWRcbiAgICAgICAgaWYgKGN1cnJlbnRJZCkge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSBpbnN0YW5jZXMuZ2V0KGN1cnJlbnRJZClcbiAgICAgICAgICBpZiAoY3VycmVudCAmJiAoY3VycmVudC5zdGF0dXMuc3RhdHVzID09PSAncnVubmluZycgfHwgY3VycmVudC5zdGF0dXMuc3RhdHVzID09PSAnc3RhcnRpbmcnKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcnVuU2VxID0gaW5zdGFsbGF0aW9uLm5leHRSdW5TZXErK1xuICAgICAgICBjb25zdCBpZGVudGl0eTogUHJvY2Vzc0luc3RhbmNlSWRlbnRpdHkgPSB7XG4gICAgICAgICAgaWRlbnRpdHk6IGluc3RhbGxhdGlvbi5pZGVudGl0eSxcbiAgICAgICAgICBydW5TZXEsXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvY2Vzc0luc3RhbmNlSWQgPSBJZGVudGl0eS5wcm9jZXNzSW5zdGFuY2VJZEZyb21JZGVudGl0eShpZGVudGl0eSlcblxuICAgICAgICBjb25zdCBwbGF0Zm9ybVRyaWdnZXJzUXVldWUgPSB5aWVsZCogUXVldWUuc2xpZGluZzxQcm9jZXNzVHJpZ2dlcj4oNjQpXG5cbiAgICAgICAgY29uc3QgaW5zdGFuY2VTdGF0ZTogSW5zdGFuY2VTdGF0ZSA9IHtcbiAgICAgICAgICBpbnN0YWxsYXRpb25LZXksXG4gICAgICAgICAgcHJvY2Vzc0luc3RhbmNlSWQsXG4gICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgcHJvY2Vzc0lkOiBpbnN0YWxsYXRpb24uaWRlbnRpdHkucHJvY2Vzc0lkLFxuICAgICAgICAgIHNjb3BlOiBpbnN0YWxsYXRpb24uaWRlbnRpdHkuc2NvcGUsXG4gICAgICAgICAgZm9ya1Njb3BlOiBpbnN0YWxsYXRpb24uZm9ya1Njb3BlLFxuICAgICAgICAgIHBsYXRmb3JtVHJpZ2dlcnNRdWV1ZSxcbiAgICAgICAgICBzdGF0dXM6IHtcbiAgICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgICAgc3RhdHVzOiAnc3RhcnRpbmcnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbmV4dEV2ZW50U2VxOiAxLFxuICAgICAgICAgIG5leHRUcmlnZ2VyU2VxOiAxLFxuICAgICAgICB9XG5cbiAgICAgICAgaW5zdGFuY2VzLnNldChwcm9jZXNzSW5zdGFuY2VJZCwgaW5zdGFuY2VTdGF0ZSlcbiAgICAgICAgaW5zdGFsbGF0aW9uLmN1cnJlbnRJbnN0YW5jZUlkID0gcHJvY2Vzc0luc3RhbmNlSWRcblxuICAgICAgICAvLyBmb3JrU2NvcGUgZGlzcG9zZVx1RkYwOFx1NEY4Qlx1NTk4MiB1aVN1YnRyZWUgXHU1Mzc4XHU4RjdEXHVGRjA5XHU2NUY2XHVGRjBDXHU3ODZFXHU0RkREXHU1QjlFXHU0RjhCXHU4RkRCXHU1MTY1XHU1MDVDXHU2QjYyXHU3MkI2XHU2MDAxXHU1RTc2XHU0RUE3XHU1MUZBIHN0b3AgXHU0RThCXHU0RUY2XHUzMDAyXG4gICAgICAgIC8vIC0gXHU5MDdGXHU1MTREXHU0RjlEXHU4RDU2XHUyMDFDXHU0RTJEXHU2NUFEXHU2NjJGXHU1NDI2XHU0RjFBXHU4RDcwXHU1MjMwIGNhdGNoQWxsQ2F1c2VcdTIwMURcdThGRDlcdTc5Q0RcdTRFMERcdTdBMzNcdTVCOUFcdTk0RkVcdThERUZcdUZGMUJcbiAgICAgICAgLy8gLSBcdTVCRjkgcnVudGltZVNjb3BlIFx1NEUwRFx1OTFDRFx1NTkwRFx1NkNFOFx1NTE4Q1x1RkYxQXJ1bnRpbWUgXHU4MUVBXHU1REYxXHU3Njg0IGZpbmFsaXplciBcdTVERjJcdTdFREZcdTRFMDAgc3RvcCBcdTYyNDBcdTY3MDlcdTVCOUVcdTRGOEJcdTMwMDJcbiAgICAgICAgaWYgKGluc3RhbGxhdGlvbi5mb3JrU2NvcGUgIT09IHJ1bnRpbWVTY29wZSkge1xuICAgICAgICAgIHlpZWxkKiBTY29wZS5hZGRGaW5hbGl6ZXIoXG4gICAgICAgICAgICBpbnN0YWxsYXRpb24uZm9ya1Njb3BlIGFzIFNjb3BlLkNsb3NlYWJsZVNjb3BlLFxuICAgICAgICAgICAgRWZmZWN0LnN1c3BlbmQoKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBzdGF0dXMgPSBpbnN0YW5jZVN0YXRlLnN0YXR1cy5zdGF0dXNcbiAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gJ3N0b3BwZWQnIHx8IHN0YXR1cyA9PT0gJ2ZhaWxlZCcgfHwgc3RhdHVzID09PSAnc3RvcHBpbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHN0b3BJbnN0YW5jZShpbnN0YW5jZVN0YXRlLCAnc2NvcGVEaXNwb3NlZCcpXG4gICAgICAgICAgICB9KS5waXBlKEVmZmVjdC5jYXRjaEFsbENhdXNlKCgpID0+IEVmZmVjdC52b2lkKSksXG4gICAgICAgICAgKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gc3RhcnQgXHU0RThCXHU0RUY2XHVGRjFBXHU4ODY4XHU3OTNBXHU1QjlFXHU0RjhCXHU1REYyXHU4RkRCXHU1MTY1XHU1NDJGXHU1MkE4XHU2RDQxXHU3QTBCXHVGRjA4ZmliZXIgXHU1REYyIGZvcmtcdUZGMDlcdTMwMDJcbiAgICAgICAgeWllbGQqIGVtaXQoe1xuICAgICAgICAgIHR5cGU6ICdwcm9jZXNzOnN0YXJ0JyxcbiAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICBzZXZlcml0eTogJ2luZm8nLFxuICAgICAgICAgIGV2ZW50U2VxOiBpbnN0YW5jZVN0YXRlLm5leHRFdmVudFNlcSsrLFxuICAgICAgICAgIHRpbWVzdGFtcE1zOiBEYXRlLm5vdygpLFxuICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IG1pc3NpbmcgPSByZXNvbHZlTWlzc2luZ0RlcGVuZGVuY2llcyhpbnN0YWxsYXRpb24pXG4gICAgICAgIGlmIChtaXNzaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb25zdCBoaW50ID0gaXNEZXZFbnYoKVxuICAgICAgICAgICAgPyBbXG4gICAgICAgICAgICAgICAgJ1N0cmljdCBzY29wZSBkZXBlbmRlbmN5IHJlc29sdXRpb246IG1pc3NpbmcgcmVxdWlyZWQgbW9kdWxlcyBpbiB0aGUgY3VycmVudCBzY29wZS4nLFxuICAgICAgICAgICAgICAgIGBtaXNzaW5nOiAke21pc3Npbmcuam9pbignLCAnKX1gLFxuICAgICAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgICAgICdmaXg6JyxcbiAgICAgICAgICAgICAgICAnLSBQcm92aWRlIHRoZSBtaXNzaW5nIG1vZHVsZSBpbXBsZW1lbnRhdGlvbihzKSBpbiB0aGUgc2FtZSBzY29wZSB2aWEgaW1wb3J0cy4nLFxuICAgICAgICAgICAgICAgIGAgIEV4YW1wbGU6IFJvb3RNb2R1bGUuaW1wbGVtZW50KHsgaW1wb3J0czogWyR7bWlzc2luZ1swXX0uaW1wbGVtZW50KC4uLikuaW1wbF0sIHByb2Nlc3NlczogWy4uLl0gfSlgLFxuICAgICAgICAgICAgICAgICctIERvIG5vdCByZWx5IG9uIGNyb3NzLXNjb3BlIGZhbGxiYWNrcyAvIGd1ZXNzaW5nIGluc3RhbmNlcy4nLFxuICAgICAgICAgICAgICBdLmpvaW4oJ1xcbicpXG4gICAgICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgICAgICAgY29uc3QgZXJyb3I6IFNlcmlhbGl6YWJsZUVycm9yU3VtbWFyeSA9IHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGBNaXNzaW5nIGRlcGVuZGVuY2llcyBpbiBzY29wZTogJHttaXNzaW5nLmpvaW4oJywgJyl9YCxcbiAgICAgICAgICAgIGNvZGU6ICdwcm9jZXNzOjptaXNzaW5nX2RlcGVuZGVuY3knLFxuICAgICAgICAgICAgaGludCxcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpbnN0YW5jZVN0YXRlLnN0YXR1cyA9IHtcbiAgICAgICAgICAgIC4uLmluc3RhbmNlU3RhdGUuc3RhdHVzLFxuICAgICAgICAgICAgc3RhdHVzOiAnZmFpbGVkJyxcbiAgICAgICAgICAgIHN0b3BwZWRSZWFzb246ICdmYWlsZWQnLFxuICAgICAgICAgICAgbGFzdEVycm9yOiBlcnJvcixcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB5aWVsZCogZW1pdCh7XG4gICAgICAgICAgICB0eXBlOiAncHJvY2VzczplcnJvcicsXG4gICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgICAgICAgICAgZXZlbnRTZXE6IGluc3RhbmNlU3RhdGUubmV4dEV2ZW50U2VxKyssXG4gICAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICB5aWVsZCogZW1pdEVycm9yRGlhZ25vc3RpYyhcbiAgICAgICAgICAgIGluc3RhbGxhdGlvbi5pZGVudGl0eS5zY29wZSxcbiAgICAgICAgICAgIGluc3RhbGxhdGlvbi5pZGVudGl0eS5wcm9jZXNzSWQsXG4gICAgICAgICAgICAncHJvY2Vzczo6bWlzc2luZ19kZXBlbmRlbmN5JyxcbiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UsXG4gICAgICAgICAgICBoaW50LFxuICAgICAgICAgIClcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNob3VsZFJlY29yZENoYWluRXZlbnRzID0gaW5zdGFsbGF0aW9uLmRlZmluaXRpb24uZGlhZ25vc3RpY3NMZXZlbCAhPT0gJ29mZidcblxuICAgICAgICBjb25zdCBiYXNlRW52ID0gaW5zdGFsbGF0aW9uLmVudlxuXG4gICAgICAgIGNvbnN0IG1ha2VXcmFwcGVkRW52ID0gKCk6IENvbnRleHQuQ29udGV4dDxhbnk+ID0+IHtcbiAgICAgICAgICBpZiAoIXNob3VsZFJlY29yZENoYWluRXZlbnRzKSB7XG4gICAgICAgICAgICByZXR1cm4gYmFzZUVudlxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHJlcXVpcmVzID0gaW5zdGFsbGF0aW9uLmRlZmluaXRpb24ucmVxdWlyZXMgPz8gW11cbiAgICAgICAgICBpZiAocmVxdWlyZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gYmFzZUVudlxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGlkcyA9IEFycmF5LmZyb20obmV3IFNldChyZXF1aXJlcykpXG4gICAgICAgICAgbGV0IG5leHRFbnYgPSBiYXNlRW52XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IG1vZHVsZUlkIG9mIGlkcykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtb2R1bGVJZCAhPT0gJ3N0cmluZycgfHwgbW9kdWxlSWQubGVuZ3RoID09PSAwKSBjb250aW51ZVxuICAgICAgICAgICAgY29uc3QgdGFnID0gQ29udGV4dC5UYWcoYEBsb2dpeC9Nb2R1bGUvJHttb2R1bGVJZH1gKSgpIGFzIENvbnRleHQuVGFnPGFueSwgYW55PlxuICAgICAgICAgICAgY29uc3QgZm91bmQgPSBDb250ZXh0LmdldE9wdGlvbihiYXNlRW52LCB0YWcpXG4gICAgICAgICAgICBpZiAoT3B0aW9uLmlzTm9uZShmb3VuZCkpIGNvbnRpbnVlXG4gICAgICAgICAgICBjb25zdCBydW50aW1lID0gZm91bmQudmFsdWUgYXMgYW55XG5cbiAgICAgICAgICAgIGNvbnN0IHJlY29yZERpc3BhdGNoID0gKGFjdGlvbjogdW5rbm93bikgPT5cbiAgICAgICAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRyaWdnZXIgPSB5aWVsZCogRmliZXJSZWYuZ2V0KGN1cnJlbnRQcm9jZXNzVHJpZ2dlcilcbiAgICAgICAgICAgICAgICBpZiAoIXRyaWdnZXIpIHJldHVyblxuXG4gICAgICAgICAgICAgICAgY29uc3QgYWN0aW9uSWQgPSBhY3Rpb25JZEZyb21Vbmtub3duKGFjdGlvbikgPz8gJ3Vua25vd24nXG4gICAgICAgICAgICAgICAgY29uc3QgZGlzcGF0Y2hNb2R1bGVJZCA9IHR5cGVvZiBydW50aW1lLm1vZHVsZUlkID09PSAnc3RyaW5nJyA/IHJ1bnRpbWUubW9kdWxlSWQgOiBtb2R1bGVJZFxuICAgICAgICAgICAgICAgIGNvbnN0IGRpc3BhdGNoSW5zdGFuY2VJZCA9IHR5cGVvZiBydW50aW1lLmluc3RhbmNlSWQgPT09ICdzdHJpbmcnID8gcnVudGltZS5pbnN0YW5jZUlkIDogJ3Vua25vd24nXG5cbiAgICAgICAgICAgICAgICBjb25zdCBldnQ6IFByb2Nlc3NFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdwcm9jZXNzOmRpc3BhdGNoJyxcbiAgICAgICAgICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgICAgICAgICAgdHJpZ2dlcixcbiAgICAgICAgICAgICAgICAgIGRpc3BhdGNoOiB7XG4gICAgICAgICAgICAgICAgICAgIG1vZHVsZUlkOiBkaXNwYXRjaE1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBkaXNwYXRjaEluc3RhbmNlSWQsXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbklkLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHNldmVyaXR5OiAnaW5mbycsXG4gICAgICAgICAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcE1zOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHlpZWxkKiBlbWl0KGV2dClcbiAgICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZCA9IHtcbiAgICAgICAgICAgICAgLi4ucnVudGltZSxcbiAgICAgICAgICAgICAgZGlzcGF0Y2g6IChhY3Rpb246IHVua25vd24pID0+IHJ1bnRpbWUuZGlzcGF0Y2goYWN0aW9uKS5waXBlKEVmZmVjdC50YXAoKCkgPT4gcmVjb3JkRGlzcGF0Y2goYWN0aW9uKSkpLFxuICAgICAgICAgICAgICBkaXNwYXRjaExvd1ByaW9yaXR5OiAoYWN0aW9uOiB1bmtub3duKSA9PlxuICAgICAgICAgICAgICAgIHJ1bnRpbWUuZGlzcGF0Y2hMb3dQcmlvcml0eShhY3Rpb24pLnBpcGUoRWZmZWN0LnRhcCgoKSA9PiByZWNvcmREaXNwYXRjaChhY3Rpb24pKSksXG4gICAgICAgICAgICAgIGRpc3BhdGNoQmF0Y2g6IChhY3Rpb25zOiBSZWFkb25seUFycmF5PHVua25vd24+KSA9PlxuICAgICAgICAgICAgICAgIHJ1bnRpbWVcbiAgICAgICAgICAgICAgICAgIC5kaXNwYXRjaEJhdGNoKGFjdGlvbnMpXG4gICAgICAgICAgICAgICAgICAucGlwZShFZmZlY3QudGFwKCgpID0+IEVmZmVjdC5mb3JFYWNoKGFjdGlvbnMsIHJlY29yZERpc3BhdGNoLCB7IGRpc2NhcmQ6IHRydWUgfSkpKSxcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV4dEVudiA9IENvbnRleHQuYWRkKHRhZywgd3JhcHBlZCkobmV4dEVudilcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbmV4dEVudlxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgd3JhcHBlZEVudiA9IG1ha2VXcmFwcGVkRW52KClcbiAgICAgICAgY29uc3QgcHJvdmlkZWRQcm9jZXNzID0gRWZmZWN0LnByb3ZpZGUoaW5zdGFsbGF0aW9uLnByb2Nlc3MsIHdyYXBwZWRFbnYpXG5cbiAgICAgICAgY29uc3QgbWFrZVRyaWdnZXJTdHJlYW0gPSAoc3BlYzogTm9uUGxhdGZvcm1UcmlnZ2VyU3BlYyk6IEVmZmVjdC5FZmZlY3Q8U3RyZWFtLlN0cmVhbTxQcm9jZXNzVHJpZ2dlcj4sIEVycm9yPiA9PlxuICAgICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGlmIChzcGVjLmtpbmQgPT09ICd0aW1lcicpIHtcbiAgICAgICAgICAgICAgY29uc3QgaW50ZXJ2YWwgPSBEdXJhdGlvbi5kZWNvZGVVbmtub3duKHNwZWMudGltZXJJZClcbiAgICAgICAgICAgICAgaWYgKE9wdGlvbi5pc05vbmUoaW50ZXJ2YWwpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKGBbUHJvY2Vzc1J1bnRpbWVdIGludmFsaWQgdGltZXJJZCAoZXhwZWN0ZWQgRHVyYXRpb25JbnB1dCk6ICR7c3BlYy50aW1lcklkfWApXG4gICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5jb2RlID0gJ3Byb2Nlc3M6OmludmFsaWRfdGltZXJfaWQnXG4gICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5oaW50ID1cbiAgICAgICAgICAgICAgICAgIFwidGltZXJJZCBtdXN0IGJlIGEgdmFsaWQgRHVyYXRpb25JbnB1dCBzdHJpbmcsIGUuZy4gJzEwIG1pbGxpcycsICcxIHNlY29uZHMnLCAnNSBtaW51dGVzJy5cIlxuICAgICAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwoZXJyKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIFN0cmVhbS50aWNrKGludGVydmFsLnZhbHVlKS5waXBlKFxuICAgICAgICAgICAgICAgIFN0cmVhbS5tYXAoXG4gICAgICAgICAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAoe1xuICAgICAgICAgICAgICAgICAgICAgIGtpbmQ6ICd0aW1lcicsXG4gICAgICAgICAgICAgICAgICAgICAgbmFtZTogc3BlYy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICAgIHRpbWVySWQ6IHNwZWMudGltZXJJZCxcbiAgICAgICAgICAgICAgICAgICAgfSkgc2F0aXNmaWVzIFByb2Nlc3NUcmlnZ2VyLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNwZWMua2luZCA9PT0gJ21vZHVsZUFjdGlvbicpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGFnID0gQ29udGV4dC5UYWcoYEBsb2dpeC9Nb2R1bGUvJHtzcGVjLm1vZHVsZUlkfWApKCkgYXMgQ29udGV4dC5UYWc8YW55LCBhbnk+XG4gICAgICAgICAgICAgIGNvbnN0IGZvdW5kID0gQ29udGV4dC5nZXRPcHRpb24oYmFzZUVudiwgdGFnKVxuICAgICAgICAgICAgICBpZiAoT3B0aW9uLmlzTm9uZShmb3VuZCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geWllbGQqIEVmZmVjdC5mYWlsKG5ldyBFcnJvcihgTWlzc2luZyBtb2R1bGUgcnVudGltZSBpbiBzY29wZTogJHtzcGVjLm1vZHVsZUlkfWApKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3QgcnVudGltZSA9IGZvdW5kLnZhbHVlIGFzIGFueVxuXG4gICAgICAgICAgICAgIC8vIHBlcmZcdUZGMUFkaWFnbm9zdGljcz1vZmYgXHU2NUY2XHU5MDdGXHU1MTREXHU4QkEyXHU5NjA1IGFjdGlvbnNXaXRoTWV0YSRcdUZGMDhcdThCRTVcdTkwMUFcdTkwNTNcdTU3MjggdHhuIFx1NTE4NSBwdWJsaXNoXHVGRjBDXHU4QkEyXHU5NjA1XHU4MDA1XHU4RDhBXHU1OTFBXHU4RDhBXHU1RjcxXHU1NENEXHU3MEVEXHU4REVGXHU1Rjg0XHVGRjA5XHUzMDAyXG4gICAgICAgICAgICAgIC8vIGRpYWdub3N0aWNzPWxpZ2h0L2Z1bGwgXHU2MjREXHU5NzAwXHU4OTgxIHR4blNlcS90eG5JZCBcdTk1MUFcdTcwQjlcdUZGMENcdTU2RTBcdTZCNjRcdTRFQzVcdTU3MjhcdTVGMDBcdTU0MkZcdTk0RkVcdThERUZcdTRFOEJcdTRFRjZcdTY1RjZcdTRGN0ZcdTc1MjggYWN0aW9uc1dpdGhNZXRhJFx1MzAwMlxuICAgICAgICAgICAgICBpZiAoIXNob3VsZFJlY29yZENoYWluRXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0gcnVudGltZS5hY3Rpb25zJCBhcyBTdHJlYW0uU3RyZWFtPGFueT4gfCB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICBpZiAoIXN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKCdNb2R1bGVSdW50aW1lIGRvZXMgbm90IHByb3ZpZGUgYWN0aW9ucyQgKHJlcXVpcmVkIGZvciBtb2R1bGVBY3Rpb24gdHJpZ2dlcikuJylcbiAgICAgICAgICAgICAgICAgIDsoZXJyIGFzIGFueSkuY29kZSA9ICdwcm9jZXNzOjptaXNzaW5nX2FjdGlvbl9zdHJlYW0nXG4gICAgICAgICAgICAgICAgICA7KGVyciBhcyBhbnkpLmhpbnQgPSBgbW9kdWxlSWQ9JHtzcGVjLm1vZHVsZUlkfWBcbiAgICAgICAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwoZXJyKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBzdHJlYW0ucGlwZShcbiAgICAgICAgICAgICAgICAgIFN0cmVhbS5maWx0ZXIoKGFjdGlvbjogYW55KSA9PiBhY3Rpb25JZEZyb21Vbmtub3duKGFjdGlvbikgPT09IHNwZWMuYWN0aW9uSWQpLFxuICAgICAgICAgICAgICAgICAgU3RyZWFtLm1hcChcbiAgICAgICAgICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAoe1xuICAgICAgICAgICAgICAgICAgICAgICAga2luZDogJ21vZHVsZUFjdGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBzcGVjLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVJZDogc3BlYy5tb2R1bGVJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCBhcyBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25JZDogc3BlYy5hY3Rpb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR4blNlcTogMSxcbiAgICAgICAgICAgICAgICAgICAgICB9KSBzYXRpc2ZpZXMgUHJvY2Vzc1RyaWdnZXIsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IHJ1bnRpbWUuYWN0aW9uc1dpdGhNZXRhJCBhcyBTdHJlYW0uU3RyZWFtPGFueT4gfCB1bmRlZmluZWRcbiAgICAgICAgICAgICAgaWYgKCFzdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAnTW9kdWxlUnVudGltZSBkb2VzIG5vdCBwcm92aWRlIGFjdGlvbnNXaXRoTWV0YSQgKHJlcXVpcmVkIGZvciBtb2R1bGVBY3Rpb24gdHJpZ2dlcikuJyxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5jb2RlID0gJ3Byb2Nlc3M6Om1pc3NpbmdfYWN0aW9uX21ldGFfc3RyZWFtJ1xuICAgICAgICAgICAgICAgIDsoZXJyIGFzIGFueSkuaGludCA9IGBtb2R1bGVJZD0ke3NwZWMubW9kdWxlSWR9YFxuICAgICAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwoZXJyKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHN0cmVhbS5waXBlKFxuICAgICAgICAgICAgICAgIFN0cmVhbS5maWx0ZXIoKGV2dDogYW55KSA9PiBhY3Rpb25JZEZyb21Vbmtub3duKGV2dC52YWx1ZSkgPT09IHNwZWMuYWN0aW9uSWQpLFxuICAgICAgICAgICAgICAgIFN0cmVhbS5tYXAoKGV2dDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICBjb25zdCB0eG5TZXEgPSBldnQ/Lm1ldGE/LnR4blNlcVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAga2luZDogJ21vZHVsZUFjdGlvbicsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IHNwZWMubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHNwZWMubW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCBhcyBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbklkOiBzcGVjLmFjdGlvbklkLFxuICAgICAgICAgICAgICAgICAgICB0eG5TZXE6IHR5cGVvZiB0eG5TZXEgPT09ICdudW1iZXInID8gdHhuU2VxIDogMSxcbiAgICAgICAgICAgICAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NUcmlnZ2VyXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbW9kdWxlU3RhdGVDaGFuZ2VcbiAgICAgICAgICAgIGNvbnN0IHRhZyA9IENvbnRleHQuVGFnKGBAbG9naXgvTW9kdWxlLyR7c3BlYy5tb2R1bGVJZH1gKSgpIGFzIENvbnRleHQuVGFnPGFueSwgYW55PlxuICAgICAgICAgICAgY29uc3QgZm91bmQgPSBDb250ZXh0LmdldE9wdGlvbihiYXNlRW52LCB0YWcpXG4gICAgICAgICAgICBpZiAoT3B0aW9uLmlzTm9uZShmb3VuZCkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbChuZXcgRXJyb3IoYE1pc3NpbmcgbW9kdWxlIHJ1bnRpbWUgaW4gc2NvcGU6ICR7c3BlYy5tb2R1bGVJZH1gKSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcnVudGltZSA9IGZvdW5kLnZhbHVlIGFzIGFueVxuICAgICAgICAgICAgY29uc3Qgc2NoZW1hQXN0ID0gcmVzb2x2ZVJ1bnRpbWVTdGF0ZVNjaGVtYUFzdChydW50aW1lKVxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0b3JSZXN1bHQgPSBtYWtlU2NoZW1hU2VsZWN0b3Ioc3BlYy5wYXRoLCBzY2hlbWFBc3QpXG4gICAgICAgICAgICBpZiAoIXNlbGVjdG9yUmVzdWx0Lm9rKSB7XG4gICAgICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwod2l0aE1vZHVsZUhpbnQoc2VsZWN0b3JSZXN1bHQuZXJyb3IsIHNwZWMubW9kdWxlSWQpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0b3JCYXNlID0gc2VsZWN0b3JSZXN1bHQuc2VsZWN0b3JcbiAgICAgICAgICAgIGNvbnN0IHByZXZSZWYgPSB5aWVsZCogUmVmLm1ha2U8T3B0aW9uLk9wdGlvbjx1bmtub3duPj4oT3B0aW9uLm5vbmUoKSlcblxuICAgICAgICAgICAgY29uc3QgZW5hYmxlU2VsZWN0b3JEaWFnbm9zdGljcyA9IHNob3VsZFJlY29yZENoYWluRXZlbnRzXG5cbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdG9yRGlhZ25vc3RpY3NSZWYgPSBlbmFibGVTZWxlY3RvckRpYWdub3N0aWNzXG4gICAgICAgICAgICAgID8geWllbGQqIFJlZi5tYWtlKHtcbiAgICAgICAgICAgICAgICAgIHdpbmRvd1N0YXJ0ZWRNczogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICAgIHRyaWdnZXJzSW5XaW5kb3c6IDAsXG4gICAgICAgICAgICAgICAgICBsYXN0V2FybmluZ0F0TXM6IDAsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgOiB1bmRlZmluZWRcblxuICAgICAgICAgICAgY29uc3Qgc2FtcGxlRXZlcnlNYXNrID0gMHg3ZiAvLyBzYW1wbGUgZXZlcnkgMTI4IGNhbGxzXG4gICAgICAgICAgICBjb25zdCBzbG93U2FtcGxlVGhyZXNob2xkTXMgPSA0XG4gICAgICAgICAgICBjb25zdCB0cmlnZ2VyV2luZG93TXMgPSAxMDAwXG4gICAgICAgICAgICBjb25zdCB0cmlnZ2VyV2FybmluZ1RocmVzaG9sZCA9IGlzRGV2RW52KCkgPyAyMCA6IDIwMFxuICAgICAgICAgICAgY29uc3Qgd2FybmluZ0Nvb2xkb3duTXMgPSAzMF8wMDBcblxuICAgICAgICAgICAgbGV0IHNlbGVjdG9yQ2FsbHMgPSAwXG4gICAgICAgICAgICBsZXQgc2VsZWN0b3JTYW1wbGVzID0gMFxuICAgICAgICAgICAgbGV0IHNlbGVjdG9yU2xvd1NhbXBsZXMgPSAwXG4gICAgICAgICAgICBsZXQgc2VsZWN0b3JNYXhTYW1wbGVNcyA9IDBcblxuICAgICAgICAgICAgY29uc3Qgbm93TXMgPSAoKTogbnVtYmVyID0+IHtcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwZXJmb3JtYW5jZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHBlcmZvcm1hbmNlLm5vdyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBwZXJmb3JtYW5jZS5ub3coKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBEYXRlLm5vdygpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdG9yID0gZW5hYmxlU2VsZWN0b3JEaWFnbm9zdGljc1xuICAgICAgICAgICAgICA/IChzdGF0ZTogdW5rbm93bik6IHVua25vd24gPT4ge1xuICAgICAgICAgICAgICAgICAgc2VsZWN0b3JDYWxscyArPSAxXG4gICAgICAgICAgICAgICAgICBpZiAoKHNlbGVjdG9yQ2FsbHMgJiBzYW1wbGVFdmVyeU1hc2spICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RvckJhc2Uoc3RhdGUpXG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIGNvbnN0IHQwID0gbm93TXMoKVxuICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzZWxlY3RvckJhc2Uoc3RhdGUpXG4gICAgICAgICAgICAgICAgICBjb25zdCBkdCA9IG5vd01zKCkgLSB0MFxuXG4gICAgICAgICAgICAgICAgICBzZWxlY3RvclNhbXBsZXMgKz0gMVxuICAgICAgICAgICAgICAgICAgaWYgKGR0ID49IHNsb3dTYW1wbGVUaHJlc2hvbGRNcykge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvclNsb3dTYW1wbGVzICs9IDFcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGlmIChkdCA+IHNlbGVjdG9yTWF4U2FtcGxlTXMpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JNYXhTYW1wbGVNcyA9IGR0XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgOiBzZWxlY3RvckJhc2VcblxuICAgICAgICAgICAgY29uc3QgbWF5YmVXYXJuU2VsZWN0b3IgPSAodHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIpOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFzZWxlY3RvckRpYWdub3N0aWNzUmVmKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KClcblxuICAgICAgICAgICAgICAgIGNvbnN0IGRlY2lzaW9uID0geWllbGQqIFJlZi5tb2RpZnkoc2VsZWN0b3JEaWFnbm9zdGljc1JlZiwgKHMpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHdpbmRvd0V4cGlyZWQgPSBub3cgLSBzLndpbmRvd1N0YXJ0ZWRNcyA+PSB0cmlnZ2VyV2luZG93TXNcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHdpbmRvd1N0YXJ0ZWRNcyA9IHdpbmRvd0V4cGlyZWQgPyBub3cgOiBzLndpbmRvd1N0YXJ0ZWRNc1xuICAgICAgICAgICAgICAgICAgY29uc3QgdHJpZ2dlcnNJbldpbmRvdyA9IHdpbmRvd0V4cGlyZWQgPyAxIDogcy50cmlnZ2Vyc0luV2luZG93ICsgMVxuXG4gICAgICAgICAgICAgICAgICBjb25zdCBzaG91bGRDb29sZG93biA9IG5vdyAtIHMubGFzdFdhcm5pbmdBdE1zIDwgd2FybmluZ0Nvb2xkb3duTXNcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRvb0ZyZXF1ZW50ID0gdHJpZ2dlcnNJbldpbmRvdyA+PSB0cmlnZ2VyV2FybmluZ1RocmVzaG9sZFxuICAgICAgICAgICAgICAgICAgY29uc3QgdG9vU2xvdyA9IHNlbGVjdG9yTWF4U2FtcGxlTXMgPj0gc2xvd1NhbXBsZVRocmVzaG9sZE1zICYmIHNlbGVjdG9yU2FtcGxlcyA+IDBcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZFdhcm4gPSAhc2hvdWxkQ29vbGRvd24gJiYgKHRvb0ZyZXF1ZW50IHx8IHRvb1Nsb3cpXG5cbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHQgPSBzaG91bGRXYXJuXG4gICAgICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93U3RhcnRlZE1zOiBub3csXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmlnZ2Vyc0luV2luZG93OiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFdhcm5pbmdBdE1zOiBub3csXG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLnMsXG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dTdGFydGVkTXMsXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmlnZ2Vyc0luV2luZG93LFxuICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgIHNob3VsZFdhcm4sXG4gICAgICAgICAgICAgICAgICAgICAgdG9vRnJlcXVlbnQsXG4gICAgICAgICAgICAgICAgICAgICAgdG9vU2xvdyxcbiAgICAgICAgICAgICAgICAgICAgICB0cmlnZ2Vyc0luV2luZG93LFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBuZXh0LFxuICAgICAgICAgICAgICAgICAgXSBhcyBjb25zdFxuICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICBpZiAoIWRlY2lzaW9uLnNob3VsZFdhcm4pIHtcbiAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGNvZGUgPSBkZWNpc2lvbi50b29GcmVxdWVudCA/ICdwcm9jZXNzOjpzZWxlY3Rvcl9oaWdoX2ZyZXF1ZW5jeScgOiAncHJvY2Vzczo6c2VsZWN0b3Jfc2xvdydcblxuICAgICAgICAgICAgICAgIGNvbnN0IGhpbnQgPSBbXG4gICAgICAgICAgICAgICAgICBgbW9kdWxlSWQ9JHtzcGVjLm1vZHVsZUlkfWAsXG4gICAgICAgICAgICAgICAgICBgcGF0aD0ke3NwZWMucGF0aH1gLFxuICAgICAgICAgICAgICAgICAgYHdpbmRvd01zPSR7dHJpZ2dlcldpbmRvd01zfWAsXG4gICAgICAgICAgICAgICAgICBgdHJpZ2dlcnNJbldpbmRvdz0ke2RlY2lzaW9uLnRyaWdnZXJzSW5XaW5kb3d9YCxcbiAgICAgICAgICAgICAgICAgIGB0aHJlc2hvbGQ9JHt0cmlnZ2VyV2FybmluZ1RocmVzaG9sZH1gLFxuICAgICAgICAgICAgICAgICAgYGNvb2xkb3duTXM9JHt3YXJuaW5nQ29vbGRvd25Nc31gLFxuICAgICAgICAgICAgICAgICAgJycsXG4gICAgICAgICAgICAgICAgICAnc2VsZWN0b3Igc2FtcGxpbmc6JyxcbiAgICAgICAgICAgICAgICAgIGBjYWxscz0ke3NlbGVjdG9yQ2FsbHN9YCxcbiAgICAgICAgICAgICAgICAgIGBzYW1wbGVkPSR7c2VsZWN0b3JTYW1wbGVzfWAsXG4gICAgICAgICAgICAgICAgICBgc2xvd1NhbXBsZXMoPj0ke3Nsb3dTYW1wbGVUaHJlc2hvbGRNc31tcyk9JHtzZWxlY3RvclNsb3dTYW1wbGVzfWAsXG4gICAgICAgICAgICAgICAgICBgbWF4U2FtcGxlTXM9JHtzZWxlY3Rvck1heFNhbXBsZU1zLnRvRml4ZWQoMil9YCxcbiAgICAgICAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgICAgICAgJ25vdGVzOicsXG4gICAgICAgICAgICAgICAgICAnLSBFbnN1cmUgdGhlIHNlbGVjdGVkIHZhbHVlIGlzIHN0YWJsZSAocHJlZmVyIHByaW1pdGl2ZS90dXBsZTsgYXZvaWQgcmV0dXJuaW5nIGZyZXNoIG9iamVjdHMpLicsXG4gICAgICAgICAgICAgICAgICAnLSBOYXJyb3cgdGhlIHBhdGggdG8gcmVkdWNlIGNoYW5nZSBmcmVxdWVuY3k7IGF2b2lkIHNlbGVjdGluZyBsYXJnZSBvYmplY3RzLicsXG4gICAgICAgICAgICAgICAgXS5qb2luKCdcXG4nKVxuXG4gICAgICAgICAgICAgICAgc2VsZWN0b3JTYW1wbGVzID0gMFxuICAgICAgICAgICAgICAgIHNlbGVjdG9yU2xvd1NhbXBsZXMgPSAwXG4gICAgICAgICAgICAgICAgc2VsZWN0b3JNYXhTYW1wbGVNcyA9IDBcblxuICAgICAgICAgICAgICAgIHlpZWxkKiBlbWl0KHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdwcm9jZXNzOnRyaWdnZXInLFxuICAgICAgICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgICB0cmlnZ2VyLFxuICAgICAgICAgICAgICAgICAgc2V2ZXJpdHk6ICd3YXJuaW5nJyxcbiAgICAgICAgICAgICAgICAgIGV2ZW50U2VxOiBpbnN0YW5jZVN0YXRlLm5leHRFdmVudFNlcSsrLFxuICAgICAgICAgICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnbW9kdWxlU3RhdGVDaGFuZ2Ugc2VsZWN0b3IgZGlhZ25vc3RpY3Mgd2FybmluZycsXG4gICAgICAgICAgICAgICAgICAgIGNvZGUsXG4gICAgICAgICAgICAgICAgICAgIGhpbnQsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NFdmVudClcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgYmFzZVN0cmVhbSA9IChydW50aW1lLmNoYW5nZXNXaXRoTWV0YShzZWxlY3RvcikgYXMgU3RyZWFtLlN0cmVhbTxhbnk+KS5waXBlKFxuICAgICAgICAgICAgICBTdHJlYW0ubWFwRWZmZWN0KChldnQ6IGFueSkgPT5cbiAgICAgICAgICAgICAgICBSZWYuZ2V0KHByZXZSZWYpLnBpcGUoXG4gICAgICAgICAgICAgICAgICBFZmZlY3QuZmxhdE1hcCgocHJldikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoT3B0aW9uLmlzU29tZShwcmV2KSAmJiBPYmplY3QuaXMocHJldi52YWx1ZSwgZXZ0LnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Quc3VjY2VlZChPcHRpb24ubm9uZSgpKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBSZWYuc2V0KHByZXZSZWYsIE9wdGlvbi5zb21lKGV2dC52YWx1ZSkpLnBpcGUoRWZmZWN0LmFzKE9wdGlvbi5zb21lKGV2dCkpKVxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgU3RyZWFtLmZpbHRlck1hcCgob3B0KSA9PiBvcHQpLFxuICAgICAgICAgICAgICBTdHJlYW0ubWFwKChldnQ6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHR4blNlcSA9IGV2dD8ubWV0YT8udHhuU2VxXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6ICdtb2R1bGVTdGF0ZUNoYW5nZScsXG4gICAgICAgICAgICAgICAgICBuYW1lOiBzcGVjLm5hbWUsXG4gICAgICAgICAgICAgICAgICBtb2R1bGVJZDogc3BlYy5tb2R1bGVJZCxcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCBhcyBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICBwYXRoOiBzcGVjLnBhdGgsXG4gICAgICAgICAgICAgICAgICB0eG5TZXE6IHR5cGVvZiB0eG5TZXEgPT09ICdudW1iZXInID8gdHhuU2VxIDogMSxcbiAgICAgICAgICAgICAgICB9IHNhdGlzZmllcyBQcm9jZXNzVHJpZ2dlclxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIClcblxuICAgICAgICAgICAgcmV0dXJuIGVuYWJsZVNlbGVjdG9yRGlhZ25vc3RpY3MgPyBiYXNlU3RyZWFtLnBpcGUoU3RyZWFtLnRhcChtYXliZVdhcm5TZWxlY3RvcikpIDogYmFzZVN0cmVhbVxuICAgICAgICAgIH0pXG5cbiAgICAgICAgY29uc3QgbWFrZVJ1biA9ICh0cmlnZ2VyOiBQcm9jZXNzVHJpZ2dlciwgZmF0YWw6IERlZmVycmVkLkRlZmVycmVkPENhdXNlLkNhdXNlPGFueT4+KTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PlxuICAgICAgICAgIEVmZmVjdC5sb2NhbGx5KFxuICAgICAgICAgICAgY3VycmVudFByb2Nlc3NUcmlnZ2VyLFxuICAgICAgICAgICAgdHJpZ2dlcixcbiAgICAgICAgICApKFxuICAgICAgICAgICAgcHJvdmlkZWRQcm9jZXNzLnBpcGUoXG4gICAgICAgICAgICAgIEVmZmVjdC5jYXRjaEFsbENhdXNlKChjYXVzZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChDYXVzZS5pc0ludGVycnVwdGVkT25seShjYXVzZSkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gRGVmZXJyZWQuc3VjY2VlZChmYXRhbCwgY2F1c2UpLnBpcGUoXG4gICAgICAgICAgICAgICAgICBFZmZlY3QuYXNWb2lkLFxuICAgICAgICAgICAgICAgICAgRWZmZWN0LmNhdGNoQWxsKCgpID0+IEVmZmVjdC52b2lkKSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApXG5cbiAgICAgICAgY29uc3QgbWFrZUNoYWluUnVuID0gKFxuICAgICAgICAgIHRyaWdnZXI6IFByb2Nlc3NUcmlnZ2VyLFxuICAgICAgICAgIGZhdGFsOiBEZWZlcnJlZC5EZWZlcnJlZDxDYXVzZS5DYXVzZTxhbnk+PixcbiAgICAgICAgKTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PiB7XG4gICAgICAgICAgaWYgKCFzaG91bGRSZWNvcmRDaGFpbkV2ZW50cykge1xuICAgICAgICAgICAgcmV0dXJuIG1ha2VSdW4odHJpZ2dlciwgZmF0YWwpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZGdldFJlZiA9IHlpZWxkKiBSZWYubWFrZShQcm9jZXNzRXZlbnRzLm1ha2VQcm9jZXNzUnVuRXZlbnRCdWRnZXRTdGF0ZSgpKVxuICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QubG9jYWxseShcbiAgICAgICAgICAgICAgY3VycmVudFByb2Nlc3NFdmVudEJ1ZGdldCxcbiAgICAgICAgICAgICAgYnVkZ2V0UmVmLFxuICAgICAgICAgICAgKShlbWl0VHJpZ2dlckV2ZW50KHRyaWdnZXIsICdpbmZvJykucGlwZShFZmZlY3QuemlwUmlnaHQobWFrZVJ1bih0cmlnZ2VyLCBmYXRhbCkpKSlcbiAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYXNzaWduVHJpZ2dlclNlcSA9ICh0cmlnZ2VyOiBQcm9jZXNzVHJpZ2dlcik6IFByb2Nlc3NUcmlnZ2VyID0+IHtcbiAgICAgICAgICBpZiAoIXNob3VsZFJlY29yZENoYWluRXZlbnRzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJpZ2dlclxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi50cmlnZ2VyLFxuICAgICAgICAgICAgdHJpZ2dlclNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0VHJpZ2dlclNlcSsrLFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVtaXRUcmlnZ2VyRXZlbnQgPSAodHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIsIHNldmVyaXR5OiBQcm9jZXNzRXZlbnRbJ3NldmVyaXR5J10pOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+IHtcbiAgICAgICAgICBpZiAoIXNob3VsZFJlY29yZENoYWluRXZlbnRzKSB7XG4gICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBldnQ6IFByb2Nlc3NFdmVudCA9IHtcbiAgICAgICAgICAgIHR5cGU6ICdwcm9jZXNzOnRyaWdnZXInLFxuICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICB0cmlnZ2VyLFxuICAgICAgICAgICAgc2V2ZXJpdHksXG4gICAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICAgIHRpbWVzdGFtcE1zOiBEYXRlLm5vdygpLFxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZW1pdChldnQpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwb2xpY3kgPSBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi5jb25jdXJyZW5jeVxuICAgICAgICBjb25zdCBhdXRvU3RhcnQgPSBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi50cmlnZ2Vycy5zb21lKFxuICAgICAgICAgICh0KSA9PiB0LmtpbmQgPT09ICdwbGF0Zm9ybUV2ZW50JyAmJiB0LnBsYXRmb3JtRXZlbnQgPT09IFJVTlRJTUVfQk9PVF9FVkVOVCxcbiAgICAgICAgKVxuICAgICAgICBjb25zdCBib290VHJpZ2dlclNwZWMgPSBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi50cmlnZ2Vycy5maW5kKFxuICAgICAgICAgICh0KTogdCBpcyBFeHRyYWN0PFByb2Nlc3NUcmlnZ2VyU3BlYywgeyByZWFkb25seSBraW5kOiAncGxhdGZvcm1FdmVudCcgfT4gPT5cbiAgICAgICAgICAgIHQua2luZCA9PT0gJ3BsYXRmb3JtRXZlbnQnICYmIHQucGxhdGZvcm1FdmVudCA9PT0gUlVOVElNRV9CT09UX0VWRU5ULFxuICAgICAgICApXG5cbiAgICAgICAgY29uc3QgaW5zdGFuY2VQcm9ncmFtID0gRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgIGNvbnN0IGZhdGFsID0geWllbGQqIERlZmVycmVkLm1ha2U8Q2F1c2UuQ2F1c2U8YW55Pj4oKVxuXG4gICAgICAgICAgY29uc3QgcGxhdGZvcm1FdmVudFN0cmVhbTogU3RyZWFtLlN0cmVhbTxQcm9jZXNzVHJpZ2dlcj4gPSBTdHJlYW0uZnJvbVF1ZXVlKFxuICAgICAgICAgICAgaW5zdGFuY2VTdGF0ZS5wbGF0Zm9ybVRyaWdnZXJzUXVldWUsXG4gICAgICAgICAgKVxuXG4gICAgICAgICAgY29uc3Qgbm9uUGxhdGZvcm1UcmlnZ2VycyA9IGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLnRyaWdnZXJzLmZpbHRlcihcbiAgICAgICAgICAgICh0KTogdCBpcyBOb25QbGF0Zm9ybVRyaWdnZXJTcGVjID0+IHQua2luZCAhPT0gJ3BsYXRmb3JtRXZlbnQnLFxuICAgICAgICAgIClcblxuICAgICAgICAgIGNvbnN0IHN0cmVhbXMgPSB5aWVsZCogRWZmZWN0LmZvckVhY2gobm9uUGxhdGZvcm1UcmlnZ2VycywgbWFrZVRyaWdnZXJTdHJlYW0pXG5cbiAgICAgICAgICBjb25zdCB0cmlnZ2VyU3RyZWFtID0gU3RyZWFtLm1lcmdlQWxsKFtwbGF0Zm9ybUV2ZW50U3RyZWFtLCAuLi5zdHJlYW1zXSwge1xuICAgICAgICAgICAgY29uY3VycmVuY3k6ICd1bmJvdW5kZWQnLFxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBjb25zdCByZXBvcnRRdWV1ZU92ZXJmbG93ID0gKFxuICAgICAgICAgICAgaW5mbzogUHJvY2Vzc0NvbmN1cnJlbmN5LlByb2Nlc3NUcmlnZ2VyUXVldWVPdmVyZmxvd0luZm8sXG4gICAgICAgICAgKTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PiB7XG4gICAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgRXJyb3IoJ1Byb2Nlc3MgdHJpZ2dlciBxdWV1ZSBvdmVyZmxvdyAoc2VyaWFsIG1heFF1ZXVlIGd1YXJkKS4nKVxuICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5jb2RlID0gJ3Byb2Nlc3M6OnNlcmlhbF9xdWV1ZV9vdmVyZmxvdydcbiAgICAgICAgICAgIDsoZXJyIGFzIGFueSkuaGludCA9IFtcbiAgICAgICAgICAgICAgYG1vZGU9JHtpbmZvLm1vZGV9YCxcbiAgICAgICAgICAgICAgYHF1ZXVlOiBjdXJyZW50PSR7aW5mby5jdXJyZW50TGVuZ3RofSBwZWFrPSR7aW5mby5wZWFrfWAsXG4gICAgICAgICAgICAgIGBtYXhRdWV1ZTogY29uZmlndXJlZD0ke2luZm8ubGltaXQuY29uZmlndXJlZH0gZ3VhcmQ9JHtpbmZvLmxpbWl0Lmd1YXJkfWAsXG4gICAgICAgICAgICAgIGBwb2xpY3k6ICR7SlNPTi5zdHJpbmdpZnkoaW5mby5wb2xpY3kpfWAsXG4gICAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgICAnZml4OicsXG4gICAgICAgICAgICAgICctIENvbmZpZ3VyZSBjb25jdXJyZW5jeS5tYXhRdWV1ZSAoc2VyaWFsKSB0byBhIGZpbml0ZSB2YWx1ZSwgb3Igc3dpdGNoIHRvIG1vZGU9bGF0ZXN0L2Ryb3AgdG8gYXZvaWQgdW5ib3VuZGVkIGJhY2tsb2cuJyxcbiAgICAgICAgICAgIF0uam9pbignXFxuJylcbiAgICAgICAgICAgIHJldHVybiBEZWZlcnJlZC5zdWNjZWVkKGZhdGFsLCBDYXVzZS5mYWlsKGVycikpLnBpcGUoXG4gICAgICAgICAgICAgIEVmZmVjdC5hc1ZvaWQsXG4gICAgICAgICAgICAgIEVmZmVjdC5jYXRjaEFsbCgoKSA9PiBFZmZlY3Qudm9pZCksXG4gICAgICAgICAgICApXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcnVubmVyRmliZXIgPSB5aWVsZCogRWZmZWN0LmZvcmtTY29wZWQoXG4gICAgICAgICAgICBQcm9jZXNzQ29uY3VycmVuY3kucnVuUHJvY2Vzc1RyaWdnZXJTdHJlYW0oe1xuICAgICAgICAgICAgICBzdHJlYW06IHRyaWdnZXJTdHJlYW0sXG4gICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgYXNzaWduVHJpZ2dlclNlcSxcbiAgICAgICAgICAgICAgcnVuOiAodHJpZ2dlcikgPT4gbWFrZUNoYWluUnVuKHRyaWdnZXIsIGZhdGFsKSxcbiAgICAgICAgICAgICAgb25Ecm9wOiAodHJpZ2dlcikgPT4gZW1pdFRyaWdnZXJFdmVudCh0cmlnZ2VyLCAnd2FybmluZycpLFxuICAgICAgICAgICAgICBvblF1ZXVlT3ZlcmZsb3c6IHJlcG9ydFF1ZXVlT3ZlcmZsb3csXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApXG5cbiAgICAgICAgICBpZiAoYXV0b1N0YXJ0KSB7XG4gICAgICAgICAgICB5aWVsZCogUXVldWUub2ZmZXIoaW5zdGFuY2VTdGF0ZS5wbGF0Zm9ybVRyaWdnZXJzUXVldWUsIHtcbiAgICAgICAgICAgICAga2luZDogJ3BsYXRmb3JtRXZlbnQnLFxuICAgICAgICAgICAgICBuYW1lOiBib290VHJpZ2dlclNwZWM/Lm5hbWUsXG4gICAgICAgICAgICAgIHBsYXRmb3JtRXZlbnQ6IFJVTlRJTUVfQk9PVF9FVkVOVCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY2F1c2UgPSB5aWVsZCogRGVmZXJyZWQuYXdhaXQoZmF0YWwpXG4gICAgICAgICAgeWllbGQqIEZpYmVyLmludGVycnVwdChydW5uZXJGaWJlcilcbiAgICAgICAgICByZXR1cm4geWllbGQqIEVmZmVjdC5mYWlsQ2F1c2UoY2F1c2UpXG4gICAgICAgIH0pXG5cbiAgICAgICAgY29uc3QgZmliZXIgPSB5aWVsZCogRWZmZWN0LmZvcmtJbihpbnN0YWxsYXRpb24uZm9ya1Njb3BlKShcbiAgICAgICAgICBFZmZlY3Quc2NvcGVkKGluc3RhbmNlUHJvZ3JhbSkucGlwZShcbiAgICAgICAgICAgIEVmZmVjdC5jYXRjaEFsbENhdXNlKChjYXVzZSkgPT5cbiAgICAgICAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgIC8vIFx1NEUyRFx1NjVBRFx1RkYwOFx1OTAxQVx1NUUzOFx1Njc2NVx1ODFFQSBzY29wZSBkaXNwb3NlIC8gXHU2MjRCXHU1MkE4IHN0b3BcdUZGMDlcdTRFMERcdTVFOTRcdTg4QUJcdTVGNTNcdTRGNUMgcHJvY2VzcyBmYWlsdXJlXHUzMDAyXG4gICAgICAgICAgICAgICAgLy8gXHU1NDI2XHU1MjE5XHU0RjFBXHU1NzI4XHU1MTczXHU5NUVEIHNjb3BlIFx1NjVGNlx1NEVBN1x1NzUxRiBwcm9jZXNzOmVycm9yIC8gZGlhZ25vc3RpY1x1RkYwQ1x1NUU3Nlx1NTNFRlx1ODBGRFx1NUJGQ1x1ODFGNCBkaXNwb3NlIFx1NTM2MVx1NkI3Qlx1MzAwMlxuICAgICAgICAgICAgICAgIGlmIChDYXVzZS5pc0ludGVycnVwdGVkT25seShjYXVzZSkpIHtcbiAgICAgICAgICAgICAgICAgIC8vIFx1ODJFNSBzdG9wSW5zdGFuY2UgXHU1REYyXHU3RUNGXHU2MjhBXHU3MkI2XHU2MDAxXHU2M0E4XHU4RkRCXHU1MjMwIHN0b3BwaW5nXHVGRjBDXHU1MjE5XHU3NTMxIHN0b3BJbnN0YW5jZSBcdThEMUZcdThEMjMgc3RvcCBcdTRFOEJcdTRFRjZcdTRFMEVcdTY3MDBcdTdFQzhcdTcyQjZcdTYwMDFcdTMwMDJcbiAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZVN0YXRlLnN0YXR1cy5zdGF0dXMgPT09ICdzdG9wcGluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIC8vIFx1NTQyNlx1NTIxOVx1ODlDNlx1NEUzQSBzY29wZSBkaXNwb3NlIFx1NUJGQ1x1ODFGNFx1NzY4NFx1ODFFQVx1NzEzNlx1NTA1Q1x1NkI2Mlx1RkYwOFx1NEY4Qlx1NTk4MiBtb2R1bGVJbnN0YW5jZSBzY29wZSBcdTUxNzNcdTk1RURcdUZGMDlcdTMwMDJcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlU3RhdGUuc3RhdHVzID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5pbnN0YW5jZVN0YXRlLnN0YXR1cyxcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiAnc3RvcHBlZCcsXG4gICAgICAgICAgICAgICAgICAgIHN0b3BwZWRSZWFzb246ICdzY29wZURpc3Bvc2VkJyxcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlU3RhdGUuZmliZXIgPSB1bmRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgeWllbGQqIEVmZmVjdC51bmludGVycnVwdGlibGUoXG4gICAgICAgICAgICAgICAgICAgIGVtaXQoe1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdwcm9jZXNzOnN0b3AnLFxuICAgICAgICAgICAgICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgICAgICAgICAgICAgIHNldmVyaXR5OiAnaW5mbycsXG4gICAgICAgICAgICAgICAgICAgICAgZXZlbnRTZXE6IGluc3RhbmNlU3RhdGUubmV4dEV2ZW50U2VxKyssXG4gICAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgKVxuXG4gICAgICAgICAgICAgICAgICBjb25zdCBpbnN0YWxsYXRpb24gPSBpbnN0YWxsYXRpb25zLmdldChpbnN0YWxsYXRpb25LZXkpXG4gICAgICAgICAgICAgICAgICBpZiAoaW5zdGFsbGF0aW9uPy5wZW5kaW5nU3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uLnBlbmRpbmdTdGFydCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICB5aWVsZCogc3RhcnRJbnN0YWxsYXRpb24oaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgcHJpbWFyeSA9IE9wdGlvbi5nZXRPckVsc2UoQ2F1c2UuZmFpbHVyZU9wdGlvbihjYXVzZSksICgpID0+XG4gICAgICAgICAgICAgICAgICBPcHRpb24uZ2V0T3JFbHNlKENhdXNlLmRpZU9wdGlvbihjYXVzZSksICgpID0+IGNhdXNlKSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgY29uc3Qgc3VtbWFyeSA9IHRvU2VyaWFsaXphYmxlRXJyb3JTdW1tYXJ5KHByaW1hcnkpXG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3I6IFNlcmlhbGl6YWJsZUVycm9yU3VtbWFyeSA9IHN1bW1hcnkuZXJyb3JTdW1tYXJ5IGFzIGFueVxuXG4gICAgICAgICAgICAgICAgaW5zdGFuY2VTdGF0ZS5zdGF0dXMgPSB7XG4gICAgICAgICAgICAgICAgICAuLi5pbnN0YW5jZVN0YXRlLnN0YXR1cyxcbiAgICAgICAgICAgICAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXG4gICAgICAgICAgICAgICAgICBzdG9wcGVkUmVhc29uOiAnZmFpbGVkJyxcbiAgICAgICAgICAgICAgICAgIGxhc3RFcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgeWllbGQqIGVtaXQoe1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3Byb2Nlc3M6ZXJyb3InLFxuICAgICAgICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgIGV2ZW50U2VxOiBpbnN0YW5jZVN0YXRlLm5leHRFdmVudFNlcSsrLFxuICAgICAgICAgICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgY29uc3QgZGVjaXNpb24gPSBTdXBlcnZpc2lvbi5vbkZhaWx1cmUoXG4gICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi5lcnJvclBvbGljeSxcbiAgICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbi5zdXBlcnZpc2lvbixcbiAgICAgICAgICAgICAgICAgIERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbi5zdXBlcnZpc2lvbiA9IGRlY2lzaW9uLm5leHRTdGF0ZVxuXG4gICAgICAgICAgICAgICAgaWYgKGRlY2lzaW9uLmRlY2lzaW9uID09PSAncmVzdGFydCcpIHtcbiAgICAgICAgICAgICAgICAgIC8vIHN1cGVydmlzZVx1RkYxQVx1NTNEN1x1NjNBN1x1OTFDRFx1NTQyRlx1RkYwOHJ1blNlcSBcdTkwMTJcdTU4OUVcdUZGMDlcdUZGMENcdTVFNzZcdTRFQTdcdTUxRkEgcmVzdGFydCBcdTRFOEJcdTRFRjZcdTMwMDJcbiAgICAgICAgICAgICAgICAgIHlpZWxkKiBlbWl0KHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3Byb2Nlc3M6cmVzdGFydCcsXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgICAgICAgICAgICBzZXZlcml0eTogJ3dhcm5pbmcnLFxuICAgICAgICAgICAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgIHlpZWxkKiBzdGFydEluc3RhbGxhdGlvbihpbnN0YWxsYXRpb25LZXkpXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHlpZWxkKiBlbWl0RXJyb3JEaWFnbm9zdGljKFxuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24uaWRlbnRpdHkuc2NvcGUsXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbi5pZGVudGl0eS5wcm9jZXNzSWQsXG4gICAgICAgICAgICAgICAgICAgICdwcm9jZXNzOjpmYWlsZWRfc3RvcCcsXG4gICAgICAgICAgICAgICAgICAgICdQcm9jZXNzIGZhaWxlZCBhbmQgc3RvcHBlZCAoZmFpbFN0b3AgLyByZXN0YXJ0IGxpbWl0IHJlYWNoZWQpLicsXG4gICAgICAgICAgICAgICAgICAgIGBwcm9jZXNzSWQ9JHtpbnN0YWxsYXRpb24uaWRlbnRpdHkucHJvY2Vzc0lkfSBzY29wZUtleT0ke2luc3RhbGxhdGlvbi5zY29wZUtleX0gZmFpbHVyZXM9JHtkZWNpc2lvbi53aXRoaW5XaW5kb3dGYWlsdXJlc30gbWF4UmVzdGFydHM9JHtkZWNpc2lvbi5tYXhSZXN0YXJ0c31gLFxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICksXG4gICAgICAgIClcblxuICAgICAgICBpbnN0YW5jZVN0YXRlLmZpYmVyID0gZmliZXIgYXMgRmliZXIuUnVudGltZUZpYmVyPHVua25vd24sIHVua25vd24+XG4gICAgICAgIGluc3RhbmNlU3RhdGUuc3RhdHVzID0ge1xuICAgICAgICAgIC4uLmluc3RhbmNlU3RhdGUuc3RhdHVzLFxuICAgICAgICAgIHN0YXR1czogJ3J1bm5pbmcnLFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gXHU1QzNEXHU5MUNGXHU0RkREXHU4QkMxXHU1NzI4IGluc3RhbGwvc3RhcnQgXHU4RkQ0XHU1NkRFXHU1MjREXHVGRjBDaW5zdGFuY2UgZmliZXIgXHU1REYyXHU1RjAwXHU1OUNCXHU4QkEyXHU5NjA1IHRyaWdnZXIgc3RyZWFtc1x1RkYwQ1xuICAgICAgICAvLyBcdTkwN0ZcdTUxNERcdTIwMUNcdTUyMUEgYnVpbGQgXHU1QjhDIGVudiBcdTVDMzEgZGlzcGF0Y2hcdTIwMURcdTVCRkNcdTgxRjQgbW9kdWxlQWN0aW9uL21vZHVsZVN0YXRlQ2hhbmdlIFx1ODlFNlx1NTNEMVx1NEUyMlx1NTkzMVx1MzAwMlxuICAgICAgICB5aWVsZCogRWZmZWN0LnlpZWxkTm93KClcbiAgICAgIH0pXG5cbiAgICBjb25zdCBpbnN0YWxsID0gPEUsIFI+KFxuICAgICAgcHJvY2VzczogRWZmZWN0LkVmZmVjdDx2b2lkLCBFLCBSPixcbiAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgcmVhZG9ubHkgc2NvcGU6IFByb2Nlc3NTY29wZVxuICAgICAgICByZWFkb25seSBlbmFibGVkPzogYm9vbGVhblxuICAgICAgICByZWFkb25seSBpbnN0YWxsZWRBdD86IHN0cmluZ1xuICAgICAgICByZWFkb25seSBtb2RlPzogUHJvY2Vzc0luc3RhbGxNb2RlXG4gICAgICB9LFxuICAgICk6IEVmZmVjdC5FZmZlY3Q8UHJvY2Vzc0luc3RhbGxhdGlvbiB8IHVuZGVmaW5lZCwgbmV2ZXIsIFI+ID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IG1ldGEgPSBNZXRhLmdldE1ldGEocHJvY2VzcylcbiAgICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW52ID0geWllbGQqIEVmZmVjdC5jb250ZXh0PFI+KClcbiAgICAgICAgY29uc3QgZm9ya1Njb3BlT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKFNjb3BlLlNjb3BlKVxuICAgICAgICBjb25zdCBmb3JrU2NvcGUgPSBPcHRpb24uaXNTb21lKGZvcmtTY29wZU9wdCkgPyBmb3JrU2NvcGVPcHQudmFsdWUgOiBydW50aW1lU2NvcGVcblxuICAgICAgICBjb25zdCBzY29wZUtleSA9IElkZW50aXR5LnNjb3BlS2V5RnJvbVNjb3BlKG9wdGlvbnMuc2NvcGUpXG4gICAgICAgIGNvbnN0IGlkZW50aXR5ID0ge1xuICAgICAgICAgIHByb2Nlc3NJZDogbWV0YS5kZWZpbml0aW9uLnByb2Nlc3NJZCxcbiAgICAgICAgICBzY29wZTogb3B0aW9ucy5zY29wZSxcbiAgICAgICAgfSBhcyBjb25zdFxuXG4gICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbktleSA9IElkZW50aXR5Lmluc3RhbGxhdGlvbktleUZyb21JZGVudGl0eShpZGVudGl0eSlcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBpbnN0YWxsYXRpb25zLmdldChpbnN0YWxsYXRpb25LZXkpXG4gICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgIGV4aXN0aW5nLmVudiA9IGVudiBhcyBDb250ZXh0LkNvbnRleHQ8YW55PlxuICAgICAgICAgIGV4aXN0aW5nLmZvcmtTY29wZSA9IGZvcmtTY29wZVxuICAgICAgICAgIGV4aXN0aW5nLmVuYWJsZWQgPSBvcHRpb25zLmVuYWJsZWQgPz8gdHJ1ZVxuICAgICAgICAgIGV4aXN0aW5nLmluc3RhbGxlZEF0ID0gb3B0aW9ucy5pbnN0YWxsZWRBdCA/PyBleGlzdGluZy5pbnN0YWxsZWRBdFxuICAgICAgICAgIGlmICghZXhpc3RpbmcuZW5hYmxlZCkge1xuICAgICAgICAgICAgZXhpc3RpbmcucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgICAgZW5hYmxlZDogZXhpc3RpbmcuZW5hYmxlZCxcbiAgICAgICAgICAgICAgaW5zdGFsbGVkQXQ6IGV4aXN0aW5nLmluc3RhbGxlZEF0LFxuICAgICAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc0luc3RhbGxhdGlvblxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGN1cnJlbnRJZCA9IGV4aXN0aW5nLmN1cnJlbnRJbnN0YW5jZUlkXG4gICAgICAgICAgY29uc3QgY3VycmVudCA9IGN1cnJlbnRJZCA/IGluc3RhbmNlcy5nZXQoY3VycmVudElkKSA6IHVuZGVmaW5lZFxuICAgICAgICAgIGNvbnN0IHN0YXR1cyA9IGN1cnJlbnQ/LnN0YXR1cy5zdGF0dXNcblxuICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdydW5uaW5nJyB8fCBzdGF0dXMgPT09ICdzdGFydGluZycpIHtcbiAgICAgICAgICAgIGNvbnN0IG1vZGU6IFByb2Nlc3NJbnN0YWxsTW9kZSA9IG9wdGlvbnMubW9kZSA/PyAnc3dpdGNoJ1xuICAgICAgICAgICAgaWYgKG1vZGUgPT09ICdzd2l0Y2gnICYmIGN1cnJlbnQgJiYgY3VycmVudC5mb3JrU2NvcGUgIT09IGZvcmtTY29wZSkge1xuICAgICAgICAgICAgICBleGlzdGluZy5wZW5kaW5nU3RhcnQgPSB7IGZvcmtTY29wZSB9XG4gICAgICAgICAgICAgIHlpZWxkKiBTY29wZS5hZGRGaW5hbGl6ZXIoXG4gICAgICAgICAgICAgICAgZm9ya1Njb3BlLFxuICAgICAgICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbiA9IGluc3RhbGxhdGlvbnMuZ2V0KGluc3RhbGxhdGlvbktleSlcbiAgICAgICAgICAgICAgICAgIGlmICghaW5zdGFsbGF0aW9uKSByZXR1cm5cbiAgICAgICAgICAgICAgICAgIGlmIChpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0Py5mb3JrU2NvcGUgPT09IGZvcmtTY29wZSkge1xuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGV4aXN0aW5nLnBlbmRpbmdTdGFydCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICAgIGVuYWJsZWQ6IGV4aXN0aW5nLmVuYWJsZWQsXG4gICAgICAgICAgICAgIGluc3RhbGxlZEF0OiBleGlzdGluZy5pbnN0YWxsZWRBdCxcbiAgICAgICAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NJbnN0YWxsYXRpb25cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc3RhdHVzID09PSAnc3RvcHBpbmcnKSB7XG4gICAgICAgICAgICBjb25zdCBtb2RlOiBQcm9jZXNzSW5zdGFsbE1vZGUgPSBvcHRpb25zLm1vZGUgPz8gJ3N3aXRjaCdcbiAgICAgICAgICAgIGlmIChtb2RlID09PSAnc3dpdGNoJykge1xuICAgICAgICAgICAgICBleGlzdGluZy5wZW5kaW5nU3RhcnQgPSB7IGZvcmtTY29wZSB9XG4gICAgICAgICAgICAgIHlpZWxkKiBTY29wZS5hZGRGaW5hbGl6ZXIoXG4gICAgICAgICAgICAgICAgZm9ya1Njb3BlLFxuICAgICAgICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbiA9IGluc3RhbGxhdGlvbnMuZ2V0KGluc3RhbGxhdGlvbktleSlcbiAgICAgICAgICAgICAgICAgIGlmICghaW5zdGFsbGF0aW9uKSByZXR1cm5cbiAgICAgICAgICAgICAgICAgIGlmIChpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0Py5mb3JrU2NvcGUgPT09IGZvcmtTY29wZSkge1xuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGV4aXN0aW5nLnBlbmRpbmdTdGFydCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICAgIGVuYWJsZWQ6IGV4aXN0aW5nLmVuYWJsZWQsXG4gICAgICAgICAgICAgIGluc3RhbGxlZEF0OiBleGlzdGluZy5pbnN0YWxsZWRBdCxcbiAgICAgICAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NJbnN0YWxsYXRpb25cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBleGlzdGluZy5wZW5kaW5nU3RhcnQgPSB1bmRlZmluZWRcbiAgICAgICAgICB5aWVsZCogc3RhcnRJbnN0YWxsYXRpb24oaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgIGVuYWJsZWQ6IGV4aXN0aW5nLmVuYWJsZWQsXG4gICAgICAgICAgICBpbnN0YWxsZWRBdDogZXhpc3RpbmcuaW5zdGFsbGVkQXQsXG4gICAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc0luc3RhbGxhdGlvblxuICAgICAgICB9XG5cbiAgICAgICAgLy8gXHU0RTNBXHU2NzJDXHU2QjIxXHU1Qjg5XHU4OEM1XHU2RDNFXHU3NTFGXHU0RTAwXHU0RTJBIGVmZmVjdFx1RkYwQ1x1OTA3Rlx1NTE0RFx1ODk4Nlx1NzZENlx1NTM5Rlx1NTlDQiBFZmZlY3QgXHU0RTBBXHU3Njg0IG1ldGFcdUZGMDhcdTU5MUEgc2NvcGUgXHU1OTBEXHU3NTI4XHVGRjA5XHUzMDAyXG4gICAgICAgIC8vIFx1NkNFOFx1NjEwRlx1RkYxQVx1OEZEOVx1OTFDQ1x1NEUwRFx1NjNEMFx1NTI0RCBwcm92aWRlIGVudlx1RkYwQ1x1OTA3Rlx1NTE0RFx1NTQwRVx1N0VFRFx1NjVFMFx1NkNENVx1NTcyOFx1NkJDRlx1NkIyMVx1ODlFNlx1NTNEMVx1NjI2N1x1ODg0Q1x1NjVGNlx1NTNFMFx1NTJBMFx1OTg5RFx1NTkxNlx1NEUwQVx1NEUwQlx1NjU4N1x1RkYwOFx1NEY4Qlx1NTk4MiBkaXNwYXRjaCBcdTk0RkVcdThERUZcdThCQ0FcdTY1QURcdUZGMDlcdTMwMDJcbiAgICAgICAgY29uc3QgZGVyaXZlZCA9IEVmZmVjdC5zdXNwZW5kKCgpID0+IHByb2Nlc3MpXG4gICAgICAgIE1ldGEuYXR0YWNoTWV0YShkZXJpdmVkLCB7XG4gICAgICAgICAgLi4ubWV0YSxcbiAgICAgICAgICBpbnN0YWxsYXRpb25TY29wZTogb3B0aW9ucy5zY29wZSxcbiAgICAgICAgfSlcblxuICAgICAgICBjb25zdCBpbnN0YWxsYXRpb246IEluc3RhbGxhdGlvblN0YXRlID0ge1xuICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgIHNjb3BlS2V5LFxuICAgICAgICAgIGRlZmluaXRpb246IG1ldGEuZGVmaW5pdGlvbixcbiAgICAgICAgICBlbnY6IGVudiBhcyBDb250ZXh0LkNvbnRleHQ8YW55PixcbiAgICAgICAgICBmb3JrU2NvcGUsXG4gICAgICAgICAgcHJvY2VzczogZGVyaXZlZCBhcyB1bmtub3duIGFzIEVmZmVjdC5FZmZlY3Q8dm9pZCwgYW55LCB1bmtub3duPixcbiAgICAgICAgICBraW5kOiBtZXRhLmtpbmQgPz8gJ3Byb2Nlc3MnLFxuICAgICAgICAgIGVuYWJsZWQ6IG9wdGlvbnMuZW5hYmxlZCA/PyB0cnVlLFxuICAgICAgICAgIGluc3RhbGxlZEF0OiBvcHRpb25zLmluc3RhbGxlZEF0LFxuICAgICAgICAgIG5leHRSdW5TZXE6IDEsXG4gICAgICAgICAgc3VwZXJ2aXNpb246IFN1cGVydmlzaW9uLmluaXRpYWxTdGF0ZSgpLFxuICAgICAgICAgIHBlbmRpbmdTdGFydDogdW5kZWZpbmVkLFxuICAgICAgICB9XG5cbiAgICAgICAgaW5zdGFsbGF0aW9ucy5zZXQoaW5zdGFsbGF0aW9uS2V5LCBpbnN0YWxsYXRpb24pXG5cbiAgICAgICAgaWYgKGluc3RhbGxhdGlvbi5lbmFibGVkKSB7XG4gICAgICAgICAgeWllbGQqIHN0YXJ0SW5zdGFsbGF0aW9uKGluc3RhbGxhdGlvbktleSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgZW5hYmxlZDogaW5zdGFsbGF0aW9uLmVuYWJsZWQsXG4gICAgICAgICAgaW5zdGFsbGVkQXQ6IGluc3RhbGxhdGlvbi5pbnN0YWxsZWRBdCxcbiAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc0luc3RhbGxhdGlvblxuICAgICAgfSlcblxuICAgIGNvbnN0IGxpc3RJbnN0YWxsYXRpb25zOiBQcm9jZXNzUnVudGltZVsnbGlzdEluc3RhbGxhdGlvbnMnXSA9IChmaWx0ZXIpID0+XG4gICAgICBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNjb3BlVHlwZSA9IGZpbHRlcj8uc2NvcGVUeXBlXG4gICAgICAgIGNvbnN0IHNjb3BlS2V5ID0gZmlsdGVyPy5zY29wZUtleVxuICAgICAgICBjb25zdCBvdXQ6IFByb2Nlc3NJbnN0YWxsYXRpb25bXSA9IFtdXG4gICAgICAgIGZvciAoY29uc3QgaW5zdGFsbGF0aW9uIG9mIGluc3RhbGxhdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgICAgICBpZiAoc2NvcGVUeXBlICYmIGluc3RhbGxhdGlvbi5pZGVudGl0eS5zY29wZS50eXBlICE9PSBzY29wZVR5cGUpIGNvbnRpbnVlXG4gICAgICAgICAgaWYgKHNjb3BlS2V5ICYmIGluc3RhbGxhdGlvbi5zY29wZUtleSAhPT0gc2NvcGVLZXkpIGNvbnRpbnVlXG4gICAgICAgICAgb3V0LnB1c2goe1xuICAgICAgICAgICAgaWRlbnRpdHk6IGluc3RhbGxhdGlvbi5pZGVudGl0eSxcbiAgICAgICAgICAgIGVuYWJsZWQ6IGluc3RhbGxhdGlvbi5lbmFibGVkLFxuICAgICAgICAgICAgaW5zdGFsbGVkQXQ6IGluc3RhbGxhdGlvbi5pbnN0YWxsZWRBdCxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXRcbiAgICAgIH0pXG5cbiAgICBjb25zdCBnZXRJbnN0YW5jZVN0YXR1czogUHJvY2Vzc1J1bnRpbWVbJ2dldEluc3RhbmNlU3RhdHVzJ10gPSAocHJvY2Vzc0luc3RhbmNlSWQpID0+XG4gICAgICBFZmZlY3Quc3luYygoKSA9PiBpbnN0YW5jZXMuZ2V0KHByb2Nlc3NJbnN0YW5jZUlkKT8uc3RhdHVzKVxuXG4gICAgY29uc3QgY29udHJvbEluc3RhbmNlOiBQcm9jZXNzUnVudGltZVsnY29udHJvbEluc3RhbmNlJ10gPSAocHJvY2Vzc0luc3RhbmNlSWQsIHJlcXVlc3QpID0+XG4gICAgICBFZmZlY3Quc3VzcGVuZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluc3RhbmNlID0gaW5zdGFuY2VzLmdldChwcm9jZXNzSW5zdGFuY2VJZClcbiAgICAgICAgaWYgKCFpbnN0YW5jZSkge1xuICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNob3VsZE5vb3BEdWVUb1N5bmNUeG4oaW5zdGFuY2Uuc2NvcGUsICdwcm9jZXNzX2NvbnRyb2xfaW5fdHJhbnNhY3Rpb24nKS5waXBlKFxuICAgICAgICAgIEVmZmVjdC5mbGF0TWFwKChub29wKSA9PiB7XG4gICAgICAgICAgICBpZiAobm9vcCkge1xuICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlcXVlc3QuYWN0aW9uID09PSAnc3RvcCcpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHN0b3BJbnN0YW5jZShpbnN0YW5jZSwgJ21hbnVhbFN0b3AnKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVxdWVzdC5hY3Rpb24gPT09ICdyZXN0YXJ0Jykge1xuICAgICAgICAgICAgICByZXR1cm4gc3RvcEluc3RhbmNlKGluc3RhbmNlLCAnbWFudWFsU3RvcCcpLnBpcGUoXG4gICAgICAgICAgICAgICAgRWZmZWN0LmZsYXRNYXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uID0gaW5zdGFsbGF0aW9ucy5nZXQoaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgICAgICAgaWYgKCFpbnN0YWxsYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24uY3VycmVudEluc3RhbmNlSWQgPSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgIHJldHVybiBzdGFydEluc3RhbGxhdGlvbihpbnN0YW5jZS5pbnN0YWxsYXRpb25LZXkpXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gc3RhcnRcdUZGMUFcdTRFQzVcdTVCRjlcdTVERjJcdTUwNUNcdTZCNjJcdTVCOUVcdTRGOEJcdTc1MUZcdTY1NDhcdUZGMUJcdTU5MERcdTc1MjhcdTVGNTNcdTUyNEQgcnVuU2VxXHVGRjBDXHU0RTBEXHU5MDEyXHU1ODlFXHUzMDAyXG4gICAgICAgICAgICBpZiAocmVxdWVzdC5hY3Rpb24gPT09ICdzdGFydCcpIHtcbiAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnN0YXR1cy5zdGF0dXMgPT09ICdydW5uaW5nJyB8fCBpbnN0YW5jZS5zdGF0dXMuc3RhdHVzID09PSAnc3RhcnRpbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjb25zdCBpbnN0YWxsYXRpb24gPSBpbnN0YWxsYXRpb25zLmdldChpbnN0YW5jZS5pbnN0YWxsYXRpb25LZXkpXG4gICAgICAgICAgICAgIGlmICghaW5zdGFsbGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uLmN1cnJlbnRJbnN0YW5jZUlkID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgIHJldHVybiBzdGFydEluc3RhbGxhdGlvbihpbnN0YW5jZS5pbnN0YWxsYXRpb25LZXkpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICB9KVxuXG4gICAgY29uc3QgZGVsaXZlclBsYXRmb3JtRXZlbnQ6IFByb2Nlc3NSdW50aW1lWydkZWxpdmVyUGxhdGZvcm1FdmVudCddID0gKGV2ZW50KSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBub29wID0geWllbGQqIFRhc2tSdW5uZXIuc2hvdWxkTm9vcEluU3luY1RyYW5zYWN0aW9uRmliZXIoe1xuICAgICAgICAgIGNvZGU6ICdwcm9jZXNzOjppbnZhbGlkX3VzYWdlJyxcbiAgICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICAgJ1Byb2Nlc3NSdW50aW1lIHBsYXRmb3JtIGV2ZW50cyBhcmUgbm90IGFsbG93ZWQgaW5zaWRlIGEgc3luY2hyb25vdXMgU3RhdGVUcmFuc2FjdGlvbiBib2R5IChpdCBtYXkgZGVhZGxvY2sgdGhlIHR4blF1ZXVlKS4nLFxuICAgICAgICAgIGhpbnQ6ICdEZWxpdmVyIHBsYXRmb3JtRXZlbnQgb3V0c2lkZSB0aGUgdHJhbnNhY3Rpb24gd2luZG93LicsXG4gICAgICAgICAga2luZDogJ3Byb2Nlc3NfcGxhdGZvcm1fZXZlbnRfaW5fdHJhbnNhY3Rpb24nLFxuICAgICAgICB9KVxuICAgICAgICBpZiAobm9vcCkgcmV0dXJuXG5cbiAgICAgICAgY29uc3QgdGFyZ2V0cyA9IEFycmF5LmZyb20oaW5zdGFuY2VzLnZhbHVlcygpKVxuICAgICAgICBjb25zdCBldmVudE5hbWUgPSBldmVudC5ldmVudE5hbWVcblxuICAgICAgICB5aWVsZCogRWZmZWN0LmZvckVhY2goXG4gICAgICAgICAgdGFyZ2V0cyxcbiAgICAgICAgICAoaW5zdGFuY2UpID0+XG4gICAgICAgICAgICBFZmZlY3Quc3VzcGVuZCgoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5zdGF0dXMuc3RhdHVzICE9PSAnc3RhcnRpbmcnICYmIGluc3RhbmNlLnN0YXR1cy5zdGF0dXMgIT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uID0gaW5zdGFsbGF0aW9ucy5nZXQoaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgICBpZiAoIWluc3RhbGxhdGlvbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3Qgc3BlY3MgPSBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi50cmlnZ2Vycy5maWx0ZXIoXG4gICAgICAgICAgICAgICAgKHQpOiB0IGlzIEV4dHJhY3Q8UHJvY2Vzc1RyaWdnZXJTcGVjLCB7IHJlYWRvbmx5IGtpbmQ6ICdwbGF0Zm9ybUV2ZW50JyB9PiA9PlxuICAgICAgICAgICAgICAgICAgdC5raW5kID09PSAncGxhdGZvcm1FdmVudCcgJiYgdC5wbGF0Zm9ybUV2ZW50ID09PSBldmVudE5hbWUsXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgaWYgKHNwZWNzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC5mb3JFYWNoKFxuICAgICAgICAgICAgICAgIHNwZWNzLFxuICAgICAgICAgICAgICAgIChzcGVjKSA9PlxuICAgICAgICAgICAgICAgICAgUXVldWUub2ZmZXIoaW5zdGFuY2UucGxhdGZvcm1UcmlnZ2Vyc1F1ZXVlLCB7XG4gICAgICAgICAgICAgICAgICAgIGtpbmQ6ICdwbGF0Zm9ybUV2ZW50JyxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogc3BlYy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybUV2ZW50OiBzcGVjLnBsYXRmb3JtRXZlbnQsXG4gICAgICAgICAgICAgICAgICB9IHNhdGlzZmllcyBQcm9jZXNzVHJpZ2dlciksXG4gICAgICAgICAgICAgICAgeyBkaXNjYXJkOiB0cnVlIH0sXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgZGlzY2FyZDogdHJ1ZSB9LFxuICAgICAgICApXG4gICAgICB9KVxuXG4gICAgY29uc3QgZXZlbnRzU3RyZWFtOiBQcm9jZXNzUnVudGltZVsnZXZlbnRzJ10gPSBTdHJlYW0uZnJvbVB1YlN1YihldmVudHNIdWIpXG5cbiAgICBjb25zdCBnZXRFdmVudHNTbmFwc2hvdDogUHJvY2Vzc1J1bnRpbWVbJ2dldEV2ZW50c1NuYXBzaG90J10gPSAoKSA9PiBFZmZlY3Quc3luYygoKSA9PiBldmVudHNCdWZmZXIuc2xpY2UoKSlcblxuICAgIHlpZWxkKiBFZmZlY3QuYWRkRmluYWxpemVyKCgpID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGZvciAoY29uc3QgaW5zdGFsbGF0aW9uIG9mIGluc3RhbGxhdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgICAgICBpbnN0YWxsYXRpb24ucGVuZGluZ1N0YXJ0ID0gdW5kZWZpbmVkXG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBpbnN0YW5jZSBvZiBpbnN0YW5jZXMudmFsdWVzKCkpIHtcbiAgICAgICAgICBpZiAoaW5zdGFuY2UuZmliZXIpIHtcbiAgICAgICAgICAgIHlpZWxkKiBzdG9wSW5zdGFuY2UoaW5zdGFuY2UsICdzY29wZURpc3Bvc2VkJylcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pLnBpcGUoXG4gICAgICAgIEVmZmVjdC5jYXRjaEFsbENhdXNlKChjYXVzZSkgPT5cbiAgICAgICAgICBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgICAgICAgICAvLyBmaW5hbGl6ZXIgXHU0RTBEXHU1RTk0XHU2MjlCXHU1MUZBXHVGRjFCXHU4RkQ5XHU5MUNDXHU0RUM1IGJlc3QtZWZmb3J0IFx1OEJCMFx1NUY1NVx1MzAwMlxuICAgICAgICAgICAgaWYgKGlzRGV2RW52KCkpIHtcbiAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdbUHJvY2Vzc1J1bnRpbWVdIGZpbmFsaXplciBmYWlsZWQnLCBDYXVzZS5wcmV0dHkoY2F1c2UpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApXG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5zdGFsbCxcbiAgICAgIGxpc3RJbnN0YWxsYXRpb25zLFxuICAgICAgZ2V0SW5zdGFuY2VTdGF0dXMsXG4gICAgICBjb250cm9sSW5zdGFuY2UsXG4gICAgICBkZWxpdmVyUGxhdGZvcm1FdmVudCxcbiAgICAgIGV2ZW50czogZXZlbnRzU3RyZWFtLFxuICAgICAgZ2V0RXZlbnRzU25hcHNob3QsXG4gICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc1J1bnRpbWVcbiAgfSlcblxuZXhwb3J0IGNvbnN0IGxheWVyID0gKG9wdGlvbnM/OiB7IHJlYWRvbmx5IG1heEV2ZW50SGlzdG9yeT86IG51bWJlciB9KTogTGF5ZXIuTGF5ZXI8UHJvY2Vzc1J1bnRpbWVUYWcsIG5ldmVyLCBuZXZlcj4gPT5cbiAgTGF5ZXIuc2NvcGVkKFByb2Nlc3NSdW50aW1lVGFnLCBtYWtlKG9wdGlvbnMpKVxuIiwgImltcG9ydCB0eXBlIHsgUHJvY2Vzc0lkZW50aXR5LCBQcm9jZXNzSW5zdGFuY2VJZGVudGl0eSwgUHJvY2Vzc1Njb3BlIH0gZnJvbSAnLi9wcm90b2NvbC5qcydcblxuZXhwb3J0IHR5cGUgUHJvY2Vzc1Njb3BlS2V5ID0gc3RyaW5nXG5cbmV4cG9ydCBjb25zdCBzY29wZUtleUZyb21TY29wZSA9IChzY29wZTogUHJvY2Vzc1Njb3BlKTogUHJvY2Vzc1Njb3BlS2V5ID0+IHtcbiAgc3dpdGNoIChzY29wZS50eXBlKSB7XG4gICAgY2FzZSAnYXBwJzpcbiAgICAgIHJldHVybiBgYXBwOiR7c2NvcGUuYXBwSWR9YFxuICAgIGNhc2UgJ21vZHVsZUluc3RhbmNlJzpcbiAgICAgIHJldHVybiBgbW9kdWxlSW5zdGFuY2U6JHtzY29wZS5tb2R1bGVJZH06OiR7c2NvcGUuaW5zdGFuY2VJZH1gXG4gICAgY2FzZSAndWlTdWJ0cmVlJzpcbiAgICAgIHJldHVybiBgdWlTdWJ0cmVlOiR7c2NvcGUuc3VidHJlZUlkfWBcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgaW5zdGFsbGF0aW9uS2V5RnJvbUlkZW50aXR5ID0gKGlkZW50aXR5OiBQcm9jZXNzSWRlbnRpdHkpOiBzdHJpbmcgPT5cbiAgYCR7aWRlbnRpdHkucHJvY2Vzc0lkfUBAJHtzY29wZUtleUZyb21TY29wZShpZGVudGl0eS5zY29wZSl9YFxuXG5leHBvcnQgY29uc3QgcHJvY2Vzc0luc3RhbmNlSWRGcm9tSWRlbnRpdHkgPSAoaWRlbnRpdHk6IFByb2Nlc3NJbnN0YW5jZUlkZW50aXR5KTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc2NvcGVLZXkgPSBzY29wZUtleUZyb21TY29wZShpZGVudGl0eS5pZGVudGl0eS5zY29wZSlcbiAgcmV0dXJuIGBwcm9jZXNzOiR7aWRlbnRpdHkuaWRlbnRpdHkucHJvY2Vzc0lkfTo6JHtzY29wZUtleX06OnIke2lkZW50aXR5LnJ1blNlcX1gXG59XG4iLCAiaW1wb3J0IHsgRWZmZWN0LCBGaWJlciwgT3B0aW9uLCBSZWYsIFNjb3BlLCBTdHJlYW0gfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgdHlwZSB7IFRhc2tSdW5uZXJNb2RlIH0gZnJvbSAnLi4vVGFza1J1bm5lci5qcydcbmltcG9ydCB0eXBlIHsgUHJvY2Vzc0NvbmN1cnJlbmN5UG9saWN5LCBQcm9jZXNzVHJpZ2dlciB9IGZyb20gJy4vcHJvdG9jb2wuanMnXG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NFUklBTF9RVUVVRV9HVUFSRF9MSU1JVCA9IDQwOTZcbmV4cG9ydCBjb25zdCBERUZBVUxUX1BBUkFMTEVMX0xJTUlUID0gMTZcblxuZXhwb3J0IGNvbnN0IHRvVGFza1J1bm5lck1vZGUgPSAocG9saWN5OiBQcm9jZXNzQ29uY3VycmVuY3lQb2xpY3kpOiBUYXNrUnVubmVyTW9kZSA9PiB7XG4gIHN3aXRjaCAocG9saWN5Lm1vZGUpIHtcbiAgICBjYXNlICdsYXRlc3QnOlxuICAgICAgcmV0dXJuICdsYXRlc3QnXG4gICAgY2FzZSAnc2VyaWFsJzpcbiAgICAgIHJldHVybiAndGFzaydcbiAgICBjYXNlICdkcm9wJzpcbiAgICAgIHJldHVybiAnZXhoYXVzdCdcbiAgICBjYXNlICdwYXJhbGxlbCc6XG4gICAgICByZXR1cm4gJ3BhcmFsbGVsJ1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIFJlc29sdmVkUXVldWVMaW1pdCA9IHtcbiAgLyoqIFx1NzUyOFx1NjIzN1x1OTE0RFx1N0Y2RVx1NzY4NFx1NEUwQVx1OTY1MFx1RkYxQlx1NjcyQVx1OTE0RFx1N0Y2RVx1NjVGNlx1ODlDNlx1NEUzQSB1bmxpbWl0ZWRcdUZGMDhcdTRGNDZcdTRFQ0RcdTUzRDcgZ3VhcmQgXHU5NjUwXHU1MjM2XHVGRjA5XHUzMDAyICovXG4gIHJlYWRvbmx5IGNvbmZpZ3VyZWQ6IG51bWJlciB8ICd1bmJvdW5kZWQnXG4gIC8qKiBcdThGRDBcdTg4NENcdTY1RjZcdTVCOUVcdTk2NDVcdTc1MUZcdTY1NDhcdTc2ODRcdTYyQTRcdTY4MEZcdTRFMEFcdTk2NTBcdUZGMDhcdTc1MjhcdTRFOEVcdTk2MzJcdTZCNjJcdTY1RTBcdTc1NENcdTUxODVcdTVCNThcdTU4OUVcdTk1N0ZcdUZGMDlcdTMwMDIgKi9cbiAgcmVhZG9ubHkgZ3VhcmQ6IG51bWJlclxufVxuXG5leHBvcnQgY29uc3QgcmVzb2x2ZVF1ZXVlTGltaXQgPSAoXG4gIG1heFF1ZXVlOiB1bmtub3duLFxuICBvcHRpb25zPzoge1xuICAgIHJlYWRvbmx5IGRlZmF1bHRHdWFyZD86IG51bWJlclxuICB9LFxuKTogUmVzb2x2ZWRRdWV1ZUxpbWl0ID0+IHtcbiAgY29uc3QgZGVmYXVsdEd1YXJkID0gb3B0aW9ucz8uZGVmYXVsdEd1YXJkID8/IERFRkFVTFRfU0VSSUFMX1FVRVVFX0dVQVJEX0xJTUlUXG5cbiAgY29uc3QgY29uZmlndXJlZCA9XG4gICAgdHlwZW9mIG1heFF1ZXVlID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUobWF4UXVldWUpICYmIG1heFF1ZXVlID49IDAgPyBNYXRoLmZsb29yKG1heFF1ZXVlKSA6ICd1bmJvdW5kZWQnXG5cbiAgcmV0dXJuIHtcbiAgICBjb25maWd1cmVkLFxuICAgIGd1YXJkOiBjb25maWd1cmVkID09PSAndW5ib3VuZGVkJyA/IGRlZmF1bHRHdWFyZCA6IGNvbmZpZ3VyZWQsXG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgUHJvY2Vzc1RyaWdnZXJRdWV1ZU92ZXJmbG93SW5mbyA9IHtcbiAgcmVhZG9ubHkgbW9kZTogJ3NlcmlhbCcgfCAncGFyYWxsZWwnXG4gIHJlYWRvbmx5IGN1cnJlbnRMZW5ndGg6IG51bWJlclxuICByZWFkb25seSBwZWFrOiBudW1iZXJcbiAgcmVhZG9ubHkgbGltaXQ6IFJlc29sdmVkUXVldWVMaW1pdFxuICByZWFkb25seSBwb2xpY3k6IFByb2Nlc3NDb25jdXJyZW5jeVBvbGljeVxufVxuXG5leHBvcnQgY29uc3QgcnVuUHJvY2Vzc1RyaWdnZXJTdHJlYW0gPSAoYXJnczoge1xuICByZWFkb25seSBzdHJlYW06IFN0cmVhbS5TdHJlYW08UHJvY2Vzc1RyaWdnZXI+XG4gIHJlYWRvbmx5IHBvbGljeTogUHJvY2Vzc0NvbmN1cnJlbmN5UG9saWN5XG4gIHJlYWRvbmx5IGFzc2lnblRyaWdnZXJTZXE6ICh0cmlnZ2VyOiBQcm9jZXNzVHJpZ2dlcikgPT4gUHJvY2Vzc1RyaWdnZXJcbiAgLyoqIHJ1biBhIHRyaWdnZXIgdG8gY29tcGxldGlvbiAodGhlIGNhbGxlciBkZWNpZGVzIHdoYXQgYSBcXFwicnVuXFxcIiBtZWFucykuICovXG4gIHJlYWRvbmx5IHJ1bjogKHRyaWdnZXI6IFByb2Nlc3NUcmlnZ2VyKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBTY29wZS5TY29wZT5cbiAgLyoqIGludm9rZWQgd2hlbiBhIHRyaWdnZXIgaXMgZHJvcHBlZCAob25seSBmb3IgbW9kZT1kcm9wKS4gKi9cbiAgcmVhZG9ubHkgb25Ecm9wOiAodHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZD5cbiAgLyoqIGludm9rZWQgd2hlbiBpbnRlcm5hbCBxdWV1ZSBndWFyZCBpcyBleGNlZWRlZCAoZmFpbC1zdG9wIGJ5IGRlZmF1bHQpLiAqL1xuICByZWFkb25seSBvblF1ZXVlT3ZlcmZsb3c6IChpbmZvOiBQcm9jZXNzVHJpZ2dlclF1ZXVlT3ZlcmZsb3dJbmZvKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQ+XG4gIHJlYWRvbmx5IGRlZmF1bHRQYXJhbGxlbExpbWl0PzogbnVtYmVyXG4gIHJlYWRvbmx5IGRlZmF1bHRRdWV1ZUd1YXJkPzogbnVtYmVyXG59KTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgU2NvcGUuU2NvcGU+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBwb2xpY3kgPSBhcmdzLnBvbGljeVxuICAgIGNvbnN0IGRlZmF1bHRRdWV1ZUd1YXJkID0gYXJncy5kZWZhdWx0UXVldWVHdWFyZCA/PyBERUZBVUxUX1NFUklBTF9RVUVVRV9HVUFSRF9MSU1JVFxuXG4gICAgaWYgKHBvbGljeS5tb2RlID09PSAnbGF0ZXN0Jykge1xuICAgICAgY29uc3Qgc3RhdGVSZWYgPSB5aWVsZCogUmVmLm1ha2U8e1xuICAgICAgICByZWFkb25seSBmaWJlcj86IEZpYmVyLlJ1bnRpbWVGaWJlcjx2b2lkLCBuZXZlcj5cbiAgICAgICAgcmVhZG9ubHkgcnVubmluZ0lkOiBudW1iZXJcbiAgICAgICAgcmVhZG9ubHkgbmV4dElkOiBudW1iZXJcbiAgICAgIH0+KHsgZmliZXI6IHVuZGVmaW5lZCwgcnVubmluZ0lkOiAwLCBuZXh0SWQ6IDAgfSlcblxuICAgICAgY29uc3Qgb25UcmlnZ2VyID0gKHRyaWdnZXIwOiBQcm9jZXNzVHJpZ2dlcik6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIFNjb3BlLlNjb3BlPiA9PlxuICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgY29uc3QgdHJpZ2dlciA9IGFyZ3MuYXNzaWduVHJpZ2dlclNlcSh0cmlnZ2VyMClcblxuICAgICAgICAgIGNvbnN0IFtwcmV2RmliZXIsIHByZXZSdW5uaW5nSWQsIHJ1bklkXSA9IHlpZWxkKiBSZWYubW9kaWZ5KHN0YXRlUmVmLCAocykgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV4dElkID0gcy5uZXh0SWQgKyAxXG4gICAgICAgICAgICByZXR1cm4gW1tzLmZpYmVyLCBzLnJ1bm5pbmdJZCwgbmV4dElkXSBhcyBjb25zdCwgeyAuLi5zLCBuZXh0SWQsIHJ1bm5pbmdJZDogbmV4dElkIH1dIGFzIGNvbnN0XG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGlmIChwcmV2RmliZXIgJiYgcHJldlJ1bm5pbmdJZCAhPT0gMCkge1xuICAgICAgICAgICAgY29uc3QgZG9uZSA9IHlpZWxkKiBGaWJlci5wb2xsKHByZXZGaWJlcilcbiAgICAgICAgICAgIGlmIChPcHRpb24uaXNOb25lKGRvbmUpKSB7XG4gICAgICAgICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHRGb3JrKHByZXZGaWJlcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBmaWJlciA9IHlpZWxkKiBFZmZlY3QuZm9ya1Njb3BlZChcbiAgICAgICAgICAgIGFyZ3NcbiAgICAgICAgICAgICAgLnJ1bih0cmlnZ2VyKVxuICAgICAgICAgICAgICAucGlwZShFZmZlY3QuZW5zdXJpbmcoUmVmLnVwZGF0ZShzdGF0ZVJlZiwgKHMpID0+IChzLnJ1bm5pbmdJZCA9PT0gcnVuSWQgPyB7IC4uLnMsIHJ1bm5pbmdJZDogMCB9IDogcykpKSksXG4gICAgICAgICAgKVxuXG4gICAgICAgICAgeWllbGQqIFJlZi51cGRhdGUoc3RhdGVSZWYsIChzKSA9PiAoeyAuLi5zLCBmaWJlciB9KSlcbiAgICAgICAgfSlcblxuICAgICAgcmV0dXJuIHlpZWxkKiBTdHJlYW0ucnVuRm9yRWFjaChhcmdzLnN0cmVhbSwgb25UcmlnZ2VyKVxuICAgIH1cblxuICAgIGNvbnN0IGJ1c3lSZWYgPSB5aWVsZCogUmVmLm1ha2UoZmFsc2UpXG4gICAgY29uc3Qgc2VyaWFsU3RhdGVSZWYgPSB5aWVsZCogUmVmLm1ha2Uoe1xuICAgICAgcnVubmluZzogZmFsc2UsXG4gICAgICBxdWV1ZTogW10gYXMgUHJvY2Vzc1RyaWdnZXJbXSxcbiAgICAgIHBlYWs6IDAsXG4gICAgfSlcbiAgICBjb25zdCBwYXJhbGxlbFN0YXRlUmVmID0geWllbGQqIFJlZi5tYWtlKHtcbiAgICAgIGFjdGl2ZTogMCxcbiAgICAgIHF1ZXVlOiBbXSBhcyBQcm9jZXNzVHJpZ2dlcltdLFxuICAgICAgcGVhazogMCxcbiAgICB9KVxuXG4gICAgY29uc3Qgc2VyaWFsUXVldWVMaW1pdCA9IHJlc29sdmVRdWV1ZUxpbWl0KHBvbGljeS5tYXhRdWV1ZSwgeyBkZWZhdWx0R3VhcmQ6IGRlZmF1bHRRdWV1ZUd1YXJkIH0pXG4gICAgY29uc3QgcGFyYWxsZWxRdWV1ZUxpbWl0ID0gcmVzb2x2ZVF1ZXVlTGltaXQodW5kZWZpbmVkLCB7IGRlZmF1bHRHdWFyZDogZGVmYXVsdFF1ZXVlR3VhcmQgfSlcbiAgICBjb25zdCBwYXJhbGxlbExpbWl0ID1cbiAgICAgIHR5cGVvZiBwb2xpY3kubWF4UGFyYWxsZWwgPT09ICdudW1iZXInICYmIE51bWJlci5pc0Zpbml0ZShwb2xpY3kubWF4UGFyYWxsZWwpICYmIHBvbGljeS5tYXhQYXJhbGxlbCA+PSAxXG4gICAgICAgID8gTWF0aC5mbG9vcihwb2xpY3kubWF4UGFyYWxsZWwpXG4gICAgICAgIDogKGFyZ3MuZGVmYXVsdFBhcmFsbGVsTGltaXQgPz8gREVGQVVMVF9QQVJBTExFTF9MSU1JVClcblxuICAgIGNvbnN0IGRyYWluU2VyaWFsID0gKCk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIFNjb3BlLlNjb3BlPiA9PlxuICAgICAgRWZmZWN0LnN1c3BlbmQoKCkgPT5cbiAgICAgICAgUmVmLm1vZGlmeShzZXJpYWxTdGF0ZVJlZiwgKHN0YXRlKSA9PiB7XG4gICAgICAgICAgaWYgKHN0YXRlLnJ1bm5pbmcgfHwgc3RhdGUucXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gW09wdGlvbi5ub25lKCksIHN0YXRlXSBhcyBjb25zdFxuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBbbmV4dCwgLi4ucmVzdF0gPSBzdGF0ZS5xdWV1ZVxuICAgICAgICAgIHJldHVybiBbT3B0aW9uLnNvbWUobmV4dCksIHsgLi4uc3RhdGUsIHJ1bm5pbmc6IHRydWUsIHF1ZXVlOiByZXN0IH1dIGFzIGNvbnN0XG4gICAgICAgIH0pLnBpcGUoXG4gICAgICAgICAgRWZmZWN0LmZsYXRNYXAoKG5leHQpID0+XG4gICAgICAgICAgICBPcHRpb24ubWF0Y2gobmV4dCwge1xuICAgICAgICAgICAgICBvbk5vbmU6ICgpID0+IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgICBvblNvbWU6ICh0cmlnZ2VyKSA9PlxuICAgICAgICAgICAgICAgIEVmZmVjdC5mb3JrU2NvcGVkKFxuICAgICAgICAgICAgICAgICAgYXJnc1xuICAgICAgICAgICAgICAgICAgICAucnVuKHRyaWdnZXIpXG4gICAgICAgICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgIEVmZmVjdC5lbnN1cmluZyhSZWYudXBkYXRlKHNlcmlhbFN0YXRlUmVmLCAocykgPT4gKHsgLi4ucywgcnVubmluZzogZmFsc2UgfSkpKSxcbiAgICAgICAgICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQoZHJhaW5TZXJpYWwoKSksXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKS5waXBlKEVmZmVjdC5hc1ZvaWQpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgKSxcbiAgICAgIClcblxuICAgIGNvbnN0IGRyYWluUGFyYWxsZWwgPSAoKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgU2NvcGUuU2NvcGU+ID0+XG4gICAgICBFZmZlY3Quc3VzcGVuZCgoKSA9PlxuICAgICAgICBSZWYubW9kaWZ5KHBhcmFsbGVsU3RhdGVSZWYsIChzdGF0ZSkgPT4ge1xuICAgICAgICAgIGlmIChzdGF0ZS5hY3RpdmUgPj0gcGFyYWxsZWxMaW1pdCB8fCBzdGF0ZS5xdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBbT3B0aW9uLm5vbmUoKSwgc3RhdGVdIGFzIGNvbnN0XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IFtuZXh0LCAuLi5yZXN0XSA9IHN0YXRlLnF1ZXVlXG4gICAgICAgICAgcmV0dXJuIFtPcHRpb24uc29tZShuZXh0KSwgeyAuLi5zdGF0ZSwgYWN0aXZlOiBzdGF0ZS5hY3RpdmUgKyAxLCBxdWV1ZTogcmVzdCB9XSBhcyBjb25zdFxuICAgICAgICB9KS5waXBlKFxuICAgICAgICAgIEVmZmVjdC5mbGF0TWFwKChuZXh0KSA9PlxuICAgICAgICAgICAgT3B0aW9uLm1hdGNoKG5leHQsIHtcbiAgICAgICAgICAgICAgb25Ob25lOiAoKSA9PiBFZmZlY3Qudm9pZCxcbiAgICAgICAgICAgICAgb25Tb21lOiAodHJpZ2dlcikgPT5cbiAgICAgICAgICAgICAgICBFZmZlY3QuZm9ya1Njb3BlZChcbiAgICAgICAgICAgICAgICAgIGFyZ3MucnVuKHRyaWdnZXIpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgIEVmZmVjdC5lbnN1cmluZyhcbiAgICAgICAgICAgICAgICAgICAgICBSZWYudXBkYXRlKHBhcmFsbGVsU3RhdGVSZWYsIChzKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZTogTWF0aC5tYXgoMCwgcy5hY3RpdmUgLSAxKSxcbiAgICAgICAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIEVmZmVjdC56aXBSaWdodChkcmFpblBhcmFsbGVsKCkpLFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICApLnBpcGUoRWZmZWN0LmFzVm9pZCwgRWZmZWN0LnppcFJpZ2h0KGRyYWluUGFyYWxsZWwoKSkpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgKSxcbiAgICAgIClcblxuICAgIGNvbnN0IG9uVHJpZ2dlciA9ICh0cmlnZ2VyMDogUHJvY2Vzc1RyaWdnZXIpOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBTY29wZS5TY29wZT4gPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgdHJpZ2dlciA9IGFyZ3MuYXNzaWduVHJpZ2dlclNlcSh0cmlnZ2VyMClcblxuICAgICAgICBpZiAocG9saWN5Lm1vZGUgPT09ICdkcm9wJykge1xuICAgICAgICAgIGNvbnN0IGFjcXVpcmVkID0geWllbGQqIFJlZi5tb2RpZnkoYnVzeVJlZiwgKGJ1c3kpID0+XG4gICAgICAgICAgICBidXN5ID8gKFtmYWxzZSwgYnVzeV0gYXMgY29uc3QpIDogKFt0cnVlLCB0cnVlXSBhcyBjb25zdCksXG4gICAgICAgICAgKVxuICAgICAgICAgIGlmICghYWNxdWlyZWQpIHtcbiAgICAgICAgICAgIHlpZWxkKiBhcmdzLm9uRHJvcCh0cmlnZ2VyKVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgeWllbGQqIEVmZmVjdC5mb3JrU2NvcGVkKGFyZ3MucnVuKHRyaWdnZXIpLnBpcGUoRWZmZWN0LmVuc3VyaW5nKFJlZi5zZXQoYnVzeVJlZiwgZmFsc2UpKSkpXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9saWN5Lm1vZGUgPT09ICdwYXJhbGxlbCcpIHtcbiAgICAgICAgICBjb25zdCBuZXh0U2l6ZSA9IHlpZWxkKiBSZWYubW9kaWZ5KHBhcmFsbGVsU3RhdGVSZWYsIChzdGF0ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcXVldWUgPSBbLi4uc3RhdGUucXVldWUsIHRyaWdnZXJdXG4gICAgICAgICAgICByZXR1cm4gW3F1ZXVlLmxlbmd0aCwgeyAuLi5zdGF0ZSwgcXVldWUsIHBlYWs6IE1hdGgubWF4KHN0YXRlLnBlYWssIHF1ZXVlLmxlbmd0aCkgfV0gYXMgY29uc3RcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgaWYgKG5leHRTaXplID4gcGFyYWxsZWxRdWV1ZUxpbWl0Lmd1YXJkKSB7XG4gICAgICAgICAgICBjb25zdCBzdGF0ZSA9IHlpZWxkKiBSZWYuZ2V0KHBhcmFsbGVsU3RhdGVSZWYpXG4gICAgICAgICAgICB5aWVsZCogYXJncy5vblF1ZXVlT3ZlcmZsb3coe1xuICAgICAgICAgICAgICBtb2RlOiAncGFyYWxsZWwnLFxuICAgICAgICAgICAgICBjdXJyZW50TGVuZ3RoOiBuZXh0U2l6ZSxcbiAgICAgICAgICAgICAgcGVhazogc3RhdGUucGVhayxcbiAgICAgICAgICAgICAgbGltaXQ6IHBhcmFsbGVsUXVldWVMaW1pdCxcbiAgICAgICAgICAgICAgcG9saWN5LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cblxuICAgICAgICAgIHlpZWxkKiBkcmFpblBhcmFsbGVsKClcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNlcmlhbFxuICAgICAgICBjb25zdCBuZXh0U2l6ZSA9IHlpZWxkKiBSZWYubW9kaWZ5KHNlcmlhbFN0YXRlUmVmLCAoc3RhdGUpID0+IHtcbiAgICAgICAgICBjb25zdCBxdWV1ZSA9IFsuLi5zdGF0ZS5xdWV1ZSwgdHJpZ2dlcl1cbiAgICAgICAgICByZXR1cm4gW3F1ZXVlLmxlbmd0aCwgeyAuLi5zdGF0ZSwgcXVldWUsIHBlYWs6IE1hdGgubWF4KHN0YXRlLnBlYWssIHF1ZXVlLmxlbmd0aCkgfV0gYXMgY29uc3RcbiAgICAgICAgfSlcblxuICAgICAgICBpZiAobmV4dFNpemUgPiBzZXJpYWxRdWV1ZUxpbWl0Lmd1YXJkKSB7XG4gICAgICAgICAgY29uc3Qgc3RhdGUgPSB5aWVsZCogUmVmLmdldChzZXJpYWxTdGF0ZVJlZilcbiAgICAgICAgICB5aWVsZCogYXJncy5vblF1ZXVlT3ZlcmZsb3coe1xuICAgICAgICAgICAgbW9kZTogJ3NlcmlhbCcsXG4gICAgICAgICAgICBjdXJyZW50TGVuZ3RoOiBuZXh0U2l6ZSxcbiAgICAgICAgICAgIHBlYWs6IHN0YXRlLnBlYWssXG4gICAgICAgICAgICBsaW1pdDogc2VyaWFsUXVldWVMaW1pdCxcbiAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgeWllbGQqIGRyYWluU2VyaWFsKClcbiAgICAgIH0pXG5cbiAgICByZXR1cm4geWllbGQqIFN0cmVhbS5ydW5Gb3JFYWNoKGFyZ3Muc3RyZWFtLCBvblRyaWdnZXIpXG4gIH0pXG4iLCAiaW1wb3J0IHR5cGUgeyBQcm9jZXNzRXZlbnQgfSBmcm9tICcuL3Byb3RvY29sLmpzJ1xuXG5leHBvcnQgY29uc3QgUFJPQ0VTU19FVkVOVF9NQVhfQllURVMgPSA0ICogMTAyNFxuZXhwb3J0IGNvbnN0IFBST0NFU1NfRVZFTlRfTUFYX0VWRU5UU19QRVJfUlVOID0gNTBcbmV4cG9ydCBjb25zdCBQUk9DRVNTX0VWRU5UX1JFU0VSVkVEX0VWRU5UU19GT1JfU1VNTUFSWSA9IDFcblxuZXhwb3J0IHR5cGUgUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0U3RhdGUgPSB7XG4gIHJlYWRvbmx5IG1heEV2ZW50czogbnVtYmVyXG4gIHJlYWRvbmx5IG1heEJ5dGVzOiBudW1iZXJcbiAgcmVhZG9ubHkgZW1pdHRlZDogbnVtYmVyXG4gIHJlYWRvbmx5IGRyb3BwZWQ6IG51bWJlclxuICByZWFkb25seSBkb3duZ3JhZGVkOiBudW1iZXJcbiAgcmVhZG9ubHkgc3VtbWFyeUVtaXR0ZWQ6IGJvb2xlYW5cbn1cblxuZXhwb3J0IGNvbnN0IG1ha2VQcm9jZXNzUnVuRXZlbnRCdWRnZXRTdGF0ZSA9IChvcHRpb25zPzoge1xuICByZWFkb25seSBtYXhFdmVudHM/OiBudW1iZXJcbiAgcmVhZG9ubHkgbWF4Qnl0ZXM/OiBudW1iZXJcbn0pOiBQcm9jZXNzUnVuRXZlbnRCdWRnZXRTdGF0ZSA9PiAoe1xuICBtYXhFdmVudHM6XG4gICAgdHlwZW9mIG9wdGlvbnM/Lm1heEV2ZW50cyA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKG9wdGlvbnMubWF4RXZlbnRzKSAmJiBvcHRpb25zLm1heEV2ZW50cyA+PSAwXG4gICAgICA/IE1hdGguZmxvb3Iob3B0aW9ucy5tYXhFdmVudHMpXG4gICAgICA6IFBST0NFU1NfRVZFTlRfTUFYX0VWRU5UU19QRVJfUlVOLFxuICBtYXhCeXRlczpcbiAgICB0eXBlb2Ygb3B0aW9ucz8ubWF4Qnl0ZXMgPT09ICdudW1iZXInICYmIE51bWJlci5pc0Zpbml0ZShvcHRpb25zLm1heEJ5dGVzKSAmJiBvcHRpb25zLm1heEJ5dGVzID49IDBcbiAgICAgID8gTWF0aC5mbG9vcihvcHRpb25zLm1heEJ5dGVzKVxuICAgICAgOiBQUk9DRVNTX0VWRU5UX01BWF9CWVRFUyxcbiAgZW1pdHRlZDogMCxcbiAgZHJvcHBlZDogMCxcbiAgZG93bmdyYWRlZDogMCxcbiAgc3VtbWFyeUVtaXR0ZWQ6IGZhbHNlLFxufSlcblxuZXhwb3J0IHR5cGUgUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0RGVjaXNpb24gPVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IF90YWc6ICdlbWl0J1xuICAgICAgcmVhZG9ubHkgZXZlbnQ6IFByb2Nlc3NFdmVudFxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBfdGFnOiAnZW1pdFN1bW1hcnknXG4gICAgICByZWFkb25seSBldmVudDogUHJvY2Vzc0V2ZW50XG4gICAgfVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IF90YWc6ICdkcm9wJ1xuICAgIH1cblxuY29uc3QgbWFrZUJ1ZGdldFN1bW1hcnlFdmVudCA9IChhcmdzOiB7XG4gIHJlYWRvbmx5IHNvdXJjZUV2ZW50OiBQcm9jZXNzRXZlbnRcbiAgcmVhZG9ubHkgbWF4RXZlbnRzOiBudW1iZXJcbiAgcmVhZG9ubHkgbWF4Qnl0ZXM6IG51bWJlclxuICByZWFkb25seSBlbWl0dGVkOiBudW1iZXJcbiAgcmVhZG9ubHkgZHJvcHBlZDogbnVtYmVyXG4gIHJlYWRvbmx5IGRvd25ncmFkZWQ6IG51bWJlclxufSk6IFByb2Nlc3NFdmVudCA9PiAoe1xuICB0eXBlOiAncHJvY2Vzczp0cmlnZ2VyJyxcbiAgaWRlbnRpdHk6IGFyZ3Muc291cmNlRXZlbnQuaWRlbnRpdHksXG4gIHRyaWdnZXI6IGFyZ3Muc291cmNlRXZlbnQudHJpZ2dlcixcbiAgc2V2ZXJpdHk6ICd3YXJuaW5nJyxcbiAgZXZlbnRTZXE6IGFyZ3Muc291cmNlRXZlbnQuZXZlbnRTZXEsXG4gIHRpbWVzdGFtcE1zOiBhcmdzLnNvdXJjZUV2ZW50LnRpbWVzdGFtcE1zLFxuICBlcnJvcjoge1xuICAgIG1lc3NhZ2U6ICdQcm9jZXNzIHJ1biBldmVudCBidWRnZXQgZXhjZWVkZWQ7IGZ1cnRoZXIgdHJpZ2dlci9kaXNwYXRjaCBldmVudHMgYXJlIHN1cHByZXNzZWQuJyxcbiAgICBjb2RlOiAncHJvY2Vzczo6ZXZlbnRfYnVkZ2V0X2V4Y2VlZGVkJyxcbiAgICBoaW50OiBgbWF4RXZlbnRzPSR7YXJncy5tYXhFdmVudHN9IG1heEJ5dGVzPSR7YXJncy5tYXhCeXRlc30gZW1pdHRlZD0ke2FyZ3MuZW1pdHRlZH0gZHJvcHBlZD0ke2FyZ3MuZHJvcHBlZH0gZG93bmdyYWRlZD0ke2FyZ3MuZG93bmdyYWRlZH1gLFxuICB9LFxufSlcblxuZXhwb3J0IGNvbnN0IGFwcGx5UHJvY2Vzc1J1bkV2ZW50QnVkZ2V0ID0gKFxuICBzdGF0ZTogUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0U3RhdGUsXG4gIGV2ZW50OiBQcm9jZXNzRXZlbnQsXG4pOiByZWFkb25seSBbUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0RGVjaXNpb24sIFByb2Nlc3NSdW5FdmVudEJ1ZGdldFN0YXRlXSA9PiB7XG4gIGNvbnN0IG1heEV2ZW50cyA9IE1hdGgubWF4KDAsIHN0YXRlLm1heEV2ZW50cylcbiAgY29uc3QgbWF4Qnl0ZXMgPSBNYXRoLm1heCgwLCBzdGF0ZS5tYXhCeXRlcylcblxuICBpZiAoc3RhdGUuc3VtbWFyeUVtaXR0ZWQpIHtcbiAgICByZXR1cm4gW1xuICAgICAgeyBfdGFnOiAnZHJvcCcgfSxcbiAgICAgIHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIGRyb3BwZWQ6IHN0YXRlLmRyb3BwZWQgKyAxLFxuICAgICAgfSxcbiAgICBdXG4gIH1cblxuICBjb25zdCByZXNlcnZlID0gUFJPQ0VTU19FVkVOVF9SRVNFUlZFRF9FVkVOVFNfRk9SX1NVTU1BUllcbiAgY29uc3QgYWxsb3dlZFJlZ3VsYXIgPSBNYXRoLm1heCgwLCBtYXhFdmVudHMgLSByZXNlcnZlKVxuXG4gIGlmIChzdGF0ZS5lbWl0dGVkIDwgYWxsb3dlZFJlZ3VsYXIpIHtcbiAgICBjb25zdCBlbmZvcmNlZCA9IGVuZm9yY2VQcm9jZXNzRXZlbnRNYXhCeXRlcyhldmVudCwgeyBtYXhCeXRlcyB9KVxuICAgIHJldHVybiBbXG4gICAgICB7IF90YWc6ICdlbWl0JywgZXZlbnQ6IGVuZm9yY2VkLmV2ZW50IH0sXG4gICAgICB7XG4gICAgICAgIC4uLnN0YXRlLFxuICAgICAgICBlbWl0dGVkOiBzdGF0ZS5lbWl0dGVkICsgMSxcbiAgICAgICAgZG93bmdyYWRlZDogc3RhdGUuZG93bmdyYWRlZCArIChlbmZvcmNlZC5kb3duZ3JhZGVkID8gMSA6IDApLFxuICAgICAgfSxcbiAgICBdXG4gIH1cblxuICBjb25zdCBkcm9wcGVkID0gc3RhdGUuZHJvcHBlZCArIDFcbiAgY29uc3Qgc3VtbWFyeSA9IG1ha2VCdWRnZXRTdW1tYXJ5RXZlbnQoe1xuICAgIHNvdXJjZUV2ZW50OiBldmVudCxcbiAgICBtYXhFdmVudHMsXG4gICAgbWF4Qnl0ZXMsXG4gICAgZW1pdHRlZDogc3RhdGUuZW1pdHRlZCxcbiAgICBkcm9wcGVkLFxuICAgIGRvd25ncmFkZWQ6IHN0YXRlLmRvd25ncmFkZWQsXG4gIH0pXG4gIGNvbnN0IGVuZm9yY2VkU3VtbWFyeSA9IGVuZm9yY2VQcm9jZXNzRXZlbnRNYXhCeXRlcyhzdW1tYXJ5LCB7IG1heEJ5dGVzIH0pXG5cbiAgcmV0dXJuIFtcbiAgICB7IF90YWc6ICdlbWl0U3VtbWFyeScsIGV2ZW50OiBlbmZvcmNlZFN1bW1hcnkuZXZlbnQgfSxcbiAgICB7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIGVtaXR0ZWQ6IE1hdGgubWluKG1heEV2ZW50cywgc3RhdGUuZW1pdHRlZCArIDEpLFxuICAgICAgZHJvcHBlZCxcbiAgICAgIGRvd25ncmFkZWQ6IHN0YXRlLmRvd25ncmFkZWQgKyAoZW5mb3JjZWRTdW1tYXJ5LmRvd25ncmFkZWQgPyAxIDogMCksXG4gICAgICBzdW1tYXJ5RW1pdHRlZDogdHJ1ZSxcbiAgICB9LFxuICBdXG59XG5cbmV4cG9ydCBjb25zdCBlc3RpbWF0ZUV2ZW50Qnl0ZXMgPSAoZXZlbnQ6IFByb2Nlc3NFdmVudCk6IG51bWJlciA9PiB7XG4gIGNvbnN0IGpzb24gPSBKU09OLnN0cmluZ2lmeShldmVudClcbiAgcmV0dXJuIHR5cGVvZiBCdWZmZXIgIT09ICd1bmRlZmluZWQnID8gQnVmZmVyLmJ5dGVMZW5ndGgoanNvbiwgJ3V0ZjgnKSA6IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShqc29uKS5sZW5ndGhcbn1cblxuY29uc3QgdHJ1bmNhdGVDaGFycyA9ICh2YWx1ZTogc3RyaW5nLCBtYXhMZW46IG51bWJlcik6IHN0cmluZyA9PlxuICB2YWx1ZS5sZW5ndGggPD0gbWF4TGVuID8gdmFsdWUgOiB2YWx1ZS5zbGljZSgwLCBtYXhMZW4pXG5cbmNvbnN0IG5vcm1hbGl6ZUVycm9yU3VtbWFyeSA9IChlcnJvcjogTm9uTnVsbGFibGU8UHJvY2Vzc0V2ZW50WydlcnJvciddPik6IE5vbk51bGxhYmxlPFByb2Nlc3NFdmVudFsnZXJyb3InXT4gPT4ge1xuICBjb25zdCBtZXNzYWdlID0gdHlwZW9mIGVycm9yLm1lc3NhZ2UgPT09ICdzdHJpbmcnICYmIGVycm9yLm1lc3NhZ2UubGVuZ3RoID4gMCA/IGVycm9yLm1lc3NhZ2UgOiAnRXJyb3InXG5cbiAgY29uc3QgaGludCA9IHR5cGVvZiBlcnJvci5oaW50ID09PSAnc3RyaW5nJyAmJiBlcnJvci5oaW50Lmxlbmd0aCA+IDAgPyB0cnVuY2F0ZUNoYXJzKGVycm9yLmhpbnQsIDEwMjQpIDogdW5kZWZpbmVkXG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiB0eXBlb2YgZXJyb3IubmFtZSA9PT0gJ3N0cmluZycgJiYgZXJyb3IubmFtZS5sZW5ndGggPiAwID8gZXJyb3IubmFtZSA6IHVuZGVmaW5lZCxcbiAgICBtZXNzYWdlOiB0cnVuY2F0ZUNoYXJzKG1lc3NhZ2UsIDI1NiksXG4gICAgY29kZTogdHlwZW9mIGVycm9yLmNvZGUgPT09ICdzdHJpbmcnICYmIGVycm9yLmNvZGUubGVuZ3RoID4gMCA/IGVycm9yLmNvZGUgOiB1bmRlZmluZWQsXG4gICAgaGludCxcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZW5mb3JjZVByb2Nlc3NFdmVudE1heEJ5dGVzID0gKFxuICBldmVudDogUHJvY2Vzc0V2ZW50LFxuICBvcHRpb25zPzoge1xuICAgIHJlYWRvbmx5IG1heEJ5dGVzPzogbnVtYmVyXG4gIH0sXG4pOiB7IHJlYWRvbmx5IGV2ZW50OiBQcm9jZXNzRXZlbnQ7IHJlYWRvbmx5IGRvd25ncmFkZWQ6IGJvb2xlYW4gfSA9PiB7XG4gIGNvbnN0IG1heEJ5dGVzID0gb3B0aW9ucz8ubWF4Qnl0ZXMgPz8gUFJPQ0VTU19FVkVOVF9NQVhfQllURVNcblxuICBsZXQgZG93bmdyYWRlZCA9IGZhbHNlXG4gIGxldCBuZXh0OiBQcm9jZXNzRXZlbnQgPSBldmVudFxuXG4gIGlmIChldmVudC5lcnJvcikge1xuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVFcnJvclN1bW1hcnkoZXZlbnQuZXJyb3IpXG4gICAgaWYgKFxuICAgICAgbm9ybWFsaXplZC5tZXNzYWdlICE9PSBldmVudC5lcnJvci5tZXNzYWdlIHx8XG4gICAgICBub3JtYWxpemVkLmhpbnQgIT09IGV2ZW50LmVycm9yLmhpbnQgfHxcbiAgICAgIG5vcm1hbGl6ZWQuY29kZSAhPT0gZXZlbnQuZXJyb3IuY29kZSB8fFxuICAgICAgbm9ybWFsaXplZC5uYW1lICE9PSBldmVudC5lcnJvci5uYW1lXG4gICAgKSB7XG4gICAgICBkb3duZ3JhZGVkID0gdHJ1ZVxuICAgICAgbmV4dCA9IHsgLi4uZXZlbnQsIGVycm9yOiBub3JtYWxpemVkIH1cbiAgICB9XG4gIH1cblxuICBpZiAoZXN0aW1hdGVFdmVudEJ5dGVzKG5leHQpIDw9IG1heEJ5dGVzKSB7XG4gICAgcmV0dXJuIHsgZXZlbnQ6IG5leHQsIGRvd25ncmFkZWQgfVxuICB9XG5cbiAgLy8gXHU0RUM1XHU1QkY5IGVycm9yLmhpbnQgXHU1MDVBXHU4RkRCXHU0RTAwXHU2QjY1XHU3Njg0XHU5MDEwXHU2QjY1XHU4OEMxXHU1MjZBXHVGRjA4XHU4OUU2XHU1M0QxXHU3MEI5XHU5MDFBXHU1RTM4XHU2NjJGIG11bHRpLWxpbmUgaGludFx1RkYwOVx1MzAwMlxuICBpZiAoIW5leHQuZXJyb3I/LmhpbnQpIHtcbiAgICAvLyBcdTVERjJcdTY1RTBcdTUzRUZcdTg4QzFcdTUyNkFcdTVCNTdcdTZCQjVcdUZGMUJiZXN0LWVmZm9ydCBcdThGRDRcdTU2REVcdTMwMDJcbiAgICByZXR1cm4geyBldmVudDogbmV4dCwgZG93bmdyYWRlZDogdHJ1ZSB9XG4gIH1cblxuICBjb25zdCBoaW50ID0gbmV4dC5lcnJvci5oaW50XG4gIGNvbnN0IHN0ZXBzID0gWzUxMiwgMjU2LCAxMjgsIDY0LCAzMiwgMF1cblxuICBmb3IgKGNvbnN0IG1heExlbiBvZiBzdGVwcykge1xuICAgIGNvbnN0IHRyaW1tZWQgPSBtYXhMZW4gPT09IDAgPyB1bmRlZmluZWQgOiB0cnVuY2F0ZUNoYXJzKGhpbnQsIG1heExlbilcbiAgICBjb25zdCBjYW5kaWRhdGU6IFByb2Nlc3NFdmVudCA9IHtcbiAgICAgIC4uLm5leHQsXG4gICAgICBlcnJvcjoge1xuICAgICAgICAuLi5uZXh0LmVycm9yLFxuICAgICAgICBoaW50OiB0cmltbWVkLFxuICAgICAgfSxcbiAgICB9XG4gICAgaWYgKGVzdGltYXRlRXZlbnRCeXRlcyhjYW5kaWRhdGUpIDw9IG1heEJ5dGVzKSB7XG4gICAgICByZXR1cm4geyBldmVudDogY2FuZGlkYXRlLCBkb3duZ3JhZGVkOiB0cnVlIH1cbiAgICB9XG4gIH1cblxuICAvLyBcdTUxNUNcdTVFOTVcdUZGMUFcdTc5RkJcdTk2NjQgaGludFx1RkYwQ1x1N0YyOVx1NzdFRCBtZXNzYWdlXHVGRjA4XHU0RkREXHU4QkMxIHByb2Nlc3M6ZXJyb3IgXHU0RUNEXHU2NzA5IG1lc3NhZ2VcdUZGMDlcdTMwMDJcbiAgY29uc3QgZmFsbGJhY2s6IFByb2Nlc3NFdmVudCA9IG5leHQuZXJyb3JcbiAgICA/ICh7XG4gICAgICAgIC4uLm5leHQsXG4gICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgLi4ubmV4dC5lcnJvcixcbiAgICAgICAgICBtZXNzYWdlOiB0cnVuY2F0ZUNoYXJzKG5leHQuZXJyb3IubWVzc2FnZSwgOTYpLFxuICAgICAgICAgIGhpbnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgfSxcbiAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NFdmVudClcbiAgICA6IG5leHRcblxuICByZXR1cm4geyBldmVudDogZmFsbGJhY2ssIGRvd25ncmFkZWQ6IHRydWUgfVxufVxuIiwgImltcG9ydCAqIGFzIFNjaGVtYUFTVCBmcm9tICdlZmZlY3QvU2NoZW1hQVNUJ1xuXG5leHBvcnQgdHlwZSBEb3RQYXRoU2VnbWVudCA9IHN0cmluZyB8IG51bWJlclxuXG50eXBlIERvdFBhdGhQYXJzZVJlc3VsdCA9XG4gIHwgeyByZWFkb25seSBvazogdHJ1ZTsgcmVhZG9ubHkgc2VnbWVudHM6IFJlYWRvbmx5QXJyYXk8RG90UGF0aFNlZ21lbnQ+IH1cbiAgfCB7IHJlYWRvbmx5IG9rOiBmYWxzZTsgcmVhZG9ubHkgZXJyb3I6IEVycm9yIH1cblxuZXhwb3J0IHR5cGUgRG90UGF0aFNlbGVjdG9yUmVzdWx0ID1cbiAgfCB7XG4gICAgICByZWFkb25seSBvazogdHJ1ZVxuICAgICAgcmVhZG9ubHkgc2VsZWN0b3I6IChzdGF0ZTogdW5rbm93bikgPT4gdW5rbm93blxuICAgICAgcmVhZG9ubHkgc2VnbWVudHM6IFJlYWRvbmx5QXJyYXk8RG90UGF0aFNlZ21lbnQ+XG4gICAgfVxuICB8IHsgcmVhZG9ubHkgb2s6IGZhbHNlOyByZWFkb25seSBlcnJvcjogRXJyb3IgfVxuXG5jb25zdCBpc1JlY29yZCA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGxcblxuZXhwb3J0IGNvbnN0IHJlc29sdmVTY2hlbWFBc3QgPSAoc2NoZW1hOiB1bmtub3duKTogU2NoZW1hQVNULkFTVCB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmICghaXNSZWNvcmQoc2NoZW1hKSkgcmV0dXJuIHVuZGVmaW5lZFxuICBjb25zdCBhc3QgPSAoc2NoZW1hIGFzIGFueSkuYXN0IGFzIFNjaGVtYUFTVC5BU1QgfCB1bmRlZmluZWRcbiAgaWYgKCFhc3QpIHJldHVybiB1bmRlZmluZWRcbiAgaWYgKHR5cGVvZiBhc3QgIT09ICdvYmplY3QnICYmIHR5cGVvZiBhc3QgIT09ICdmdW5jdGlvbicpIHJldHVybiB1bmRlZmluZWRcbiAgcmV0dXJuIGFzdFxufVxuXG5jb25zdCBtYWtlRG90UGF0aEVycm9yID0gKHBhdGg6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBoaW50Pzogc3RyaW5nKTogRXJyb3IgPT4ge1xuICBjb25zdCBlcnIgPSBuZXcgRXJyb3IobWVzc2FnZSlcbiAgOyhlcnIgYXMgYW55KS5jb2RlID0gJ3Byb2Nlc3M6OmludmFsaWRfZG90X3BhdGgnXG4gIDsoZXJyIGFzIGFueSkuaGludCA9XG4gICAgaGludCA/P1xuICAgIFtcbiAgICAgIFwiRXhwZWN0ZWQgZG90LXBhdGggc3ludGF4OiBzZWdtZW50cyBzZXBhcmF0ZWQgYnkgJy4nLCBudW1lcmljIHNlZ21lbnRzIHJlcHJlc2VudCBhcnJheSBpbmRpY2VzLlwiLFxuICAgICAgYHBhdGg6ICR7cGF0aH1gLFxuICAgICAgJycsXG4gICAgICAnZXhhbXBsZXM6JyxcbiAgICAgICctIGNvdW50JyxcbiAgICAgICctIHVzZXIubmFtZScsXG4gICAgICAnLSBpdGVtcy4wLmlkJyxcbiAgICBdLmpvaW4oJ1xcbicpXG4gIHJldHVybiBlcnJcbn1cblxuY29uc3QgbWFrZVNjaGVtYU1pc21hdGNoRXJyb3IgPSAocGF0aDogc3RyaW5nKTogRXJyb3IgPT5cbiAgbWFrZURvdFBhdGhFcnJvcihcbiAgICBwYXRoLFxuICAgICdJbnZhbGlkIGRvdC1wYXRoOiBwYXRoIGRvZXMgbm90IG1hdGNoIHRoZSBzdGF0ZSBzY2hlbWEuJyxcbiAgICBbXG4gICAgICAnVGhlIG1vZHVsZSBzdGF0ZSBzY2hlbWEgZG9lcyBub3QgY29udGFpbiB0aGUgcmVxdWVzdGVkIGRvdC1wYXRoLicsXG4gICAgICBgcGF0aDogJHtwYXRofWAsXG4gICAgICAnJyxcbiAgICAgICdmaXg6JyxcbiAgICAgICctIEVuc3VyZSB0aGUgcGF0aCBleGlzdHMgaW4gdGhlIHN0YXRlIHNjaGVtYS4nLFxuICAgICAgJy0gVXNlIG51bWVyaWMgc2VnbWVudHMgZm9yIGFycmF5IGluZGljZXMgKGUuZy4gaXRlbXMuMC5pZCkuJyxcbiAgICBdLmpvaW4oJ1xcbicpLFxuICApXG5cbmNvbnN0IHBhcnNlRG90UGF0aCA9IChwYXRoOiBzdHJpbmcpOiBEb3RQYXRoUGFyc2VSZXN1bHQgPT4ge1xuICBpZiAodHlwZW9mIHBhdGggIT09ICdzdHJpbmcnIHx8IHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHsgb2s6IGZhbHNlLCBlcnJvcjogbWFrZURvdFBhdGhFcnJvcihTdHJpbmcocGF0aCksICdkb3QtcGF0aCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpIH1cbiAgfVxuXG4gIGNvbnN0IHJhdyA9IHBhdGguc3BsaXQoJy4nKVxuICBpZiAocmF3Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IG1ha2VEb3RQYXRoRXJyb3IocGF0aCwgJ2RvdC1wYXRoIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgc2VnbWVudCcpIH1cbiAgfVxuXG4gIGNvbnN0IHNlZ21lbnRzOiBEb3RQYXRoU2VnbWVudFtdID0gW11cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYXcubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzZWcgPSByYXdbaV0hXG4gICAgaWYgKHNlZy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgZXJyb3I6IG1ha2VEb3RQYXRoRXJyb3IoXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICBgSW52YWxpZCBkb3QtcGF0aDogZW1wdHkgc2VnbWVudCBhdCBpbmRleCAke2l9LmAsXG4gICAgICAgICAgW1xuICAgICAgICAgICAgXCJFeHBlY3RlZCBkb3QtcGF0aCBzeW50YXg6IHNlZ21lbnRzIHNlcGFyYXRlZCBieSAnLicsIG51bWVyaWMgc2VnbWVudHMgcmVwcmVzZW50IGFycmF5IGluZGljZXMuXCIsXG4gICAgICAgICAgICBgcGF0aDogJHtwYXRofWAsXG4gICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICdleGFtcGxlczonLFxuICAgICAgICAgICAgJy0gY291bnQnLFxuICAgICAgICAgICAgJy0gdXNlci5uYW1lJyxcbiAgICAgICAgICAgICctIGl0ZW1zLjAuaWQnLFxuICAgICAgICAgICAgJycsXG4gICAgICAgICAgICAnZml4OicsXG4gICAgICAgICAgICAnLSBSZW1vdmUgY29uc2VjdXRpdmUgZG90cyBvciB0cmFpbGluZyBkb3RzLicsXG4gICAgICAgICAgXS5qb2luKCdcXG4nKSxcbiAgICAgICAgKSxcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoL15bMC05XSskLy50ZXN0KHNlZykpIHtcbiAgICAgIGNvbnN0IG4gPSBOdW1iZXIoc2VnKVxuICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobikgfHwgbiA8IDApIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvazogZmFsc2UsXG4gICAgICAgICAgZXJyb3I6IG1ha2VEb3RQYXRoRXJyb3IocGF0aCwgYEludmFsaWQgYXJyYXkgaW5kZXggc2VnbWVudCBcIiR7c2VnfVwiIGF0IGluZGV4ICR7aX0uYCksXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNlZ21lbnRzLnB1c2goTWF0aC5mbG9vcihuKSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgc2VnbWVudHMucHVzaChzZWcpXG4gIH1cblxuICByZXR1cm4geyBvazogdHJ1ZSwgc2VnbWVudHMgfVxufVxuXG5jb25zdCByZXNvbHZlQXN0Rm9yUGF0aCA9IChcbiAgYXN0OiBTY2hlbWFBU1QuQVNULFxuICBzZWdtZW50czogUmVhZG9ubHlBcnJheTxEb3RQYXRoU2VnbWVudD4sXG4gIHNlZW46IFNldDxTY2hlbWFBU1QuQVNUPixcbik6IFNjaGVtYUFTVC5BU1QgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoc2VnbWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gYXN0XG5cbiAgbGV0IGN1cnJlbnQgPSBhc3RcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoU2NoZW1hQVNULmlzU3VzcGVuZChjdXJyZW50KSkge1xuICAgICAgaWYgKHNlZW4uaGFzKGN1cnJlbnQpKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgICBzZWVuLmFkZChjdXJyZW50KVxuICAgICAgY3VycmVudCA9IGN1cnJlbnQuZigpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoU2NoZW1hQVNULmlzUmVmaW5lbWVudChjdXJyZW50KSkge1xuICAgICAgY3VycmVudCA9IGN1cnJlbnQuZnJvbVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgYnJlYWtcbiAgfVxuXG4gIGlmIChTY2hlbWFBU1QuaXNUcmFuc2Zvcm1hdGlvbihjdXJyZW50KSkge1xuICAgIGNvbnN0IGZyb20gPSByZXNvbHZlQXN0Rm9yUGF0aChjdXJyZW50LmZyb20sIHNlZ21lbnRzLCBzZWVuKVxuICAgIGlmIChmcm9tKSByZXR1cm4gZnJvbVxuICAgIHJldHVybiByZXNvbHZlQXN0Rm9yUGF0aChjdXJyZW50LnRvLCBzZWdtZW50cywgc2VlbilcbiAgfVxuXG4gIGlmIChTY2hlbWFBU1QuaXNVbmlvbihjdXJyZW50KSkge1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBjdXJyZW50LnR5cGVzKSB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVBc3RGb3JQYXRoKG5vZGUsIHNlZ21lbnRzLCBzZWVuKVxuICAgICAgaWYgKHJlc29sdmVkKSByZXR1cm4gcmVzb2x2ZWRcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG5cbiAgaWYgKFNjaGVtYUFTVC5pc1R1cGxlVHlwZShjdXJyZW50KSkge1xuICAgIGNvbnN0IFtoZWFkLCAuLi50YWlsXSA9IHNlZ21lbnRzXG4gICAgaWYgKHR5cGVvZiBoZWFkICE9PSAnbnVtYmVyJykgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGNvbnN0IGVsZW1lbnQgPVxuICAgICAgaGVhZCA8IGN1cnJlbnQuZWxlbWVudHMubGVuZ3RoID8gY3VycmVudC5lbGVtZW50c1toZWFkXSA6IGN1cnJlbnQucmVzdC5sZW5ndGggPiAwID8gY3VycmVudC5yZXN0WzBdIDogdW5kZWZpbmVkXG4gICAgcmV0dXJuIGVsZW1lbnQgPyByZXNvbHZlQXN0Rm9yUGF0aChlbGVtZW50LnR5cGUsIHRhaWwsIHNlZW4pIDogdW5kZWZpbmVkXG4gIH1cblxuICBpZiAoU2NoZW1hQVNULmlzVHlwZUxpdGVyYWwoY3VycmVudCkpIHtcbiAgICBjb25zdCBbaGVhZCwgLi4udGFpbF0gPSBzZWdtZW50c1xuICAgIGlmIChoZWFkID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWRcblxuICAgIGlmICh0eXBlb2YgaGVhZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGZvciAoY29uc3QgcHMgb2YgY3VycmVudC5wcm9wZXJ0eVNpZ25hdHVyZXMpIHtcbiAgICAgICAgaWYgKFN0cmluZyhwcy5uYW1lKSAhPT0gaGVhZCkgY29udGludWVcbiAgICAgICAgcmV0dXJuIHJlc29sdmVBc3RGb3JQYXRoKHBzLnR5cGUsIHRhaWwsIHNlZW4pXG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzaWcgb2YgY3VycmVudC5pbmRleFNpZ25hdHVyZXMpIHtcbiAgICAgIGxldCBwYXJhbTogU2NoZW1hQVNULkFTVCA9IHNpZy5wYXJhbWV0ZXIgYXMgdW5rbm93biBhcyBTY2hlbWFBU1QuQVNUXG4gICAgICB3aGlsZSAoU2NoZW1hQVNULmlzUmVmaW5lbWVudChwYXJhbSkpIHtcbiAgICAgICAgcGFyYW0gPSBwYXJhbS5mcm9tXG4gICAgICB9XG4gICAgICBjb25zdCB0YWcgPSAocGFyYW0gYXMgYW55KT8uX3RhZ1xuICAgICAgY29uc3QgYWNjZXB0c1N0cmluZyA9IHRhZyA9PT0gJ1N0cmluZ0tleXdvcmQnIHx8IHRhZyA9PT0gJ1RlbXBsYXRlTGl0ZXJhbCdcbiAgICAgIGNvbnN0IGFjY2VwdHNOdW1iZXIgPSB0YWcgPT09ICdOdW1iZXJLZXl3b3JkJ1xuICAgICAgaWYgKHR5cGVvZiBoZWFkID09PSAnc3RyaW5nJyAmJiBhY2NlcHRzU3RyaW5nKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlQXN0Rm9yUGF0aChzaWcudHlwZSwgdGFpbCwgc2VlbilcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgaGVhZCA9PT0gJ251bWJlcicgJiYgYWNjZXB0c051bWJlcikge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZUFzdEZvclBhdGgoc2lnLnR5cGUsIHRhaWwsIHNlZW4pXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgdGFnID0gKGN1cnJlbnQgYXMgYW55KT8uX3RhZ1xuICBpZiAodGFnID09PSAnQW55S2V5d29yZCcgfHwgdGFnID09PSAnVW5rbm93bktleXdvcmQnIHx8IHRhZyA9PT0gJ09iamVjdEtleXdvcmQnIHx8IHRhZyA9PT0gJ0RlY2xhcmF0aW9uJykge1xuICAgIHJldHVybiBjdXJyZW50XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmNvbnN0IHNlbGVjdEJ5U2VnbWVudHMgPVxuICAoc2VnbWVudHM6IFJlYWRvbmx5QXJyYXk8RG90UGF0aFNlZ21lbnQ+KSA9PlxuICAoc3RhdGU6IHVua25vd24pOiB1bmtub3duID0+IHtcbiAgICBsZXQgY3VycmVudDogdW5rbm93biA9IHN0YXRlXG4gICAgZm9yIChjb25zdCBzZWcgb2Ygc2VnbWVudHMpIHtcbiAgICAgIGlmIChjdXJyZW50ID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcbiAgICAgIGlmICh0eXBlb2Ygc2VnID09PSAnbnVtYmVyJykge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShjdXJyZW50KSkge1xuICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W3NlZ11cbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc1JlY29yZChjdXJyZW50KSkge1xuICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W1N0cmluZyhzZWcpXVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgfVxuICAgICAgaWYgKGlzUmVjb3JkKGN1cnJlbnQpKSB7XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W3NlZ11cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG4gICAgcmV0dXJuIGN1cnJlbnRcbiAgfVxuXG5leHBvcnQgY29uc3QgbWFrZVNjaGVtYVNlbGVjdG9yID0gKHBhdGg6IHN0cmluZywgc2NoZW1hQXN0PzogU2NoZW1hQVNULkFTVCk6IERvdFBhdGhTZWxlY3RvclJlc3VsdCA9PiB7XG4gIGNvbnN0IHBhcnNlZCA9IHBhcnNlRG90UGF0aChwYXRoKVxuICBpZiAoIXBhcnNlZC5vaykgcmV0dXJuIHsgb2s6IGZhbHNlLCBlcnJvcjogcGFyc2VkLmVycm9yIH1cblxuICBpZiAoc2NoZW1hQXN0KSB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlQXN0Rm9yUGF0aChzY2hlbWFBc3QsIHBhcnNlZC5zZWdtZW50cywgbmV3IFNldCgpKVxuICAgIGlmICghcmVzb2x2ZWQpIHtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IG1ha2VTY2hlbWFNaXNtYXRjaEVycm9yKHBhdGgpIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG9rOiB0cnVlLFxuICAgIHNlbGVjdG9yOiBzZWxlY3RCeVNlZ21lbnRzKHBhcnNlZC5zZWdtZW50cyksXG4gICAgc2VnbWVudHM6IHBhcnNlZC5zZWdtZW50cyxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgUHJvY2Vzc0Vycm9yUG9saWN5IH0gZnJvbSAnLi9wcm90b2NvbC5qcydcblxuZXhwb3J0IHR5cGUgU3VwZXJ2aXNpb25EZWNpc2lvbiA9ICdzdG9wJyB8ICdyZXN0YXJ0J1xuXG5leHBvcnQgdHlwZSBTdXBlcnZpc2lvblN0YXRlID0ge1xuICByZWFkb25seSBmYWlsdXJlVGltZXM6IFJlYWRvbmx5QXJyYXk8bnVtYmVyPlxufVxuXG5leHBvcnQgY29uc3QgaW5pdGlhbFN0YXRlID0gKCk6IFN1cGVydmlzaW9uU3RhdGUgPT4gKHsgZmFpbHVyZVRpbWVzOiBbXSB9KVxuXG5leHBvcnQgdHlwZSBGYWlsdXJlRGVjaXNpb24gPSB7XG4gIHJlYWRvbmx5IGRlY2lzaW9uOiBTdXBlcnZpc2lvbkRlY2lzaW9uXG4gIHJlYWRvbmx5IG5leHRTdGF0ZTogU3VwZXJ2aXNpb25TdGF0ZVxuICByZWFkb25seSB3aXRoaW5XaW5kb3dGYWlsdXJlczogbnVtYmVyXG4gIHJlYWRvbmx5IG1heFJlc3RhcnRzOiBudW1iZXJcbiAgcmVhZG9ubHkgd2luZG93TXM/OiBudW1iZXJcbn1cblxuZXhwb3J0IGNvbnN0IG9uRmFpbHVyZSA9IChwb2xpY3k6IFByb2Nlc3NFcnJvclBvbGljeSwgc3RhdGU6IFN1cGVydmlzaW9uU3RhdGUsIG5vd01zOiBudW1iZXIpOiBGYWlsdXJlRGVjaXNpb24gPT4ge1xuICBpZiAocG9saWN5Lm1vZGUgPT09ICdmYWlsU3RvcCcpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZGVjaXNpb246ICdzdG9wJyxcbiAgICAgIG5leHRTdGF0ZTogc3RhdGUsXG4gICAgICB3aXRoaW5XaW5kb3dGYWlsdXJlczogc3RhdGUuZmFpbHVyZVRpbWVzLmxlbmd0aCxcbiAgICAgIG1heFJlc3RhcnRzOiAwLFxuICAgICAgd2luZG93TXM6IHBvbGljeS53aW5kb3dNcyxcbiAgICB9XG4gIH1cblxuICBjb25zdCBtYXhSZXN0YXJ0c1JhdyA9IHBvbGljeS5tYXhSZXN0YXJ0c1xuICBjb25zdCBtYXhSZXN0YXJ0cyA9XG4gICAgdHlwZW9mIG1heFJlc3RhcnRzUmF3ID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUobWF4UmVzdGFydHNSYXcpICYmIG1heFJlc3RhcnRzUmF3ID49IDBcbiAgICAgID8gTWF0aC5mbG9vcihtYXhSZXN0YXJ0c1JhdylcbiAgICAgIDogMFxuXG4gIGlmIChtYXhSZXN0YXJ0cyA8PSAwKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRlY2lzaW9uOiAnc3RvcCcsXG4gICAgICBuZXh0U3RhdGU6IHN0YXRlLFxuICAgICAgd2l0aGluV2luZG93RmFpbHVyZXM6IHN0YXRlLmZhaWx1cmVUaW1lcy5sZW5ndGgsXG4gICAgICBtYXhSZXN0YXJ0cyxcbiAgICAgIHdpbmRvd01zOiBwb2xpY3kud2luZG93TXMsXG4gICAgfVxuICB9XG5cbiAgY29uc3Qgd2luZG93TXNSYXcgPSBwb2xpY3kud2luZG93TXNcbiAgY29uc3Qgd2luZG93TXMgPVxuICAgIHR5cGVvZiB3aW5kb3dNc1JhdyA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKHdpbmRvd01zUmF3KSAmJiB3aW5kb3dNc1JhdyA+IDBcbiAgICAgID8gTWF0aC5mbG9vcih3aW5kb3dNc1JhdylcbiAgICAgIDogdW5kZWZpbmVkXG5cbiAgY29uc3QgZmFpbHVyZVRpbWVzUmF3ID0gWy4uLnN0YXRlLmZhaWx1cmVUaW1lcywgbm93TXNdXG4gIGNvbnN0IGZhaWx1cmVUaW1lcyA9IHdpbmRvd01zID8gZmFpbHVyZVRpbWVzUmF3LmZpbHRlcigodCkgPT4gdCA+PSBub3dNcyAtIHdpbmRvd01zKSA6IGZhaWx1cmVUaW1lc1Jhd1xuXG4gIC8vIEtlZXAgYXQgbW9zdCBtYXhSZXN0YXJ0cysxIHRpbWVzdGFtcHMgdG8gYXZvaWQgdW5ib3VuZGVkIGdyb3d0aC5cbiAgY29uc3QgY2FwID0gbWF4UmVzdGFydHMgKyAxXG4gIGNvbnN0IGNhcHBlZCA9IGZhaWx1cmVUaW1lcy5sZW5ndGggPiBjYXAgPyBmYWlsdXJlVGltZXMuc2xpY2UoZmFpbHVyZVRpbWVzLmxlbmd0aCAtIGNhcCkgOiBmYWlsdXJlVGltZXNcblxuICBjb25zdCB3aXRoaW5XaW5kb3dGYWlsdXJlcyA9IGNhcHBlZC5sZW5ndGhcbiAgY29uc3QgZGVjaXNpb246IFN1cGVydmlzaW9uRGVjaXNpb24gPSB3aXRoaW5XaW5kb3dGYWlsdXJlcyA8PSBtYXhSZXN0YXJ0cyA/ICdyZXN0YXJ0JyA6ICdzdG9wJ1xuXG4gIHJldHVybiB7XG4gICAgZGVjaXNpb24sXG4gICAgbmV4dFN0YXRlOiB7IGZhaWx1cmVUaW1lczogY2FwcGVkIH0sXG4gICAgd2l0aGluV2luZG93RmFpbHVyZXMsXG4gICAgbWF4UmVzdGFydHMsXG4gICAgd2luZG93TXMsXG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFjTyxJQUFNLGVBQWUsdUJBQU8sSUFBSSx5QkFBeUI7QUFNaEUsSUFBTSxlQUFlLENBQUMsUUFBZ0IsS0FBYSxVQUF5QjtBQUMxRSxTQUFPLGVBQWUsUUFBUSxLQUFLO0FBQUEsSUFDakM7QUFBQSxJQUNBLFlBQVk7QUFBQSxJQUNaLGNBQWM7QUFBQSxJQUNkLFVBQVU7QUFBQSxFQUNaLENBQUM7QUFDSDtBQUVPLElBQU0sVUFBVSxDQUFDLFdBQ3JCLE9BQXlCLFlBQVk7QUFFakMsSUFBTSxnQkFBZ0IsQ0FBQyxXQUM1QixRQUFRLE1BQU0sR0FBRztBQUVaLElBQU0sYUFBYSxDQUFPLFFBQW1DLFNBQTJDO0FBQzdHLGVBQWEsUUFBZSxjQUFjLElBQUk7QUFDOUMsU0FBTztBQUNUOzs7QUN0Q0EsU0FBUyxTQUFTLFFBQVEsVUFBVSxhQUFhO0FBdUJqRCxJQUFNLDJCQUFOLGNBQXVDLFFBQVEsSUFBSSwrQkFBK0IsRUFHaEYsRUFBRTtBQUFDO0FBRUUsSUFBTSx1QkFBdUI7QUFFN0IsSUFBTSx5QkFBeUIsQ0FDcEMsY0FFQSxNQUFNLFFBQVEsc0JBQXNCLFNBQVM7QUFFL0MsSUFBTSxXQUFXLENBQUMsVUFDaEIsT0FBTyxVQUFVLFlBQVksVUFBVSxRQUFRLENBQUMsTUFBTSxRQUFRLEtBQUs7QUFFOUQsSUFBTSx3QkFBd0IsQ0FBQyxZQUEyQztBQUMvRSxRQUFNLE9BQU8saUJBQWlCLE9BQU87QUFFckMsUUFBTSwyQkFBMkIsb0JBQUksSUFBdUI7QUFDNUQsTUFBSTtBQUNKLE1BQUk7QUFFSixRQUFNLGVBQWU7QUFBQSxJQUNuQixTQUFTO0FBQUEsSUFDVCxXQUFXO0FBQUEsSUFDWCxpQkFBaUI7QUFBQSxFQUNuQjtBQUVBLFFBQU0sWUFBdUI7QUFBQSxJQUMzQixRQUFRLENBQUMsVUFDUCxPQUFPLElBQUksYUFBYTtBQUN0QixZQUFNLFFBQVEsT0FBTyxTQUFTLElBQUksdUJBQXVCO0FBQ3pELFlBQU0sZ0JBQWlCLE1BQWM7QUFDckMsWUFBTSxhQUFhLE9BQU8sa0JBQWtCLFlBQVksY0FBYyxTQUFTLElBQUksZ0JBQWdCO0FBQ25HLFlBQU0sV0FBVyxVQUFVLFFBQVEsU0FBWSxRQUFRLE1BQU0sUUFBUSxZQUFZLFVBQVU7QUFDM0YsWUFBTSxNQUFNLHVCQUF1QixPQUFPO0FBQUEsUUFDeEMsa0JBQWtCO0FBQUEsUUFDbEI7QUFBQSxRQUNBLGtCQUFrQixDQUFDLEVBQUUsTUFBTSxNQUFNO0FBQy9CLHVCQUFhLFdBQVcsTUFBTTtBQUM5Qix1QkFBYSxhQUFhLE1BQU07QUFBQSxRQUNsQztBQUFBLE1BQ0YsQ0FBQztBQUNELFVBQUksQ0FBQyxJQUFLO0FBRVYsWUFBTSxZQUFZLGlCQUFpQixHQUFHO0FBQ3RDLG1CQUFhLFdBQVcsVUFBVSxNQUFNO0FBQ3hDLG1CQUFhLGFBQWEsVUFBVSxNQUFNO0FBQzFDLG1CQUFhLG1CQUFtQixVQUFVLE1BQU07QUFFaEQsV0FBSyxPQUFPLGVBQWUsVUFBVSxPQUFPO0FBQUEsUUFDMUMsV0FBVyxJQUFJO0FBQUEsTUFDakIsQ0FBQztBQUFBLElBQ0gsQ0FBQztBQUFBLEVBQ0w7QUFFQSxRQUFNLDJCQUEyQixDQUFDLGFBQTRCO0FBQzVELFFBQUksQ0FBQyxTQUFTLFFBQVEsRUFBRztBQUN6QixVQUFNLFNBQVMsU0FBUztBQUN4QixRQUFJLE9BQU8sV0FBVyxZQUFZLE9BQU8sV0FBVyxFQUFHO0FBQ3ZELFVBQU0sWUFBWSxpQkFBaUIsUUFBUTtBQUMzQyxpQkFBYSxXQUFXLFVBQVUsTUFBTTtBQUN4QyxpQkFBYSxhQUFhLFVBQVUsTUFBTTtBQUMxQyxpQkFBYSxtQkFBbUIsVUFBVSxNQUFNO0FBQ2hELDZCQUF5QixJQUFJLFFBQVEsVUFBVSxLQUFLO0FBQUEsRUFDdEQ7QUFFQSxRQUFNLDZCQUE2QixDQUFDLFFBQXVCO0FBQ3pELFVBQU0sWUFBWSxpQkFBaUIsR0FBRztBQUN0QyxpQkFBYSxXQUFXLFVBQVUsTUFBTTtBQUN4QyxpQkFBYSxhQUFhLFVBQVUsTUFBTTtBQUMxQyxpQkFBYSxtQkFBbUIsVUFBVSxNQUFNO0FBQ2hELDhCQUEwQixVQUFVO0FBQUEsRUFDdEM7QUFFQSxRQUFNLDZCQUE2QixDQUFDLGFBQTRCO0FBQzlELFVBQU0sWUFBWSxpQkFBaUIsUUFBUTtBQUMzQyxpQkFBYSxXQUFXLFVBQVUsTUFBTTtBQUN4QyxpQkFBYSxhQUFhLFVBQVUsTUFBTTtBQUMxQyxpQkFBYSxtQkFBbUIsVUFBVSxNQUFNO0FBQ2hELDhCQUEwQixVQUFVO0FBQUEsRUFDdEM7QUFFQSxRQUFNLHdCQUF3QixDQUFDLFlBQStEO0FBQzVGLFVBQU0sa0JBQ0oseUJBQXlCLE9BQU8sSUFDM0I7QUFBQSxNQUNDLGtCQUFrQixPQUFPLFlBQVksd0JBQXdCO0FBQUEsSUFDL0QsSUFDQTtBQUVOLFVBQU0saUJBQ0osMkJBQTJCLFFBQVEsMkJBQTJCLE9BQ3pEO0FBQUEsTUFDQyxHQUFJLDJCQUEyQixPQUFPLEVBQUUsd0JBQXdCLElBQUksQ0FBQztBQUFBLE1BQ3JFLEdBQUksMkJBQTJCLE9BQU8sRUFBRSxVQUFVLHdCQUF3QixJQUFJLENBQUM7QUFBQSxJQUNqRixJQUNBO0FBRU4sVUFBTSxVQUNKLG1CQUFtQixRQUFRLGtCQUFrQixPQUN4QztBQUFBLE1BQ0MsR0FBSSxtQkFBbUIsT0FBTyxFQUFFLFVBQVUsZ0JBQWdCLElBQUksQ0FBQztBQUFBLE1BQy9ELEdBQUksa0JBQWtCLE9BQU8sRUFBRSxTQUFTLGVBQWUsSUFBSSxDQUFDO0FBQUEsSUFDOUQsSUFDQTtBQUVOLFdBQU8sS0FBSyxPQUFPO0FBQUEsTUFDakIsV0FBVyxTQUFTO0FBQUEsTUFDcEI7QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNIO0FBRUEsUUFBTSxRQUFRLE1BQVk7QUFDeEIsU0FBSyxNQUFNO0FBQ1gsNkJBQXlCLE1BQU07QUFDL0IsOEJBQTBCO0FBQzFCLDhCQUEwQjtBQUMxQixpQkFBYSxVQUFVO0FBQ3ZCLGlCQUFhLFlBQVk7QUFDekIsaUJBQWEsa0JBQWtCO0FBQUEsRUFDakM7QUFFQSxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0Y7QUFDRjs7O0FDM0pBO0FBQUEsRUFDRTtBQUFBLEVBQ0EsV0FBQUE7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0EsVUFBQUM7QUFBQSxFQUNBLFNBQUFDO0FBQUEsRUFDQSxZQUFBQztBQUFBLEVBQ0EsU0FBQUM7QUFBQSxFQUNBLFVBQUFDO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBLE9BQUFDO0FBQUEsRUFDQSxTQUFBQztBQUFBLEVBQ0EsVUFBQUM7QUFBQSxPQUNLOzs7QUNYQSxJQUFNLG9CQUFvQixDQUFDLFVBQXlDO0FBQ3pFLFVBQVEsTUFBTSxNQUFNO0FBQUEsSUFDbEIsS0FBSztBQUNILGFBQU8sT0FBTyxNQUFNLEtBQUs7QUFBQSxJQUMzQixLQUFLO0FBQ0gsYUFBTyxrQkFBa0IsTUFBTSxRQUFRLEtBQUssTUFBTSxVQUFVO0FBQUEsSUFDOUQsS0FBSztBQUNILGFBQU8sYUFBYSxNQUFNLFNBQVM7QUFBQSxFQUN2QztBQUNGO0FBRU8sSUFBTSw4QkFBOEIsQ0FBQyxhQUMxQyxHQUFHLFNBQVMsU0FBUyxLQUFLLGtCQUFrQixTQUFTLEtBQUssQ0FBQztBQUV0RCxJQUFNLGdDQUFnQyxDQUFDLGFBQThDO0FBQzFGLFFBQU0sV0FBVyxrQkFBa0IsU0FBUyxTQUFTLEtBQUs7QUFDMUQsU0FBTyxXQUFXLFNBQVMsU0FBUyxTQUFTLEtBQUssUUFBUSxNQUFNLFNBQVMsTUFBTTtBQUNqRjs7O0FDckJBLFNBQVMsVUFBQUMsU0FBUSxPQUFPLFFBQVEsS0FBWSxjQUFjO0FBSW5ELElBQU0sbUNBQW1DO0FBQ3pDLElBQU0seUJBQXlCO0FBc0IvQixJQUFNLG9CQUFvQixDQUMvQixVQUNBLFlBR3VCO0FBQ3ZCLFFBQU0sZUFBZSxTQUFTLGdCQUFnQjtBQUU5QyxRQUFNLGFBQ0osT0FBTyxhQUFhLFlBQVksT0FBTyxTQUFTLFFBQVEsS0FBSyxZQUFZLElBQUksS0FBSyxNQUFNLFFBQVEsSUFBSTtBQUV0RyxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0EsT0FBTyxlQUFlLGNBQWMsZUFBZTtBQUFBLEVBQ3JEO0FBQ0Y7QUFVTyxJQUFNLDBCQUEwQixDQUFDLFNBYXRDQyxRQUFPLElBQUksYUFBYTtBQUN0QixRQUFNLFNBQVMsS0FBSztBQUNwQixRQUFNLG9CQUFvQixLQUFLLHFCQUFxQjtBQUVwRCxNQUFJLE9BQU8sU0FBUyxVQUFVO0FBQzVCLFVBQU0sV0FBVyxPQUFPLElBQUksS0FJekIsRUFBRSxPQUFPLFFBQVcsV0FBVyxHQUFHLFFBQVEsRUFBRSxDQUFDO0FBRWhELFVBQU1DLGFBQVksQ0FBQyxhQUNqQkQsUUFBTyxJQUFJLGFBQWE7QUFDdEIsWUFBTSxVQUFVLEtBQUssaUJBQWlCLFFBQVE7QUFFOUMsWUFBTSxDQUFDLFdBQVcsZUFBZSxLQUFLLElBQUksT0FBTyxJQUFJLE9BQU8sVUFBVSxDQUFDLE1BQU07QUFDM0UsY0FBTSxTQUFTLEVBQUUsU0FBUztBQUMxQixlQUFPLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxXQUFXLE1BQU0sR0FBWSxFQUFFLEdBQUcsR0FBRyxRQUFRLFdBQVcsT0FBTyxDQUFDO0FBQUEsTUFDdEYsQ0FBQztBQUVELFVBQUksYUFBYSxrQkFBa0IsR0FBRztBQUNwQyxjQUFNLE9BQU8sT0FBTyxNQUFNLEtBQUssU0FBUztBQUN4QyxZQUFJLE9BQU8sT0FBTyxJQUFJLEdBQUc7QUFDdkIsaUJBQU8sTUFBTSxjQUFjLFNBQVM7QUFBQSxRQUN0QztBQUFBLE1BQ0Y7QUFFQSxZQUFNLFFBQVEsT0FBT0EsUUFBTztBQUFBLFFBQzFCLEtBQ0csSUFBSSxPQUFPLEVBQ1gsS0FBS0EsUUFBTyxTQUFTLElBQUksT0FBTyxVQUFVLENBQUMsTUFBTyxFQUFFLGNBQWMsUUFBUSxFQUFFLEdBQUcsR0FBRyxXQUFXLEVBQUUsSUFBSSxDQUFFLENBQUMsQ0FBQztBQUFBLE1BQzVHO0FBRUEsYUFBTyxJQUFJLE9BQU8sVUFBVSxDQUFDLE9BQU8sRUFBRSxHQUFHLEdBQUcsTUFBTSxFQUFFO0FBQUEsSUFDdEQsQ0FBQztBQUVILFdBQU8sT0FBTyxPQUFPLFdBQVcsS0FBSyxRQUFRQyxVQUFTO0FBQUEsRUFDeEQ7QUFFQSxRQUFNLFVBQVUsT0FBTyxJQUFJLEtBQUssS0FBSztBQUNyQyxRQUFNLGlCQUFpQixPQUFPLElBQUksS0FBSztBQUFBLElBQ3JDLFNBQVM7QUFBQSxJQUNULE9BQU8sQ0FBQztBQUFBLElBQ1IsTUFBTTtBQUFBLEVBQ1IsQ0FBQztBQUNELFFBQU0sbUJBQW1CLE9BQU8sSUFBSSxLQUFLO0FBQUEsSUFDdkMsUUFBUTtBQUFBLElBQ1IsT0FBTyxDQUFDO0FBQUEsSUFDUixNQUFNO0FBQUEsRUFDUixDQUFDO0FBRUQsUUFBTSxtQkFBbUIsa0JBQWtCLE9BQU8sVUFBVSxFQUFFLGNBQWMsa0JBQWtCLENBQUM7QUFDL0YsUUFBTSxxQkFBcUIsa0JBQWtCLFFBQVcsRUFBRSxjQUFjLGtCQUFrQixDQUFDO0FBQzNGLFFBQU0sZ0JBQ0osT0FBTyxPQUFPLGdCQUFnQixZQUFZLE9BQU8sU0FBUyxPQUFPLFdBQVcsS0FBSyxPQUFPLGVBQWUsSUFDbkcsS0FBSyxNQUFNLE9BQU8sV0FBVyxJQUM1QixLQUFLLHdCQUF3QjtBQUVwQyxRQUFNLGNBQWMsTUFDbEJELFFBQU87QUFBQSxJQUFRLE1BQ2IsSUFBSSxPQUFPLGdCQUFnQixDQUFDLFVBQVU7QUFDcEMsVUFBSSxNQUFNLFdBQVcsTUFBTSxNQUFNLFdBQVcsR0FBRztBQUM3QyxlQUFPLENBQUMsT0FBTyxLQUFLLEdBQUcsS0FBSztBQUFBLE1BQzlCO0FBQ0EsWUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLElBQUksTUFBTTtBQUM5QixhQUFPLENBQUMsT0FBTyxLQUFLLElBQUksR0FBRyxFQUFFLEdBQUcsT0FBTyxTQUFTLE1BQU0sT0FBTyxLQUFLLENBQUM7QUFBQSxJQUNyRSxDQUFDLEVBQUU7QUFBQSxNQUNEQSxRQUFPO0FBQUEsUUFBUSxDQUFDLFNBQ2QsT0FBTyxNQUFNLE1BQU07QUFBQSxVQUNqQixRQUFRLE1BQU1BLFFBQU87QUFBQSxVQUNyQixRQUFRLENBQUMsWUFDUEEsUUFBTztBQUFBLFlBQ0wsS0FDRyxJQUFJLE9BQU8sRUFDWDtBQUFBLGNBQ0NBLFFBQU8sU0FBUyxJQUFJLE9BQU8sZ0JBQWdCLENBQUMsT0FBTyxFQUFFLEdBQUcsR0FBRyxTQUFTLE1BQU0sRUFBRSxDQUFDO0FBQUEsY0FDN0VBLFFBQU8sU0FBUyxZQUFZLENBQUM7QUFBQSxZQUMvQjtBQUFBLFVBQ0osRUFBRSxLQUFLQSxRQUFPLE1BQU07QUFBQSxRQUN4QixDQUFDO0FBQUEsTUFDSDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUYsUUFBTSxnQkFBZ0IsTUFDcEJBLFFBQU87QUFBQSxJQUFRLE1BQ2IsSUFBSSxPQUFPLGtCQUFrQixDQUFDLFVBQVU7QUFDdEMsVUFBSSxNQUFNLFVBQVUsaUJBQWlCLE1BQU0sTUFBTSxXQUFXLEdBQUc7QUFDN0QsZUFBTyxDQUFDLE9BQU8sS0FBSyxHQUFHLEtBQUs7QUFBQSxNQUM5QjtBQUNBLFlBQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxJQUFJLE1BQU07QUFDOUIsYUFBTyxDQUFDLE9BQU8sS0FBSyxJQUFJLEdBQUcsRUFBRSxHQUFHLE9BQU8sUUFBUSxNQUFNLFNBQVMsR0FBRyxPQUFPLEtBQUssQ0FBQztBQUFBLElBQ2hGLENBQUMsRUFBRTtBQUFBLE1BQ0RBLFFBQU87QUFBQSxRQUFRLENBQUMsU0FDZCxPQUFPLE1BQU0sTUFBTTtBQUFBLFVBQ2pCLFFBQVEsTUFBTUEsUUFBTztBQUFBLFVBQ3JCLFFBQVEsQ0FBQyxZQUNQQSxRQUFPO0FBQUEsWUFDTCxLQUFLLElBQUksT0FBTyxFQUFFO0FBQUEsY0FDaEJBLFFBQU87QUFBQSxnQkFDTCxJQUFJLE9BQU8sa0JBQWtCLENBQUMsT0FBTztBQUFBLGtCQUNuQyxHQUFHO0FBQUEsa0JBQ0gsUUFBUSxLQUFLLElBQUksR0FBRyxFQUFFLFNBQVMsQ0FBQztBQUFBLGdCQUNsQyxFQUFFO0FBQUEsY0FDSjtBQUFBLGNBQ0FBLFFBQU8sU0FBUyxjQUFjLENBQUM7QUFBQSxZQUNqQztBQUFBLFVBQ0YsRUFBRSxLQUFLQSxRQUFPLFFBQVFBLFFBQU8sU0FBUyxjQUFjLENBQUMsQ0FBQztBQUFBLFFBQzFELENBQUM7QUFBQSxNQUNIO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFRixRQUFNLFlBQVksQ0FBQyxhQUNqQkEsUUFBTyxJQUFJLGFBQWE7QUFDdEIsVUFBTSxVQUFVLEtBQUssaUJBQWlCLFFBQVE7QUFFOUMsUUFBSSxPQUFPLFNBQVMsUUFBUTtBQUMxQixZQUFNLFdBQVcsT0FBTyxJQUFJO0FBQUEsUUFBTztBQUFBLFFBQVMsQ0FBQyxTQUMzQyxPQUFRLENBQUMsT0FBTyxJQUFJLElBQWUsQ0FBQyxNQUFNLElBQUk7QUFBQSxNQUNoRDtBQUNBLFVBQUksQ0FBQyxVQUFVO0FBQ2IsZUFBTyxLQUFLLE9BQU8sT0FBTztBQUMxQjtBQUFBLE1BQ0Y7QUFFQSxhQUFPQSxRQUFPLFdBQVcsS0FBSyxJQUFJLE9BQU8sRUFBRSxLQUFLQSxRQUFPLFNBQVMsSUFBSSxJQUFJLFNBQVMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN6RjtBQUFBLElBQ0Y7QUFFQSxRQUFJLE9BQU8sU0FBUyxZQUFZO0FBQzlCLFlBQU1FLFlBQVcsT0FBTyxJQUFJLE9BQU8sa0JBQWtCLENBQUMsVUFBVTtBQUM5RCxjQUFNLFFBQVEsQ0FBQyxHQUFHLE1BQU0sT0FBTyxPQUFPO0FBQ3RDLGVBQU8sQ0FBQyxNQUFNLFFBQVEsRUFBRSxHQUFHLE9BQU8sT0FBTyxNQUFNLEtBQUssSUFBSSxNQUFNLE1BQU0sTUFBTSxNQUFNLEVBQUUsQ0FBQztBQUFBLE1BQ3JGLENBQUM7QUFFRCxVQUFJQSxZQUFXLG1CQUFtQixPQUFPO0FBQ3ZDLGNBQU0sUUFBUSxPQUFPLElBQUksSUFBSSxnQkFBZ0I7QUFDN0MsZUFBTyxLQUFLLGdCQUFnQjtBQUFBLFVBQzFCLE1BQU07QUFBQSxVQUNOLGVBQWVBO0FBQUEsVUFDZixNQUFNLE1BQU07QUFBQSxVQUNaLE9BQU87QUFBQSxVQUNQO0FBQUEsUUFDRixDQUFDO0FBQ0Q7QUFBQSxNQUNGO0FBRUEsYUFBTyxjQUFjO0FBQ3JCO0FBQUEsSUFDRjtBQUdBLFVBQU0sV0FBVyxPQUFPLElBQUksT0FBTyxnQkFBZ0IsQ0FBQyxVQUFVO0FBQzVELFlBQU0sUUFBUSxDQUFDLEdBQUcsTUFBTSxPQUFPLE9BQU87QUFDdEMsYUFBTyxDQUFDLE1BQU0sUUFBUSxFQUFFLEdBQUcsT0FBTyxPQUFPLE1BQU0sS0FBSyxJQUFJLE1BQU0sTUFBTSxNQUFNLE1BQU0sRUFBRSxDQUFDO0FBQUEsSUFDckYsQ0FBQztBQUVELFFBQUksV0FBVyxpQkFBaUIsT0FBTztBQUNyQyxZQUFNLFFBQVEsT0FBTyxJQUFJLElBQUksY0FBYztBQUMzQyxhQUFPLEtBQUssZ0JBQWdCO0FBQUEsUUFDMUIsTUFBTTtBQUFBLFFBQ04sZUFBZTtBQUFBLFFBQ2YsTUFBTSxNQUFNO0FBQUEsUUFDWixPQUFPO0FBQUEsUUFDUDtBQUFBLE1BQ0YsQ0FBQztBQUNEO0FBQUEsSUFDRjtBQUVBLFdBQU8sWUFBWTtBQUFBLEVBQ3JCLENBQUM7QUFFSCxTQUFPLE9BQU8sT0FBTyxXQUFXLEtBQUssUUFBUSxTQUFTO0FBQ3hELENBQUM7OztBQzdPSSxJQUFNLDBCQUEwQixJQUFJO0FBQ3BDLElBQU0sbUNBQW1DO0FBQ3pDLElBQU0sNENBQTRDO0FBV2xELElBQU0saUNBQWlDLENBQUMsYUFHWjtBQUFBLEVBQ2pDLFdBQ0UsT0FBTyxTQUFTLGNBQWMsWUFBWSxPQUFPLFNBQVMsUUFBUSxTQUFTLEtBQUssUUFBUSxhQUFhLElBQ2pHLEtBQUssTUFBTSxRQUFRLFNBQVMsSUFDNUI7QUFBQSxFQUNOLFVBQ0UsT0FBTyxTQUFTLGFBQWEsWUFBWSxPQUFPLFNBQVMsUUFBUSxRQUFRLEtBQUssUUFBUSxZQUFZLElBQzlGLEtBQUssTUFBTSxRQUFRLFFBQVEsSUFDM0I7QUFBQSxFQUNOLFNBQVM7QUFBQSxFQUNULFNBQVM7QUFBQSxFQUNULFlBQVk7QUFBQSxFQUNaLGdCQUFnQjtBQUNsQjtBQWVBLElBQU0seUJBQXlCLENBQUMsVUFPWDtBQUFBLEVBQ25CLE1BQU07QUFBQSxFQUNOLFVBQVUsS0FBSyxZQUFZO0FBQUEsRUFDM0IsU0FBUyxLQUFLLFlBQVk7QUFBQSxFQUMxQixVQUFVO0FBQUEsRUFDVixVQUFVLEtBQUssWUFBWTtBQUFBLEVBQzNCLGFBQWEsS0FBSyxZQUFZO0FBQUEsRUFDOUIsT0FBTztBQUFBLElBQ0wsU0FBUztBQUFBLElBQ1QsTUFBTTtBQUFBLElBQ04sTUFBTSxhQUFhLEtBQUssU0FBUyxhQUFhLEtBQUssUUFBUSxZQUFZLEtBQUssT0FBTyxZQUFZLEtBQUssT0FBTyxlQUFlLEtBQUssVUFBVTtBQUFBLEVBQzNJO0FBQ0Y7QUFFTyxJQUFNLDZCQUE2QixDQUN4QyxPQUNBLFVBQ3lFO0FBQ3pFLFFBQU0sWUFBWSxLQUFLLElBQUksR0FBRyxNQUFNLFNBQVM7QUFDN0MsUUFBTSxXQUFXLEtBQUssSUFBSSxHQUFHLE1BQU0sUUFBUTtBQUUzQyxNQUFJLE1BQU0sZ0JBQWdCO0FBQ3hCLFdBQU87QUFBQSxNQUNMLEVBQUUsTUFBTSxPQUFPO0FBQUEsTUFDZjtBQUFBLFFBQ0UsR0FBRztBQUFBLFFBQ0gsU0FBUyxNQUFNLFVBQVU7QUFBQSxNQUMzQjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsUUFBTSxVQUFVO0FBQ2hCLFFBQU0saUJBQWlCLEtBQUssSUFBSSxHQUFHLFlBQVksT0FBTztBQUV0RCxNQUFJLE1BQU0sVUFBVSxnQkFBZ0I7QUFDbEMsVUFBTSxXQUFXLDRCQUE0QixPQUFPLEVBQUUsU0FBUyxDQUFDO0FBQ2hFLFdBQU87QUFBQSxNQUNMLEVBQUUsTUFBTSxRQUFRLE9BQU8sU0FBUyxNQUFNO0FBQUEsTUFDdEM7QUFBQSxRQUNFLEdBQUc7QUFBQSxRQUNILFNBQVMsTUFBTSxVQUFVO0FBQUEsUUFDekIsWUFBWSxNQUFNLGNBQWMsU0FBUyxhQUFhLElBQUk7QUFBQSxNQUM1RDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsUUFBTSxVQUFVLE1BQU0sVUFBVTtBQUNoQyxRQUFNLFVBQVUsdUJBQXVCO0FBQUEsSUFDckMsYUFBYTtBQUFBLElBQ2I7QUFBQSxJQUNBO0FBQUEsSUFDQSxTQUFTLE1BQU07QUFBQSxJQUNmO0FBQUEsSUFDQSxZQUFZLE1BQU07QUFBQSxFQUNwQixDQUFDO0FBQ0QsUUFBTSxrQkFBa0IsNEJBQTRCLFNBQVMsRUFBRSxTQUFTLENBQUM7QUFFekUsU0FBTztBQUFBLElBQ0wsRUFBRSxNQUFNLGVBQWUsT0FBTyxnQkFBZ0IsTUFBTTtBQUFBLElBQ3BEO0FBQUEsTUFDRSxHQUFHO0FBQUEsTUFDSCxTQUFTLEtBQUssSUFBSSxXQUFXLE1BQU0sVUFBVSxDQUFDO0FBQUEsTUFDOUM7QUFBQSxNQUNBLFlBQVksTUFBTSxjQUFjLGdCQUFnQixhQUFhLElBQUk7QUFBQSxNQUNqRSxnQkFBZ0I7QUFBQSxJQUNsQjtBQUFBLEVBQ0Y7QUFDRjtBQUVPLElBQU0scUJBQXFCLENBQUMsVUFBZ0M7QUFDakUsUUFBTSxPQUFPLEtBQUssVUFBVSxLQUFLO0FBQ2pDLFNBQU8sT0FBTyxXQUFXLGNBQWMsT0FBTyxXQUFXLE1BQU0sTUFBTSxJQUFJLElBQUksWUFBWSxFQUFFLE9BQU8sSUFBSSxFQUFFO0FBQzFHO0FBRUEsSUFBTSxnQkFBZ0IsQ0FBQyxPQUFlLFdBQ3BDLE1BQU0sVUFBVSxTQUFTLFFBQVEsTUFBTSxNQUFNLEdBQUcsTUFBTTtBQUV4RCxJQUFNLHdCQUF3QixDQUFDLFVBQWtGO0FBQy9HLFFBQU0sVUFBVSxPQUFPLE1BQU0sWUFBWSxZQUFZLE1BQU0sUUFBUSxTQUFTLElBQUksTUFBTSxVQUFVO0FBRWhHLFFBQU0sT0FBTyxPQUFPLE1BQU0sU0FBUyxZQUFZLE1BQU0sS0FBSyxTQUFTLElBQUksY0FBYyxNQUFNLE1BQU0sSUFBSSxJQUFJO0FBRXpHLFNBQU87QUFBQSxJQUNMLE1BQU0sT0FBTyxNQUFNLFNBQVMsWUFBWSxNQUFNLEtBQUssU0FBUyxJQUFJLE1BQU0sT0FBTztBQUFBLElBQzdFLFNBQVMsY0FBYyxTQUFTLEdBQUc7QUFBQSxJQUNuQyxNQUFNLE9BQU8sTUFBTSxTQUFTLFlBQVksTUFBTSxLQUFLLFNBQVMsSUFBSSxNQUFNLE9BQU87QUFBQSxJQUM3RTtBQUFBLEVBQ0Y7QUFDRjtBQUVPLElBQU0sOEJBQThCLENBQ3pDLE9BQ0EsWUFHbUU7QUFDbkUsUUFBTSxXQUFXLFNBQVMsWUFBWTtBQUV0QyxNQUFJLGFBQWE7QUFDakIsTUFBSSxPQUFxQjtBQUV6QixNQUFJLE1BQU0sT0FBTztBQUNmLFVBQU0sYUFBYSxzQkFBc0IsTUFBTSxLQUFLO0FBQ3BELFFBQ0UsV0FBVyxZQUFZLE1BQU0sTUFBTSxXQUNuQyxXQUFXLFNBQVMsTUFBTSxNQUFNLFFBQ2hDLFdBQVcsU0FBUyxNQUFNLE1BQU0sUUFDaEMsV0FBVyxTQUFTLE1BQU0sTUFBTSxNQUNoQztBQUNBLG1CQUFhO0FBQ2IsYUFBTyxFQUFFLEdBQUcsT0FBTyxPQUFPLFdBQVc7QUFBQSxJQUN2QztBQUFBLEVBQ0Y7QUFFQSxNQUFJLG1CQUFtQixJQUFJLEtBQUssVUFBVTtBQUN4QyxXQUFPLEVBQUUsT0FBTyxNQUFNLFdBQVc7QUFBQSxFQUNuQztBQUdBLE1BQUksQ0FBQyxLQUFLLE9BQU8sTUFBTTtBQUVyQixXQUFPLEVBQUUsT0FBTyxNQUFNLFlBQVksS0FBSztBQUFBLEVBQ3pDO0FBRUEsUUFBTSxPQUFPLEtBQUssTUFBTTtBQUN4QixRQUFNLFFBQVEsQ0FBQyxLQUFLLEtBQUssS0FBSyxJQUFJLElBQUksQ0FBQztBQUV2QyxhQUFXLFVBQVUsT0FBTztBQUMxQixVQUFNLFVBQVUsV0FBVyxJQUFJLFNBQVksY0FBYyxNQUFNLE1BQU07QUFDckUsVUFBTSxZQUEwQjtBQUFBLE1BQzlCLEdBQUc7QUFBQSxNQUNILE9BQU87QUFBQSxRQUNMLEdBQUcsS0FBSztBQUFBLFFBQ1IsTUFBTTtBQUFBLE1BQ1I7QUFBQSxJQUNGO0FBQ0EsUUFBSSxtQkFBbUIsU0FBUyxLQUFLLFVBQVU7QUFDN0MsYUFBTyxFQUFFLE9BQU8sV0FBVyxZQUFZLEtBQUs7QUFBQSxJQUM5QztBQUFBLEVBQ0Y7QUFHQSxRQUFNLFdBQXlCLEtBQUssUUFDL0I7QUFBQSxJQUNDLEdBQUc7QUFBQSxJQUNILE9BQU87QUFBQSxNQUNMLEdBQUcsS0FBSztBQUFBLE1BQ1IsU0FBUyxjQUFjLEtBQUssTUFBTSxTQUFTLEVBQUU7QUFBQSxNQUM3QyxNQUFNO0FBQUEsSUFDUjtBQUFBLEVBQ0YsSUFDQTtBQUVKLFNBQU8sRUFBRSxPQUFPLFVBQVUsWUFBWSxLQUFLO0FBQzdDOzs7QUMvTUEsWUFBWSxlQUFlO0FBZ0IzQixJQUFNQyxZQUFXLENBQUMsVUFBcUQsT0FBTyxVQUFVLFlBQVksVUFBVTtBQUV2RyxJQUFNLG1CQUFtQixDQUFDLFdBQStDO0FBQzlFLE1BQUksQ0FBQ0EsVUFBUyxNQUFNLEVBQUcsUUFBTztBQUM5QixRQUFNLE1BQU8sT0FBZTtBQUM1QixNQUFJLENBQUMsSUFBSyxRQUFPO0FBQ2pCLE1BQUksT0FBTyxRQUFRLFlBQVksT0FBTyxRQUFRLFdBQVksUUFBTztBQUNqRSxTQUFPO0FBQ1Q7QUFFQSxJQUFNLG1CQUFtQixDQUFDLE1BQWMsU0FBaUIsU0FBeUI7QUFDaEYsUUFBTSxNQUFNLElBQUksTUFBTSxPQUFPO0FBQzVCLEVBQUMsSUFBWSxPQUFPO0FBQ3BCLEVBQUMsSUFBWSxPQUNaLFFBQ0E7QUFBQSxJQUNFO0FBQUEsSUFDQSxTQUFTLElBQUk7QUFBQSxJQUNiO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0YsRUFBRSxLQUFLLElBQUk7QUFDYixTQUFPO0FBQ1Q7QUFFQSxJQUFNLDBCQUEwQixDQUFDLFNBQy9CO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsSUFDRTtBQUFBLElBQ0EsU0FBUyxJQUFJO0FBQUEsSUFDYjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0YsRUFBRSxLQUFLLElBQUk7QUFDYjtBQUVGLElBQU0sZUFBZSxDQUFDLFNBQXFDO0FBQ3pELE1BQUksT0FBTyxTQUFTLFlBQVksS0FBSyxXQUFXLEdBQUc7QUFDakQsV0FBTyxFQUFFLElBQUksT0FBTyxPQUFPLGlCQUFpQixPQUFPLElBQUksR0FBRyxxQ0FBcUMsRUFBRTtBQUFBLEVBQ25HO0FBRUEsUUFBTSxNQUFNLEtBQUssTUFBTSxHQUFHO0FBQzFCLE1BQUksSUFBSSxXQUFXLEdBQUc7QUFDcEIsV0FBTyxFQUFFLElBQUksT0FBTyxPQUFPLGlCQUFpQixNQUFNLDRDQUE0QyxFQUFFO0FBQUEsRUFDbEc7QUFFQSxRQUFNLFdBQTZCLENBQUM7QUFDcEMsV0FBUyxJQUFJLEdBQUcsSUFBSSxJQUFJLFFBQVEsS0FBSztBQUNuQyxVQUFNLE1BQU0sSUFBSSxDQUFDO0FBQ2pCLFFBQUksSUFBSSxXQUFXLEdBQUc7QUFDcEIsYUFBTztBQUFBLFFBQ0wsSUFBSTtBQUFBLFFBQ0osT0FBTztBQUFBLFVBQ0w7QUFBQSxVQUNBLDRDQUE0QyxDQUFDO0FBQUEsVUFDN0M7QUFBQSxZQUNFO0FBQUEsWUFDQSxTQUFTLElBQUk7QUFBQSxZQUNiO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFVBQ0YsRUFBRSxLQUFLLElBQUk7QUFBQSxRQUNiO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFFQSxRQUFJLFdBQVcsS0FBSyxHQUFHLEdBQUc7QUFDeEIsWUFBTSxJQUFJLE9BQU8sR0FBRztBQUNwQixVQUFJLENBQUMsT0FBTyxTQUFTLENBQUMsS0FBSyxJQUFJLEdBQUc7QUFDaEMsZUFBTztBQUFBLFVBQ0wsSUFBSTtBQUFBLFVBQ0osT0FBTyxpQkFBaUIsTUFBTSxnQ0FBZ0MsR0FBRyxjQUFjLENBQUMsR0FBRztBQUFBLFFBQ3JGO0FBQUEsTUFDRjtBQUNBLGVBQVMsS0FBSyxLQUFLLE1BQU0sQ0FBQyxDQUFDO0FBQzNCO0FBQUEsSUFDRjtBQUVBLGFBQVMsS0FBSyxHQUFHO0FBQUEsRUFDbkI7QUFFQSxTQUFPLEVBQUUsSUFBSSxNQUFNLFNBQVM7QUFDOUI7QUFFQSxJQUFNLG9CQUFvQixDQUN4QixLQUNBLFVBQ0EsU0FDOEI7QUFDOUIsTUFBSSxTQUFTLFdBQVcsRUFBRyxRQUFPO0FBRWxDLE1BQUksVUFBVTtBQUNkLFNBQU8sTUFBTTtBQUNYLFFBQWMsb0JBQVUsT0FBTyxHQUFHO0FBQ2hDLFVBQUksS0FBSyxJQUFJLE9BQU8sRUFBRyxRQUFPO0FBQzlCLFdBQUssSUFBSSxPQUFPO0FBQ2hCLGdCQUFVLFFBQVEsRUFBRTtBQUNwQjtBQUFBLElBQ0Y7QUFDQSxRQUFjLHVCQUFhLE9BQU8sR0FBRztBQUNuQyxnQkFBVSxRQUFRO0FBQ2xCO0FBQUEsSUFDRjtBQUNBO0FBQUEsRUFDRjtBQUVBLE1BQWMsMkJBQWlCLE9BQU8sR0FBRztBQUN2QyxVQUFNLE9BQU8sa0JBQWtCLFFBQVEsTUFBTSxVQUFVLElBQUk7QUFDM0QsUUFBSSxLQUFNLFFBQU87QUFDakIsV0FBTyxrQkFBa0IsUUFBUSxJQUFJLFVBQVUsSUFBSTtBQUFBLEVBQ3JEO0FBRUEsTUFBYyxrQkFBUSxPQUFPLEdBQUc7QUFDOUIsZUFBVyxRQUFRLFFBQVEsT0FBTztBQUNoQyxZQUFNLFdBQVcsa0JBQWtCLE1BQU0sVUFBVSxJQUFJO0FBQ3ZELFVBQUksU0FBVSxRQUFPO0FBQUEsSUFDdkI7QUFDQSxXQUFPO0FBQUEsRUFDVDtBQUVBLE1BQWMsc0JBQVksT0FBTyxHQUFHO0FBQ2xDLFVBQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxJQUFJO0FBQ3hCLFFBQUksT0FBTyxTQUFTLFNBQVUsUUFBTztBQUNyQyxVQUFNLFVBQ0osT0FBTyxRQUFRLFNBQVMsU0FBUyxRQUFRLFNBQVMsSUFBSSxJQUFJLFFBQVEsS0FBSyxTQUFTLElBQUksUUFBUSxLQUFLLENBQUMsSUFBSTtBQUN4RyxXQUFPLFVBQVUsa0JBQWtCLFFBQVEsTUFBTSxNQUFNLElBQUksSUFBSTtBQUFBLEVBQ2pFO0FBRUEsTUFBYyx3QkFBYyxPQUFPLEdBQUc7QUFDcEMsVUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLElBQUk7QUFDeEIsUUFBSSxTQUFTLE9BQVcsUUFBTztBQUUvQixRQUFJLE9BQU8sU0FBUyxVQUFVO0FBQzVCLGlCQUFXLE1BQU0sUUFBUSxvQkFBb0I7QUFDM0MsWUFBSSxPQUFPLEdBQUcsSUFBSSxNQUFNLEtBQU07QUFDOUIsZUFBTyxrQkFBa0IsR0FBRyxNQUFNLE1BQU0sSUFBSTtBQUFBLE1BQzlDO0FBQUEsSUFDRjtBQUVBLGVBQVcsT0FBTyxRQUFRLGlCQUFpQjtBQUN6QyxVQUFJLFFBQXVCLElBQUk7QUFDL0IsYUFBaUIsdUJBQWEsS0FBSyxHQUFHO0FBQ3BDLGdCQUFRLE1BQU07QUFBQSxNQUNoQjtBQUNBLFlBQU1DLE9BQU8sT0FBZTtBQUM1QixZQUFNLGdCQUFnQkEsU0FBUSxtQkFBbUJBLFNBQVE7QUFDekQsWUFBTSxnQkFBZ0JBLFNBQVE7QUFDOUIsVUFBSSxPQUFPLFNBQVMsWUFBWSxlQUFlO0FBQzdDLGVBQU8sa0JBQWtCLElBQUksTUFBTSxNQUFNLElBQUk7QUFBQSxNQUMvQztBQUNBLFVBQUksT0FBTyxTQUFTLFlBQVksZUFBZTtBQUM3QyxlQUFPLGtCQUFrQixJQUFJLE1BQU0sTUFBTSxJQUFJO0FBQUEsTUFDL0M7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUVBLFFBQU0sTUFBTyxTQUFpQjtBQUM5QixNQUFJLFFBQVEsZ0JBQWdCLFFBQVEsb0JBQW9CLFFBQVEsbUJBQW1CLFFBQVEsZUFBZTtBQUN4RyxXQUFPO0FBQUEsRUFDVDtBQUVBLFNBQU87QUFDVDtBQUVBLElBQU0sbUJBQ0osQ0FBQyxhQUNELENBQUMsVUFBNEI7QUFDM0IsTUFBSSxVQUFtQjtBQUN2QixhQUFXLE9BQU8sVUFBVTtBQUMxQixRQUFJLFdBQVcsS0FBTSxRQUFPO0FBQzVCLFFBQUksT0FBTyxRQUFRLFVBQVU7QUFDM0IsVUFBSSxNQUFNLFFBQVEsT0FBTyxHQUFHO0FBQzFCLGtCQUFVLFFBQVEsR0FBRztBQUNyQjtBQUFBLE1BQ0Y7QUFDQSxVQUFJRCxVQUFTLE9BQU8sR0FBRztBQUNyQixrQkFBVSxRQUFRLE9BQU8sR0FBRyxDQUFDO0FBQzdCO0FBQUEsTUFDRjtBQUNBLGFBQU87QUFBQSxJQUNUO0FBQ0EsUUFBSUEsVUFBUyxPQUFPLEdBQUc7QUFDckIsZ0JBQVUsUUFBUSxHQUFHO0FBQ3JCO0FBQUEsSUFDRjtBQUNBLFdBQU87QUFBQSxFQUNUO0FBQ0EsU0FBTztBQUNUO0FBRUssSUFBTSxxQkFBcUIsQ0FBQyxNQUFjLGNBQXFEO0FBQ3BHLFFBQU0sU0FBUyxhQUFhLElBQUk7QUFDaEMsTUFBSSxDQUFDLE9BQU8sR0FBSSxRQUFPLEVBQUUsSUFBSSxPQUFPLE9BQU8sT0FBTyxNQUFNO0FBRXhELE1BQUksV0FBVztBQUNiLFVBQU0sV0FBVyxrQkFBa0IsV0FBVyxPQUFPLFVBQVUsb0JBQUksSUFBSSxDQUFDO0FBQ3hFLFFBQUksQ0FBQyxVQUFVO0FBQ2IsYUFBTyxFQUFFLElBQUksT0FBTyxPQUFPLHdCQUF3QixJQUFJLEVBQUU7QUFBQSxJQUMzRDtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQUEsSUFDTCxJQUFJO0FBQUEsSUFDSixVQUFVLGlCQUFpQixPQUFPLFFBQVE7QUFBQSxJQUMxQyxVQUFVLE9BQU87QUFBQSxFQUNuQjtBQUNGOzs7QUNoT08sSUFBTSxlQUFlLE9BQXlCLEVBQUUsY0FBYyxDQUFDLEVBQUU7QUFVakUsSUFBTSxZQUFZLENBQUMsUUFBNEIsT0FBeUIsVUFBbUM7QUFDaEgsTUFBSSxPQUFPLFNBQVMsWUFBWTtBQUM5QixXQUFPO0FBQUEsTUFDTCxVQUFVO0FBQUEsTUFDVixXQUFXO0FBQUEsTUFDWCxzQkFBc0IsTUFBTSxhQUFhO0FBQUEsTUFDekMsYUFBYTtBQUFBLE1BQ2IsVUFBVSxPQUFPO0FBQUEsSUFDbkI7QUFBQSxFQUNGO0FBRUEsUUFBTSxpQkFBaUIsT0FBTztBQUM5QixRQUFNLGNBQ0osT0FBTyxtQkFBbUIsWUFBWSxPQUFPLFNBQVMsY0FBYyxLQUFLLGtCQUFrQixJQUN2RixLQUFLLE1BQU0sY0FBYyxJQUN6QjtBQUVOLE1BQUksZUFBZSxHQUFHO0FBQ3BCLFdBQU87QUFBQSxNQUNMLFVBQVU7QUFBQSxNQUNWLFdBQVc7QUFBQSxNQUNYLHNCQUFzQixNQUFNLGFBQWE7QUFBQSxNQUN6QztBQUFBLE1BQ0EsVUFBVSxPQUFPO0FBQUEsSUFDbkI7QUFBQSxFQUNGO0FBRUEsUUFBTSxjQUFjLE9BQU87QUFDM0IsUUFBTSxXQUNKLE9BQU8sZ0JBQWdCLFlBQVksT0FBTyxTQUFTLFdBQVcsS0FBSyxjQUFjLElBQzdFLEtBQUssTUFBTSxXQUFXLElBQ3RCO0FBRU4sUUFBTSxrQkFBa0IsQ0FBQyxHQUFHLE1BQU0sY0FBYyxLQUFLO0FBQ3JELFFBQU0sZUFBZSxXQUFXLGdCQUFnQixPQUFPLENBQUMsTUFBTSxLQUFLLFFBQVEsUUFBUSxJQUFJO0FBR3ZGLFFBQU0sTUFBTSxjQUFjO0FBQzFCLFFBQU0sU0FBUyxhQUFhLFNBQVMsTUFBTSxhQUFhLE1BQU0sYUFBYSxTQUFTLEdBQUcsSUFBSTtBQUUzRixRQUFNLHVCQUF1QixPQUFPO0FBQ3BDLFFBQU0sV0FBZ0Msd0JBQXdCLGNBQWMsWUFBWTtBQUV4RixTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0EsV0FBVyxFQUFFLGNBQWMsT0FBTztBQUFBLElBQ2xDO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7OztBTGdDTyxJQUFNLG9CQUFOLGNBQWdDRSxTQUFRLElBQUksNEJBQTRCLEVBQXFDLEVBQUU7QUFBQztBQUV2SCxJQUFNLHdCQUF3QkMsVUFBUyxXQUF1QyxNQUFTO0FBQ3ZGLElBQU0sNEJBQTRCQSxVQUFTO0FBQUEsRUFDekM7QUFDRjtBQUNBLElBQU0scUJBQXFCO0FBRTNCLElBQU0sc0JBQXNCLENBQUMsY0FBOEIsV0FBVyxTQUFTO0FBSS9FLElBQU0sa0JBQWtCLENBQUMsVUFBK0U7QUFDdEcsUUFBTSxVQUFlLE1BQU07QUFDM0IsTUFBSSxDQUFDLFFBQVMsUUFBTyxDQUFDO0FBQ3RCLE9BQ0csUUFBUSxTQUFTLGtCQUFrQixRQUFRLFNBQVMsd0JBQ3JELE9BQU8sUUFBUSxlQUFlLFlBQzlCLE9BQU8sUUFBUSxXQUFXLFlBQzFCLE9BQU8sU0FBUyxRQUFRLE1BQU0sS0FDOUIsUUFBUSxVQUFVLEdBQ2xCO0FBQ0EsVUFBTSxTQUFTLEtBQUssTUFBTSxRQUFRLE1BQU07QUFDeEMsV0FBTztBQUFBLE1BQ0w7QUFBQSxNQUNBLE9BQU8sR0FBRyxRQUFRLFVBQVUsTUFBTSxNQUFNO0FBQUEsSUFDMUM7QUFBQSxFQUNGO0FBQ0EsU0FBTyxDQUFDO0FBQ1Y7QUFFQSxJQUFNLHlCQUF5QixDQUFDLE9BQXFCLFNBQXlDO0FBQzVGLFFBQU0sV0FBVyxNQUFNLFNBQVMsbUJBQW1CLE1BQU0sV0FBVztBQUNwRSxRQUFNLGFBQWEsTUFBTSxTQUFTLG1CQUFtQixNQUFNLGFBQWE7QUFDeEUsU0FBa0IsaUNBQWlDO0FBQUEsSUFDakQ7QUFBQSxJQUNBO0FBQUEsSUFDQSxNQUFNO0FBQUEsSUFDTixVQUFVO0FBQUEsSUFDVixTQUNFO0FBQUEsSUFDRixNQUNFO0FBQUEsSUFFRjtBQUFBLEVBQ0YsQ0FBQztBQUNIO0FBRUEsSUFBTSwrQkFBK0IsQ0FBQyxZQUEwRDtBQUM5RixNQUFJO0FBQ0YsVUFBTSxZQUFZLG9CQUFvQixPQUFjO0FBQ3BELFdBQU8saUJBQWlCLFVBQVUsV0FBVztBQUFBLEVBQy9DLFFBQVE7QUFDTixXQUFPO0FBQUEsRUFDVDtBQUNGO0FBRUEsSUFBTSxpQkFBaUIsQ0FBQyxPQUFjLGFBQTRCO0FBQ2hFLFFBQU0sT0FBUSxNQUFjO0FBQzVCLE1BQUksT0FBTyxTQUFTLFlBQVksS0FBSyxTQUFTLEdBQUc7QUFDL0MsUUFBSSxDQUFDLEtBQUssU0FBUyxXQUFXLEdBQUc7QUFDL0I7QUFBQyxNQUFDLE1BQWMsT0FBTyxZQUFZLFFBQVE7QUFBQSxFQUFLLElBQUk7QUFBQSxJQUN0RDtBQUNBLFdBQU87QUFBQSxFQUNUO0FBQ0E7QUFBQyxFQUFDLE1BQWMsT0FBTyxZQUFZLFFBQVE7QUFDM0MsU0FBTztBQUNUO0FBRUEsSUFBTSxzQkFBc0IsQ0FBQyxXQUF3QztBQUNuRSxNQUFJLENBQUMsVUFBVSxPQUFPLFdBQVcsU0FBVSxRQUFPO0FBQ2xELFFBQU0sWUFBWTtBQUNsQixNQUFJLE9BQU8sVUFBVSxTQUFTLFlBQVksVUFBVSxLQUFLLFNBQVMsRUFBRyxRQUFPLFVBQVU7QUFDdEYsTUFBSSxPQUFPLFVBQVUsU0FBUyxZQUFZLFVBQVUsS0FBSyxTQUFTLEVBQUcsUUFBTyxVQUFVO0FBQ3RGLFNBQU87QUFDVDtBQUVPLElBQU0sT0FBTyxDQUFDLFlBR25CQyxRQUFPLElBQUksYUFBYTtBQUN0QixRQUFNLGVBQWUsT0FBT0EsUUFBTztBQUNuQyxRQUFNLGtCQUNKLE9BQU8sU0FBUyxvQkFBb0IsWUFDcEMsT0FBTyxTQUFTLFFBQVEsZUFBZSxLQUN2QyxRQUFRLG1CQUFtQixJQUN2QixLQUFLLE1BQU0sUUFBUSxlQUFlLElBQ2xDO0FBRU4sUUFBTSxnQkFBZ0Isb0JBQUksSUFBd0M7QUFDbEUsUUFBTSxZQUFZLG9CQUFJLElBQXNDO0FBRTVELFFBQU0sZUFBK0IsQ0FBQztBQUN0QyxRQUFNLFlBQVksT0FBTyxPQUFPLFFBQXNCLEtBQUssSUFBSSxHQUFHLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQyxDQUFDO0FBRWxHLFFBQU0sYUFBYSxNQUFNO0FBQ3ZCLFFBQUksbUJBQW1CLEdBQUc7QUFDeEIsbUJBQWEsU0FBUztBQUN0QjtBQUFBLElBQ0Y7QUFDQSxRQUFJLGFBQWEsVUFBVSxnQkFBaUI7QUFDNUMsVUFBTSxTQUFTLGFBQWEsU0FBUztBQUNyQyxpQkFBYSxPQUFPLEdBQUcsTUFBTTtBQUFBLEVBQy9CO0FBRUEsUUFBTSxtQkFBbUIsQ0FBQyxVQUN4QkEsUUFBTyxJQUFJLGFBQWE7QUFDdEIsVUFBTSxtQkFBbUIsT0FBT0QsVUFBUyxJQUFVLHVCQUF1QjtBQUcxRSxRQUFJLHFCQUFxQixPQUFPO0FBQzlCO0FBQUEsSUFDRjtBQUVBLFVBQU0sWUFBWSxNQUFNLFNBQVMsU0FBUztBQUMxQyxVQUFNLG9CQUE2Qiw4QkFBOEIsTUFBTSxRQUFRO0FBQy9FLFVBQU0sV0FBVyxvQkFBb0IsU0FBUztBQUM5QyxVQUFNLEVBQUUsUUFBUSxNQUFNLElBQUksZ0JBQWdCLEtBQUs7QUFFL0MsV0FBYSxPQUFPO0FBQUEsTUFDbEIsTUFBTSxNQUFNO0FBQUEsTUFDWjtBQUFBLE1BQ0EsWUFBWTtBQUFBLE1BQ1osVUFBVSxNQUFNO0FBQUEsTUFDaEIsVUFBVSxNQUFNO0FBQUEsTUFDaEIsVUFBVSxNQUFNO0FBQUEsTUFDaEIsYUFBYSxNQUFNO0FBQUEsTUFDbkIsU0FBUyxNQUFNO0FBQUEsTUFDZixVQUFVLE1BQU07QUFBQSxNQUNoQixPQUFPLE1BQU07QUFBQSxNQUNiO0FBQUEsTUFDQTtBQUFBLElBQ0YsQ0FBUTtBQUFBLEVBQ1YsQ0FBQztBQUVILFFBQU0sZUFBZSxDQUFDLFVBQ3BCQyxRQUFPLElBQUksYUFBYTtBQUN0QixpQkFBYSxLQUFLLEtBQUs7QUFDdkIsZUFBVztBQUNYLFdBQU8sT0FBTyxRQUFRLFdBQVcsS0FBSztBQUN0QyxXQUFPLGlCQUFpQixLQUFLO0FBQUEsRUFDL0IsQ0FBQztBQUVILFFBQU0sT0FBTyxDQUFDLFVBQ1pBLFFBQU8sSUFBSSxhQUFhO0FBQ3RCLFVBQU0sWUFBWSxPQUFPRCxVQUFTLElBQUkseUJBQXlCO0FBQy9ELFFBQUksV0FBVztBQUNiLFlBQU0sV0FBVyxPQUFPRSxLQUFJLE9BQU8sV0FBVyxDQUFDLFVBQVU7QUFDdkQsY0FBTSxDQUFDLGNBQWMsU0FBUyxJQUFrQiwyQkFBMkIsT0FBTyxLQUFLO0FBQ3ZGLGVBQU8sQ0FBQyxjQUFjLFNBQVM7QUFBQSxNQUNqQyxDQUFDO0FBRUQsVUFBSSxTQUFTLFNBQVMsVUFBVSxTQUFTLFNBQVMsZUFBZTtBQUMvRCxlQUFPLGFBQWEsU0FBUyxLQUFLO0FBQUEsTUFDcEM7QUFDQTtBQUFBLElBQ0Y7QUFFQSxVQUFNLFdBQXlCLDRCQUE0QixLQUFLO0FBQ2hFLFdBQU8sYUFBYSxTQUFTLEtBQUs7QUFBQSxFQUNwQyxDQUFDO0FBRUgsUUFBTSxzQkFBc0IsQ0FDMUIsT0FDQSxXQUNBLE1BQ0EsU0FDQSxTQUN3QjtBQUN4QixRQUFJLENBQUMsU0FBUyxHQUFHO0FBQ2YsYUFBT0QsUUFBTztBQUFBLElBQ2hCO0FBQ0EsVUFBTSxXQUFXLE1BQU0sU0FBUyxtQkFBbUIsTUFBTSxXQUFXO0FBQ3BFLFVBQU0sYUFBYSxNQUFNLFNBQVMsbUJBQW1CLE1BQU0sYUFBYTtBQUN4RSxXQUFhLE9BQU87QUFBQSxNQUNsQixNQUFNO0FBQUEsTUFDTjtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQSxVQUFVO0FBQUEsTUFDVjtBQUFBLE1BQ0E7QUFBQSxNQUNBLFdBQVc7QUFBQSxNQUNYLE1BQU07QUFBQSxJQUNSLENBQUM7QUFBQSxFQUNIO0FBRUEsUUFBTSw2QkFBNkIsQ0FBQyxpQkFBMkQ7QUFDN0YsVUFBTSxXQUFXLGFBQWEsV0FBVyxZQUFZLENBQUM7QUFDdEQsVUFBTSx1QkFBaUMsQ0FBQztBQUN4QyxlQUFXLFdBQVcsYUFBYSxXQUFXLFVBQVU7QUFDdEQsVUFBSSxRQUFRLFNBQVMsa0JBQWtCLFFBQVEsU0FBUyxxQkFBcUI7QUFDM0UsNkJBQXFCLEtBQUssUUFBUSxRQUFRO0FBQUEsTUFDNUM7QUFBQSxJQUNGO0FBRUEsVUFBTSxXQUFXLE1BQU0sS0FBSyxvQkFBSSxJQUFJLENBQUMsR0FBRyxVQUFVLEdBQUcsb0JBQW9CLENBQUMsQ0FBQztBQUMzRSxRQUFJLFNBQVMsV0FBVyxFQUFHLFFBQU8sQ0FBQztBQUVuQyxVQUFNLFVBQW9CLENBQUM7QUFDM0IsZUFBVyxPQUFPLFVBQVU7QUFDMUIsVUFBSSxPQUFPLFFBQVEsWUFBWSxJQUFJLFdBQVcsRUFBRztBQUdqRCxZQUFNLE1BQU1GLFNBQVEsSUFBSSxpQkFBaUIsR0FBRyxFQUFFLEVBQUU7QUFDaEQsWUFBTSxRQUFRQSxTQUFRLFVBQVUsYUFBYSxLQUFLLEdBQUc7QUFDckQsVUFBSUksUUFBTyxPQUFPLEtBQUssR0FBRztBQUN4QixnQkFBUSxLQUFLLEdBQUc7QUFBQSxNQUNsQjtBQUFBLElBQ0Y7QUFDQSxXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sZUFBZSxDQUNuQixVQUNBLFdBRUFGLFFBQU8sSUFBSSxhQUFhO0FBQ3RCLFFBQ0UsU0FBUyxPQUFPLFdBQVcsYUFDM0IsU0FBUyxPQUFPLFdBQVcsWUFDM0IsU0FBUyxPQUFPLFdBQVcsWUFDM0I7QUFDQTtBQUFBLElBQ0Y7QUFFQSxVQUFNLFFBQVEsU0FBUztBQUN2QixhQUFTLFNBQVM7QUFBQSxNQUNoQixHQUFHLFNBQVM7QUFBQSxNQUNaLFFBQVE7QUFBQSxNQUNSLGVBQWU7QUFBQSxJQUNqQjtBQUVBLFFBQUksT0FBTztBQUNULGFBQU9HLE9BQU0sVUFBVSxLQUFLO0FBQUEsSUFDOUI7QUFFQSxXQUFPLE1BQU0sU0FBUyxTQUFTLHFCQUFxQjtBQUVwRCxhQUFTLFNBQVM7QUFBQSxNQUNoQixHQUFHLFNBQVM7QUFBQSxNQUNaLFFBQVE7QUFBQSxNQUNSLGVBQWU7QUFBQSxJQUNqQjtBQUNBLGFBQVMsUUFBUTtBQUVqQixVQUFNLE1BQW9CO0FBQUEsTUFDeEIsTUFBTTtBQUFBLE1BQ04sVUFBVSxTQUFTO0FBQUEsTUFDbkIsVUFBVTtBQUFBLE1BQ1YsVUFBVSxTQUFTO0FBQUEsTUFDbkIsYUFBYSxLQUFLLElBQUk7QUFBQSxJQUN4QjtBQUNBLFdBQU8sS0FBSyxHQUFHO0FBRWYsVUFBTSxlQUFlLGNBQWMsSUFBSSxTQUFTLGVBQWU7QUFDL0QsUUFBSSxjQUFjLGNBQWM7QUFDOUIsbUJBQWEsZUFBZTtBQUM1QixhQUFPLGtCQUFrQixTQUFTLGVBQWU7QUFBQSxJQUNuRDtBQUFBLEVBQ0YsQ0FBQztBQUVILFFBQU0sb0JBQStFLENBQUMsb0JBQ3BGSCxRQUFPLElBQUksYUFBYTtBQUN0QixVQUFNLGVBQWUsY0FBYyxJQUFJLGVBQWU7QUFDdEQsUUFBSSxDQUFDLGFBQWM7QUFDbkIsaUJBQWEsZUFBZTtBQUU1QixVQUFNLE9BQU8sT0FBTyx1QkFBdUIsYUFBYSxTQUFTLE9BQU8sOEJBQThCO0FBQ3RHLFFBQUksS0FBTTtBQUdWLFVBQU0sWUFBWSxhQUFhO0FBQy9CLFFBQUksV0FBVztBQUNiLFlBQU0sVUFBVSxVQUFVLElBQUksU0FBUztBQUN2QyxVQUFJLFlBQVksUUFBUSxPQUFPLFdBQVcsYUFBYSxRQUFRLE9BQU8sV0FBVyxhQUFhO0FBQzVGO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFFQSxVQUFNLFNBQVMsYUFBYTtBQUM1QixVQUFNLFdBQW9DO0FBQUEsTUFDeEMsVUFBVSxhQUFhO0FBQUEsTUFDdkI7QUFBQSxJQUNGO0FBQ0EsVUFBTSxvQkFBNkIsOEJBQThCLFFBQVE7QUFFekUsVUFBTSx3QkFBd0IsT0FBTyxNQUFNLFFBQXdCLEVBQUU7QUFFckUsVUFBTSxnQkFBK0I7QUFBQSxNQUNuQztBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQSxXQUFXLGFBQWEsU0FBUztBQUFBLE1BQ2pDLE9BQU8sYUFBYSxTQUFTO0FBQUEsTUFDN0IsV0FBVyxhQUFhO0FBQUEsTUFDeEI7QUFBQSxNQUNBLFFBQVE7QUFBQSxRQUNOO0FBQUEsUUFDQSxRQUFRO0FBQUEsTUFDVjtBQUFBLE1BQ0EsY0FBYztBQUFBLE1BQ2QsZ0JBQWdCO0FBQUEsSUFDbEI7QUFFQSxjQUFVLElBQUksbUJBQW1CLGFBQWE7QUFDOUMsaUJBQWEsb0JBQW9CO0FBS2pDLFFBQUksYUFBYSxjQUFjLGNBQWM7QUFDM0MsYUFBT0ksT0FBTTtBQUFBLFFBQ1gsYUFBYTtBQUFBLFFBQ2JKLFFBQU8sUUFBUSxNQUFNO0FBQ25CLGdCQUFNLFNBQVMsY0FBYyxPQUFPO0FBQ3BDLGNBQUksV0FBVyxhQUFhLFdBQVcsWUFBWSxXQUFXLFlBQVk7QUFDeEUsbUJBQU9BLFFBQU87QUFBQSxVQUNoQjtBQUNBLGlCQUFPLGFBQWEsZUFBZSxlQUFlO0FBQUEsUUFDcEQsQ0FBQyxFQUFFLEtBQUtBLFFBQU8sY0FBYyxNQUFNQSxRQUFPLElBQUksQ0FBQztBQUFBLE1BQ2pEO0FBQUEsSUFDRjtBQUdBLFdBQU8sS0FBSztBQUFBLE1BQ1YsTUFBTTtBQUFBLE1BQ047QUFBQSxNQUNBLFVBQVU7QUFBQSxNQUNWLFVBQVUsY0FBYztBQUFBLE1BQ3hCLGFBQWEsS0FBSyxJQUFJO0FBQUEsSUFDeEIsQ0FBQztBQUVELFVBQU0sVUFBVSwyQkFBMkIsWUFBWTtBQUN2RCxRQUFJLFFBQVEsU0FBUyxHQUFHO0FBQ3RCLFlBQU0sT0FBTyxTQUFTLElBQ2xCO0FBQUEsUUFDRTtBQUFBLFFBQ0EsWUFBWSxRQUFRLEtBQUssSUFBSSxDQUFDO0FBQUEsUUFDOUI7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0EsK0NBQStDLFFBQVEsQ0FBQyxDQUFDO0FBQUEsUUFDekQ7QUFBQSxNQUNGLEVBQUUsS0FBSyxJQUFJLElBQ1g7QUFFSixZQUFNLFFBQWtDO0FBQUEsUUFDdEMsU0FBUyxrQ0FBa0MsUUFBUSxLQUFLLElBQUksQ0FBQztBQUFBLFFBQzdELE1BQU07QUFBQSxRQUNOO0FBQUEsTUFDRjtBQUVBLG9CQUFjLFNBQVM7QUFBQSxRQUNyQixHQUFHLGNBQWM7QUFBQSxRQUNqQixRQUFRO0FBQUEsUUFDUixlQUFlO0FBQUEsUUFDZixXQUFXO0FBQUEsTUFDYjtBQUVBLGFBQU8sS0FBSztBQUFBLFFBQ1YsTUFBTTtBQUFBLFFBQ047QUFBQSxRQUNBLFVBQVU7QUFBQSxRQUNWLFVBQVUsY0FBYztBQUFBLFFBQ3hCLGFBQWEsS0FBSyxJQUFJO0FBQUEsUUFDdEI7QUFBQSxNQUNGLENBQUM7QUFFRCxhQUFPO0FBQUEsUUFDTCxhQUFhLFNBQVM7QUFBQSxRQUN0QixhQUFhLFNBQVM7QUFBQSxRQUN0QjtBQUFBLFFBQ0EsTUFBTTtBQUFBLFFBQ047QUFBQSxNQUNGO0FBQ0E7QUFBQSxJQUNGO0FBRUEsVUFBTSwwQkFBMEIsYUFBYSxXQUFXLHFCQUFxQjtBQUU3RSxVQUFNLFVBQVUsYUFBYTtBQUU3QixVQUFNLGlCQUFpQixNQUE0QjtBQUNqRCxVQUFJLENBQUMseUJBQXlCO0FBQzVCLGVBQU87QUFBQSxNQUNUO0FBRUEsWUFBTSxXQUFXLGFBQWEsV0FBVyxZQUFZLENBQUM7QUFDdEQsVUFBSSxTQUFTLFdBQVcsR0FBRztBQUN6QixlQUFPO0FBQUEsTUFDVDtBQUVBLFlBQU0sTUFBTSxNQUFNLEtBQUssSUFBSSxJQUFJLFFBQVEsQ0FBQztBQUN4QyxVQUFJLFVBQVU7QUFFZCxpQkFBVyxZQUFZLEtBQUs7QUFDMUIsWUFBSSxPQUFPLGFBQWEsWUFBWSxTQUFTLFdBQVcsRUFBRztBQUMzRCxjQUFNLE1BQU1GLFNBQVEsSUFBSSxpQkFBaUIsUUFBUSxFQUFFLEVBQUU7QUFDckQsY0FBTSxRQUFRQSxTQUFRLFVBQVUsU0FBUyxHQUFHO0FBQzVDLFlBQUlJLFFBQU8sT0FBTyxLQUFLLEVBQUc7QUFDMUIsY0FBTSxVQUFVLE1BQU07QUFFdEIsY0FBTSxpQkFBaUIsQ0FBQyxXQUN0QkYsUUFBTyxJQUFJLGFBQWE7QUFDdEIsZ0JBQU0sVUFBVSxPQUFPRCxVQUFTLElBQUkscUJBQXFCO0FBQ3pELGNBQUksQ0FBQyxRQUFTO0FBRWQsZ0JBQU0sV0FBVyxvQkFBb0IsTUFBTSxLQUFLO0FBQ2hELGdCQUFNLG1CQUFtQixPQUFPLFFBQVEsYUFBYSxXQUFXLFFBQVEsV0FBVztBQUNuRixnQkFBTSxxQkFBcUIsT0FBTyxRQUFRLGVBQWUsV0FBVyxRQUFRLGFBQWE7QUFFekYsZ0JBQU0sTUFBb0I7QUFBQSxZQUN4QixNQUFNO0FBQUEsWUFDTjtBQUFBLFlBQ0E7QUFBQSxZQUNBLFVBQVU7QUFBQSxjQUNSLFVBQVU7QUFBQSxjQUNWLFlBQVk7QUFBQSxjQUNaO0FBQUEsWUFDRjtBQUFBLFlBQ0EsVUFBVTtBQUFBLFlBQ1YsVUFBVSxjQUFjO0FBQUEsWUFDeEIsYUFBYSxLQUFLLElBQUk7QUFBQSxVQUN4QjtBQUVBLGlCQUFPLEtBQUssR0FBRztBQUFBLFFBQ2pCLENBQUM7QUFFSCxjQUFNLFVBQVU7QUFBQSxVQUNkLEdBQUc7QUFBQSxVQUNILFVBQVUsQ0FBQyxXQUFvQixRQUFRLFNBQVMsTUFBTSxFQUFFLEtBQUtDLFFBQU8sSUFBSSxNQUFNLGVBQWUsTUFBTSxDQUFDLENBQUM7QUFBQSxVQUNyRyxxQkFBcUIsQ0FBQyxXQUNwQixRQUFRLG9CQUFvQixNQUFNLEVBQUUsS0FBS0EsUUFBTyxJQUFJLE1BQU0sZUFBZSxNQUFNLENBQUMsQ0FBQztBQUFBLFVBQ25GLGVBQWUsQ0FBQyxZQUNkLFFBQ0csY0FBYyxPQUFPLEVBQ3JCLEtBQUtBLFFBQU8sSUFBSSxNQUFNQSxRQUFPLFFBQVEsU0FBUyxnQkFBZ0IsRUFBRSxTQUFTLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFBQSxRQUN4RjtBQUVBLGtCQUFVRixTQUFRLElBQUksS0FBSyxPQUFPLEVBQUUsT0FBTztBQUFBLE1BQzdDO0FBRUEsYUFBTztBQUFBLElBQ1Q7QUFFQSxVQUFNLGFBQWEsZUFBZTtBQUNsQyxVQUFNLGtCQUFrQkUsUUFBTyxRQUFRLGFBQWEsU0FBUyxVQUFVO0FBRXZFLFVBQU0sb0JBQW9CLENBQUMsU0FDekJBLFFBQU8sSUFBSSxhQUFhO0FBQ3RCLFVBQUksS0FBSyxTQUFTLFNBQVM7QUFDekIsY0FBTSxXQUFXLFNBQVMsY0FBYyxLQUFLLE9BQU87QUFDcEQsWUFBSUUsUUFBTyxPQUFPLFFBQVEsR0FBRztBQUMzQixnQkFBTSxNQUFNLElBQUksTUFBTSw4REFBOEQsS0FBSyxPQUFPLEVBQUU7QUFDakcsVUFBQyxJQUFZLE9BQU87QUFDcEIsVUFBQyxJQUFZLE9BQ1o7QUFDRixpQkFBTyxPQUFPRixRQUFPLEtBQUssR0FBRztBQUFBLFFBQy9CO0FBRUEsZUFBT0ssUUFBTyxLQUFLLFNBQVMsS0FBSyxFQUFFO0FBQUEsVUFDakNBLFFBQU87QUFBQSxZQUNMLE9BQ0c7QUFBQSxjQUNDLE1BQU07QUFBQSxjQUNOLE1BQU0sS0FBSztBQUFBLGNBQ1gsU0FBUyxLQUFLO0FBQUEsWUFDaEI7QUFBQSxVQUNKO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFFQSxVQUFJLEtBQUssU0FBUyxnQkFBZ0I7QUFDaEMsY0FBTUMsT0FBTVIsU0FBUSxJQUFJLGlCQUFpQixLQUFLLFFBQVEsRUFBRSxFQUFFO0FBQzFELGNBQU1TLFNBQVFULFNBQVEsVUFBVSxTQUFTUSxJQUFHO0FBQzVDLFlBQUlKLFFBQU8sT0FBT0ssTUFBSyxHQUFHO0FBQ3hCLGlCQUFPLE9BQU9QLFFBQU8sS0FBSyxJQUFJLE1BQU0sb0NBQW9DLEtBQUssUUFBUSxFQUFFLENBQUM7QUFBQSxRQUMxRjtBQUVBLGNBQU1RLFdBQVVELE9BQU07QUFJdEIsWUFBSSxDQUFDLHlCQUF5QjtBQUM1QixnQkFBTUUsVUFBU0QsU0FBUTtBQUN2QixjQUFJLENBQUNDLFNBQVE7QUFDWCxrQkFBTSxNQUFNLElBQUksTUFBTSw4RUFBOEU7QUFDbkcsWUFBQyxJQUFZLE9BQU87QUFDcEIsWUFBQyxJQUFZLE9BQU8sWUFBWSxLQUFLLFFBQVE7QUFDOUMsbUJBQU8sT0FBT1QsUUFBTyxLQUFLLEdBQUc7QUFBQSxVQUMvQjtBQUVBLGlCQUFPUyxRQUFPO0FBQUEsWUFDWkosUUFBTyxPQUFPLENBQUMsV0FBZ0Isb0JBQW9CLE1BQU0sTUFBTSxLQUFLLFFBQVE7QUFBQSxZQUM1RUEsUUFBTztBQUFBLGNBQ0wsT0FDRztBQUFBLGdCQUNDLE1BQU07QUFBQSxnQkFDTixNQUFNLEtBQUs7QUFBQSxnQkFDWCxVQUFVLEtBQUs7QUFBQSxnQkFDZixZQUFZRyxTQUFRO0FBQUEsZ0JBQ3BCLFVBQVUsS0FBSztBQUFBLGdCQUNmLFFBQVE7QUFBQSxjQUNWO0FBQUEsWUFDSjtBQUFBLFVBQ0Y7QUFBQSxRQUNGO0FBRUEsY0FBTSxTQUFTQSxTQUFRO0FBQ3ZCLFlBQUksQ0FBQyxRQUFRO0FBQ1gsZ0JBQU0sTUFBTSxJQUFJO0FBQUEsWUFDZDtBQUFBLFVBQ0Y7QUFDQyxVQUFDLElBQVksT0FBTztBQUNwQixVQUFDLElBQVksT0FBTyxZQUFZLEtBQUssUUFBUTtBQUM5QyxpQkFBTyxPQUFPUixRQUFPLEtBQUssR0FBRztBQUFBLFFBQy9CO0FBRUEsZUFBTyxPQUFPO0FBQUEsVUFDWkssUUFBTyxPQUFPLENBQUMsUUFBYSxvQkFBb0IsSUFBSSxLQUFLLE1BQU0sS0FBSyxRQUFRO0FBQUEsVUFDNUVBLFFBQU8sSUFBSSxDQUFDLFFBQWE7QUFDdkIsa0JBQU0sU0FBUyxLQUFLLE1BQU07QUFDMUIsbUJBQU87QUFBQSxjQUNMLE1BQU07QUFBQSxjQUNOLE1BQU0sS0FBSztBQUFBLGNBQ1gsVUFBVSxLQUFLO0FBQUEsY0FDZixZQUFZRyxTQUFRO0FBQUEsY0FDcEIsVUFBVSxLQUFLO0FBQUEsY0FDZixRQUFRLE9BQU8sV0FBVyxXQUFXLFNBQVM7QUFBQSxZQUNoRDtBQUFBLFVBQ0YsQ0FBQztBQUFBLFFBQ0g7QUFBQSxNQUNGO0FBR0EsWUFBTSxNQUFNVixTQUFRLElBQUksaUJBQWlCLEtBQUssUUFBUSxFQUFFLEVBQUU7QUFDMUQsWUFBTSxRQUFRQSxTQUFRLFVBQVUsU0FBUyxHQUFHO0FBQzVDLFVBQUlJLFFBQU8sT0FBTyxLQUFLLEdBQUc7QUFDeEIsZUFBTyxPQUFPRixRQUFPLEtBQUssSUFBSSxNQUFNLG9DQUFvQyxLQUFLLFFBQVEsRUFBRSxDQUFDO0FBQUEsTUFDMUY7QUFFQSxZQUFNLFVBQVUsTUFBTTtBQUN0QixZQUFNLFlBQVksNkJBQTZCLE9BQU87QUFDdEQsWUFBTSxpQkFBaUIsbUJBQW1CLEtBQUssTUFBTSxTQUFTO0FBQzlELFVBQUksQ0FBQyxlQUFlLElBQUk7QUFDdEIsZUFBTyxPQUFPQSxRQUFPLEtBQUssZUFBZSxlQUFlLE9BQU8sS0FBSyxRQUFRLENBQUM7QUFBQSxNQUMvRTtBQUNBLFlBQU0sZUFBZSxlQUFlO0FBQ3BDLFlBQU0sVUFBVSxPQUFPQyxLQUFJLEtBQTZCQyxRQUFPLEtBQUssQ0FBQztBQUVyRSxZQUFNLDRCQUE0QjtBQUVsQyxZQUFNLHlCQUF5Qiw0QkFDM0IsT0FBT0QsS0FBSSxLQUFLO0FBQUEsUUFDZCxpQkFBaUIsS0FBSyxJQUFJO0FBQUEsUUFDMUIsa0JBQWtCO0FBQUEsUUFDbEIsaUJBQWlCO0FBQUEsTUFDbkIsQ0FBQyxJQUNEO0FBRUosWUFBTSxrQkFBa0I7QUFDeEIsWUFBTSx3QkFBd0I7QUFDOUIsWUFBTSxrQkFBa0I7QUFDeEIsWUFBTSwwQkFBMEIsU0FBUyxJQUFJLEtBQUs7QUFDbEQsWUFBTSxvQkFBb0I7QUFFMUIsVUFBSSxnQkFBZ0I7QUFDcEIsVUFBSSxrQkFBa0I7QUFDdEIsVUFBSSxzQkFBc0I7QUFDMUIsVUFBSSxzQkFBc0I7QUFFMUIsWUFBTSxRQUFRLE1BQWM7QUFDMUIsWUFBSSxPQUFPLGdCQUFnQixlQUFlLE9BQU8sWUFBWSxRQUFRLFlBQVk7QUFDL0UsaUJBQU8sWUFBWSxJQUFJO0FBQUEsUUFDekI7QUFDQSxlQUFPLEtBQUssSUFBSTtBQUFBLE1BQ2xCO0FBRUEsWUFBTSxXQUFXLDRCQUNiLENBQUMsVUFBNEI7QUFDM0IseUJBQWlCO0FBQ2pCLGFBQUssZ0JBQWdCLHFCQUFxQixHQUFHO0FBQzNDLGlCQUFPLGFBQWEsS0FBSztBQUFBLFFBQzNCO0FBRUEsY0FBTSxLQUFLLE1BQU07QUFDakIsY0FBTSxRQUFRLGFBQWEsS0FBSztBQUNoQyxjQUFNLEtBQUssTUFBTSxJQUFJO0FBRXJCLDJCQUFtQjtBQUNuQixZQUFJLE1BQU0sdUJBQXVCO0FBQy9CLGlDQUF1QjtBQUFBLFFBQ3pCO0FBQ0EsWUFBSSxLQUFLLHFCQUFxQjtBQUM1QixnQ0FBc0I7QUFBQSxRQUN4QjtBQUVBLGVBQU87QUFBQSxNQUNULElBQ0E7QUFFSixZQUFNLG9CQUFvQixDQUFDLFlBQWlEO0FBQzFFLFlBQUksQ0FBQyx3QkFBd0I7QUFDM0IsaUJBQU9ELFFBQU87QUFBQSxRQUNoQjtBQUVBLGVBQU9BLFFBQU8sSUFBSSxhQUFhO0FBQzdCLGdCQUFNLE1BQU0sS0FBSyxJQUFJO0FBRXJCLGdCQUFNLFdBQVcsT0FBT0MsS0FBSSxPQUFPLHdCQUF3QixDQUFDLE1BQU07QUFDaEUsa0JBQU0sZ0JBQWdCLE1BQU0sRUFBRSxtQkFBbUI7QUFDakQsa0JBQU0sa0JBQWtCLGdCQUFnQixNQUFNLEVBQUU7QUFDaEQsa0JBQU0sbUJBQW1CLGdCQUFnQixJQUFJLEVBQUUsbUJBQW1CO0FBRWxFLGtCQUFNLGlCQUFpQixNQUFNLEVBQUUsa0JBQWtCO0FBQ2pELGtCQUFNLGNBQWMsb0JBQW9CO0FBQ3hDLGtCQUFNLFVBQVUsdUJBQXVCLHlCQUF5QixrQkFBa0I7QUFDbEYsa0JBQU0sYUFBYSxDQUFDLG1CQUFtQixlQUFlO0FBRXRELGtCQUFNLE9BQU8sYUFDVDtBQUFBLGNBQ0UsaUJBQWlCO0FBQUEsY0FDakIsa0JBQWtCO0FBQUEsY0FDbEIsaUJBQWlCO0FBQUEsWUFDbkIsSUFDQTtBQUFBLGNBQ0UsR0FBRztBQUFBLGNBQ0g7QUFBQSxjQUNBO0FBQUEsWUFDRjtBQUVKLG1CQUFPO0FBQUEsY0FDTDtBQUFBLGdCQUNFO0FBQUEsZ0JBQ0E7QUFBQSxnQkFDQTtBQUFBLGdCQUNBO0FBQUEsY0FDRjtBQUFBLGNBQ0E7QUFBQSxZQUNGO0FBQUEsVUFDRixDQUFDO0FBRUQsY0FBSSxDQUFDLFNBQVMsWUFBWTtBQUN4QjtBQUFBLFVBQ0Y7QUFFQSxnQkFBTSxPQUFPLFNBQVMsY0FBYyxxQ0FBcUM7QUFFekUsZ0JBQU0sT0FBTztBQUFBLFlBQ1gsWUFBWSxLQUFLLFFBQVE7QUFBQSxZQUN6QixRQUFRLEtBQUssSUFBSTtBQUFBLFlBQ2pCLFlBQVksZUFBZTtBQUFBLFlBQzNCLG9CQUFvQixTQUFTLGdCQUFnQjtBQUFBLFlBQzdDLGFBQWEsdUJBQXVCO0FBQUEsWUFDcEMsY0FBYyxpQkFBaUI7QUFBQSxZQUMvQjtBQUFBLFlBQ0E7QUFBQSxZQUNBLFNBQVMsYUFBYTtBQUFBLFlBQ3RCLFdBQVcsZUFBZTtBQUFBLFlBQzFCLGlCQUFpQixxQkFBcUIsT0FBTyxtQkFBbUI7QUFBQSxZQUNoRSxlQUFlLG9CQUFvQixRQUFRLENBQUMsQ0FBQztBQUFBLFlBQzdDO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsVUFDRixFQUFFLEtBQUssSUFBSTtBQUVYLDRCQUFrQjtBQUNsQixnQ0FBc0I7QUFDdEIsZ0NBQXNCO0FBRXRCLGlCQUFPLEtBQUs7QUFBQSxZQUNWLE1BQU07QUFBQSxZQUNOO0FBQUEsWUFDQTtBQUFBLFlBQ0EsVUFBVTtBQUFBLFlBQ1YsVUFBVSxjQUFjO0FBQUEsWUFDeEIsYUFBYSxLQUFLLElBQUk7QUFBQSxZQUN0QixPQUFPO0FBQUEsY0FDTCxTQUFTO0FBQUEsY0FDVDtBQUFBLGNBQ0E7QUFBQSxZQUNGO0FBQUEsVUFDRixDQUF3QjtBQUFBLFFBQzFCLENBQUM7QUFBQSxNQUNIO0FBRUEsWUFBTSxhQUFjLFFBQVEsZ0JBQWdCLFFBQVEsRUFBeUI7QUFBQSxRQUMzRUksUUFBTztBQUFBLFVBQVUsQ0FBQyxRQUNoQkosS0FBSSxJQUFJLE9BQU8sRUFBRTtBQUFBLFlBQ2ZELFFBQU8sUUFBUSxDQUFDLFNBQVM7QUFDdkIsa0JBQUlFLFFBQU8sT0FBTyxJQUFJLEtBQUssT0FBTyxHQUFHLEtBQUssT0FBTyxJQUFJLEtBQUssR0FBRztBQUMzRCx1QkFBT0YsUUFBTyxRQUFRRSxRQUFPLEtBQUssQ0FBQztBQUFBLGNBQ3JDO0FBQ0EscUJBQU9ELEtBQUksSUFBSSxTQUFTQyxRQUFPLEtBQUssSUFBSSxLQUFLLENBQUMsRUFBRSxLQUFLRixRQUFPLEdBQUdFLFFBQU8sS0FBSyxHQUFHLENBQUMsQ0FBQztBQUFBLFlBQ2xGLENBQUM7QUFBQSxVQUNIO0FBQUEsUUFDRjtBQUFBLFFBQ0FHLFFBQU8sVUFBVSxDQUFDLFFBQVEsR0FBRztBQUFBLFFBQzdCQSxRQUFPLElBQUksQ0FBQyxRQUFhO0FBQ3ZCLGdCQUFNLFNBQVMsS0FBSyxNQUFNO0FBQzFCLGlCQUFPO0FBQUEsWUFDTCxNQUFNO0FBQUEsWUFDTixNQUFNLEtBQUs7QUFBQSxZQUNYLFVBQVUsS0FBSztBQUFBLFlBQ2YsWUFBWSxRQUFRO0FBQUEsWUFDcEIsTUFBTSxLQUFLO0FBQUEsWUFDWCxRQUFRLE9BQU8sV0FBVyxXQUFXLFNBQVM7QUFBQSxVQUNoRDtBQUFBLFFBQ0YsQ0FBQztBQUFBLE1BQ0g7QUFFQSxhQUFPLDRCQUE0QixXQUFXLEtBQUtBLFFBQU8sSUFBSSxpQkFBaUIsQ0FBQyxJQUFJO0FBQUEsSUFDdEYsQ0FBQztBQUVILFVBQU0sVUFBVSxDQUFDLFNBQXlCLFVBQ3hDTCxRQUFPO0FBQUEsTUFDTDtBQUFBLE1BQ0E7QUFBQSxJQUNGO0FBQUEsTUFDRSxnQkFBZ0I7QUFBQSxRQUNkQSxRQUFPLGNBQWMsQ0FBQyxVQUFVO0FBQzlCLGNBQUksTUFBTSxrQkFBa0IsS0FBSyxHQUFHO0FBQ2xDLG1CQUFPQSxRQUFPO0FBQUEsVUFDaEI7QUFDQSxpQkFBTyxTQUFTLFFBQVEsT0FBTyxLQUFLLEVBQUU7QUFBQSxZQUNwQ0EsUUFBTztBQUFBLFlBQ1BBLFFBQU8sU0FBUyxNQUFNQSxRQUFPLElBQUk7QUFBQSxVQUNuQztBQUFBLFFBQ0YsQ0FBQztBQUFBLE1BQ0g7QUFBQSxJQUNGO0FBRUYsVUFBTSxlQUFlLENBQ25CLFNBQ0EsVUFDd0I7QUFDeEIsVUFBSSxDQUFDLHlCQUF5QjtBQUM1QixlQUFPLFFBQVEsU0FBUyxLQUFLO0FBQUEsTUFDL0I7QUFFQSxhQUFPQSxRQUFPLElBQUksYUFBYTtBQUM3QixjQUFNLFlBQVksT0FBT0MsS0FBSSxLQUFtQiwrQkFBK0IsQ0FBQztBQUNoRixlQUFPLE9BQU9ELFFBQU87QUFBQSxVQUNuQjtBQUFBLFVBQ0E7QUFBQSxRQUNGLEVBQUUsaUJBQWlCLFNBQVMsTUFBTSxFQUFFLEtBQUtBLFFBQU8sU0FBUyxRQUFRLFNBQVMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUFBLE1BQ3BGLENBQUM7QUFBQSxJQUNIO0FBRUEsVUFBTSxtQkFBbUIsQ0FBQyxZQUE0QztBQUNwRSxVQUFJLENBQUMseUJBQXlCO0FBQzVCLGVBQU87QUFBQSxNQUNUO0FBRUEsYUFBTztBQUFBLFFBQ0wsR0FBRztBQUFBLFFBQ0gsWUFBWSxjQUFjO0FBQUEsTUFDNUI7QUFBQSxJQUNGO0FBRUEsVUFBTSxtQkFBbUIsQ0FBQyxTQUF5QixhQUE0RDtBQUM3RyxVQUFJLENBQUMseUJBQXlCO0FBQzVCLGVBQU9BLFFBQU87QUFBQSxNQUNoQjtBQUVBLFlBQU0sTUFBb0I7QUFBQSxRQUN4QixNQUFNO0FBQUEsUUFDTjtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQSxVQUFVLGNBQWM7QUFBQSxRQUN4QixhQUFhLEtBQUssSUFBSTtBQUFBLE1BQ3hCO0FBQ0EsYUFBTyxLQUFLLEdBQUc7QUFBQSxJQUNqQjtBQUVBLFVBQU0sU0FBUyxhQUFhLFdBQVc7QUFDdkMsVUFBTSxZQUFZLGFBQWEsV0FBVyxTQUFTO0FBQUEsTUFDakQsQ0FBQyxNQUFNLEVBQUUsU0FBUyxtQkFBbUIsRUFBRSxrQkFBa0I7QUFBQSxJQUMzRDtBQUNBLFVBQU0sa0JBQWtCLGFBQWEsV0FBVyxTQUFTO0FBQUEsTUFDdkQsQ0FBQyxNQUNDLEVBQUUsU0FBUyxtQkFBbUIsRUFBRSxrQkFBa0I7QUFBQSxJQUN0RDtBQUVBLFVBQU0sa0JBQWtCQSxRQUFPLElBQUksYUFBYTtBQUM5QyxZQUFNLFFBQVEsT0FBTyxTQUFTLEtBQXVCO0FBRXJELFlBQU0sc0JBQXFESyxRQUFPO0FBQUEsUUFDaEUsY0FBYztBQUFBLE1BQ2hCO0FBRUEsWUFBTSxzQkFBc0IsYUFBYSxXQUFXLFNBQVM7QUFBQSxRQUMzRCxDQUFDLE1BQW1DLEVBQUUsU0FBUztBQUFBLE1BQ2pEO0FBRUEsWUFBTSxVQUFVLE9BQU9MLFFBQU8sUUFBUSxxQkFBcUIsaUJBQWlCO0FBRTVFLFlBQU0sZ0JBQWdCSyxRQUFPLFNBQVMsQ0FBQyxxQkFBcUIsR0FBRyxPQUFPLEdBQUc7QUFBQSxRQUN2RSxhQUFhO0FBQUEsTUFDZixDQUFDO0FBRUQsWUFBTSxzQkFBc0IsQ0FDMUIsU0FDd0I7QUFDeEIsY0FBTSxNQUFNLElBQUksTUFBTSx5REFBeUQ7QUFDOUUsUUFBQyxJQUFZLE9BQU87QUFDcEIsUUFBQyxJQUFZLE9BQU87QUFBQSxVQUNuQixRQUFRLEtBQUssSUFBSTtBQUFBLFVBQ2pCLGtCQUFrQixLQUFLLGFBQWEsU0FBUyxLQUFLLElBQUk7QUFBQSxVQUN0RCx3QkFBd0IsS0FBSyxNQUFNLFVBQVUsVUFBVSxLQUFLLE1BQU0sS0FBSztBQUFBLFVBQ3ZFLFdBQVcsS0FBSyxVQUFVLEtBQUssTUFBTSxDQUFDO0FBQUEsVUFDdEM7QUFBQSxVQUNBO0FBQUEsVUFDQTtBQUFBLFFBQ0YsRUFBRSxLQUFLLElBQUk7QUFDWCxlQUFPLFNBQVMsUUFBUSxPQUFPLE1BQU0sS0FBSyxHQUFHLENBQUMsRUFBRTtBQUFBLFVBQzlDTCxRQUFPO0FBQUEsVUFDUEEsUUFBTyxTQUFTLE1BQU1BLFFBQU8sSUFBSTtBQUFBLFFBQ25DO0FBQUEsTUFDRjtBQUVBLFlBQU0sY0FBYyxPQUFPQSxRQUFPO0FBQUEsUUFDYix3QkFBd0I7QUFBQSxVQUN6QyxRQUFRO0FBQUEsVUFDUjtBQUFBLFVBQ0E7QUFBQSxVQUNBLEtBQUssQ0FBQyxZQUFZLGFBQWEsU0FBUyxLQUFLO0FBQUEsVUFDN0MsUUFBUSxDQUFDLFlBQVksaUJBQWlCLFNBQVMsU0FBUztBQUFBLFVBQ3hELGlCQUFpQjtBQUFBLFFBQ25CLENBQUM7QUFBQSxNQUNIO0FBRUEsVUFBSSxXQUFXO0FBQ2IsZUFBTyxNQUFNLE1BQU0sY0FBYyx1QkFBdUI7QUFBQSxVQUN0RCxNQUFNO0FBQUEsVUFDTixNQUFNLGlCQUFpQjtBQUFBLFVBQ3ZCLGVBQWU7QUFBQSxRQUNqQixDQUFDO0FBQUEsTUFDSDtBQUVBLFlBQU0sUUFBUSxPQUFPLFNBQVMsTUFBTSxLQUFLO0FBQ3pDLGFBQU9HLE9BQU0sVUFBVSxXQUFXO0FBQ2xDLGFBQU8sT0FBT0gsUUFBTyxVQUFVLEtBQUs7QUFBQSxJQUN0QyxDQUFDO0FBRUQsVUFBTSxRQUFRLE9BQU9BLFFBQU8sT0FBTyxhQUFhLFNBQVM7QUFBQSxNQUN2REEsUUFBTyxPQUFPLGVBQWUsRUFBRTtBQUFBLFFBQzdCQSxRQUFPO0FBQUEsVUFBYyxDQUFDLFVBQ3BCQSxRQUFPLElBQUksYUFBYTtBQUd0QixnQkFBSSxNQUFNLGtCQUFrQixLQUFLLEdBQUc7QUFFbEMsa0JBQUksY0FBYyxPQUFPLFdBQVcsWUFBWTtBQUM5QztBQUFBLGNBQ0Y7QUFHQSw0QkFBYyxTQUFTO0FBQUEsZ0JBQ3JCLEdBQUcsY0FBYztBQUFBLGdCQUNqQixRQUFRO0FBQUEsZ0JBQ1IsZUFBZTtBQUFBLGNBQ2pCO0FBQ0EsNEJBQWMsUUFBUTtBQUV0QixxQkFBT0EsUUFBTztBQUFBLGdCQUNaLEtBQUs7QUFBQSxrQkFDSCxNQUFNO0FBQUEsa0JBQ047QUFBQSxrQkFDQSxVQUFVO0FBQUEsa0JBQ1YsVUFBVSxjQUFjO0FBQUEsa0JBQ3hCLGFBQWEsS0FBSyxJQUFJO0FBQUEsZ0JBQ3hCLENBQUM7QUFBQSxjQUNIO0FBRUEsb0JBQU1VLGdCQUFlLGNBQWMsSUFBSSxlQUFlO0FBQ3RELGtCQUFJQSxlQUFjLGNBQWM7QUFDOUIsZ0JBQUFBLGNBQWEsZUFBZTtBQUM1Qix1QkFBTyxrQkFBa0IsZUFBZTtBQUFBLGNBQzFDO0FBQ0E7QUFBQSxZQUNGO0FBRUEsa0JBQU0sVUFBVVIsUUFBTztBQUFBLGNBQVUsTUFBTSxjQUFjLEtBQUs7QUFBQSxjQUFHLE1BQzNEQSxRQUFPLFVBQVUsTUFBTSxVQUFVLEtBQUssR0FBRyxNQUFNLEtBQUs7QUFBQSxZQUN0RDtBQUNBLGtCQUFNLFVBQVUsMkJBQTJCLE9BQU87QUFDbEQsa0JBQU0sUUFBa0MsUUFBUTtBQUVoRCwwQkFBYyxTQUFTO0FBQUEsY0FDckIsR0FBRyxjQUFjO0FBQUEsY0FDakIsUUFBUTtBQUFBLGNBQ1IsZUFBZTtBQUFBLGNBQ2YsV0FBVztBQUFBLFlBQ2I7QUFFQSxtQkFBTyxLQUFLO0FBQUEsY0FDVixNQUFNO0FBQUEsY0FDTjtBQUFBLGNBQ0EsVUFBVTtBQUFBLGNBQ1YsVUFBVSxjQUFjO0FBQUEsY0FDeEIsYUFBYSxLQUFLLElBQUk7QUFBQSxjQUN0QjtBQUFBLFlBQ0YsQ0FBQztBQUVELGtCQUFNLFdBQXVCO0FBQUEsY0FDM0IsYUFBYSxXQUFXO0FBQUEsY0FDeEIsYUFBYTtBQUFBLGNBQ2IsS0FBSyxJQUFJO0FBQUEsWUFDWDtBQUNBLHlCQUFhLGNBQWMsU0FBUztBQUVwQyxnQkFBSSxTQUFTLGFBQWEsV0FBVztBQUVuQyxxQkFBTyxLQUFLO0FBQUEsZ0JBQ1YsTUFBTTtBQUFBLGdCQUNOO0FBQUEsZ0JBQ0EsVUFBVTtBQUFBLGdCQUNWLFVBQVUsY0FBYztBQUFBLGdCQUN4QixhQUFhLEtBQUssSUFBSTtBQUFBLGdCQUN0QjtBQUFBLGNBQ0YsQ0FBQztBQUNELHFCQUFPLGtCQUFrQixlQUFlO0FBQUEsWUFDMUMsT0FBTztBQUNMLHFCQUFPO0FBQUEsZ0JBQ0wsYUFBYSxTQUFTO0FBQUEsZ0JBQ3RCLGFBQWEsU0FBUztBQUFBLGdCQUN0QjtBQUFBLGdCQUNBO0FBQUEsZ0JBQ0EsYUFBYSxhQUFhLFNBQVMsU0FBUyxhQUFhLGFBQWEsUUFBUSxhQUFhLFNBQVMsb0JBQW9CLGdCQUFnQixTQUFTLFdBQVc7QUFBQSxjQUM5SjtBQUFBLFlBQ0Y7QUFBQSxVQUNGLENBQUM7QUFBQSxRQUNIO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFFQSxrQkFBYyxRQUFRO0FBQ3RCLGtCQUFjLFNBQVM7QUFBQSxNQUNyQixHQUFHLGNBQWM7QUFBQSxNQUNqQixRQUFRO0FBQUEsSUFDVjtBQUlBLFdBQU9GLFFBQU8sU0FBUztBQUFBLEVBQ3pCLENBQUM7QUFFSCxRQUFNLFVBQVUsQ0FDZCxTQUNBVyxhQU9BWCxRQUFPLElBQUksYUFBYTtBQUN0QixVQUFNLE9BQVksUUFBUSxPQUFPO0FBQ2pDLFFBQUksQ0FBQyxNQUFNO0FBQ1QsYUFBTztBQUFBLElBQ1Q7QUFFQSxVQUFNLE1BQU0sT0FBT0EsUUFBTyxRQUFXO0FBQ3JDLFVBQU0sZUFBZSxPQUFPQSxRQUFPLGNBQWNJLE9BQU0sS0FBSztBQUM1RCxVQUFNLFlBQVlGLFFBQU8sT0FBTyxZQUFZLElBQUksYUFBYSxRQUFRO0FBRXJFLFVBQU0sV0FBb0Isa0JBQWtCUyxTQUFRLEtBQUs7QUFDekQsVUFBTSxXQUFXO0FBQUEsTUFDZixXQUFXLEtBQUssV0FBVztBQUFBLE1BQzNCLE9BQU9BLFNBQVE7QUFBQSxJQUNqQjtBQUVBLFVBQU0sa0JBQTJCLDRCQUE0QixRQUFRO0FBQ3JFLFVBQU0sV0FBVyxjQUFjLElBQUksZUFBZTtBQUNsRCxRQUFJLFVBQVU7QUFDWixlQUFTLE1BQU07QUFDZixlQUFTLFlBQVk7QUFDckIsZUFBUyxVQUFVQSxTQUFRLFdBQVc7QUFDdEMsZUFBUyxjQUFjQSxTQUFRLGVBQWUsU0FBUztBQUN2RCxVQUFJLENBQUMsU0FBUyxTQUFTO0FBQ3JCLGlCQUFTLGVBQWU7QUFDeEIsZUFBTztBQUFBLFVBQ0w7QUFBQSxVQUNBLFNBQVMsU0FBUztBQUFBLFVBQ2xCLGFBQWEsU0FBUztBQUFBLFFBQ3hCO0FBQUEsTUFDRjtBQUVBLFlBQU0sWUFBWSxTQUFTO0FBQzNCLFlBQU0sVUFBVSxZQUFZLFVBQVUsSUFBSSxTQUFTLElBQUk7QUFDdkQsWUFBTSxTQUFTLFNBQVMsT0FBTztBQUUvQixVQUFJLFdBQVcsYUFBYSxXQUFXLFlBQVk7QUFDakQsY0FBTSxPQUEyQkEsU0FBUSxRQUFRO0FBQ2pELFlBQUksU0FBUyxZQUFZLFdBQVcsUUFBUSxjQUFjLFdBQVc7QUFDbkUsbUJBQVMsZUFBZSxFQUFFLFVBQVU7QUFDcEMsaUJBQU9QLE9BQU07QUFBQSxZQUNYO0FBQUEsWUFDQUosUUFBTyxLQUFLLE1BQU07QUFDaEIsb0JBQU1VLGdCQUFlLGNBQWMsSUFBSSxlQUFlO0FBQ3RELGtCQUFJLENBQUNBLGNBQWM7QUFDbkIsa0JBQUlBLGNBQWEsY0FBYyxjQUFjLFdBQVc7QUFDdEQsZ0JBQUFBLGNBQWEsZUFBZTtBQUFBLGNBQzlCO0FBQUEsWUFDRixDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0YsT0FBTztBQUNMLG1CQUFTLGVBQWU7QUFBQSxRQUMxQjtBQUNBLGVBQU87QUFBQSxVQUNMO0FBQUEsVUFDQSxTQUFTLFNBQVM7QUFBQSxVQUNsQixhQUFhLFNBQVM7QUFBQSxRQUN4QjtBQUFBLE1BQ0Y7QUFFQSxVQUFJLFdBQVcsWUFBWTtBQUN6QixjQUFNLE9BQTJCQyxTQUFRLFFBQVE7QUFDakQsWUFBSSxTQUFTLFVBQVU7QUFDckIsbUJBQVMsZUFBZSxFQUFFLFVBQVU7QUFDcEMsaUJBQU9QLE9BQU07QUFBQSxZQUNYO0FBQUEsWUFDQUosUUFBTyxLQUFLLE1BQU07QUFDaEIsb0JBQU1VLGdCQUFlLGNBQWMsSUFBSSxlQUFlO0FBQ3RELGtCQUFJLENBQUNBLGNBQWM7QUFDbkIsa0JBQUlBLGNBQWEsY0FBYyxjQUFjLFdBQVc7QUFDdEQsZ0JBQUFBLGNBQWEsZUFBZTtBQUFBLGNBQzlCO0FBQUEsWUFDRixDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0YsT0FBTztBQUNMLG1CQUFTLGVBQWU7QUFBQSxRQUMxQjtBQUNBLGVBQU87QUFBQSxVQUNMO0FBQUEsVUFDQSxTQUFTLFNBQVM7QUFBQSxVQUNsQixhQUFhLFNBQVM7QUFBQSxRQUN4QjtBQUFBLE1BQ0Y7QUFFQSxlQUFTLGVBQWU7QUFDeEIsYUFBTyxrQkFBa0IsZUFBZTtBQUN4QyxhQUFPO0FBQUEsUUFDTDtBQUFBLFFBQ0EsU0FBUyxTQUFTO0FBQUEsUUFDbEIsYUFBYSxTQUFTO0FBQUEsTUFDeEI7QUFBQSxJQUNGO0FBSUEsVUFBTSxVQUFVVixRQUFPLFFBQVEsTUFBTSxPQUFPO0FBQzVDLElBQUssV0FBVyxTQUFTO0FBQUEsTUFDdkIsR0FBRztBQUFBLE1BQ0gsbUJBQW1CVyxTQUFRO0FBQUEsSUFDN0IsQ0FBQztBQUVELFVBQU0sZUFBa0M7QUFBQSxNQUN0QztBQUFBLE1BQ0E7QUFBQSxNQUNBLFlBQVksS0FBSztBQUFBLE1BQ2pCO0FBQUEsTUFDQTtBQUFBLE1BQ0EsU0FBUztBQUFBLE1BQ1QsTUFBTSxLQUFLLFFBQVE7QUFBQSxNQUNuQixTQUFTQSxTQUFRLFdBQVc7QUFBQSxNQUM1QixhQUFhQSxTQUFRO0FBQUEsTUFDckIsWUFBWTtBQUFBLE1BQ1osYUFBeUIsYUFBYTtBQUFBLE1BQ3RDLGNBQWM7QUFBQSxJQUNoQjtBQUVBLGtCQUFjLElBQUksaUJBQWlCLFlBQVk7QUFFL0MsUUFBSSxhQUFhLFNBQVM7QUFDeEIsYUFBTyxrQkFBa0IsZUFBZTtBQUFBLElBQzFDO0FBRUEsV0FBTztBQUFBLE1BQ0w7QUFBQSxNQUNBLFNBQVMsYUFBYTtBQUFBLE1BQ3RCLGFBQWEsYUFBYTtBQUFBLElBQzVCO0FBQUEsRUFDRixDQUFDO0FBRUgsUUFBTSxvQkFBeUQsQ0FBQyxXQUM5RFgsUUFBTyxLQUFLLE1BQU07QUFDaEIsVUFBTSxZQUFZLFFBQVE7QUFDMUIsVUFBTSxXQUFXLFFBQVE7QUFDekIsVUFBTSxNQUE2QixDQUFDO0FBQ3BDLGVBQVcsZ0JBQWdCLGNBQWMsT0FBTyxHQUFHO0FBQ2pELFVBQUksYUFBYSxhQUFhLFNBQVMsTUFBTSxTQUFTLFVBQVc7QUFDakUsVUFBSSxZQUFZLGFBQWEsYUFBYSxTQUFVO0FBQ3BELFVBQUksS0FBSztBQUFBLFFBQ1AsVUFBVSxhQUFhO0FBQUEsUUFDdkIsU0FBUyxhQUFhO0FBQUEsUUFDdEIsYUFBYSxhQUFhO0FBQUEsTUFDNUIsQ0FBQztBQUFBLElBQ0g7QUFDQSxXQUFPO0FBQUEsRUFDVCxDQUFDO0FBRUgsUUFBTSxvQkFBeUQsQ0FBQyxzQkFDOURBLFFBQU8sS0FBSyxNQUFNLFVBQVUsSUFBSSxpQkFBaUIsR0FBRyxNQUFNO0FBRTVELFFBQU0sa0JBQXFELENBQUMsbUJBQW1CLFlBQzdFQSxRQUFPLFFBQVEsTUFBTTtBQUNuQixVQUFNLFdBQVcsVUFBVSxJQUFJLGlCQUFpQjtBQUNoRCxRQUFJLENBQUMsVUFBVTtBQUNiLGFBQU9BLFFBQU87QUFBQSxJQUNoQjtBQUVBLFdBQU8sdUJBQXVCLFNBQVMsT0FBTyxnQ0FBZ0MsRUFBRTtBQUFBLE1BQzlFQSxRQUFPLFFBQVEsQ0FBQyxTQUFTO0FBQ3ZCLFlBQUksTUFBTTtBQUNSLGlCQUFPQSxRQUFPO0FBQUEsUUFDaEI7QUFFQSxZQUFJLFFBQVEsV0FBVyxRQUFRO0FBQzdCLGlCQUFPLGFBQWEsVUFBVSxZQUFZO0FBQUEsUUFDNUM7QUFFQSxZQUFJLFFBQVEsV0FBVyxXQUFXO0FBQ2hDLGlCQUFPLGFBQWEsVUFBVSxZQUFZLEVBQUU7QUFBQSxZQUMxQ0EsUUFBTyxRQUFRLE1BQU07QUFDbkIsb0JBQU0sZUFBZSxjQUFjLElBQUksU0FBUyxlQUFlO0FBQy9ELGtCQUFJLENBQUMsY0FBYztBQUNqQix1QkFBT0EsUUFBTztBQUFBLGNBQ2hCO0FBQ0EsMkJBQWEsb0JBQW9CO0FBQ2pDLHFCQUFPLGtCQUFrQixTQUFTLGVBQWU7QUFBQSxZQUNuRCxDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0Y7QUFHQSxZQUFJLFFBQVEsV0FBVyxTQUFTO0FBQzlCLGNBQUksU0FBUyxPQUFPLFdBQVcsYUFBYSxTQUFTLE9BQU8sV0FBVyxZQUFZO0FBQ2pGLG1CQUFPQSxRQUFPO0FBQUEsVUFDaEI7QUFFQSxnQkFBTSxlQUFlLGNBQWMsSUFBSSxTQUFTLGVBQWU7QUFDL0QsY0FBSSxDQUFDLGNBQWM7QUFDakIsbUJBQU9BLFFBQU87QUFBQSxVQUNoQjtBQUNBLHVCQUFhLG9CQUFvQjtBQUNqQyxpQkFBTyxrQkFBa0IsU0FBUyxlQUFlO0FBQUEsUUFDbkQ7QUFFQSxlQUFPQSxRQUFPO0FBQUEsTUFDaEIsQ0FBQztBQUFBLElBQ0g7QUFBQSxFQUNGLENBQUM7QUFFSCxRQUFNLHVCQUErRCxDQUFDLFVBQ3BFQSxRQUFPLElBQUksYUFBYTtBQUN0QixVQUFNLE9BQU8sT0FBa0IsaUNBQWlDO0FBQUEsTUFDOUQsTUFBTTtBQUFBLE1BQ04sVUFBVTtBQUFBLE1BQ1YsU0FDRTtBQUFBLE1BQ0YsTUFBTTtBQUFBLE1BQ04sTUFBTTtBQUFBLElBQ1IsQ0FBQztBQUNELFFBQUksS0FBTTtBQUVWLFVBQU0sVUFBVSxNQUFNLEtBQUssVUFBVSxPQUFPLENBQUM7QUFDN0MsVUFBTSxZQUFZLE1BQU07QUFFeEIsV0FBT0EsUUFBTztBQUFBLE1BQ1o7QUFBQSxNQUNBLENBQUMsYUFDQ0EsUUFBTyxRQUFRLE1BQU07QUFDbkIsWUFBSSxTQUFTLE9BQU8sV0FBVyxjQUFjLFNBQVMsT0FBTyxXQUFXLFdBQVc7QUFDakYsaUJBQU9BLFFBQU87QUFBQSxRQUNoQjtBQUVBLGNBQU0sZUFBZSxjQUFjLElBQUksU0FBUyxlQUFlO0FBQy9ELFlBQUksQ0FBQyxjQUFjO0FBQ2pCLGlCQUFPQSxRQUFPO0FBQUEsUUFDaEI7QUFFQSxjQUFNLFFBQVEsYUFBYSxXQUFXLFNBQVM7QUFBQSxVQUM3QyxDQUFDLE1BQ0MsRUFBRSxTQUFTLG1CQUFtQixFQUFFLGtCQUFrQjtBQUFBLFFBQ3REO0FBQ0EsWUFBSSxNQUFNLFdBQVcsR0FBRztBQUN0QixpQkFBT0EsUUFBTztBQUFBLFFBQ2hCO0FBRUEsZUFBT0EsUUFBTztBQUFBLFVBQ1o7QUFBQSxVQUNBLENBQUMsU0FDQyxNQUFNLE1BQU0sU0FBUyx1QkFBdUI7QUFBQSxZQUMxQyxNQUFNO0FBQUEsWUFDTixNQUFNLEtBQUs7QUFBQSxZQUNYLGVBQWUsS0FBSztBQUFBLFVBQ3RCLENBQTBCO0FBQUEsVUFDNUIsRUFBRSxTQUFTLEtBQUs7QUFBQSxRQUNsQjtBQUFBLE1BQ0YsQ0FBQztBQUFBLE1BQ0gsRUFBRSxTQUFTLEtBQUs7QUFBQSxJQUNsQjtBQUFBLEVBQ0YsQ0FBQztBQUVILFFBQU0sZUFBeUNLLFFBQU8sV0FBVyxTQUFTO0FBRTFFLFFBQU0sb0JBQXlELE1BQU1MLFFBQU8sS0FBSyxNQUFNLGFBQWEsTUFBTSxDQUFDO0FBRTNHLFNBQU9BLFFBQU87QUFBQSxJQUFhLE1BQ3pCQSxRQUFPLElBQUksYUFBYTtBQUN0QixpQkFBVyxnQkFBZ0IsY0FBYyxPQUFPLEdBQUc7QUFDakQscUJBQWEsZUFBZTtBQUFBLE1BQzlCO0FBQ0EsaUJBQVcsWUFBWSxVQUFVLE9BQU8sR0FBRztBQUN6QyxZQUFJLFNBQVMsT0FBTztBQUNsQixpQkFBTyxhQUFhLFVBQVUsZUFBZTtBQUFBLFFBQy9DO0FBQUEsTUFDRjtBQUFBLElBQ0YsQ0FBQyxFQUFFO0FBQUEsTUFDREEsUUFBTztBQUFBLFFBQWMsQ0FBQyxVQUNwQkEsUUFBTyxLQUFLLE1BQU07QUFFaEIsY0FBSSxTQUFTLEdBQUc7QUFFZCxvQkFBUSxLQUFLLHFDQUFxQyxNQUFNLE9BQU8sS0FBSyxDQUFDO0FBQUEsVUFDdkU7QUFBQSxRQUNGLENBQUM7QUFBQSxNQUNIO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBLFFBQVE7QUFBQSxJQUNSO0FBQUEsRUFDRjtBQUNGLENBQUM7QUFFSSxJQUFNLFFBQVEsQ0FBQyxZQUNwQlksT0FBTSxPQUFPLG1CQUFtQixLQUFLLE9BQU8sQ0FBQzsiLAogICJuYW1lcyI6IFsiQ29udGV4dCIsICJFZmZlY3QiLCAiRmliZXIiLCAiRmliZXJSZWYiLCAiTGF5ZXIiLCAiT3B0aW9uIiwgIlJlZiIsICJTY29wZSIsICJTdHJlYW0iLCAiRWZmZWN0IiwgIkVmZmVjdCIsICJvblRyaWdnZXIiLCAibmV4dFNpemUiLCAiaXNSZWNvcmQiLCAidGFnIiwgIkNvbnRleHQiLCAiRmliZXJSZWYiLCAiRWZmZWN0IiwgIlJlZiIsICJPcHRpb24iLCAiRmliZXIiLCAiU2NvcGUiLCAiU3RyZWFtIiwgInRhZyIsICJmb3VuZCIsICJydW50aW1lIiwgInN0cmVhbSIsICJpbnN0YWxsYXRpb24iLCAib3B0aW9ucyIsICJMYXllciJdCn0K