@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,1991 @@
1
+ // @logixjs/core subpath bundles for @logixjs/sandbox
2
+
3
+ import {
4
+ ReplayLog,
5
+ getAtPath,
6
+ parseListItemFieldPath,
7
+ setAtPathMutating,
8
+ toListItemValuePath
9
+ } from "./chunk-C2MYMMO4.js";
10
+ import {
11
+ Snapshot,
12
+ internal,
13
+ keyHash
14
+ } from "./chunk-EZTMVCJF.js";
15
+ import {
16
+ create
17
+ } from "./chunk-KE2H62D6.js";
18
+ import {
19
+ mergeCanonical,
20
+ sanitize
21
+ } from "./chunk-X2Z5VYG3.js";
22
+ import {
23
+ compareFieldPath,
24
+ getFieldPathId,
25
+ makeFieldPathIdRegistry,
26
+ normalizeFieldPath
27
+ } from "./chunk-ASVMK364.js";
28
+ import {
29
+ getBoundInternals
30
+ } from "./chunk-7GPAF2UK.js";
31
+ import {
32
+ ReplayModeConfigTag,
33
+ forceSourceRefresh,
34
+ inSyncTransactionFiber,
35
+ isDevEnv
36
+ } from "./chunk-YMVMZA3U.js";
37
+ import {
38
+ RunSessionTag,
39
+ make,
40
+ run
41
+ } from "./chunk-W365QUZ5.js";
42
+ import {
43
+ currentDiagnosticsLevel,
44
+ record
45
+ } from "./chunk-SH7TP5CJ.js";
46
+ import {
47
+ EffectOpMiddlewareTag
48
+ } from "./chunk-SI5OKFFY.js";
49
+ import {
50
+ fnv1a32,
51
+ stableStringify
52
+ } from "./chunk-DT7YIIWE.js";
53
+
54
+ // ../logix-core/src/internal/state-trait/build.ts
55
+ import * as SchemaAST from "../effect/SchemaAST.js";
56
+
57
+ // ../logix-core/src/internal/state-trait/model.ts
58
+ var normalizeSpec = (spec) => {
59
+ const entries = [];
60
+ const isNode = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitNode";
61
+ const isList = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitList";
62
+ const joinPath = (prefix, suffix) => {
63
+ if (!prefix) return suffix;
64
+ if (!suffix) return prefix;
65
+ return `${prefix}.${suffix}`;
66
+ };
67
+ const prefixDeps = (deps, prefix) => {
68
+ if (!deps || deps.length === 0) return [];
69
+ return deps.map((d) => prefix ? joinPath(prefix, d) : d);
70
+ };
71
+ const normalizeEntry = (entry, fieldPath, depPrefix) => {
72
+ if (entry.kind === "computed") {
73
+ const meta = entry.meta;
74
+ const rawDeps = meta.deps;
75
+ const deps = rawDeps !== void 0 ? prefixDeps(rawDeps, depPrefix) : void 0;
76
+ return {
77
+ ...entry,
78
+ fieldPath,
79
+ meta: { ...meta, deps }
80
+ };
81
+ }
82
+ if (entry.kind === "source") {
83
+ const meta = entry.meta;
84
+ const rawDeps = meta.deps;
85
+ const deps = rawDeps !== void 0 ? prefixDeps(rawDeps, depPrefix) : void 0;
86
+ return {
87
+ ...entry,
88
+ fieldPath,
89
+ meta: { ...meta, deps, _fieldPath: fieldPath }
90
+ };
91
+ }
92
+ if (entry.kind === "externalStore") {
93
+ const meta = entry.meta;
94
+ return {
95
+ ...entry,
96
+ fieldPath,
97
+ meta: { ...meta, _fieldPath: fieldPath }
98
+ };
99
+ }
100
+ if (entry.kind === "link") {
101
+ const meta = entry.meta;
102
+ const from = prefixDeps([meta.from], depPrefix)[0] ?? meta.from;
103
+ return {
104
+ ...entry,
105
+ fieldPath,
106
+ meta: { ...meta, from }
107
+ };
108
+ }
109
+ return {
110
+ ...entry,
111
+ fieldPath
112
+ };
113
+ };
114
+ const expandNode = (scopeId, joinPrefix, node, options) => {
115
+ const addEntry = (relativeTarget, raw) => {
116
+ const rel = raw.fieldPath ?? relativeTarget;
117
+ const fieldPath = joinPrefix ? joinPath(joinPrefix, String(rel)) : String(rel);
118
+ entries.push(normalizeEntry(raw, fieldPath, joinPrefix));
119
+ };
120
+ const expandMaybeRecord = (value) => {
121
+ if (!value) return;
122
+ if (typeof value.kind === "string") {
123
+ addEntry("", value);
124
+ return;
125
+ }
126
+ const record2 = value;
127
+ for (const key in record2) {
128
+ if (!Object.prototype.hasOwnProperty.call(record2, key)) continue;
129
+ const entry = record2[key];
130
+ if (!entry) continue;
131
+ addEntry(key, entry);
132
+ }
133
+ };
134
+ expandMaybeRecord(node.computed);
135
+ expandMaybeRecord(node.source);
136
+ expandMaybeRecord(node.link);
137
+ expandMaybeRecord(node.externalStore);
138
+ if (node.check) {
139
+ const rules = {};
140
+ const checkDepsPrefix = options?.checkDepsPrefix ?? (joinPrefix.endsWith("[]") ? joinPrefix : "");
141
+ const prefixCheckDeps = (deps) => {
142
+ if (!deps || deps.length === 0) return [];
143
+ return deps.map((d) => d === "" ? scopeId : checkDepsPrefix ? joinPath(checkDepsPrefix, d) : d);
144
+ };
145
+ for (const name of Object.keys(node.check)) {
146
+ const rule = node.check[name];
147
+ if (typeof rule === "function") {
148
+ rules[name] = rule;
149
+ continue;
150
+ }
151
+ if (rule && typeof rule === "object") {
152
+ const meta = sanitize(rule.meta);
153
+ rules[name] = {
154
+ ...rule,
155
+ deps: prefixCheckDeps(rule.deps),
156
+ meta
157
+ };
158
+ continue;
159
+ }
160
+ }
161
+ entries.push({
162
+ fieldPath: scopeId,
163
+ kind: "check",
164
+ meta: {
165
+ rules,
166
+ writeback: { kind: "errors" }
167
+ }
168
+ });
169
+ }
170
+ };
171
+ for (const key in spec) {
172
+ if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
173
+ const raw = spec[key];
174
+ if (!raw) continue;
175
+ if (isList(raw)) {
176
+ const listPath = key;
177
+ if (raw.item) {
178
+ expandNode(`${listPath}[]`, `${listPath}[]`, raw.item);
179
+ }
180
+ if (raw.list) {
181
+ expandNode(listPath, listPath, raw.list, {
182
+ checkDepsPrefix: `${listPath}[]`
183
+ });
184
+ }
185
+ continue;
186
+ }
187
+ if (isNode(raw)) {
188
+ if (key === "$root") {
189
+ expandNode("$root", "", raw);
190
+ } else {
191
+ expandNode(key, key, raw);
192
+ }
193
+ continue;
194
+ }
195
+ const entry = raw;
196
+ const fieldPath = entry.fieldPath ?? key;
197
+ entries.push(normalizeEntry(entry, String(fieldPath), ""));
198
+ }
199
+ return entries;
200
+ };
201
+ var collectNodeMeta = (spec) => {
202
+ const out = /* @__PURE__ */ new Map();
203
+ const isNode = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitNode";
204
+ const isList = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitList";
205
+ const add = (scopeId, node) => {
206
+ const meta = sanitize(node.meta);
207
+ if (meta) out.set(scopeId, meta);
208
+ };
209
+ for (const key in spec) {
210
+ if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
211
+ const raw = spec[key];
212
+ if (!raw) continue;
213
+ if (isList(raw)) {
214
+ const listPath = key;
215
+ if (raw.item) add(`${listPath}[]`, raw.item);
216
+ if (raw.list) add(listPath, raw.list);
217
+ continue;
218
+ }
219
+ if (isNode(raw)) {
220
+ if (key === "$root") add("$root", raw);
221
+ else add(key, raw);
222
+ continue;
223
+ }
224
+ }
225
+ return out;
226
+ };
227
+
228
+ // ../logix-core/src/internal/state-trait/build.ts
229
+ var nowPerf = () => typeof globalThis.performance !== "undefined" && typeof globalThis.performance.now === "function" ? globalThis.performance.now() : Date.now();
230
+ var collectMultipleWritersError = (entries) => {
231
+ const kindsByFieldPath = /* @__PURE__ */ new Map();
232
+ for (const entry of entries) {
233
+ if (entry.kind !== "computed" && entry.kind !== "link" && entry.kind !== "source" && entry.kind !== "externalStore") {
234
+ continue;
235
+ }
236
+ const set = kindsByFieldPath.get(entry.fieldPath) ?? /* @__PURE__ */ new Set();
237
+ set.add(entry.kind);
238
+ kindsByFieldPath.set(entry.fieldPath, set);
239
+ }
240
+ const conflicts = [];
241
+ for (const [fieldPath, kinds] of kindsByFieldPath.entries()) {
242
+ if (kinds.size <= 1) continue;
243
+ conflicts.push({ fieldPath, kinds: Array.from(kinds).sort() });
244
+ }
245
+ if (conflicts.length === 0) return void 0;
246
+ conflicts.sort((a, b) => a.fieldPath < b.fieldPath ? -1 : a.fieldPath > b.fieldPath ? 1 : 0);
247
+ const fields = conflicts.map((c) => c.fieldPath);
248
+ const primary = conflicts[0];
249
+ const kindSummary = primary.kinds.join(" + ");
250
+ return {
251
+ code: "MULTIPLE_WRITERS",
252
+ message: `[StateTrait.build] Multiple writers for field "${primary.fieldPath}" (${kindSummary}). Only one of computed/link/source/externalStore can write a fieldPath.`,
253
+ fields
254
+ };
255
+ };
256
+ var getConvergeWriterDeps = (entry) => {
257
+ if (entry.kind === "computed") {
258
+ return entry.meta?.deps ?? [];
259
+ }
260
+ return [entry.meta.from];
261
+ };
262
+ var computeConvergeTopoOrder = (writers) => {
263
+ const writerByPath = /* @__PURE__ */ new Map();
264
+ for (const entry of writers) {
265
+ const existing = writerByPath.get(entry.fieldPath);
266
+ if (existing) {
267
+ return {
268
+ order: [],
269
+ configError: {
270
+ code: "MULTIPLE_WRITERS",
271
+ message: `[StateTrait.converge] Multiple writers for field "${entry.fieldPath}" (${existing.kind} + ${entry.kind}).`,
272
+ fields: [entry.fieldPath]
273
+ }
274
+ };
275
+ }
276
+ writerByPath.set(entry.fieldPath, entry);
277
+ }
278
+ const nodes = /* @__PURE__ */ new Set();
279
+ for (const entry of writers) {
280
+ nodes.add(entry.fieldPath);
281
+ }
282
+ const indegree = /* @__PURE__ */ new Map();
283
+ const forward = /* @__PURE__ */ new Map();
284
+ for (const node of nodes) {
285
+ indegree.set(node, 0);
286
+ forward.set(node, []);
287
+ }
288
+ for (const entry of writers) {
289
+ const to = entry.fieldPath;
290
+ const deps = getConvergeWriterDeps(entry);
291
+ for (const dep of deps) {
292
+ if (!nodes.has(dep)) continue;
293
+ forward.get(dep).push(to);
294
+ indegree.set(to, (indegree.get(to) ?? 0) + 1);
295
+ }
296
+ }
297
+ const queue = [];
298
+ for (const [node, deg] of indegree.entries()) {
299
+ if (deg === 0) queue.push(node);
300
+ }
301
+ const order = [];
302
+ while (queue.length) {
303
+ const n = queue.shift();
304
+ order.push(n);
305
+ const outs = forward.get(n);
306
+ for (const to of outs) {
307
+ const next = (indegree.get(to) ?? 0) - 1;
308
+ indegree.set(to, next);
309
+ if (next === 0) queue.push(to);
310
+ }
311
+ }
312
+ if (order.length !== nodes.size) {
313
+ const remaining = Array.from(nodes).filter((n) => !order.includes(n));
314
+ return {
315
+ order: [],
316
+ configError: {
317
+ code: "CYCLE_DETECTED",
318
+ message: `[StateTrait.converge] Cycle detected in computed/link graph: ${remaining.join(", ")}`,
319
+ fields: remaining
320
+ }
321
+ };
322
+ }
323
+ return { order };
324
+ };
325
+ var collectSchemaFieldPaths = (schema) => {
326
+ const byKey = /* @__PURE__ */ new Map();
327
+ const add = (path) => {
328
+ const normalized = normalizeFieldPath(path);
329
+ if (!normalized) return;
330
+ byKey.set(JSON.stringify(normalized), normalized);
331
+ };
332
+ const visit = (ast, prefix, seen) => {
333
+ let current = ast;
334
+ while (true) {
335
+ if (SchemaAST.isSuspend(current)) {
336
+ if (seen.has(current)) return;
337
+ seen.add(current);
338
+ current = current.f();
339
+ continue;
340
+ }
341
+ if (SchemaAST.isRefinement(current)) {
342
+ current = current.from;
343
+ continue;
344
+ }
345
+ break;
346
+ }
347
+ if (SchemaAST.isTransformation(current)) {
348
+ visit(current.to, prefix, seen);
349
+ visit(current.from, prefix, seen);
350
+ return;
351
+ }
352
+ if (SchemaAST.isUnion(current)) {
353
+ for (const t of current.types) {
354
+ visit(t, prefix, seen);
355
+ }
356
+ return;
357
+ }
358
+ if (SchemaAST.isTupleType(current)) {
359
+ for (const e of current.elements) {
360
+ visit(e.type, prefix, seen);
361
+ }
362
+ for (const r of current.rest) {
363
+ visit(r.type, prefix, seen);
364
+ }
365
+ return;
366
+ }
367
+ if (SchemaAST.isTypeLiteral(current)) {
368
+ for (const ps of current.propertySignatures) {
369
+ const seg = String(ps.name);
370
+ if (!seg) continue;
371
+ const next = [...prefix, seg];
372
+ add(next);
373
+ visit(ps.type, next, seen);
374
+ }
375
+ return;
376
+ }
377
+ };
378
+ visit(schema.ast, [], /* @__PURE__ */ new Set());
379
+ return Array.from(byKey.values()).sort(compareFieldPath);
380
+ };
381
+ var buildConvergeIr = (stateSchema, entries) => {
382
+ const startedAt = nowPerf();
383
+ const generation = 0;
384
+ const multipleWritersError = collectMultipleWritersError(entries);
385
+ const writers = entries.filter((e) => e.kind === "computed" || e.kind === "link");
386
+ const writersKey = writers.map((entry) => `${entry.kind}:${entry.fieldPath}`).sort().join("|");
387
+ const depsKey = writers.map((entry) => {
388
+ const deps = getConvergeWriterDeps(entry).slice().sort().join(",");
389
+ const scheduling = entry.meta?.scheduling === "deferred" ? "d" : "i";
390
+ return `${entry.kind}:${entry.fieldPath}@${scheduling}=>${deps}`;
391
+ }).sort().join("|");
392
+ const writerByPath = /* @__PURE__ */ new Map();
393
+ for (const entry of writers) {
394
+ writerByPath.set(entry.fieldPath, entry);
395
+ }
396
+ const topo = multipleWritersError ? { order: [] } : writers.length > 0 ? computeConvergeTopoOrder(writers) : { order: [] };
397
+ const stepsById = topo.configError ? [] : topo.order.map((path) => writerByPath.get(path));
398
+ const fieldPathTable = /* @__PURE__ */ new Map();
399
+ const addPath = (path) => {
400
+ for (let i = 1; i <= path.length; i++) {
401
+ const prefix = path.slice(0, i);
402
+ const key = JSON.stringify(prefix);
403
+ if (!fieldPathTable.has(key)) fieldPathTable.set(key, prefix);
404
+ }
405
+ };
406
+ for (const schemaPath of collectSchemaFieldPaths(stateSchema)) {
407
+ addPath(schemaPath);
408
+ }
409
+ for (const entry of writers) {
410
+ const out = normalizeFieldPath(entry.fieldPath);
411
+ if (out) addPath(out);
412
+ for (const dep of getConvergeWriterDeps(entry)) {
413
+ const depPath = normalizeFieldPath(dep);
414
+ if (depPath) addPath(depPath);
415
+ }
416
+ }
417
+ const fieldPaths = Array.from(fieldPathTable.values()).sort(compareFieldPath);
418
+ const fieldPathIdRegistry = makeFieldPathIdRegistry(fieldPaths);
419
+ const fieldPathsKey = fnv1a32(stableStringify(fieldPaths));
420
+ const stepOutFieldPathIdByStepId = [];
421
+ const stepDepsFieldPathIdsByStepId = [];
422
+ const stepSchedulingByStepId = [];
423
+ for (const entry of stepsById) {
424
+ const out = normalizeFieldPath(entry.fieldPath);
425
+ const outId = out != null ? getFieldPathId(fieldPathIdRegistry, out) : void 0;
426
+ if (outId == null) {
427
+ throw new Error(`[StateTrait.build] Failed to map converge output fieldPath "${entry.fieldPath}" to FieldPathId.`);
428
+ }
429
+ const depIds = [];
430
+ for (const dep of getConvergeWriterDeps(entry)) {
431
+ const depPath = normalizeFieldPath(dep);
432
+ if (!depPath) continue;
433
+ const depId = getFieldPathId(fieldPathIdRegistry, depPath);
434
+ if (depId != null) depIds.push(depId);
435
+ }
436
+ stepOutFieldPathIdByStepId.push(outId);
437
+ stepDepsFieldPathIdsByStepId.push(depIds);
438
+ stepSchedulingByStepId.push(entry.meta?.scheduling === "deferred" ? "deferred" : "immediate");
439
+ }
440
+ const topoOrder = stepsById.map((_, i) => i);
441
+ const buildDurationMs = Math.max(0, nowPerf() - startedAt);
442
+ return {
443
+ generation,
444
+ writersKey,
445
+ depsKey,
446
+ fieldPathsKey,
447
+ fieldPaths,
448
+ fieldPathIdRegistry,
449
+ ...multipleWritersError ? { configError: multipleWritersError } : topo.configError ? { configError: topo.configError } : null,
450
+ stepsById,
451
+ stepOutFieldPathIdByStepId,
452
+ stepDepsFieldPathIdsByStepId,
453
+ stepSchedulingByStepId,
454
+ topoOrder,
455
+ buildDurationMs
456
+ };
457
+ };
458
+ var toFieldTrait = (entry) => {
459
+ const deps = [];
460
+ if (entry.kind === "computed") {
461
+ const meta = entry.meta;
462
+ const list = meta.deps;
463
+ if (list) deps.push(...list);
464
+ } else if (entry.kind === "source") {
465
+ const meta = entry.meta;
466
+ const list = meta.deps;
467
+ if (list) deps.push(...list);
468
+ } else if (entry.kind === "link") {
469
+ deps.push(entry.meta.from);
470
+ } else if (entry.kind === "check") {
471
+ const meta = entry.meta;
472
+ const rules = meta?.rules ?? {};
473
+ for (const name of Object.keys(rules)) {
474
+ const rule = rules[name];
475
+ if (rule && typeof rule === "object") {
476
+ const list = rule.deps;
477
+ if (list) deps.push(...list);
478
+ }
479
+ }
480
+ }
481
+ return {
482
+ fieldId: entry.fieldPath,
483
+ kind: entry.kind,
484
+ // Keep meta identical to Entry.meta at runtime so install can reuse it directly.
485
+ meta: entry.meta,
486
+ deps
487
+ };
488
+ };
489
+ var buildGraph = (entries, nodeMetaByFieldPath) => {
490
+ const fieldMap = /* @__PURE__ */ new Map();
491
+ const nodes = [];
492
+ const edges = [];
493
+ const resourcesById = /* @__PURE__ */ new Map();
494
+ const planSteps = [];
495
+ const ensureField = (fieldPath) => {
496
+ let field = fieldMap.get(fieldPath);
497
+ if (!field) {
498
+ field = {
499
+ id: fieldPath,
500
+ path: fieldPath,
501
+ traits: []
502
+ };
503
+ fieldMap.set(fieldPath, field);
504
+ }
505
+ return field;
506
+ };
507
+ for (const entry of entries) {
508
+ const fieldPath = entry.fieldPath;
509
+ const field = ensureField(fieldPath);
510
+ const trait = toFieldTrait(entry);
511
+ field.traits.push(trait);
512
+ if (entry.kind === "computed") {
513
+ const stepId = `computed:${fieldPath}`;
514
+ planSteps.push({
515
+ id: stepId,
516
+ kind: "computed-update",
517
+ targetFieldPath: fieldPath
518
+ // Note: the current version does not statically analyze computed dependencies; sourceFieldPaths remains empty.
519
+ });
520
+ const deps = entry.meta.deps;
521
+ if (deps) {
522
+ for (const dep of deps) {
523
+ ensureField(dep);
524
+ edges.push({
525
+ id: `computed:${dep}->${fieldPath}`,
526
+ from: dep,
527
+ to: fieldPath,
528
+ kind: "computed"
529
+ });
530
+ }
531
+ }
532
+ } else if (entry.kind === "link") {
533
+ const from = entry.meta.from;
534
+ ensureField(from);
535
+ const edgeId = `link:${from}->${fieldPath}`;
536
+ edges.push({
537
+ id: edgeId,
538
+ from,
539
+ to: fieldPath,
540
+ kind: "link"
541
+ });
542
+ planSteps.push({
543
+ id: `link:${fieldPath}`,
544
+ kind: "link-propagate",
545
+ targetFieldPath: fieldPath,
546
+ sourceFieldPaths: [from],
547
+ debugInfo: {
548
+ graphEdgeId: edgeId
549
+ }
550
+ });
551
+ } else if (entry.kind === "source") {
552
+ const resourceId = entry.meta.resource;
553
+ const resourceMeta = sanitize(entry.meta.meta);
554
+ const existing = resourcesById.get(resourceId);
555
+ if (existing) {
556
+ const ownerFields = [...existing.ownerFields, fieldPath];
557
+ let meta = existing.meta;
558
+ let metaOrigin = existing.metaOrigin;
559
+ let metaConflicts = existing.metaConflicts;
560
+ if (resourceMeta) {
561
+ const merged = mergeCanonical(
562
+ { meta, origin: metaOrigin, conflicts: metaConflicts },
563
+ { origin: fieldPath, meta: resourceMeta }
564
+ );
565
+ meta = merged.meta;
566
+ metaOrigin = merged.origin;
567
+ metaConflicts = merged.conflicts;
568
+ }
569
+ resourcesById.set(resourceId, {
570
+ ...existing,
571
+ ownerFields,
572
+ meta,
573
+ metaOrigin,
574
+ metaConflicts
575
+ });
576
+ } else {
577
+ resourcesById.set(resourceId, {
578
+ resourceId,
579
+ // Use a simple identifier string for now; may evolve into a structured form based on key rules.
580
+ keySelector: `StateTrait.source@${fieldPath}`,
581
+ ownerFields: [fieldPath],
582
+ meta: resourceMeta,
583
+ metaOrigin: resourceMeta ? fieldPath : void 0
584
+ });
585
+ }
586
+ planSteps.push({
587
+ id: `source:${fieldPath}`,
588
+ kind: "source-refresh",
589
+ targetFieldPath: fieldPath,
590
+ resourceId,
591
+ keySelectorId: `StateTrait.source@${fieldPath}`
592
+ });
593
+ const deps = entry.meta.deps;
594
+ if (deps) {
595
+ for (const dep of deps) {
596
+ ensureField(dep);
597
+ edges.push({
598
+ id: `source-dep:${dep}->${fieldPath}`,
599
+ from: dep,
600
+ to: fieldPath,
601
+ kind: "source-dep"
602
+ });
603
+ }
604
+ }
605
+ } else if (entry.kind === "externalStore") {
606
+ planSteps.push({
607
+ id: `external-store:${fieldPath}`,
608
+ kind: "external-store-sync",
609
+ targetFieldPath: fieldPath
610
+ });
611
+ } else if (entry.kind === "check") {
612
+ planSteps.push({
613
+ id: `check:${fieldPath}`,
614
+ kind: "check-validate",
615
+ targetFieldPath: fieldPath
616
+ });
617
+ if (trait.deps.length > 0) {
618
+ for (const dep of trait.deps) {
619
+ ensureField(dep);
620
+ edges.push({
621
+ id: `check-dep:${dep}->${fieldPath}`,
622
+ from: dep,
623
+ to: fieldPath,
624
+ kind: "check-dep"
625
+ });
626
+ }
627
+ }
628
+ }
629
+ }
630
+ for (const field of fieldMap.values()) {
631
+ nodes.push({
632
+ id: field.id,
633
+ field,
634
+ traits: field.traits,
635
+ meta: nodeMetaByFieldPath.get(field.id)
636
+ });
637
+ }
638
+ const graph = {
639
+ _tag: "StateTraitGraph",
640
+ nodes,
641
+ edges,
642
+ resources: Array.from(resourcesById.values())
643
+ };
644
+ const plan = {
645
+ _tag: "StateTraitPlan",
646
+ steps: planSteps
647
+ };
648
+ return { graph, plan };
649
+ };
650
+ var assertNoLinkCycles = (edges) => {
651
+ const adjacency = /* @__PURE__ */ new Map();
652
+ for (const edge of edges) {
653
+ if (edge.kind !== "link") continue;
654
+ const list = adjacency.get(edge.from) ?? [];
655
+ list.push(edge.to);
656
+ adjacency.set(edge.from, list);
657
+ }
658
+ const visited = /* @__PURE__ */ new Set();
659
+ const stack = /* @__PURE__ */ new Set();
660
+ const dfs = (node) => {
661
+ if (stack.has(node)) {
662
+ throw new Error(
663
+ `[StateTrait.build] link cycle detected at field "${node}". Please check link traits for circular dependencies.`
664
+ );
665
+ }
666
+ if (visited.has(node)) return;
667
+ visited.add(node);
668
+ stack.add(node);
669
+ const nexts = adjacency.get(node);
670
+ if (nexts) {
671
+ for (const to of nexts) {
672
+ dfs(to);
673
+ }
674
+ }
675
+ stack.delete(node);
676
+ };
677
+ for (const node of adjacency.keys()) {
678
+ if (!visited.has(node)) {
679
+ dfs(node);
680
+ }
681
+ }
682
+ };
683
+ var collectSchemaPaths = (entries) => {
684
+ const byKey = /* @__PURE__ */ new Map();
685
+ const add = (ref) => {
686
+ if (!ref.path) return;
687
+ const k = `${ref.kind}|${ref.entryKind}|${ref.entryFieldPath}|${ref.ruleName ?? ""}|${ref.path}`;
688
+ byKey.set(k, ref);
689
+ };
690
+ const getCheckWritebackPath = (entry) => {
691
+ const wb = entry.meta?.writeback;
692
+ const p = wb && typeof wb === "object" ? wb.path : void 0;
693
+ const writebackPath = typeof p === "string" && p.startsWith("errors.") ? p : void 0;
694
+ if (writebackPath) return writebackPath;
695
+ const fieldPath = entry.fieldPath;
696
+ if (fieldPath.endsWith("[]")) {
697
+ return `errors.${fieldPath.slice(0, -2)}`;
698
+ }
699
+ return `errors.${fieldPath}`;
700
+ };
701
+ for (const entry of entries) {
702
+ add({
703
+ kind: "fieldPath",
704
+ entryKind: entry.kind,
705
+ entryFieldPath: entry.fieldPath,
706
+ path: entry.fieldPath
707
+ });
708
+ if (entry.kind === "computed" || entry.kind === "source") {
709
+ const deps = entry.meta?.deps ?? [];
710
+ for (const dep of deps) {
711
+ add({
712
+ kind: "dep",
713
+ entryKind: entry.kind,
714
+ entryFieldPath: entry.fieldPath,
715
+ path: dep
716
+ });
717
+ }
718
+ }
719
+ if (entry.kind === "link") {
720
+ add({
721
+ kind: "link_from",
722
+ entryKind: "link",
723
+ entryFieldPath: entry.fieldPath,
724
+ path: entry.meta.from
725
+ });
726
+ }
727
+ if (entry.kind === "check") {
728
+ add({
729
+ kind: "check_writeback",
730
+ entryKind: "check",
731
+ entryFieldPath: entry.fieldPath,
732
+ path: getCheckWritebackPath(entry)
733
+ });
734
+ const rules = entry.meta?.rules ?? {};
735
+ for (const name of Object.keys(rules)) {
736
+ const rule = rules[name];
737
+ if (!rule || typeof rule !== "object") continue;
738
+ const deps = rule.deps ?? [];
739
+ for (const dep of deps) {
740
+ add({
741
+ kind: "dep",
742
+ entryKind: "check",
743
+ entryFieldPath: entry.fieldPath,
744
+ ruleName: name,
745
+ path: dep
746
+ });
747
+ }
748
+ }
749
+ }
750
+ }
751
+ return Array.from(byKey.entries()).sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0).map(([, v]) => v);
752
+ };
753
+ var build = (stateSchema, spec) => {
754
+ const entries = normalizeSpec(spec);
755
+ const nodeMetaByFieldPath = collectNodeMeta(spec);
756
+ for (const entry of entries) {
757
+ if (entry.kind === "computed") {
758
+ const deps = entry.meta.deps;
759
+ if (deps === void 0) {
760
+ throw new Error(
761
+ `[StateTrait.build] Missing explicit deps for computed "${entry.fieldPath}". Please use StateTrait.computed({ deps: [...], get: ... }).`
762
+ );
763
+ }
764
+ }
765
+ if (entry.kind === "source") {
766
+ const deps = entry.meta.deps;
767
+ if (deps === void 0) {
768
+ throw new Error(
769
+ `[StateTrait.build] Missing explicit deps for source "${entry.fieldPath}". Please provide meta.deps for StateTrait.source({ deps: [...], ... }).`
770
+ );
771
+ }
772
+ }
773
+ if (entry.kind === "check") {
774
+ const rules = entry.meta?.rules ?? {};
775
+ for (const name of Object.keys(rules)) {
776
+ const rule = rules[name];
777
+ if (typeof rule === "function" || !rule || typeof rule !== "object") {
778
+ throw new Error(
779
+ `[StateTrait.build] Missing explicit deps for check "${entry.fieldPath}" rule "${name}". Please use { deps: [...], validate: ... } form.`
780
+ );
781
+ }
782
+ if (rule.deps === void 0) {
783
+ throw new Error(
784
+ `[StateTrait.build] Missing explicit deps for check "${entry.fieldPath}" rule "${name}". Please provide deps: [...].`
785
+ );
786
+ }
787
+ }
788
+ }
789
+ }
790
+ const { graph, plan } = buildGraph(entries, nodeMetaByFieldPath);
791
+ assertNoLinkCycles(graph.edges);
792
+ return {
793
+ stateSchema,
794
+ spec,
795
+ entries,
796
+ graph,
797
+ plan,
798
+ convergeIr: buildConvergeIr(stateSchema, entries),
799
+ schemaPaths: collectSchemaPaths(entries)
800
+ };
801
+ };
802
+
803
+ // ../logix-core/src/internal/state-trait/source.impl.ts
804
+ import { Effect, Fiber, FiberRef, Option } from "../effect.js";
805
+
806
+ // ../logix-core/src/internal/state-trait/deps-trace.ts
807
+ var isTraceableObject = (value) => {
808
+ if (!value || typeof value !== "object") return false;
809
+ if (Array.isArray(value)) return true;
810
+ if (value instanceof Date) return false;
811
+ if (value instanceof RegExp) return false;
812
+ if (value instanceof Error) return false;
813
+ if (value instanceof Map) return false;
814
+ if (value instanceof Set) return false;
815
+ if (value instanceof WeakMap) return false;
816
+ if (value instanceof WeakSet) return false;
817
+ return true;
818
+ };
819
+ var shouldIgnoreKey = (key) => key === "__proto__" || key === "prototype" || key === "constructor";
820
+ var normalizeReads = (reads) => {
821
+ const all = Array.from(reads).filter((p) => typeof p === "string" && p.length > 0);
822
+ all.sort();
823
+ const isPrefix = (prefix, full) => full !== prefix && full.startsWith(prefix + ".");
824
+ const pruned = [];
825
+ for (const p of all) {
826
+ let hasMoreSpecific = false;
827
+ for (const other of all) {
828
+ if (isPrefix(p, other)) {
829
+ hasMoreSpecific = true;
830
+ break;
831
+ }
832
+ }
833
+ if (!hasMoreSpecific) {
834
+ pruned.push(p);
835
+ }
836
+ }
837
+ pruned.sort();
838
+ return pruned;
839
+ };
840
+ var covers = (declared, read) => declared === read || read.startsWith(declared + ".");
841
+ var diffDeps = (declared, reads) => {
842
+ const declaredList = Array.from(new Set(declared)).filter((p) => typeof p === "string" && p.length > 0);
843
+ declaredList.sort();
844
+ const readList = Array.from(new Set(reads)).filter((p) => typeof p === "string" && p.length > 0);
845
+ readList.sort();
846
+ const missing = readList.filter((r) => declaredList.every((d) => !covers(d, r)));
847
+ const unused = declaredList.filter((d) => readList.every((r) => !covers(d, r)));
848
+ if (missing.length === 0 && unused.length === 0) return void 0;
849
+ return {
850
+ reads: readList,
851
+ declared: declaredList,
852
+ missing,
853
+ unused
854
+ };
855
+ };
856
+ var trace = (fn, state) => {
857
+ if (!isTraceableObject(state)) {
858
+ return { value: fn(state), reads: [] };
859
+ }
860
+ const reads = /* @__PURE__ */ new Set();
861
+ const proxyCache = /* @__PURE__ */ new WeakMap();
862
+ const proxyToTarget = /* @__PURE__ */ new WeakMap();
863
+ const wrap = (value2, path) => {
864
+ if (!isTraceableObject(value2)) return value2;
865
+ return getProxy(value2, path);
866
+ };
867
+ const unwrap = (value2) => {
868
+ if (value2 && (typeof value2 === "object" || typeof value2 === "function")) {
869
+ const target = proxyToTarget.get(value2);
870
+ if (target) return target;
871
+ }
872
+ return value2;
873
+ };
874
+ const getProxy = (target, basePath) => {
875
+ let byPath = proxyCache.get(target);
876
+ if (!byPath) {
877
+ byPath = /* @__PURE__ */ new Map();
878
+ proxyCache.set(target, byPath);
879
+ }
880
+ const cached = byPath.get(basePath);
881
+ if (cached) return cached;
882
+ const record2 = (path) => {
883
+ if (path) reads.add(path);
884
+ };
885
+ const proxy = new Proxy(target, {
886
+ get: (t, prop, receiver) => {
887
+ if (typeof prop === "symbol") {
888
+ return Reflect.get(t, prop, receiver);
889
+ }
890
+ const key = String(prop);
891
+ if (shouldIgnoreKey(key)) {
892
+ return Reflect.get(t, prop, receiver);
893
+ }
894
+ const nextPath = basePath ? `${basePath}.${key}` : key;
895
+ record2(nextPath);
896
+ const value2 = Reflect.get(t, prop, receiver);
897
+ return wrap(value2, nextPath);
898
+ },
899
+ has: (t, prop) => {
900
+ if (typeof prop === "symbol") return Reflect.has(t, prop);
901
+ const key = String(prop);
902
+ if (!shouldIgnoreKey(key)) {
903
+ const nextPath = basePath ? `${basePath}.${key}` : key;
904
+ record2(nextPath);
905
+ }
906
+ return Reflect.has(t, prop);
907
+ },
908
+ ownKeys: (t) => {
909
+ if (basePath) record2(basePath);
910
+ return Reflect.ownKeys(t);
911
+ },
912
+ getOwnPropertyDescriptor: (t, prop) => {
913
+ if (typeof prop === "symbol") {
914
+ return Reflect.getOwnPropertyDescriptor(t, prop);
915
+ }
916
+ const key = String(prop);
917
+ if (!shouldIgnoreKey(key)) {
918
+ const nextPath = basePath ? `${basePath}.${key}` : key;
919
+ record2(nextPath);
920
+ }
921
+ return Reflect.getOwnPropertyDescriptor(t, prop);
922
+ },
923
+ set: () => {
924
+ throw new Error(
925
+ "[deps-trace] Attempted to mutate state during deps tracing (state is readonly in dev-mode diagnostics)."
926
+ );
927
+ },
928
+ defineProperty: () => {
929
+ throw new Error(
930
+ "[deps-trace] Attempted to define property on state during deps tracing (state is readonly in dev-mode diagnostics)."
931
+ );
932
+ },
933
+ deleteProperty: () => {
934
+ throw new Error(
935
+ "[deps-trace] Attempted to delete property on state during deps tracing (state is readonly in dev-mode diagnostics)."
936
+ );
937
+ }
938
+ });
939
+ byPath.set(basePath, proxy);
940
+ proxyToTarget.set(proxy, target);
941
+ return proxy;
942
+ };
943
+ const root = getProxy(state, "");
944
+ const value = unwrap(fn(root));
945
+ return {
946
+ value,
947
+ reads: normalizeReads(reads)
948
+ };
949
+ };
950
+
951
+ // ../logix-core/src/internal/state-trait/source.impl.ts
952
+ var onceInRunSession = (key) => Effect.serviceOption(RunSessionTag).pipe(
953
+ Effect.map((maybe) => Option.isSome(maybe) ? maybe.value.local.once(key) : true)
954
+ );
955
+ var formatList = (items, limit = 10) => {
956
+ if (items.length === 0) return "";
957
+ if (items.length <= limit) return items.join(", ");
958
+ return `${items.slice(0, limit).join(", ")}, \u2026(+${items.length - limit})`;
959
+ };
960
+ var emitDepsMismatch = (params) => Effect.gen(function* () {
961
+ const key = `${params.instanceId ?? "unknown"}::${params.kind}::${params.fieldPath}`;
962
+ const shouldEmit = yield* onceInRunSession(`deps_mismatch:${key}`);
963
+ if (!shouldEmit) return;
964
+ yield* record({
965
+ type: "diagnostic",
966
+ moduleId: params.moduleId,
967
+ instanceId: params.instanceId,
968
+ code: "state_trait::deps_mismatch",
969
+ severity: "warning",
970
+ message: `[deps] ${params.kind} "${params.fieldPath}" declared=[${formatList(params.diff.declared)}] reads=[${formatList(params.diff.reads)}] missing=[${formatList(params.diff.missing)}] unused=[${formatList(params.diff.unused)}]`,
971
+ hint: 'deps is the single source of truth for dependencies: incremental scheduling / reverse closures / performance optimizations rely on deps only. Keep deps consistent with actual reads; if you really depend on the whole object, declare a coarser-grained dep (e.g. "profile") to cover sub-field reads.',
972
+ kind: `deps_mismatch:${params.kind}`
973
+ });
974
+ });
975
+ var getMiddlewareStack = () => Effect.serviceOption(EffectOpMiddlewareTag).pipe(
976
+ Effect.map((maybe) => Option.isSome(maybe) ? maybe.value.stack : [])
977
+ );
978
+ var recordTraitPatch = (bound, path, reason, from, to, traitNodeId) => {
979
+ const normalized = normalizeFieldPath(path) ?? [];
980
+ try {
981
+ const internals = getBoundInternals(bound);
982
+ internals.txn.recordStatePatch(normalized, reason, from, to, traitNodeId);
983
+ } catch {
984
+ }
985
+ };
986
+ var recordReplayEvent = (bound, event) => {
987
+ try {
988
+ const internals = getBoundInternals(bound);
989
+ internals.txn.recordReplayEvent(event);
990
+ } catch {
991
+ }
992
+ };
993
+ var getBoundScope = (bound) => {
994
+ try {
995
+ const internals = getBoundInternals(bound);
996
+ return { moduleId: internals.moduleId, instanceId: internals.instanceId };
997
+ } catch {
998
+ return { moduleId: void 0, instanceId: void 0 };
999
+ }
1000
+ };
1001
+ var setSnapshotInTxn = (bound, fieldPath, next, reason, stepId, traitNodeId) => Effect.gen(function* () {
1002
+ let wrote = false;
1003
+ yield* bound.state.mutate((draft) => {
1004
+ const prev = getAtPath(draft, fieldPath);
1005
+ if (Object.is(prev, next)) return;
1006
+ wrote = true;
1007
+ setAtPathMutating(draft, fieldPath, next);
1008
+ recordTraitPatch(bound, fieldPath, reason, prev, next, traitNodeId);
1009
+ });
1010
+ return wrote;
1011
+ });
1012
+ var writebackIfCurrentKeyHash = (bound, fieldPath, keyHash2, next, reason, stepId, traitNodeId, replayEvent) => Effect.gen(function* () {
1013
+ let wrote = false;
1014
+ yield* bound.state.mutate((draft) => {
1015
+ const current = getAtPath(draft, fieldPath);
1016
+ const currentKeyHash = current && typeof current === "object" ? current.keyHash : void 0;
1017
+ if (currentKeyHash !== keyHash2) return;
1018
+ const prev = current;
1019
+ if (Object.is(prev, next)) return;
1020
+ wrote = true;
1021
+ setAtPathMutating(draft, fieldPath, next);
1022
+ if (replayEvent) {
1023
+ recordReplayEvent(bound, replayEvent);
1024
+ }
1025
+ recordTraitPatch(bound, fieldPath, reason, prev, next, traitNodeId);
1026
+ });
1027
+ return wrote;
1028
+ });
1029
+ var syncIdleInTransaction = (program, ctx) => Effect.sync(() => {
1030
+ const draft = ctx.getDraft();
1031
+ const updates = [];
1032
+ for (const entry of program.entries) {
1033
+ if (entry.kind !== "source") continue;
1034
+ const fieldPath = entry.fieldPath;
1035
+ const listItem = parseListItemFieldPath(fieldPath);
1036
+ if (listItem) {
1037
+ const listValue = getAtPath(draft, listItem.listPath);
1038
+ const items = Array.isArray(listValue) ? listValue : [];
1039
+ for (let index = 0; index < items.length; index++) {
1040
+ const item = items[index];
1041
+ let key2;
1042
+ try {
1043
+ key2 = entry.meta.key(item);
1044
+ } catch {
1045
+ continue;
1046
+ }
1047
+ if (key2 !== void 0) continue;
1048
+ const concretePath = toListItemValuePath(listItem.listPath, index, listItem.itemPath);
1049
+ const prev2 = getAtPath(draft, concretePath);
1050
+ const prevStatus2 = prev2 && typeof prev2 === "object" ? prev2.status : void 0;
1051
+ if (prevStatus2 === "idle") {
1052
+ const data = prev2?.data;
1053
+ const error = prev2?.error;
1054
+ if (data === void 0 && error === void 0) {
1055
+ continue;
1056
+ }
1057
+ }
1058
+ updates.push({ fieldPath: concretePath, prev: prev2 });
1059
+ }
1060
+ continue;
1061
+ }
1062
+ let key;
1063
+ try {
1064
+ key = entry.meta.key(draft);
1065
+ } catch {
1066
+ continue;
1067
+ }
1068
+ if (key !== void 0) continue;
1069
+ const prev = getAtPath(draft, fieldPath);
1070
+ const prevStatus = prev && typeof prev === "object" ? prev.status : void 0;
1071
+ if (prevStatus === "idle") {
1072
+ const data = prev?.data;
1073
+ const error = prev?.error;
1074
+ if (data === void 0 && error === void 0) {
1075
+ continue;
1076
+ }
1077
+ }
1078
+ updates.push({ fieldPath, prev });
1079
+ }
1080
+ if (updates.length === 0) return;
1081
+ const reason = "source-refresh";
1082
+ const nextDraft = create(draft, (next) => {
1083
+ for (const u of updates) {
1084
+ setAtPathMutating(next, u.fieldPath, Snapshot.idle());
1085
+ }
1086
+ });
1087
+ ctx.setDraft(nextDraft);
1088
+ for (const u of updates) {
1089
+ const normalized = normalizeFieldPath(u.fieldPath) ?? [];
1090
+ ctx.recordPatch(normalized, reason, u.prev, Snapshot.idle(), `source:${u.fieldPath}:idle`);
1091
+ }
1092
+ });
1093
+ var installSourceRefresh = (bound, step, entry) => {
1094
+ if (!step.targetFieldPath) return Effect.void;
1095
+ const fieldPath = step.targetFieldPath;
1096
+ const resourceId = step.resourceId ?? entry.meta.resource;
1097
+ const listItem = parseListItemFieldPath(fieldPath);
1098
+ let internals;
1099
+ try {
1100
+ internals = getBoundInternals(bound);
1101
+ } catch {
1102
+ return Effect.void;
1103
+ }
1104
+ const register = internals.traits.registerSourceRefresh;
1105
+ const recordSnapshot = (replayMode, replayLog, input) => {
1106
+ if (!replayLog) return Effect.void;
1107
+ if (replayMode !== "live") return Effect.void;
1108
+ const event = input && typeof input === "object" && input._tag === "ResourceSnapshot" ? input : {
1109
+ _tag: "ResourceSnapshot",
1110
+ resourceId,
1111
+ fieldPath: input.fieldPath,
1112
+ keyHash: input.keyHash,
1113
+ concurrency: input.concurrency,
1114
+ phase: input.phase,
1115
+ snapshot: input.snapshot,
1116
+ timestamp: Date.now(),
1117
+ moduleId: input.moduleId,
1118
+ instanceId: input.instanceId
1119
+ };
1120
+ return replayLog.record(event);
1121
+ };
1122
+ if (listItem) {
1123
+ const store = internals.traits.rowIdStore;
1124
+ if (!store) {
1125
+ return Effect.void;
1126
+ }
1127
+ const listPath = listItem.listPath;
1128
+ const itemPath = listItem.itemPath;
1129
+ if (!itemPath) {
1130
+ return Effect.void;
1131
+ }
1132
+ const concurrency2 = entry.meta.concurrency;
1133
+ const mode2 = concurrency2 ?? "switch";
1134
+ const inFlight2 = /* @__PURE__ */ new Map();
1135
+ const trailing2 = /* @__PURE__ */ new Map();
1136
+ let gen2 = 0;
1137
+ store.onRemoved(listPath, (rowId) => {
1138
+ trailing2.delete(rowId);
1139
+ inFlight2.delete(rowId);
1140
+ });
1141
+ const setSnapshotForRowInTxn = (rowId, next, reason, stepId) => Effect.gen(function* () {
1142
+ let wrotePath;
1143
+ yield* bound.state.mutate((draft) => {
1144
+ const index = store.getIndex(listPath, rowId);
1145
+ if (index === void 0) return;
1146
+ const concretePath = toListItemValuePath(listPath, index, itemPath);
1147
+ const prev = getAtPath(draft, concretePath);
1148
+ if (Object.is(prev, next)) return;
1149
+ wrotePath = concretePath;
1150
+ setAtPathMutating(draft, concretePath, next);
1151
+ recordTraitPatch(bound, concretePath, reason, prev, next, step.debugInfo?.graphNodeId);
1152
+ });
1153
+ return wrotePath;
1154
+ });
1155
+ const writebackIfCurrentKeyHashForRow = (rowId, keyHash2, next, reason, stepId, phase) => Effect.gen(function* () {
1156
+ let wrotePath;
1157
+ yield* bound.state.mutate((draft) => {
1158
+ const index = store.getIndex(listPath, rowId);
1159
+ if (index === void 0) return;
1160
+ const concretePath = toListItemValuePath(listPath, index, itemPath);
1161
+ const current = getAtPath(draft, concretePath);
1162
+ const currentKeyHash = current && typeof current === "object" ? current.keyHash : void 0;
1163
+ if (currentKeyHash !== keyHash2) return;
1164
+ const prev = current;
1165
+ if (Object.is(prev, next)) return;
1166
+ wrotePath = concretePath;
1167
+ setAtPathMutating(draft, concretePath, next);
1168
+ if (phase) {
1169
+ const { moduleId, instanceId } = getBoundScope(bound);
1170
+ recordReplayEvent(bound, {
1171
+ _tag: "ResourceSnapshot",
1172
+ resourceId,
1173
+ fieldPath: concretePath,
1174
+ keyHash: keyHash2,
1175
+ concurrency: mode2,
1176
+ phase,
1177
+ snapshot: next,
1178
+ timestamp: Date.now(),
1179
+ moduleId,
1180
+ instanceId
1181
+ });
1182
+ }
1183
+ recordTraitPatch(bound, concretePath, reason, prev, next, step.debugInfo?.graphNodeId);
1184
+ });
1185
+ return wrotePath;
1186
+ });
1187
+ const startFetch2 = (rowId, key, keyHash2, replayMode, replayLog) => Effect.gen(function* () {
1188
+ const { moduleId, instanceId } = getBoundScope(bound);
1189
+ const indexForLog = store.getIndex(listPath, rowId);
1190
+ const logFieldPath = indexForLog === void 0 ? void 0 : toListItemValuePath(listPath, indexForLog, itemPath);
1191
+ let loadingSnapshot = Snapshot.loading({ keyHash: keyHash2 });
1192
+ if (replayMode === "replay" && replayLog && logFieldPath) {
1193
+ const replayLoading = yield* replayLog.consumeNextResourceSnapshot({
1194
+ resourceId,
1195
+ fieldPath: logFieldPath,
1196
+ keyHash: keyHash2,
1197
+ phase: "loading"
1198
+ });
1199
+ if (replayLoading) {
1200
+ loadingSnapshot = replayLoading.snapshot;
1201
+ }
1202
+ }
1203
+ const wroteLoadingPath = yield* setSnapshotForRowInTxn(
1204
+ rowId,
1205
+ loadingSnapshot,
1206
+ "source-refresh",
1207
+ `source:${fieldPath}:${rowId}:loading`
1208
+ );
1209
+ if (wroteLoadingPath) {
1210
+ const event = {
1211
+ _tag: "ResourceSnapshot",
1212
+ resourceId,
1213
+ fieldPath: wroteLoadingPath,
1214
+ keyHash: keyHash2,
1215
+ concurrency: mode2,
1216
+ phase: "loading",
1217
+ snapshot: loadingSnapshot,
1218
+ timestamp: Date.now(),
1219
+ moduleId,
1220
+ instanceId
1221
+ };
1222
+ recordReplayEvent(bound, event);
1223
+ yield* recordSnapshot(replayMode, replayLog, event);
1224
+ }
1225
+ const io = Effect.gen(function* () {
1226
+ if (replayMode === "replay" && replayLog) {
1227
+ yield* Effect.yieldNow();
1228
+ const consumePath = wroteLoadingPath ?? logFieldPath;
1229
+ if (!consumePath) return yield* Effect.void;
1230
+ const replayed = yield* replayLog.consumeNextResourceSnapshot({
1231
+ resourceId,
1232
+ fieldPath: consumePath,
1233
+ keyHash: keyHash2
1234
+ });
1235
+ if (!replayed) return yield* Effect.void;
1236
+ if (replayed.phase === "success") {
1237
+ yield* writebackIfCurrentKeyHashForRow(
1238
+ rowId,
1239
+ keyHash2,
1240
+ replayed.snapshot,
1241
+ "source-refresh",
1242
+ `source:${fieldPath}:${rowId}:success`,
1243
+ "success"
1244
+ );
1245
+ } else if (replayed.phase === "error") {
1246
+ yield* writebackIfCurrentKeyHashForRow(
1247
+ rowId,
1248
+ keyHash2,
1249
+ replayed.snapshot,
1250
+ "source-refresh",
1251
+ `source:${fieldPath}:${rowId}:error`,
1252
+ "error"
1253
+ );
1254
+ }
1255
+ return yield* Effect.void;
1256
+ }
1257
+ const stack = yield* getMiddlewareStack();
1258
+ const registryOpt = yield* Effect.serviceOption(internal.ResourceRegistryTag);
1259
+ const registry = Option.isSome(registryOpt) ? registryOpt.value : void 0;
1260
+ const spec = registry?.specs.get(resourceId);
1261
+ if (!spec) {
1262
+ return yield* Effect.void;
1263
+ }
1264
+ const loadEffect = spec.load(key);
1265
+ const meta = {
1266
+ moduleId,
1267
+ instanceId,
1268
+ fieldPath,
1269
+ resourceId,
1270
+ key,
1271
+ keyHash: keyHash2,
1272
+ rowId,
1273
+ traitNodeId: step.debugInfo?.graphNodeId,
1274
+ stepId: step.id
1275
+ };
1276
+ if (!(typeof meta.opSeq === "number" && Number.isFinite(meta.opSeq))) {
1277
+ const sessionOpt = yield* Effect.serviceOption(RunSessionTag);
1278
+ if (Option.isSome(sessionOpt)) {
1279
+ const seqKey = instanceId ?? "global";
1280
+ meta.opSeq = sessionOpt.value.local.nextSeq("opSeq", seqKey);
1281
+ }
1282
+ }
1283
+ const op = make({
1284
+ kind: "service",
1285
+ name: resourceId,
1286
+ effect: loadEffect,
1287
+ meta
1288
+ });
1289
+ const exit = yield* Effect.exit(run(op, stack));
1290
+ if (exit._tag === "Success") {
1291
+ const successSnapshot = Snapshot.success({ keyHash: keyHash2, data: exit.value });
1292
+ const wroteSuccessPath = yield* writebackIfCurrentKeyHashForRow(
1293
+ rowId,
1294
+ keyHash2,
1295
+ successSnapshot,
1296
+ "source-refresh",
1297
+ `source:${fieldPath}:${rowId}:success`,
1298
+ "success"
1299
+ );
1300
+ if (wroteSuccessPath) {
1301
+ yield* recordSnapshot(replayMode, replayLog, {
1302
+ _tag: "ResourceSnapshot",
1303
+ resourceId,
1304
+ fieldPath: wroteSuccessPath,
1305
+ keyHash: keyHash2,
1306
+ concurrency: mode2,
1307
+ phase: "success",
1308
+ snapshot: successSnapshot,
1309
+ timestamp: Date.now(),
1310
+ moduleId,
1311
+ instanceId
1312
+ });
1313
+ }
1314
+ } else {
1315
+ const errorSnapshot = Snapshot.error({ keyHash: keyHash2, error: exit.cause });
1316
+ const wroteErrorPath = yield* writebackIfCurrentKeyHashForRow(
1317
+ rowId,
1318
+ keyHash2,
1319
+ errorSnapshot,
1320
+ "source-refresh",
1321
+ `source:${fieldPath}:${rowId}:error`,
1322
+ "error"
1323
+ );
1324
+ if (wroteErrorPath) {
1325
+ yield* recordSnapshot(replayMode, replayLog, {
1326
+ _tag: "ResourceSnapshot",
1327
+ resourceId,
1328
+ fieldPath: wroteErrorPath,
1329
+ keyHash: keyHash2,
1330
+ concurrency: mode2,
1331
+ phase: "error",
1332
+ snapshot: errorSnapshot,
1333
+ timestamp: Date.now(),
1334
+ moduleId,
1335
+ instanceId
1336
+ });
1337
+ }
1338
+ }
1339
+ }).pipe(Effect.catchAllCause(() => Effect.void));
1340
+ const fiber = yield* Effect.forkScoped(Effect.locally(inSyncTransactionFiber, false)(io));
1341
+ const myGen = gen2 += 1;
1342
+ inFlight2.set(rowId, { gen: myGen, fiber, keyHash: keyHash2 });
1343
+ yield* Effect.forkScoped(
1344
+ Effect.locally(
1345
+ inSyncTransactionFiber,
1346
+ false
1347
+ )(
1348
+ Fiber.await(fiber).pipe(
1349
+ Effect.zipRight(
1350
+ Effect.sync(() => {
1351
+ const current = inFlight2.get(rowId);
1352
+ if (current && current.gen === myGen) {
1353
+ inFlight2.delete(rowId);
1354
+ }
1355
+ })
1356
+ ),
1357
+ Effect.zipRight(
1358
+ mode2 === "exhaust-trailing" ? Effect.gen(function* () {
1359
+ const next = trailing2.get(rowId);
1360
+ trailing2.delete(rowId);
1361
+ if (next) {
1362
+ yield* startFetch2(rowId, next.key, next.keyHash, replayMode, replayLog);
1363
+ }
1364
+ }) : Effect.void
1365
+ ),
1366
+ Effect.catchAllCause(() => Effect.void)
1367
+ )
1368
+ )
1369
+ );
1370
+ });
1371
+ register(
1372
+ fieldPath,
1373
+ (state) => Effect.gen(function* () {
1374
+ const { moduleId, instanceId } = getBoundScope(bound);
1375
+ const replayModeOpt = yield* Effect.serviceOption(ReplayModeConfigTag);
1376
+ const replayMode = Option.isSome(replayModeOpt) ? replayModeOpt.value.mode : "live";
1377
+ const replayLogOpt = yield* Effect.serviceOption(ReplayLog);
1378
+ const replayLog = Option.isSome(replayLogOpt) ? replayLogOpt.value : void 0;
1379
+ const force = yield* FiberRef.get(forceSourceRefresh);
1380
+ const listValue = getAtPath(state, listPath);
1381
+ const items = Array.isArray(listValue) ? listValue : [];
1382
+ const ids = store.ensureList(listPath, items);
1383
+ const traceKey = `${instanceId ?? "unknown"}::source::${fieldPath}`;
1384
+ if (isDevEnv() && (yield* onceInRunSession(`deps_trace_settled:${traceKey}`))) {
1385
+ try {
1386
+ const sample = items[0];
1387
+ if (sample !== void 0) {
1388
+ const traced = trace((s) => entry.meta.key(s), sample);
1389
+ const prefixedReads = traced.reads.map((r) => r ? `${listPath}[].${r}` : `${listPath}[]`);
1390
+ const diff = diffDeps(entry.meta.deps ?? [], prefixedReads);
1391
+ if (diff) {
1392
+ yield* emitDepsMismatch({
1393
+ moduleId,
1394
+ instanceId,
1395
+ kind: "source",
1396
+ fieldPath,
1397
+ diff
1398
+ });
1399
+ }
1400
+ }
1401
+ } catch {
1402
+ }
1403
+ }
1404
+ for (let index = 0; index < items.length; index++) {
1405
+ const rowId = ids[index];
1406
+ if (!rowId) continue;
1407
+ const concretePath = toListItemValuePath(listPath, index, itemPath);
1408
+ const prevSnapshot = getAtPath(state, concretePath);
1409
+ let key;
1410
+ try {
1411
+ key = entry.meta.key(items[index]);
1412
+ } catch {
1413
+ key = void 0;
1414
+ }
1415
+ const current = inFlight2.get(rowId);
1416
+ if (key === void 0) {
1417
+ trailing2.delete(rowId);
1418
+ inFlight2.delete(rowId);
1419
+ if (prevSnapshot && typeof prevSnapshot === "object" && prevSnapshot.status === "idle" && prevSnapshot.data === void 0 && prevSnapshot.error === void 0) {
1420
+ continue;
1421
+ }
1422
+ const idleSnapshot = Snapshot.idle();
1423
+ const wroteIdlePath = yield* setSnapshotForRowInTxn(
1424
+ rowId,
1425
+ idleSnapshot,
1426
+ "source-refresh",
1427
+ `source:${fieldPath}:${rowId}:idle`
1428
+ );
1429
+ if (wroteIdlePath) {
1430
+ const event = {
1431
+ _tag: "ResourceSnapshot",
1432
+ resourceId,
1433
+ fieldPath: wroteIdlePath,
1434
+ keyHash: void 0,
1435
+ concurrency: mode2,
1436
+ phase: "idle",
1437
+ snapshot: idleSnapshot,
1438
+ timestamp: Date.now(),
1439
+ moduleId,
1440
+ instanceId
1441
+ };
1442
+ recordReplayEvent(bound, event);
1443
+ yield* recordSnapshot(replayMode, replayLog, event);
1444
+ }
1445
+ continue;
1446
+ }
1447
+ const h = keyHash(key);
1448
+ if (!force && current && current.keyHash === h) {
1449
+ continue;
1450
+ }
1451
+ const prevKeyHash = prevSnapshot && typeof prevSnapshot === "object" ? prevSnapshot.keyHash : void 0;
1452
+ if (!force && !current && prevKeyHash === h) {
1453
+ continue;
1454
+ }
1455
+ if (mode2 === "exhaust-trailing" && current) {
1456
+ trailing2.set(rowId, { key, keyHash: h });
1457
+ const loadingSnapshot = Snapshot.loading({ keyHash: h });
1458
+ const wroteLoadingPath = yield* setSnapshotForRowInTxn(
1459
+ rowId,
1460
+ loadingSnapshot,
1461
+ "source-refresh",
1462
+ `source:${fieldPath}:${rowId}:loading`
1463
+ );
1464
+ if (wroteLoadingPath) {
1465
+ const event = {
1466
+ _tag: "ResourceSnapshot",
1467
+ resourceId,
1468
+ fieldPath: wroteLoadingPath,
1469
+ keyHash: h,
1470
+ concurrency: mode2,
1471
+ phase: "loading",
1472
+ snapshot: loadingSnapshot,
1473
+ timestamp: Date.now(),
1474
+ moduleId,
1475
+ instanceId
1476
+ };
1477
+ recordReplayEvent(bound, event);
1478
+ yield* recordSnapshot(replayMode, replayLog, event);
1479
+ }
1480
+ continue;
1481
+ }
1482
+ if (mode2 === "switch" && current) {
1483
+ trailing2.delete(rowId);
1484
+ inFlight2.delete(rowId);
1485
+ }
1486
+ yield* startFetch2(rowId, key, h, replayMode, replayLog);
1487
+ }
1488
+ })
1489
+ );
1490
+ return Effect.void;
1491
+ }
1492
+ let inFlight;
1493
+ let gen = 0;
1494
+ let trailing;
1495
+ const concurrency = entry.meta.concurrency;
1496
+ const mode = concurrency ?? "switch";
1497
+ const startFetch = (key, keyHash2, replayMode, replayLog) => Effect.gen(function* () {
1498
+ const { moduleId, instanceId } = getBoundScope(bound);
1499
+ let loadingSnapshot = Snapshot.loading({ keyHash: keyHash2 });
1500
+ if (replayMode === "replay" && replayLog) {
1501
+ const replayLoading = yield* replayLog.consumeNextResourceSnapshot({
1502
+ resourceId,
1503
+ fieldPath,
1504
+ keyHash: keyHash2,
1505
+ phase: "loading"
1506
+ });
1507
+ if (replayLoading) {
1508
+ loadingSnapshot = replayLoading.snapshot;
1509
+ }
1510
+ }
1511
+ const wroteLoading = yield* setSnapshotInTxn(
1512
+ bound,
1513
+ fieldPath,
1514
+ loadingSnapshot,
1515
+ "source-refresh",
1516
+ `source:${fieldPath}:loading`,
1517
+ step.debugInfo?.graphNodeId
1518
+ );
1519
+ if (wroteLoading) {
1520
+ const event = {
1521
+ _tag: "ResourceSnapshot",
1522
+ resourceId,
1523
+ fieldPath,
1524
+ keyHash: keyHash2,
1525
+ concurrency: mode,
1526
+ phase: "loading",
1527
+ snapshot: loadingSnapshot,
1528
+ timestamp: Date.now(),
1529
+ moduleId,
1530
+ instanceId
1531
+ };
1532
+ recordReplayEvent(bound, event);
1533
+ yield* recordSnapshot(replayMode, replayLog, event);
1534
+ }
1535
+ const io = Effect.gen(function* () {
1536
+ if (replayMode === "replay" && replayLog) {
1537
+ yield* Effect.yieldNow();
1538
+ const replayed = yield* replayLog.consumeNextResourceSnapshot({
1539
+ resourceId,
1540
+ fieldPath,
1541
+ keyHash: keyHash2
1542
+ });
1543
+ if (!replayed) return yield* Effect.void;
1544
+ if (replayed.phase === "success") {
1545
+ const event = {
1546
+ _tag: "ResourceSnapshot",
1547
+ resourceId,
1548
+ fieldPath,
1549
+ keyHash: keyHash2,
1550
+ concurrency: mode,
1551
+ phase: "success",
1552
+ snapshot: replayed.snapshot,
1553
+ timestamp: Date.now(),
1554
+ moduleId,
1555
+ instanceId
1556
+ };
1557
+ yield* writebackIfCurrentKeyHash(
1558
+ bound,
1559
+ fieldPath,
1560
+ keyHash2,
1561
+ replayed.snapshot,
1562
+ "source-refresh",
1563
+ `source:${fieldPath}:success`,
1564
+ step.debugInfo?.graphNodeId,
1565
+ event
1566
+ );
1567
+ } else if (replayed.phase === "error") {
1568
+ const event = {
1569
+ _tag: "ResourceSnapshot",
1570
+ resourceId,
1571
+ fieldPath,
1572
+ keyHash: keyHash2,
1573
+ concurrency: mode,
1574
+ phase: "error",
1575
+ snapshot: replayed.snapshot,
1576
+ timestamp: Date.now(),
1577
+ moduleId,
1578
+ instanceId
1579
+ };
1580
+ yield* writebackIfCurrentKeyHash(
1581
+ bound,
1582
+ fieldPath,
1583
+ keyHash2,
1584
+ replayed.snapshot,
1585
+ "source-refresh",
1586
+ `source:${fieldPath}:error`,
1587
+ step.debugInfo?.graphNodeId,
1588
+ event
1589
+ );
1590
+ }
1591
+ return yield* Effect.void;
1592
+ }
1593
+ const stack = yield* getMiddlewareStack();
1594
+ const registryOpt = yield* Effect.serviceOption(internal.ResourceRegistryTag);
1595
+ const registry = Option.isSome(registryOpt) ? registryOpt.value : void 0;
1596
+ const spec = registry?.specs.get(resourceId);
1597
+ if (!spec) {
1598
+ return yield* Effect.void;
1599
+ }
1600
+ const loadEffect = spec.load(key);
1601
+ const meta = {
1602
+ moduleId,
1603
+ instanceId,
1604
+ fieldPath,
1605
+ resourceId,
1606
+ key,
1607
+ keyHash: keyHash2,
1608
+ traitNodeId: step.debugInfo?.graphNodeId,
1609
+ stepId: step.id
1610
+ };
1611
+ if (!(typeof meta.opSeq === "number" && Number.isFinite(meta.opSeq))) {
1612
+ const sessionOpt = yield* Effect.serviceOption(RunSessionTag);
1613
+ if (Option.isSome(sessionOpt)) {
1614
+ const seqKey = instanceId ?? "global";
1615
+ meta.opSeq = sessionOpt.value.local.nextSeq("opSeq", seqKey);
1616
+ }
1617
+ }
1618
+ const op = make({
1619
+ kind: "trait-source",
1620
+ name: resourceId,
1621
+ effect: loadEffect,
1622
+ meta
1623
+ });
1624
+ const exit = yield* Effect.exit(run(op, stack));
1625
+ if (exit._tag === "Success") {
1626
+ const successSnapshot = Snapshot.success({ keyHash: keyHash2, data: exit.value });
1627
+ const event = {
1628
+ _tag: "ResourceSnapshot",
1629
+ resourceId,
1630
+ fieldPath,
1631
+ keyHash: keyHash2,
1632
+ concurrency: mode,
1633
+ phase: "success",
1634
+ snapshot: successSnapshot,
1635
+ timestamp: Date.now(),
1636
+ moduleId,
1637
+ instanceId
1638
+ };
1639
+ const wroteSuccess = yield* writebackIfCurrentKeyHash(
1640
+ bound,
1641
+ fieldPath,
1642
+ keyHash2,
1643
+ successSnapshot,
1644
+ "source-refresh",
1645
+ `source:${fieldPath}:success`,
1646
+ step.debugInfo?.graphNodeId,
1647
+ event
1648
+ );
1649
+ if (wroteSuccess) {
1650
+ yield* recordSnapshot(replayMode, replayLog, event);
1651
+ }
1652
+ } else {
1653
+ const errorSnapshot = Snapshot.error({ keyHash: keyHash2, error: exit.cause });
1654
+ const event = {
1655
+ _tag: "ResourceSnapshot",
1656
+ resourceId,
1657
+ fieldPath,
1658
+ keyHash: keyHash2,
1659
+ concurrency: mode,
1660
+ phase: "error",
1661
+ snapshot: errorSnapshot,
1662
+ timestamp: Date.now(),
1663
+ moduleId,
1664
+ instanceId
1665
+ };
1666
+ const wroteError = yield* writebackIfCurrentKeyHash(
1667
+ bound,
1668
+ fieldPath,
1669
+ keyHash2,
1670
+ errorSnapshot,
1671
+ "source-refresh",
1672
+ `source:${fieldPath}:error`,
1673
+ step.debugInfo?.graphNodeId,
1674
+ event
1675
+ );
1676
+ if (wroteError) {
1677
+ yield* recordSnapshot(replayMode, replayLog, event);
1678
+ }
1679
+ }
1680
+ }).pipe(Effect.catchAllCause(() => Effect.void));
1681
+ const fiber = yield* Effect.forkScoped(Effect.locally(inSyncTransactionFiber, false)(io));
1682
+ const myGen = gen += 1;
1683
+ inFlight = { gen: myGen, fiber, keyHash: keyHash2 };
1684
+ yield* Effect.forkScoped(
1685
+ Effect.locally(
1686
+ inSyncTransactionFiber,
1687
+ false
1688
+ )(
1689
+ Fiber.await(fiber).pipe(
1690
+ Effect.zipRight(
1691
+ Effect.sync(() => {
1692
+ if (inFlight && inFlight.gen === myGen) {
1693
+ inFlight = void 0;
1694
+ }
1695
+ })
1696
+ ),
1697
+ Effect.zipRight(
1698
+ mode === "exhaust-trailing" ? Effect.gen(function* () {
1699
+ const next = trailing;
1700
+ trailing = void 0;
1701
+ if (next) {
1702
+ yield* startFetch(next.key, next.keyHash, replayMode, replayLog);
1703
+ }
1704
+ }) : Effect.void
1705
+ ),
1706
+ Effect.catchAllCause(() => Effect.void)
1707
+ )
1708
+ )
1709
+ );
1710
+ });
1711
+ register(
1712
+ fieldPath,
1713
+ (state) => Effect.gen(function* () {
1714
+ const { moduleId, instanceId } = getBoundScope(bound);
1715
+ const replayModeOpt = yield* Effect.serviceOption(ReplayModeConfigTag);
1716
+ const replayMode = Option.isSome(replayModeOpt) ? replayModeOpt.value.mode : "live";
1717
+ const replayLogOpt = yield* Effect.serviceOption(ReplayLog);
1718
+ const replayLog = Option.isSome(replayLogOpt) ? replayLogOpt.value : void 0;
1719
+ const force = yield* FiberRef.get(forceSourceRefresh);
1720
+ let key;
1721
+ try {
1722
+ key = entry.meta.key(state);
1723
+ } catch {
1724
+ key = void 0;
1725
+ }
1726
+ const traceKey = `${instanceId ?? "unknown"}::source::${fieldPath}`;
1727
+ if (isDevEnv() && (yield* onceInRunSession(`deps_trace_settled:${traceKey}`))) {
1728
+ try {
1729
+ const traced = trace((s) => entry.meta.key(s), state);
1730
+ const diff = diffDeps(entry.meta.deps ?? [], traced.reads);
1731
+ if (diff) {
1732
+ yield* emitDepsMismatch({
1733
+ moduleId,
1734
+ instanceId,
1735
+ kind: "source",
1736
+ fieldPath,
1737
+ diff
1738
+ });
1739
+ }
1740
+ } catch {
1741
+ }
1742
+ }
1743
+ if (key === void 0) {
1744
+ if (inFlight) {
1745
+ yield* Fiber.interruptFork(inFlight.fiber);
1746
+ inFlight = void 0;
1747
+ }
1748
+ trailing = void 0;
1749
+ const idleSnapshot = Snapshot.idle();
1750
+ const wroteIdle = yield* setSnapshotInTxn(
1751
+ bound,
1752
+ fieldPath,
1753
+ idleSnapshot,
1754
+ "source-refresh",
1755
+ `source:${fieldPath}:idle`,
1756
+ step.debugInfo?.graphNodeId
1757
+ );
1758
+ if (wroteIdle) {
1759
+ const event = {
1760
+ _tag: "ResourceSnapshot",
1761
+ resourceId,
1762
+ fieldPath,
1763
+ keyHash: void 0,
1764
+ concurrency: mode,
1765
+ phase: "idle",
1766
+ snapshot: idleSnapshot,
1767
+ timestamp: Date.now(),
1768
+ moduleId,
1769
+ instanceId
1770
+ };
1771
+ recordReplayEvent(bound, event);
1772
+ yield* recordSnapshot(replayMode, replayLog, event);
1773
+ }
1774
+ return;
1775
+ }
1776
+ const h = keyHash(key);
1777
+ if (!force) {
1778
+ if (inFlight && inFlight.keyHash === h) {
1779
+ return;
1780
+ }
1781
+ const currentSnapshot = getAtPath(state, fieldPath);
1782
+ const currentKeyHash = currentSnapshot && typeof currentSnapshot === "object" ? currentSnapshot.keyHash : void 0;
1783
+ const currentStatus = currentSnapshot && typeof currentSnapshot === "object" ? currentSnapshot.status : void 0;
1784
+ if (currentStatus && currentStatus !== "idle" && currentKeyHash === h) {
1785
+ return;
1786
+ }
1787
+ }
1788
+ if (mode === "exhaust-trailing" && inFlight) {
1789
+ trailing = { key, keyHash: h };
1790
+ const loadingSnapshot = Snapshot.loading({ keyHash: h });
1791
+ const wroteLoading = yield* setSnapshotInTxn(
1792
+ bound,
1793
+ fieldPath,
1794
+ loadingSnapshot,
1795
+ "source-refresh",
1796
+ `source:${fieldPath}:loading`,
1797
+ step.debugInfo?.graphNodeId
1798
+ );
1799
+ if (wroteLoading) {
1800
+ const event = {
1801
+ _tag: "ResourceSnapshot",
1802
+ resourceId,
1803
+ fieldPath,
1804
+ keyHash: h,
1805
+ concurrency: mode,
1806
+ phase: "loading",
1807
+ snapshot: loadingSnapshot,
1808
+ timestamp: Date.now(),
1809
+ moduleId,
1810
+ instanceId
1811
+ };
1812
+ recordReplayEvent(bound, event);
1813
+ yield* recordSnapshot(replayMode, replayLog, event);
1814
+ }
1815
+ return;
1816
+ }
1817
+ if (mode === "switch" && inFlight) {
1818
+ yield* Fiber.interruptFork(inFlight.fiber);
1819
+ inFlight = void 0;
1820
+ trailing = void 0;
1821
+ }
1822
+ yield* startFetch(key, h, replayMode, replayLog);
1823
+ })
1824
+ );
1825
+ return Effect.void;
1826
+ };
1827
+
1828
+ // ../logix-core/src/internal/state-trait/converge-diagnostics.ts
1829
+ import { Effect as Effect2, FiberRef as FiberRef2, Option as Option2 } from "../effect.js";
1830
+ import * as SchemaAST2 from "../effect/SchemaAST.js";
1831
+ var onceKeysFallback = /* @__PURE__ */ new Set();
1832
+ var onceInRunSession2 = (key) => Effect2.serviceOption(RunSessionTag).pipe(
1833
+ Effect2.map((maybe) => {
1834
+ if (Option2.isSome(maybe)) {
1835
+ return maybe.value.local.once(key);
1836
+ }
1837
+ if (onceKeysFallback.has(key)) return false;
1838
+ onceKeysFallback.add(key);
1839
+ return true;
1840
+ })
1841
+ );
1842
+ var formatList2 = (items, limit = 10) => {
1843
+ if (items.length === 0) return "";
1844
+ if (items.length <= limit) return items.join(", ");
1845
+ return `${items.slice(0, limit).join(", ")}, \u2026(+${items.length - limit})`;
1846
+ };
1847
+ var emitDepsMismatch2 = (params) => {
1848
+ return Effect2.gen(function* () {
1849
+ const key = `${params.moduleId ?? "unknown"}::${params.instanceId ?? "unknown"}::${params.kind}::${params.fieldPath}`;
1850
+ const shouldEmit = yield* onceInRunSession2(`deps_mismatch:${key}`);
1851
+ if (!shouldEmit) return;
1852
+ yield* record({
1853
+ type: "diagnostic",
1854
+ moduleId: params.moduleId,
1855
+ instanceId: params.instanceId,
1856
+ code: "state_trait::deps_mismatch",
1857
+ severity: "warning",
1858
+ message: `[deps] ${params.kind} "${params.fieldPath}" declared=[${formatList2(params.diff.declared)}] reads=[${formatList2(params.diff.reads)}] missing=[${formatList2(params.diff.missing)}] unused=[${formatList2(params.diff.unused)}]`,
1859
+ hint: 'deps is the single source of truth for dependencies: incremental scheduling / reverse closures / performance optimizations rely on deps only. Keep deps consistent with actual reads; if you really depend on the whole object, declare a coarser-grained dep (e.g. "profile") to cover sub-field reads.',
1860
+ kind: `deps_mismatch:${params.kind}`
1861
+ });
1862
+ });
1863
+ };
1864
+ var schemaHasPath = (ast, segments, seen = /* @__PURE__ */ new Set()) => {
1865
+ if (segments.length === 0) return true;
1866
+ let current = ast;
1867
+ while (true) {
1868
+ if (SchemaAST2.isSuspend(current)) {
1869
+ if (seen.has(current)) {
1870
+ return true;
1871
+ }
1872
+ seen.add(current);
1873
+ current = current.f();
1874
+ continue;
1875
+ }
1876
+ if (SchemaAST2.isRefinement(current)) {
1877
+ current = current.from;
1878
+ continue;
1879
+ }
1880
+ break;
1881
+ }
1882
+ if (SchemaAST2.isTransformation(current)) {
1883
+ return schemaHasPath(current.to, segments, seen) || schemaHasPath(current.from, segments, seen);
1884
+ }
1885
+ if (SchemaAST2.isUnion(current)) {
1886
+ return current.types.some((t) => schemaHasPath(t, segments, seen));
1887
+ }
1888
+ if (SchemaAST2.isTupleType(current)) {
1889
+ const candidates = [];
1890
+ for (const e of current.elements) candidates.push(e.type);
1891
+ for (const r of current.rest) candidates.push(r.type);
1892
+ if (candidates.length === 0) return true;
1893
+ return candidates.some((t) => schemaHasPath(t, segments, seen));
1894
+ }
1895
+ if (SchemaAST2.isTypeLiteral(current)) {
1896
+ const [head, ...tail] = segments;
1897
+ for (const ps of current.propertySignatures) {
1898
+ if (String(ps.name) !== head) continue;
1899
+ return schemaHasPath(ps.type, tail, seen);
1900
+ }
1901
+ for (const sig of current.indexSignatures) {
1902
+ let param = sig.parameter;
1903
+ while (SchemaAST2.isRefinement(param)) {
1904
+ param = param.from;
1905
+ }
1906
+ const tag2 = param?._tag;
1907
+ if (tag2 === "StringKeyword" || tag2 === "TemplateLiteral") {
1908
+ return schemaHasPath(sig.type, tail, seen);
1909
+ }
1910
+ }
1911
+ return false;
1912
+ }
1913
+ const tag = current?._tag;
1914
+ if (tag === "AnyKeyword" || tag === "UnknownKeyword" || tag === "ObjectKeyword" || tag === "Declaration") {
1915
+ return true;
1916
+ }
1917
+ return false;
1918
+ };
1919
+ var schemaHasFieldPath = (stateSchemaAst, path) => {
1920
+ if (!path) return true;
1921
+ if (path === "$root") return true;
1922
+ const normalized = normalizeFieldPath(path);
1923
+ if (!normalized) return false;
1924
+ const segs = normalized[0] === "$root" ? normalized.slice(1) : normalized;
1925
+ return schemaHasPath(stateSchemaAst, segs);
1926
+ };
1927
+ var formatSchemaMismatchLine = (ref) => {
1928
+ if (ref.kind === "fieldPath") {
1929
+ return `- ${ref.entryKind} "${ref.entryFieldPath}" fieldPath="${ref.path}"`;
1930
+ }
1931
+ if (ref.kind === "dep") {
1932
+ const rule = ref.ruleName ? ` rule="${ref.ruleName}"` : "";
1933
+ return `- ${ref.entryKind} "${ref.entryFieldPath}" deps="${ref.path}"${rule}`;
1934
+ }
1935
+ if (ref.kind === "link_from") {
1936
+ return `- link "${ref.entryFieldPath}" from="${ref.path}"`;
1937
+ }
1938
+ if (ref.kind === "check_writeback") {
1939
+ return `- check "${ref.entryFieldPath}" writeback="${ref.path}"`;
1940
+ }
1941
+ return `- ${ref.entryKind} "${ref.entryFieldPath}" path="${ref.path}"`;
1942
+ };
1943
+ var emitSchemaMismatch = (program, ctx) => Effect2.gen(function* () {
1944
+ if (!isDevEnv()) return;
1945
+ const level = yield* FiberRef2.get(currentDiagnosticsLevel);
1946
+ if (level === "off") return;
1947
+ const key = `${ctx.moduleId ?? "unknown"}::${ctx.instanceId}`;
1948
+ const shouldEmit = yield* onceInRunSession2(`schema_mismatch:${key}`);
1949
+ if (!shouldEmit) return;
1950
+ const refs = program.schemaPaths ?? [];
1951
+ if (refs.length === 0) return;
1952
+ const stateSchemaAst = program.stateSchema.ast;
1953
+ const mismatches = [];
1954
+ const seen = /* @__PURE__ */ new Set();
1955
+ for (const ref of refs) {
1956
+ if (schemaHasFieldPath(stateSchemaAst, ref.path)) continue;
1957
+ const k = `${ref.kind}|${ref.entryKind}|${ref.entryFieldPath}|${ref.ruleName ?? ""}|${ref.path}`;
1958
+ if (seen.has(k)) continue;
1959
+ seen.add(k);
1960
+ mismatches.push(ref);
1961
+ }
1962
+ if (mismatches.length === 0) return;
1963
+ const limit = level === "light" ? 8 : 24;
1964
+ const lines = mismatches.slice(0, limit).map(formatSchemaMismatchLine);
1965
+ if (mismatches.length > limit) {
1966
+ lines.push(`- \u2026(+${mismatches.length - limit})`);
1967
+ }
1968
+ yield* record({
1969
+ type: "diagnostic",
1970
+ moduleId: ctx.moduleId,
1971
+ instanceId: ctx.instanceId,
1972
+ code: "state_trait::schema_mismatch",
1973
+ severity: "warning",
1974
+ message: `[schema] The following paths are not declared in stateSchema (total ${mismatches.length}):
1975
+ ${lines.join("\n")}`,
1976
+ hint: "StateTrait writeback will create missing objects/fields. Declare all fieldPath/deps/link.from and errors.* writeback paths in stateSchema, or fix typos in trait paths.",
1977
+ kind: "schema_mismatch"
1978
+ });
1979
+ });
1980
+
1981
+ export {
1982
+ onceInRunSession2 as onceInRunSession,
1983
+ emitDepsMismatch2 as emitDepsMismatch,
1984
+ emitSchemaMismatch,
1985
+ diffDeps,
1986
+ trace,
1987
+ syncIdleInTransaction,
1988
+ installSourceRefresh,
1989
+ build
1990
+ };
1991
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvYnVpbGQudHMiLCAiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvbW9kZWwudHMiLCAiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvc291cmNlLmltcGwudHMiLCAiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvZGVwcy10cmFjZS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9zdGF0ZS10cmFpdC9jb252ZXJnZS1kaWFnbm9zdGljcy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHR5cGUgeyBTY2hlbWEgfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgKiBhcyBTY2hlbWFBU1QgZnJvbSAnZWZmZWN0L1NjaGVtYUFTVCdcbmltcG9ydCB7XG4gIHR5cGUgU3RhdGVUcmFpdFByb2dyYW0sXG4gIHR5cGUgU3RhdGVUcmFpdFNwZWMsXG4gIHR5cGUgU3RhdGVUcmFpdEVudHJ5LFxuICB0eXBlIFN0YXRlVHJhaXRHcmFwaCxcbiAgdHlwZSBTdGF0ZVRyYWl0R3JhcGhFZGdlLFxuICB0eXBlIFN0YXRlVHJhaXRHcmFwaE5vZGUsXG4gIHR5cGUgU3RhdGVUcmFpdEZpZWxkLFxuICB0eXBlIFN0YXRlVHJhaXRGaWVsZFRyYWl0LFxuICB0eXBlIFN0YXRlVHJhaXRLaW5kLFxuICB0eXBlIFN0YXRlVHJhaXRQbGFuLFxuICB0eXBlIFN0YXRlVHJhaXRQbGFuU3RlcCxcbiAgdHlwZSBTdGF0ZVRyYWl0UmVzb3VyY2UsXG4gIHR5cGUgU3RhdGVUcmFpdFNjaGVtYVBhdGhSZWYsXG4gIGNvbGxlY3ROb2RlTWV0YSxcbiAgbm9ybWFsaXplU3BlYyxcbn0gZnJvbSAnLi9tb2RlbC5qcydcbmltcG9ydCAqIGFzIE1ldGEgZnJvbSAnLi9tZXRhLmpzJ1xuaW1wb3J0IHtcbiAgY29tcGFyZUZpZWxkUGF0aCxcbiAgZ2V0RmllbGRQYXRoSWQsXG4gIG1ha2VGaWVsZFBhdGhJZFJlZ2lzdHJ5LFxuICBub3JtYWxpemVGaWVsZFBhdGgsXG4gIHR5cGUgRmllbGRQYXRoLFxuICB0eXBlIEZpZWxkUGF0aElkLFxufSBmcm9tICcuLi9maWVsZC1wYXRoLmpzJ1xuaW1wb3J0IHsgZm52MWEzMiwgc3RhYmxlU3RyaW5naWZ5IH0gZnJvbSAnLi4vZGlnZXN0LmpzJ1xuaW1wb3J0IHR5cGUgeyBDb252ZXJnZVN0YXRpY0lyUmVnaXN0cnkgfSBmcm9tICcuL2NvbnZlcmdlLWlyLmpzJ1xuXG5jb25zdCBub3dQZXJmID0gKCk6IG51bWJlciA9PlxuICB0eXBlb2YgZ2xvYmFsVGhpcy5wZXJmb3JtYW5jZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGdsb2JhbFRoaXMucGVyZm9ybWFuY2Uubm93ID09PSAnZnVuY3Rpb24nXG4gICAgPyBnbG9iYWxUaGlzLnBlcmZvcm1hbmNlLm5vdygpXG4gICAgOiBEYXRlLm5vdygpXG5cbnR5cGUgQ29udmVyZ2VXcml0ZXIgPSBFeHRyYWN0PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4sIHsgcmVhZG9ubHkga2luZDogJ2NvbXB1dGVkJyB8ICdsaW5rJyB9PlxuXG5jb25zdCBjb2xsZWN0TXVsdGlwbGVXcml0ZXJzRXJyb3IgPSAoXG4gIGVudHJpZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj4sXG4pOiBDb252ZXJnZVN0YXRpY0lyUmVnaXN0cnlbJ2NvbmZpZ0Vycm9yJ10gfCB1bmRlZmluZWQgPT4ge1xuICBjb25zdCBraW5kc0J5RmllbGRQYXRoID0gbmV3IE1hcDxzdHJpbmcsIFNldDxTdGF0ZVRyYWl0S2luZD4+KClcblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICBpZiAoZW50cnkua2luZCAhPT0gJ2NvbXB1dGVkJyAmJiBlbnRyeS5raW5kICE9PSAnbGluaycgJiYgZW50cnkua2luZCAhPT0gJ3NvdXJjZScgJiYgZW50cnkua2luZCAhPT0gJ2V4dGVybmFsU3RvcmUnKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBjb25zdCBzZXQgPSBraW5kc0J5RmllbGRQYXRoLmdldChlbnRyeS5maWVsZFBhdGgpID8/IG5ldyBTZXQ8U3RhdGVUcmFpdEtpbmQ+KClcbiAgICBzZXQuYWRkKGVudHJ5LmtpbmQpXG4gICAga2luZHNCeUZpZWxkUGF0aC5zZXQoZW50cnkuZmllbGRQYXRoLCBzZXQpXG4gIH1cblxuICBjb25zdCBjb25mbGljdHM6IEFycmF5PHsgcmVhZG9ubHkgZmllbGRQYXRoOiBzdHJpbmc7IHJlYWRvbmx5IGtpbmRzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRLaW5kPiB9PiA9IFtdXG4gIGZvciAoY29uc3QgW2ZpZWxkUGF0aCwga2luZHNdIG9mIGtpbmRzQnlGaWVsZFBhdGguZW50cmllcygpKSB7XG4gICAgaWYgKGtpbmRzLnNpemUgPD0gMSkgY29udGludWVcbiAgICBjb25mbGljdHMucHVzaCh7IGZpZWxkUGF0aCwga2luZHM6IEFycmF5LmZyb20oa2luZHMpLnNvcnQoKSB9KVxuICB9XG5cbiAgaWYgKGNvbmZsaWN0cy5sZW5ndGggPT09IDApIHJldHVybiB1bmRlZmluZWRcblxuICBjb25mbGljdHMuc29ydCgoYSwgYikgPT4gKGEuZmllbGRQYXRoIDwgYi5maWVsZFBhdGggPyAtMSA6IGEuZmllbGRQYXRoID4gYi5maWVsZFBhdGggPyAxIDogMCkpXG4gIGNvbnN0IGZpZWxkcyA9IGNvbmZsaWN0cy5tYXAoKGMpID0+IGMuZmllbGRQYXRoKVxuICBjb25zdCBwcmltYXJ5ID0gY29uZmxpY3RzWzBdIVxuICBjb25zdCBraW5kU3VtbWFyeSA9IHByaW1hcnkua2luZHMuam9pbignICsgJylcblxuICByZXR1cm4ge1xuICAgIGNvZGU6ICdNVUxUSVBMRV9XUklURVJTJyxcbiAgICBtZXNzYWdlOlxuICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBNdWx0aXBsZSB3cml0ZXJzIGZvciBmaWVsZCBcIiR7cHJpbWFyeS5maWVsZFBhdGh9XCIgKCR7a2luZFN1bW1hcnl9KS4gYCArXG4gICAgICAnT25seSBvbmUgb2YgY29tcHV0ZWQvbGluay9zb3VyY2UvZXh0ZXJuYWxTdG9yZSBjYW4gd3JpdGUgYSBmaWVsZFBhdGguJyxcbiAgICBmaWVsZHMsXG4gIH1cbn1cblxuY29uc3QgZ2V0Q29udmVyZ2VXcml0ZXJEZXBzID0gKGVudHJ5OiBDb252ZXJnZVdyaXRlcik6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiA9PiB7XG4gIGlmIChlbnRyeS5raW5kID09PSAnY29tcHV0ZWQnKSB7XG4gICAgcmV0dXJuICgoZW50cnkubWV0YSBhcyBhbnkpPy5kZXBzID8/IFtdKSBhcyBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgfVxuICByZXR1cm4gW2VudHJ5Lm1ldGEuZnJvbSBhcyBzdHJpbmddXG59XG5cbmNvbnN0IGNvbXB1dGVDb252ZXJnZVRvcG9PcmRlciA9IChcbiAgd3JpdGVyczogUmVhZG9ubHlBcnJheTxDb252ZXJnZVdyaXRlcj4sXG4pOiB7IHJlYWRvbmx5IG9yZGVyOiBSZWFkb25seUFycmF5PHN0cmluZz47IHJlYWRvbmx5IGNvbmZpZ0Vycm9yPzogQ29udmVyZ2VTdGF0aWNJclJlZ2lzdHJ5Wydjb25maWdFcnJvciddIH0gPT4ge1xuICBjb25zdCB3cml0ZXJCeVBhdGggPSBuZXcgTWFwPHN0cmluZywgQ29udmVyZ2VXcml0ZXI+KClcbiAgZm9yIChjb25zdCBlbnRyeSBvZiB3cml0ZXJzKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB3cml0ZXJCeVBhdGguZ2V0KGVudHJ5LmZpZWxkUGF0aClcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9yZGVyOiBbXSxcbiAgICAgICAgY29uZmlnRXJyb3I6IHtcbiAgICAgICAgICBjb2RlOiAnTVVMVElQTEVfV1JJVEVSUycsXG4gICAgICAgICAgbWVzc2FnZTogYFtTdGF0ZVRyYWl0LmNvbnZlcmdlXSBNdWx0aXBsZSB3cml0ZXJzIGZvciBmaWVsZCBcIiR7ZW50cnkuZmllbGRQYXRofVwiICgke2V4aXN0aW5nLmtpbmR9ICsgJHtlbnRyeS5raW5kfSkuYCxcbiAgICAgICAgICBmaWVsZHM6IFtlbnRyeS5maWVsZFBhdGhdLFxuICAgICAgICB9LFxuICAgICAgfVxuICAgIH1cbiAgICB3cml0ZXJCeVBhdGguc2V0KGVudHJ5LmZpZWxkUGF0aCwgZW50cnkpXG4gIH1cblxuICBjb25zdCBub2RlcyA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gIGZvciAoY29uc3QgZW50cnkgb2Ygd3JpdGVycykge1xuICAgIG5vZGVzLmFkZChlbnRyeS5maWVsZFBhdGgpXG4gIH1cblxuICBjb25zdCBpbmRlZ3JlZSA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KClcbiAgY29uc3QgZm9yd2FyZCA9IG5ldyBNYXA8c3RyaW5nLCBBcnJheTxzdHJpbmc+PigpXG5cbiAgZm9yIChjb25zdCBub2RlIG9mIG5vZGVzKSB7XG4gICAgaW5kZWdyZWUuc2V0KG5vZGUsIDApXG4gICAgZm9yd2FyZC5zZXQobm9kZSwgW10pXG4gIH1cblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHdyaXRlcnMpIHtcbiAgICBjb25zdCB0byA9IGVudHJ5LmZpZWxkUGF0aFxuICAgIGNvbnN0IGRlcHMgPSBnZXRDb252ZXJnZVdyaXRlckRlcHMoZW50cnkpXG4gICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgaWYgKCFub2Rlcy5oYXMoZGVwKSkgY29udGludWVcbiAgICAgIGZvcndhcmQuZ2V0KGRlcCkhLnB1c2godG8pXG4gICAgICBpbmRlZ3JlZS5zZXQodG8sIChpbmRlZ3JlZS5nZXQodG8pID8/IDApICsgMSlcbiAgICB9XG4gIH1cblxuICBjb25zdCBxdWV1ZTogQXJyYXk8c3RyaW5nPiA9IFtdXG4gIGZvciAoY29uc3QgW25vZGUsIGRlZ10gb2YgaW5kZWdyZWUuZW50cmllcygpKSB7XG4gICAgaWYgKGRlZyA9PT0gMCkgcXVldWUucHVzaChub2RlKVxuICB9XG5cbiAgY29uc3Qgb3JkZXI6IEFycmF5PHN0cmluZz4gPSBbXVxuICB3aGlsZSAocXVldWUubGVuZ3RoKSB7XG4gICAgY29uc3QgbiA9IHF1ZXVlLnNoaWZ0KCkhXG4gICAgb3JkZXIucHVzaChuKVxuICAgIGNvbnN0IG91dHMgPSBmb3J3YXJkLmdldChuKSFcbiAgICBmb3IgKGNvbnN0IHRvIG9mIG91dHMpIHtcbiAgICAgIGNvbnN0IG5leHQgPSAoaW5kZWdyZWUuZ2V0KHRvKSA/PyAwKSAtIDFcbiAgICAgIGluZGVncmVlLnNldCh0bywgbmV4dClcbiAgICAgIGlmIChuZXh0ID09PSAwKSBxdWV1ZS5wdXNoKHRvKVxuICAgIH1cbiAgfVxuXG4gIGlmIChvcmRlci5sZW5ndGggIT09IG5vZGVzLnNpemUpIHtcbiAgICBjb25zdCByZW1haW5pbmcgPSBBcnJheS5mcm9tKG5vZGVzKS5maWx0ZXIoKG4pID0+ICFvcmRlci5pbmNsdWRlcyhuKSlcbiAgICByZXR1cm4ge1xuICAgICAgb3JkZXI6IFtdLFxuICAgICAgY29uZmlnRXJyb3I6IHtcbiAgICAgICAgY29kZTogJ0NZQ0xFX0RFVEVDVEVEJyxcbiAgICAgICAgbWVzc2FnZTogYFtTdGF0ZVRyYWl0LmNvbnZlcmdlXSBDeWNsZSBkZXRlY3RlZCBpbiBjb21wdXRlZC9saW5rIGdyYXBoOiAke3JlbWFpbmluZy5qb2luKCcsICcpfWAsXG4gICAgICAgIGZpZWxkczogcmVtYWluaW5nLFxuICAgICAgfSxcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBvcmRlciB9XG59XG5cbmNvbnN0IGNvbGxlY3RTY2hlbWFGaWVsZFBhdGhzID0gKHNjaGVtYTogU2NoZW1hLlNjaGVtYTxhbnksIGFueT4pOiBSZWFkb25seUFycmF5PEZpZWxkUGF0aD4gPT4ge1xuICBjb25zdCBieUtleSA9IG5ldyBNYXA8c3RyaW5nLCBGaWVsZFBhdGg+KClcblxuICBjb25zdCBhZGQgPSAocGF0aDogRmllbGRQYXRoKTogdm9pZCA9PiB7XG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZUZpZWxkUGF0aChwYXRoKVxuICAgIGlmICghbm9ybWFsaXplZCkgcmV0dXJuXG4gICAgYnlLZXkuc2V0KEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZWQpLCBub3JtYWxpemVkKVxuICB9XG5cbiAgY29uc3QgdmlzaXQgPSAoYXN0OiBTY2hlbWFBU1QuQVNULCBwcmVmaXg6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiwgc2VlbjogU2V0PFNjaGVtYUFTVC5BU1Q+KTogdm9pZCA9PiB7XG4gICAgbGV0IGN1cnJlbnQ6IFNjaGVtYUFTVC5BU1QgPSBhc3RcblxuICAgIC8vIFVud3JhcCBTdXNwZW5kL1JlZmluZW1lbnQgKHJlY3Vyc2l2ZSBzY2hlbWEgLyBicmFuZGVkIHNjaGVtYSkuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmIChTY2hlbWFBU1QuaXNTdXNwZW5kKGN1cnJlbnQpKSB7XG4gICAgICAgIGlmIChzZWVuLmhhcyhjdXJyZW50KSkgcmV0dXJuXG4gICAgICAgIHNlZW4uYWRkKGN1cnJlbnQpXG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LmYoKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgaWYgKFNjaGVtYUFTVC5pc1JlZmluZW1lbnQoY3VycmVudCkpIHtcbiAgICAgICAgY3VycmVudCA9IGN1cnJlbnQuZnJvbVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgYnJlYWtcbiAgICB9XG5cbiAgICBpZiAoU2NoZW1hQVNULmlzVHJhbnNmb3JtYXRpb24oY3VycmVudCkpIHtcbiAgICAgIHZpc2l0KGN1cnJlbnQudG8sIHByZWZpeCwgc2VlbilcbiAgICAgIHZpc2l0KGN1cnJlbnQuZnJvbSwgcHJlZml4LCBzZWVuKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKFNjaGVtYUFTVC5pc1VuaW9uKGN1cnJlbnQpKSB7XG4gICAgICBmb3IgKGNvbnN0IHQgb2YgY3VycmVudC50eXBlcykge1xuICAgICAgICB2aXNpdCh0LCBwcmVmaXgsIHNlZW4pXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBBcnJheSAvIFR1cGxlOiBpbmRpY2VzIGRvIG5vdCBlbnRlciB0aGUgRmllbGRQYXRoSWQgc3BhY2U7IHJlY3Vyc2UgaW50byBlbGVtZW50IHR5cGVzIHRvIHN1cHBvcnQgYGl0ZW1zWzBdLm5hbWUgLT4gaXRlbXMubmFtZWAuXG4gICAgaWYgKFNjaGVtYUFTVC5pc1R1cGxlVHlwZShjdXJyZW50KSkge1xuICAgICAgZm9yIChjb25zdCBlIG9mIGN1cnJlbnQuZWxlbWVudHMpIHtcbiAgICAgICAgdmlzaXQoZS50eXBlLCBwcmVmaXgsIHNlZW4pXG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IHIgb2YgY3VycmVudC5yZXN0KSB7XG4gICAgICAgIHZpc2l0KHIudHlwZSwgcHJlZml4LCBzZWVuKVxuICAgICAgfVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKFNjaGVtYUFTVC5pc1R5cGVMaXRlcmFsKGN1cnJlbnQpKSB7XG4gICAgICBmb3IgKGNvbnN0IHBzIG9mIGN1cnJlbnQucHJvcGVydHlTaWduYXR1cmVzKSB7XG4gICAgICAgIGNvbnN0IHNlZyA9IFN0cmluZyhwcy5uYW1lKVxuICAgICAgICBpZiAoIXNlZykgY29udGludWVcbiAgICAgICAgY29uc3QgbmV4dCA9IFsuLi5wcmVmaXgsIHNlZ11cbiAgICAgICAgYWRkKG5leHQpXG4gICAgICAgIHZpc2l0KHBzLnR5cGUsIG5leHQsIHNlZW4pXG4gICAgICB9XG4gICAgICAvLyBJbmRleCBzaWduYXR1cmUgKFJlY29yZDxzdHJpbmcsIFQ+KSBjYW4ndCBiZSBlbnVtZXJhdGVkIHN0YXRpY2FsbHk6IGF2b2lkIGdlbmVyYXRpbmcgbWlzYWxpZ25lZCBkeW5hbWljIGtleSBwYXRocy5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIEFueSAvIFVua25vd24gLyBPYmplY3QgLyBEZWNsYXJhdGlvbiAob3BlbiB0eXBlcyk6IGNhbm5vdCBlbnVtZXJhdGUgbmVzdGVkIHBhdGhzOyBzdG9wIGNvbnNlcnZhdGl2ZWx5LlxuICB9XG5cbiAgdmlzaXQoc2NoZW1hLmFzdCBhcyB1bmtub3duIGFzIFNjaGVtYUFTVC5BU1QsIFtdLCBuZXcgU2V0KCkpXG4gIHJldHVybiBBcnJheS5mcm9tKGJ5S2V5LnZhbHVlcygpKS5zb3J0KGNvbXBhcmVGaWVsZFBhdGgpXG59XG5cbmNvbnN0IGJ1aWxkQ29udmVyZ2VJciA9IChcbiAgc3RhdGVTY2hlbWE6IFNjaGVtYS5TY2hlbWE8YW55LCBhbnk+LFxuICBlbnRyaWVzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+LFxuKTogQ29udmVyZ2VTdGF0aWNJclJlZ2lzdHJ5ID0+IHtcbiAgY29uc3Qgc3RhcnRlZEF0ID0gbm93UGVyZigpXG4gIGNvbnN0IGdlbmVyYXRpb24gPSAwXG5cbiAgY29uc3QgbXVsdGlwbGVXcml0ZXJzRXJyb3IgPSBjb2xsZWN0TXVsdGlwbGVXcml0ZXJzRXJyb3IoZW50cmllcylcblxuICBjb25zdCB3cml0ZXJzID0gZW50cmllcy5maWx0ZXIoKGUpOiBlIGlzIENvbnZlcmdlV3JpdGVyID0+IGUua2luZCA9PT0gJ2NvbXB1dGVkJyB8fCBlLmtpbmQgPT09ICdsaW5rJylcblxuICBjb25zdCB3cml0ZXJzS2V5ID0gd3JpdGVyc1xuICAgIC5tYXAoKGVudHJ5KSA9PiBgJHtlbnRyeS5raW5kfToke2VudHJ5LmZpZWxkUGF0aH1gKVxuICAgIC5zb3J0KClcbiAgICAuam9pbignfCcpXG5cbiAgY29uc3QgZGVwc0tleSA9IHdyaXRlcnNcbiAgICAubWFwKChlbnRyeSkgPT4ge1xuICAgICAgY29uc3QgZGVwcyA9IGdldENvbnZlcmdlV3JpdGVyRGVwcyhlbnRyeSkuc2xpY2UoKS5zb3J0KCkuam9pbignLCcpXG4gICAgICBjb25zdCBzY2hlZHVsaW5nID0gKGVudHJ5Lm1ldGEgYXMgYW55KT8uc2NoZWR1bGluZyA9PT0gJ2RlZmVycmVkJyA/ICdkJyA6ICdpJ1xuICAgICAgcmV0dXJuIGAke2VudHJ5LmtpbmR9OiR7ZW50cnkuZmllbGRQYXRofUAke3NjaGVkdWxpbmd9PT4ke2RlcHN9YFxuICAgIH0pXG4gICAgLnNvcnQoKVxuICAgIC5qb2luKCd8JylcblxuICBjb25zdCB3cml0ZXJCeVBhdGggPSBuZXcgTWFwPHN0cmluZywgQ29udmVyZ2VXcml0ZXI+KClcbiAgZm9yIChjb25zdCBlbnRyeSBvZiB3cml0ZXJzKSB7XG4gICAgd3JpdGVyQnlQYXRoLnNldChlbnRyeS5maWVsZFBhdGgsIGVudHJ5KVxuICB9XG5cbiAgY29uc3QgdG9wbyA9IG11bHRpcGxlV3JpdGVyc0Vycm9yXG4gICAgPyB7IG9yZGVyOiBbXSBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfVxuICAgIDogd3JpdGVycy5sZW5ndGggPiAwXG4gICAgICA/IGNvbXB1dGVDb252ZXJnZVRvcG9PcmRlcih3cml0ZXJzKVxuICAgICAgOiB7IG9yZGVyOiBbXSBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfVxuICBjb25zdCBzdGVwc0J5SWQ6IEFycmF5PENvbnZlcmdlV3JpdGVyPiA9IHRvcG8uY29uZmlnRXJyb3IgPyBbXSA6IHRvcG8ub3JkZXIubWFwKChwYXRoKSA9PiB3cml0ZXJCeVBhdGguZ2V0KHBhdGgpISlcblxuICBjb25zdCBmaWVsZFBhdGhUYWJsZSA9IG5ldyBNYXA8c3RyaW5nLCBGaWVsZFBhdGg+KClcbiAgY29uc3QgYWRkUGF0aCA9IChwYXRoOiBGaWVsZFBhdGgpOiB2b2lkID0+IHtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBwcmVmaXggPSBwYXRoLnNsaWNlKDAsIGkpXG4gICAgICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShwcmVmaXgpXG4gICAgICBpZiAoIWZpZWxkUGF0aFRhYmxlLmhhcyhrZXkpKSBmaWVsZFBhdGhUYWJsZS5zZXQoa2V5LCBwcmVmaXgpXG4gICAgfVxuICB9XG5cbiAgLy8gMDY1OiBGaWVsZFBhdGhJZCBzZW1hbnRpY3MgbXVzdCBjb3ZlciBhbGwgZW51bWVyYWJsZSBmaWVsZCBwYXRocyBvZiBzdGF0ZVNjaGVtYTsgb3RoZXJ3aXNlIHJlZHVjZXIgcGF0Y2hQYXRocyBjYW4ndCBtYXAgYW5kIHdpbGwgZmFsbCBiYWNrIHRvIGRpcnR5QWxsLlxuICBmb3IgKGNvbnN0IHNjaGVtYVBhdGggb2YgY29sbGVjdFNjaGVtYUZpZWxkUGF0aHMoc3RhdGVTY2hlbWEpKSB7XG4gICAgYWRkUGF0aChzY2hlbWFQYXRoKVxuICB9XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiB3cml0ZXJzKSB7XG4gICAgY29uc3Qgb3V0ID0gbm9ybWFsaXplRmllbGRQYXRoKGVudHJ5LmZpZWxkUGF0aClcbiAgICBpZiAob3V0KSBhZGRQYXRoKG91dClcbiAgICBmb3IgKGNvbnN0IGRlcCBvZiBnZXRDb252ZXJnZVdyaXRlckRlcHMoZW50cnkpKSB7XG4gICAgICBjb25zdCBkZXBQYXRoID0gbm9ybWFsaXplRmllbGRQYXRoKGRlcClcbiAgICAgIGlmIChkZXBQYXRoKSBhZGRQYXRoKGRlcFBhdGgpXG4gICAgfVxuICB9XG5cbiAgY29uc3QgZmllbGRQYXRocyA9IEFycmF5LmZyb20oZmllbGRQYXRoVGFibGUudmFsdWVzKCkpLnNvcnQoY29tcGFyZUZpZWxkUGF0aClcbiAgY29uc3QgZmllbGRQYXRoSWRSZWdpc3RyeSA9IG1ha2VGaWVsZFBhdGhJZFJlZ2lzdHJ5KGZpZWxkUGF0aHMpXG4gIGNvbnN0IGZpZWxkUGF0aHNLZXkgPSBmbnYxYTMyKHN0YWJsZVN0cmluZ2lmeShmaWVsZFBhdGhzKSlcblxuICBjb25zdCBzdGVwT3V0RmllbGRQYXRoSWRCeVN0ZXBJZDogQXJyYXk8RmllbGRQYXRoSWQ+ID0gW11cbiAgY29uc3Qgc3RlcERlcHNGaWVsZFBhdGhJZHNCeVN0ZXBJZDogQXJyYXk8UmVhZG9ubHlBcnJheTxGaWVsZFBhdGhJZD4+ID0gW11cbiAgY29uc3Qgc3RlcFNjaGVkdWxpbmdCeVN0ZXBJZDogQXJyYXk8J2ltbWVkaWF0ZScgfCAnZGVmZXJyZWQnPiA9IFtdXG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiBzdGVwc0J5SWQpIHtcbiAgICBjb25zdCBvdXQgPSBub3JtYWxpemVGaWVsZFBhdGgoZW50cnkuZmllbGRQYXRoKVxuICAgIGNvbnN0IG91dElkID0gb3V0ICE9IG51bGwgPyBnZXRGaWVsZFBhdGhJZChmaWVsZFBhdGhJZFJlZ2lzdHJ5LCBvdXQpIDogdW5kZWZpbmVkXG4gICAgaWYgKG91dElkID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgW1N0YXRlVHJhaXQuYnVpbGRdIEZhaWxlZCB0byBtYXAgY29udmVyZ2Ugb3V0cHV0IGZpZWxkUGF0aCBcIiR7ZW50cnkuZmllbGRQYXRofVwiIHRvIEZpZWxkUGF0aElkLmApXG4gICAgfVxuXG4gICAgY29uc3QgZGVwSWRzOiBBcnJheTxGaWVsZFBhdGhJZD4gPSBbXVxuICAgIGZvciAoY29uc3QgZGVwIG9mIGdldENvbnZlcmdlV3JpdGVyRGVwcyhlbnRyeSkpIHtcbiAgICAgIGNvbnN0IGRlcFBhdGggPSBub3JtYWxpemVGaWVsZFBhdGgoZGVwKVxuICAgICAgaWYgKCFkZXBQYXRoKSBjb250aW51ZVxuICAgICAgY29uc3QgZGVwSWQgPSBnZXRGaWVsZFBhdGhJZChmaWVsZFBhdGhJZFJlZ2lzdHJ5LCBkZXBQYXRoKVxuICAgICAgaWYgKGRlcElkICE9IG51bGwpIGRlcElkcy5wdXNoKGRlcElkKVxuICAgIH1cblxuICAgIHN0ZXBPdXRGaWVsZFBhdGhJZEJ5U3RlcElkLnB1c2gob3V0SWQpXG4gICAgc3RlcERlcHNGaWVsZFBhdGhJZHNCeVN0ZXBJZC5wdXNoKGRlcElkcylcbiAgICBzdGVwU2NoZWR1bGluZ0J5U3RlcElkLnB1c2goKGVudHJ5Lm1ldGEgYXMgYW55KT8uc2NoZWR1bGluZyA9PT0gJ2RlZmVycmVkJyA/ICdkZWZlcnJlZCcgOiAnaW1tZWRpYXRlJylcbiAgfVxuXG4gIGNvbnN0IHRvcG9PcmRlciA9IHN0ZXBzQnlJZC5tYXAoKF8sIGkpID0+IGkpXG4gIGNvbnN0IGJ1aWxkRHVyYXRpb25NcyA9IE1hdGgubWF4KDAsIG5vd1BlcmYoKSAtIHN0YXJ0ZWRBdClcblxuICByZXR1cm4ge1xuICAgIGdlbmVyYXRpb24sXG4gICAgd3JpdGVyc0tleSxcbiAgICBkZXBzS2V5LFxuICAgIGZpZWxkUGF0aHNLZXksXG4gICAgZmllbGRQYXRocyxcbiAgICBmaWVsZFBhdGhJZFJlZ2lzdHJ5LFxuICAgIC4uLihtdWx0aXBsZVdyaXRlcnNFcnJvciA/IHsgY29uZmlnRXJyb3I6IG11bHRpcGxlV3JpdGVyc0Vycm9yIH0gOiB0b3BvLmNvbmZpZ0Vycm9yID8geyBjb25maWdFcnJvcjogdG9wby5jb25maWdFcnJvciB9IDogbnVsbCksXG4gICAgc3RlcHNCeUlkLFxuICAgIHN0ZXBPdXRGaWVsZFBhdGhJZEJ5U3RlcElkLFxuICAgIHN0ZXBEZXBzRmllbGRQYXRoSWRzQnlTdGVwSWQsXG4gICAgc3RlcFNjaGVkdWxpbmdCeVN0ZXBJZCxcbiAgICB0b3BvT3JkZXIsXG4gICAgYnVpbGREdXJhdGlvbk1zLFxuICB9XG59XG5cbi8qKlxuICogQnVpbGRzIGEgbm9ybWFsaXplZCBGaWVsZFRyYWl0IGZyb20gYSBTdGF0ZVRyYWl0RW50cnkuXG4gKlxuICogLSBDdXJyZW50bHkgdXNlcyBleHBsaWNpdCBkZXBzIGZvciBjb21wdXRlZC9zb3VyY2UgYW5kIGxpbmsgZWRnZXM7IGRlZXBlciBkZXBlbmRlbmN5IGFuYWx5c2lzIGlzIGludGVudGlvbmFsbHkgbm90IHBlcmZvcm1lZC5cbiAqIC0gSWYgd2UgZXZvbHZlIGV4cGxpY2l0IGRlcGVuZGVuY3kgZGVjbGFyYXRpb25zIGZ1cnRoZXIsIGV4dGVuZCBoZXJlLlxuICovXG5jb25zdCB0b0ZpZWxkVHJhaXQgPSAoZW50cnk6IFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4pOiBTdGF0ZVRyYWl0RmllbGRUcmFpdCA9PiB7XG4gIGNvbnN0IGRlcHM6IEFycmF5PHN0cmluZz4gPSBbXVxuXG4gIGlmIChlbnRyeS5raW5kID09PSAnY29tcHV0ZWQnKSB7XG4gICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgY29uc3QgbGlzdCA9IG1ldGEuZGVwcyBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICBpZiAobGlzdCkgZGVwcy5wdXNoKC4uLmxpc3QpXG4gIH0gZWxzZSBpZiAoZW50cnkua2luZCA9PT0gJ3NvdXJjZScpIHtcbiAgICBjb25zdCBtZXRhID0gZW50cnkubWV0YSBhcyBhbnlcbiAgICBjb25zdCBsaXN0ID0gbWV0YS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgIGlmIChsaXN0KSBkZXBzLnB1c2goLi4ubGlzdClcbiAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSAnbGluaycpIHtcbiAgICBkZXBzLnB1c2goZW50cnkubWV0YS5mcm9tIGFzIHN0cmluZylcbiAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSAnY2hlY2snKSB7XG4gICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgY29uc3QgcnVsZXMgPSAobWV0YT8ucnVsZXMgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXMocnVsZXMpKSB7XG4gICAgICBjb25zdCBydWxlID0gcnVsZXNbbmFtZV1cbiAgICAgIGlmIChydWxlICYmIHR5cGVvZiBydWxlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBjb25zdCBsaXN0ID0gcnVsZS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgICBpZiAobGlzdCkgZGVwcy5wdXNoKC4uLmxpc3QpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBmaWVsZElkOiBlbnRyeS5maWVsZFBhdGgsXG4gICAga2luZDogZW50cnkua2luZCxcbiAgICAvLyBLZWVwIG1ldGEgaWRlbnRpY2FsIHRvIEVudHJ5Lm1ldGEgYXQgcnVudGltZSBzbyBpbnN0YWxsIGNhbiByZXVzZSBpdCBkaXJlY3RseS5cbiAgICBtZXRhOiBlbnRyeS5tZXRhIGFzIGFueSxcbiAgICBkZXBzLFxuICB9XG59XG5cbi8qKlxuICogQnVpbGRzIEZpZWxkIC8gTm9kZSAvIEVkZ2UgLyBSZXNvdXJjZSBzZXRzIGZyb20gbm9ybWFsaXplZCBlbnRyaWVzLlxuICovXG5jb25zdCBidWlsZEdyYXBoID0gKFxuICBlbnRyaWVzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+LFxuICBub2RlTWV0YUJ5RmllbGRQYXRoOiBSZWFkb25seU1hcDxzdHJpbmcsIE1ldGEuVHJhaXRNZXRhPixcbik6IHtcbiAgcmVhZG9ubHkgZ3JhcGg6IFN0YXRlVHJhaXRHcmFwaFxuICByZWFkb25seSBwbGFuOiBTdGF0ZVRyYWl0UGxhblxufSA9PiB7XG4gIGNvbnN0IGZpZWxkTWFwID0gbmV3IE1hcDxzdHJpbmcsIFN0YXRlVHJhaXRGaWVsZD4oKVxuICBjb25zdCBub2RlczogQXJyYXk8U3RhdGVUcmFpdEdyYXBoTm9kZT4gPSBbXVxuICBjb25zdCBlZGdlczogQXJyYXk8U3RhdGVUcmFpdEdyYXBoRWRnZT4gPSBbXVxuICBjb25zdCByZXNvdXJjZXNCeUlkID0gbmV3IE1hcDxzdHJpbmcsIFN0YXRlVHJhaXRSZXNvdXJjZT4oKVxuICBjb25zdCBwbGFuU3RlcHM6IEFycmF5PFN0YXRlVHJhaXRQbGFuU3RlcD4gPSBbXVxuXG4gIGNvbnN0IGVuc3VyZUZpZWxkID0gKGZpZWxkUGF0aDogc3RyaW5nKTogU3RhdGVUcmFpdEZpZWxkID0+IHtcbiAgICBsZXQgZmllbGQgPSBmaWVsZE1hcC5nZXQoZmllbGRQYXRoKVxuICAgIGlmICghZmllbGQpIHtcbiAgICAgIGZpZWxkID0ge1xuICAgICAgICBpZDogZmllbGRQYXRoLFxuICAgICAgICBwYXRoOiBmaWVsZFBhdGgsXG4gICAgICAgIHRyYWl0czogW10sXG4gICAgICB9XG4gICAgICBmaWVsZE1hcC5zZXQoZmllbGRQYXRoLCBmaWVsZClcbiAgICB9XG4gICAgcmV0dXJuIGZpZWxkXG4gIH1cblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICBjb25zdCBmaWVsZFBhdGggPSBlbnRyeS5maWVsZFBhdGhcbiAgICBjb25zdCBmaWVsZCA9IGVuc3VyZUZpZWxkKGZpZWxkUGF0aClcbiAgICBjb25zdCB0cmFpdCA9IHRvRmllbGRUcmFpdChlbnRyeSlcblxuICAgIDsoZmllbGQudHJhaXRzIGFzIEFycmF5PFN0YXRlVHJhaXRGaWVsZFRyYWl0PikucHVzaCh0cmFpdClcblxuICAgIC8vIEJ1aWxkIEdyYXBoIGVkZ2VzIGFuZCBQbGFuIHN0ZXBzIGJ5IGtpbmQuXG4gICAgaWYgKGVudHJ5LmtpbmQgPT09ICdjb21wdXRlZCcpIHtcbiAgICAgIGNvbnN0IHN0ZXBJZCA9IGBjb21wdXRlZDoke2ZpZWxkUGF0aH1gXG4gICAgICBwbGFuU3RlcHMucHVzaCh7XG4gICAgICAgIGlkOiBzdGVwSWQsXG4gICAgICAgIGtpbmQ6ICdjb21wdXRlZC11cGRhdGUnLFxuICAgICAgICB0YXJnZXRGaWVsZFBhdGg6IGZpZWxkUGF0aCxcbiAgICAgICAgLy8gTm90ZTogdGhlIGN1cnJlbnQgdmVyc2lvbiBkb2VzIG5vdCBzdGF0aWNhbGx5IGFuYWx5emUgY29tcHV0ZWQgZGVwZW5kZW5jaWVzOyBzb3VyY2VGaWVsZFBhdGhzIHJlbWFpbnMgZW1wdHkuXG4gICAgICB9KVxuICAgICAgLy8gSWYgZGVwcyBpcyBleHBsaWNpdGx5IGRlY2xhcmVkLCBhZGQgR3JhcGggZWRnZXMgKGZvciBkaWFnbm9zdGljcyAvIHJldmVyc2UtY2xvc3VyZSBjb21wdXRhdGlvbikuXG4gICAgICBjb25zdCBkZXBzID0gKGVudHJ5Lm1ldGEgYXMgYW55KS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgaWYgKGRlcHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgICAgIGVuc3VyZUZpZWxkKGRlcClcbiAgICAgICAgICBlZGdlcy5wdXNoKHtcbiAgICAgICAgICAgIGlkOiBgY29tcHV0ZWQ6JHtkZXB9LT4ke2ZpZWxkUGF0aH1gLFxuICAgICAgICAgICAgZnJvbTogZGVwLFxuICAgICAgICAgICAgdG86IGZpZWxkUGF0aCxcbiAgICAgICAgICAgIGtpbmQ6ICdjb21wdXRlZCcsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZW50cnkua2luZCA9PT0gJ2xpbmsnKSB7XG4gICAgICBjb25zdCBmcm9tID0gZW50cnkubWV0YS5mcm9tIGFzIHN0cmluZ1xuICAgICAgZW5zdXJlRmllbGQoZnJvbSlcblxuICAgICAgY29uc3QgZWRnZUlkID0gYGxpbms6JHtmcm9tfS0+JHtmaWVsZFBhdGh9YFxuICAgICAgZWRnZXMucHVzaCh7XG4gICAgICAgIGlkOiBlZGdlSWQsXG4gICAgICAgIGZyb20sXG4gICAgICAgIHRvOiBmaWVsZFBhdGgsXG4gICAgICAgIGtpbmQ6ICdsaW5rJyxcbiAgICAgIH0pXG5cbiAgICAgIHBsYW5TdGVwcy5wdXNoKHtcbiAgICAgICAgaWQ6IGBsaW5rOiR7ZmllbGRQYXRofWAsXG4gICAgICAgIGtpbmQ6ICdsaW5rLXByb3BhZ2F0ZScsXG4gICAgICAgIHRhcmdldEZpZWxkUGF0aDogZmllbGRQYXRoLFxuICAgICAgICBzb3VyY2VGaWVsZFBhdGhzOiBbZnJvbV0sXG4gICAgICAgIGRlYnVnSW5mbzoge1xuICAgICAgICAgIGdyYXBoRWRnZUlkOiBlZGdlSWQsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH0gZWxzZSBpZiAoZW50cnkua2luZCA9PT0gJ3NvdXJjZScpIHtcbiAgICAgIGNvbnN0IHJlc291cmNlSWQgPSBlbnRyeS5tZXRhLnJlc291cmNlXG4gICAgICBjb25zdCByZXNvdXJjZU1ldGEgPSBNZXRhLnNhbml0aXplKChlbnRyeS5tZXRhIGFzIGFueSkubWV0YSlcblxuICAgICAgY29uc3QgZXhpc3RpbmcgPSByZXNvdXJjZXNCeUlkLmdldChyZXNvdXJjZUlkKVxuICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgIGNvbnN0IG93bmVyRmllbGRzID0gWy4uLmV4aXN0aW5nLm93bmVyRmllbGRzLCBmaWVsZFBhdGhdXG4gICAgICAgIGxldCBtZXRhID0gZXhpc3RpbmcubWV0YVxuICAgICAgICBsZXQgbWV0YU9yaWdpbiA9IGV4aXN0aW5nLm1ldGFPcmlnaW5cbiAgICAgICAgbGV0IG1ldGFDb25mbGljdHMgPSBleGlzdGluZy5tZXRhQ29uZmxpY3RzXG5cbiAgICAgICAgaWYgKHJlc291cmNlTWV0YSkge1xuICAgICAgICAgIGNvbnN0IG1lcmdlZCA9IE1ldGEubWVyZ2VDYW5vbmljYWwoXG4gICAgICAgICAgICB7IG1ldGEsIG9yaWdpbjogbWV0YU9yaWdpbiwgY29uZmxpY3RzOiBtZXRhQ29uZmxpY3RzIH0sXG4gICAgICAgICAgICB7IG9yaWdpbjogZmllbGRQYXRoLCBtZXRhOiByZXNvdXJjZU1ldGEgfSxcbiAgICAgICAgICApXG4gICAgICAgICAgbWV0YSA9IG1lcmdlZC5tZXRhXG4gICAgICAgICAgbWV0YU9yaWdpbiA9IG1lcmdlZC5vcmlnaW5cbiAgICAgICAgICBtZXRhQ29uZmxpY3RzID0gbWVyZ2VkLmNvbmZsaWN0c1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzb3VyY2VzQnlJZC5zZXQocmVzb3VyY2VJZCwge1xuICAgICAgICAgIC4uLmV4aXN0aW5nLFxuICAgICAgICAgIG93bmVyRmllbGRzLFxuICAgICAgICAgIG1ldGEsXG4gICAgICAgICAgbWV0YU9yaWdpbixcbiAgICAgICAgICBtZXRhQ29uZmxpY3RzLFxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb3VyY2VzQnlJZC5zZXQocmVzb3VyY2VJZCwge1xuICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgLy8gVXNlIGEgc2ltcGxlIGlkZW50aWZpZXIgc3RyaW5nIGZvciBub3c7IG1heSBldm9sdmUgaW50byBhIHN0cnVjdHVyZWQgZm9ybSBiYXNlZCBvbiBrZXkgcnVsZXMuXG4gICAgICAgICAga2V5U2VsZWN0b3I6IGBTdGF0ZVRyYWl0LnNvdXJjZUAke2ZpZWxkUGF0aH1gLFxuICAgICAgICAgIG93bmVyRmllbGRzOiBbZmllbGRQYXRoXSxcbiAgICAgICAgICBtZXRhOiByZXNvdXJjZU1ldGEsXG4gICAgICAgICAgbWV0YU9yaWdpbjogcmVzb3VyY2VNZXRhID8gZmllbGRQYXRoIDogdW5kZWZpbmVkLFxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBwbGFuU3RlcHMucHVzaCh7XG4gICAgICAgIGlkOiBgc291cmNlOiR7ZmllbGRQYXRofWAsXG4gICAgICAgIGtpbmQ6ICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgIHRhcmdldEZpZWxkUGF0aDogZmllbGRQYXRoLFxuICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICBrZXlTZWxlY3RvcklkOiBgU3RhdGVUcmFpdC5zb3VyY2VAJHtmaWVsZFBhdGh9YCxcbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IGRlcHMgPSAoZW50cnkubWV0YSBhcyBhbnkpLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgICBpZiAoZGVwcykge1xuICAgICAgICBmb3IgKGNvbnN0IGRlcCBvZiBkZXBzKSB7XG4gICAgICAgICAgZW5zdXJlRmllbGQoZGVwKVxuICAgICAgICAgIGVkZ2VzLnB1c2goe1xuICAgICAgICAgICAgaWQ6IGBzb3VyY2UtZGVwOiR7ZGVwfS0+JHtmaWVsZFBhdGh9YCxcbiAgICAgICAgICAgIGZyb206IGRlcCxcbiAgICAgICAgICAgIHRvOiBmaWVsZFBhdGgsXG4gICAgICAgICAgICBraW5kOiAnc291cmNlLWRlcCcsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZW50cnkua2luZCA9PT0gJ2V4dGVybmFsU3RvcmUnKSB7XG4gICAgICBwbGFuU3RlcHMucHVzaCh7XG4gICAgICAgIGlkOiBgZXh0ZXJuYWwtc3RvcmU6JHtmaWVsZFBhdGh9YCxcbiAgICAgICAga2luZDogJ2V4dGVybmFsLXN0b3JlLXN5bmMnLFxuICAgICAgICB0YXJnZXRGaWVsZFBhdGg6IGZpZWxkUGF0aCxcbiAgICAgIH0pXG4gICAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSAnY2hlY2snKSB7XG4gICAgICBwbGFuU3RlcHMucHVzaCh7XG4gICAgICAgIGlkOiBgY2hlY2s6JHtmaWVsZFBhdGh9YCxcbiAgICAgICAga2luZDogJ2NoZWNrLXZhbGlkYXRlJyxcbiAgICAgICAgdGFyZ2V0RmllbGRQYXRoOiBmaWVsZFBhdGgsXG4gICAgICB9KVxuXG4gICAgICAvLyBJZiB0aGUgcnVsZSBleHBsaWNpdGx5IGRlY2xhcmVzIGRlcHMsIGFkZCBHcmFwaCBlZGdlcyAoZm9yIFJldmVyc2VDbG9zdXJlIHNjb3BlZCB2YWxpZGF0ZSkuXG4gICAgICBpZiAodHJhaXQuZGVwcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvciAoY29uc3QgZGVwIG9mIHRyYWl0LmRlcHMpIHtcbiAgICAgICAgICBlbnN1cmVGaWVsZChkZXApXG4gICAgICAgICAgZWRnZXMucHVzaCh7XG4gICAgICAgICAgICBpZDogYGNoZWNrLWRlcDoke2RlcH0tPiR7ZmllbGRQYXRofWAsXG4gICAgICAgICAgICBmcm9tOiBkZXAsXG4gICAgICAgICAgICB0bzogZmllbGRQYXRoLFxuICAgICAgICAgICAga2luZDogJ2NoZWNrLWRlcCcsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRNYXAudmFsdWVzKCkpIHtcbiAgICBub2Rlcy5wdXNoKHtcbiAgICAgIGlkOiBmaWVsZC5pZCxcbiAgICAgIGZpZWxkLFxuICAgICAgdHJhaXRzOiBmaWVsZC50cmFpdHMsXG4gICAgICBtZXRhOiBub2RlTWV0YUJ5RmllbGRQYXRoLmdldChmaWVsZC5pZCksXG4gICAgfSlcbiAgfVxuXG4gIGNvbnN0IGdyYXBoOiBTdGF0ZVRyYWl0R3JhcGggPSB7XG4gICAgX3RhZzogJ1N0YXRlVHJhaXRHcmFwaCcsXG4gICAgbm9kZXMsXG4gICAgZWRnZXMsXG4gICAgcmVzb3VyY2VzOiBBcnJheS5mcm9tKHJlc291cmNlc0J5SWQudmFsdWVzKCkpLFxuICB9XG5cbiAgY29uc3QgcGxhbjogU3RhdGVUcmFpdFBsYW4gPSB7XG4gICAgX3RhZzogJ1N0YXRlVHJhaXRQbGFuJyxcbiAgICBzdGVwczogcGxhblN0ZXBzLFxuICB9XG5cbiAgcmV0dXJuIHsgZ3JhcGgsIHBsYW4gfVxufVxuXG4vKipcbiAqIFBlcmZvcm1zIGEgc2ltcGxlIGN5Y2xlIGRldGVjdGlvbiBmb3IgbGluayBlZGdlcy5cbiAqXG4gKiAtIE9ubHkgY29uc2lkZXJzIGVkZ2VzIHdpdGgga2luZCA9ICdsaW5rJzsgY29tcHV0ZWQvc291cmNlIGRvIG5vdCBwYXJ0aWNpcGF0ZSBpbiB0aGUgZmlyc3QgdmVyc2lvbi5cbiAqIC0gT24gY3ljbGUgZGV0ZWN0aW9uLCB0aHJvd3MgYW4gZXJyb3Igd2l0aCBwYXRoIGNvbnRleHQgdG8gYXZvaWQgaW5maW5pdGUgdXBkYXRlcyBhdCBydW50aW1lLlxuICovXG5jb25zdCBhc3NlcnROb0xpbmtDeWNsZXMgPSAoZWRnZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEdyYXBoRWRnZT4pOiB2b2lkID0+IHtcbiAgY29uc3QgYWRqYWNlbmN5ID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZ1tdPigpXG5cbiAgZm9yIChjb25zdCBlZGdlIG9mIGVkZ2VzKSB7XG4gICAgaWYgKGVkZ2Uua2luZCAhPT0gJ2xpbmsnKSBjb250aW51ZVxuICAgIGNvbnN0IGxpc3QgPSBhZGphY2VuY3kuZ2V0KGVkZ2UuZnJvbSkgPz8gW11cbiAgICBsaXN0LnB1c2goZWRnZS50bylcbiAgICBhZGphY2VuY3kuc2V0KGVkZ2UuZnJvbSwgbGlzdClcbiAgfVxuXG4gIGNvbnN0IHZpc2l0ZWQgPSBuZXcgU2V0PHN0cmluZz4oKVxuICBjb25zdCBzdGFjayA9IG5ldyBTZXQ8c3RyaW5nPigpXG5cbiAgY29uc3QgZGZzID0gKG5vZGU6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIGlmIChzdGFjay5oYXMobm9kZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBsaW5rIGN5Y2xlIGRldGVjdGVkIGF0IGZpZWxkIFwiJHtub2RlfVwiLiBgICtcbiAgICAgICAgICAnUGxlYXNlIGNoZWNrIGxpbmsgdHJhaXRzIGZvciBjaXJjdWxhciBkZXBlbmRlbmNpZXMuJyxcbiAgICAgIClcbiAgICB9XG4gICAgaWYgKHZpc2l0ZWQuaGFzKG5vZGUpKSByZXR1cm5cbiAgICB2aXNpdGVkLmFkZChub2RlKVxuICAgIHN0YWNrLmFkZChub2RlKVxuXG4gICAgY29uc3QgbmV4dHMgPSBhZGphY2VuY3kuZ2V0KG5vZGUpXG4gICAgaWYgKG5leHRzKSB7XG4gICAgICBmb3IgKGNvbnN0IHRvIG9mIG5leHRzKSB7XG4gICAgICAgIGRmcyh0bylcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzdGFjay5kZWxldGUobm9kZSlcbiAgfVxuXG4gIGZvciAoY29uc3Qgbm9kZSBvZiBhZGphY2VuY3kua2V5cygpKSB7XG4gICAgaWYgKCF2aXNpdGVkLmhhcyhub2RlKSkge1xuICAgICAgZGZzKG5vZGUpXG4gICAgfVxuICB9XG59XG5cbmNvbnN0IGNvbGxlY3RTY2hlbWFQYXRocyA9IChcbiAgZW50cmllczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+Pixcbik6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdFNjaGVtYVBhdGhSZWY+ID0+IHtcbiAgY29uc3QgYnlLZXkgPSBuZXcgTWFwPHN0cmluZywgU3RhdGVUcmFpdFNjaGVtYVBhdGhSZWY+KClcblxuICBjb25zdCBhZGQgPSAocmVmOiBTdGF0ZVRyYWl0U2NoZW1hUGF0aFJlZik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVmLnBhdGgpIHJldHVyblxuICAgIGNvbnN0IGsgPSBgJHtyZWYua2luZH18JHtyZWYuZW50cnlLaW5kfXwke3JlZi5lbnRyeUZpZWxkUGF0aH18JHtyZWYucnVsZU5hbWUgPz8gJyd9fCR7cmVmLnBhdGh9YFxuICAgIGJ5S2V5LnNldChrLCByZWYpXG4gIH1cblxuICBjb25zdCBnZXRDaGVja1dyaXRlYmFja1BhdGggPSAoZW50cnk6IEV4dHJhY3Q8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPiwgeyByZWFkb25seSBraW5kOiAnY2hlY2snIH0+KTogc3RyaW5nID0+IHtcbiAgICBjb25zdCB3YiA9IChlbnRyeS5tZXRhIGFzIGFueSk/LndyaXRlYmFja1xuICAgIGNvbnN0IHAgPSB3YiAmJiB0eXBlb2Ygd2IgPT09ICdvYmplY3QnID8gKHdiIGFzIGFueSkucGF0aCA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IHdyaXRlYmFja1BhdGggPSB0eXBlb2YgcCA9PT0gJ3N0cmluZycgJiYgcC5zdGFydHNXaXRoKCdlcnJvcnMuJykgPyBwIDogdW5kZWZpbmVkXG5cbiAgICBpZiAod3JpdGViYWNrUGF0aCkgcmV0dXJuIHdyaXRlYmFja1BhdGhcblxuICAgIGNvbnN0IGZpZWxkUGF0aCA9IGVudHJ5LmZpZWxkUGF0aFxuICAgIGlmIChmaWVsZFBhdGguZW5kc1dpdGgoJ1tdJykpIHtcbiAgICAgIHJldHVybiBgZXJyb3JzLiR7ZmllbGRQYXRoLnNsaWNlKDAsIC0yKX1gXG4gICAgfVxuICAgIHJldHVybiBgZXJyb3JzLiR7ZmllbGRQYXRofWBcbiAgfVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGFkZCh7XG4gICAgICBraW5kOiAnZmllbGRQYXRoJyxcbiAgICAgIGVudHJ5S2luZDogZW50cnkua2luZCxcbiAgICAgIGVudHJ5RmllbGRQYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgICBwYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgfSlcblxuICAgIGlmIChlbnRyeS5raW5kID09PSAnY29tcHV0ZWQnIHx8IGVudHJ5LmtpbmQgPT09ICdzb3VyY2UnKSB7XG4gICAgICBjb25zdCBkZXBzID0gKChlbnRyeS5tZXRhIGFzIGFueSk/LmRlcHMgPz8gW10pIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgICBhZGQoe1xuICAgICAgICAgIGtpbmQ6ICdkZXAnLFxuICAgICAgICAgIGVudHJ5S2luZDogZW50cnkua2luZCxcbiAgICAgICAgICBlbnRyeUZpZWxkUGF0aDogZW50cnkuZmllbGRQYXRoLFxuICAgICAgICAgIHBhdGg6IGRlcCxcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ2xpbmsnKSB7XG4gICAgICBhZGQoe1xuICAgICAgICBraW5kOiAnbGlua19mcm9tJyxcbiAgICAgICAgZW50cnlLaW5kOiAnbGluaycsXG4gICAgICAgIGVudHJ5RmllbGRQYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgICAgIHBhdGg6IGVudHJ5Lm1ldGEuZnJvbSBhcyBzdHJpbmcsXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChlbnRyeS5raW5kID09PSAnY2hlY2snKSB7XG4gICAgICBhZGQoe1xuICAgICAgICBraW5kOiAnY2hlY2tfd3JpdGViYWNrJyxcbiAgICAgICAgZW50cnlLaW5kOiAnY2hlY2snLFxuICAgICAgICBlbnRyeUZpZWxkUGF0aDogZW50cnkuZmllbGRQYXRoLFxuICAgICAgICBwYXRoOiBnZXRDaGVja1dyaXRlYmFja1BhdGgoZW50cnkpLFxuICAgICAgfSlcblxuICAgICAgY29uc3QgcnVsZXMgPSAoKGVudHJ5Lm1ldGEgYXMgYW55KT8ucnVsZXMgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhydWxlcykpIHtcbiAgICAgICAgY29uc3QgcnVsZSA9IHJ1bGVzW25hbWVdXG4gICAgICAgIGlmICghcnVsZSB8fCB0eXBlb2YgcnVsZSAhPT0gJ29iamVjdCcpIGNvbnRpbnVlXG4gICAgICAgIGNvbnN0IGRlcHMgPSAocnVsZS5kZXBzID8/IFtdKSBhcyBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgICAgIGFkZCh7XG4gICAgICAgICAgICBraW5kOiAnZGVwJyxcbiAgICAgICAgICAgIGVudHJ5S2luZDogJ2NoZWNrJyxcbiAgICAgICAgICAgIGVudHJ5RmllbGRQYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgICAgICAgICBydWxlTmFtZTogbmFtZSxcbiAgICAgICAgICAgIHBhdGg6IGRlcCxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIEFycmF5LmZyb20oYnlLZXkuZW50cmllcygpKVxuICAgIC5zb3J0KChhLCBiKSA9PiAoYVswXSA8IGJbMF0gPyAtMSA6IGFbMF0gPiBiWzBdID8gMSA6IDApKVxuICAgIC5tYXAoKFssIHZdKSA9PiB2KVxufVxuXG4vKipcbiAqIEJ1aWxkcyBhIFN0YXRlVHJhaXRQcm9ncmFtIGZyb20gdGhlIGdpdmVuIHN0YXRlU2NoZW1hIGFuZCB0cmFpdCBzcGVjLlxuICpcbiAqIC0gUHVyZSBmdW5jdGlvbjogZG9lcyBub3QgZGVwZW5kIG9uIGV4dGVybmFsIEVudiAvIGdsb2JhbCBzdGF0ZS5cbiAqIC0gQ3VycmVudCBpbXBsZW1lbnRhdGlvbiBmb2N1c2VzIG9uOlxuICogICAtIE5vcm1hbGl6aW5nIFNwZWMgaW50byBlbnRyaWVzLlxuICogICAtIEJ1aWxkaW5nIGEgbGlnaHR3ZWlnaHQgR3JhcGggLyBQbGFuIGZyb20gZW50cmllcy5cbiAqICAgLSBSdW5uaW5nIGJhc2ljIGN5Y2xlIGRldGVjdGlvbiBmb3IgbGluayBlZGdlcy5cbiAqXG4gKiBJZiB3ZSBsYXRlciBuZWVkIGZpbmVyLWdyYWluZWQgZGVwZW5kZW5jeSBhbmFseXNpcyAoZS5nLiBzdGF0aWMgYW5hbHlzaXMgZm9yIGNvbXB1dGVkL2tleSksXG4gKiBldm9sdmUgaXQgaW5zaWRlIHRoaXMgbW9kdWxlIHdpdGhvdXQgY2hhbmdpbmcgdGhlIHB1YmxpYyBBUEkgc3VyZmFjZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGJ1aWxkID0gPFMgZXh0ZW5kcyBvYmplY3Q+KFxuICBzdGF0ZVNjaGVtYTogU2NoZW1hLlNjaGVtYTxTLCBhbnk+LFxuICBzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPixcbik6IFN0YXRlVHJhaXRQcm9ncmFtPFM+ID0+IHtcbiAgY29uc3QgZW50cmllcyA9IG5vcm1hbGl6ZVNwZWMoc3BlYykgYXMgUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8Uywgc3RyaW5nPj5cbiAgY29uc3Qgbm9kZU1ldGFCeUZpZWxkUGF0aCA9IGNvbGxlY3ROb2RlTWV0YShzcGVjKVxuXG4gIC8vIFBoYXNlIDQgKFVTMik6IHJlcXVpcmUgZXhwbGljaXQgZGVwcyAoR3JhcGgvZGlhZ25vc3RpY3MvcmVwbGF5IHRyZWF0IGRlcHMgYXMgdGhlIHNpbmdsZSBkZXBlbmRlbmN5IHNvdXJjZSBvZiB0cnV0aCkuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGlmIChlbnRyeS5raW5kID09PSAnY29tcHV0ZWQnKSB7XG4gICAgICBjb25zdCBkZXBzID0gKGVudHJ5Lm1ldGEgYXMgYW55KS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgaWYgKGRlcHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBNaXNzaW5nIGV4cGxpY2l0IGRlcHMgZm9yIGNvbXB1dGVkIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIuIGAgK1xuICAgICAgICAgICAgJ1BsZWFzZSB1c2UgU3RhdGVUcmFpdC5jb21wdXRlZCh7IGRlcHM6IFsuLi5dLCBnZXQ6IC4uLiB9KS4nLFxuICAgICAgICApXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbnRyeS5raW5kID09PSAnc291cmNlJykge1xuICAgICAgY29uc3QgZGVwcyA9IChlbnRyeS5tZXRhIGFzIGFueSkuZGVwcyBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICAgIGlmIChkZXBzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBbU3RhdGVUcmFpdC5idWlsZF0gTWlzc2luZyBleHBsaWNpdCBkZXBzIGZvciBzb3VyY2UgXCIke2VudHJ5LmZpZWxkUGF0aH1cIi4gYCArXG4gICAgICAgICAgICAnUGxlYXNlIHByb3ZpZGUgbWV0YS5kZXBzIGZvciBTdGF0ZVRyYWl0LnNvdXJjZSh7IGRlcHM6IFsuLi5dLCAuLi4gfSkuJyxcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ2NoZWNrJykge1xuICAgICAgY29uc3QgcnVsZXMgPSAoKGVudHJ5Lm1ldGEgYXMgYW55KT8ucnVsZXMgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhydWxlcykpIHtcbiAgICAgICAgY29uc3QgcnVsZSA9IHJ1bGVzW25hbWVdXG4gICAgICAgIGlmICh0eXBlb2YgcnVsZSA9PT0gJ2Z1bmN0aW9uJyB8fCAhcnVsZSB8fCB0eXBlb2YgcnVsZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgW1N0YXRlVHJhaXQuYnVpbGRdIE1pc3NpbmcgZXhwbGljaXQgZGVwcyBmb3IgY2hlY2sgXCIke2VudHJ5LmZpZWxkUGF0aH1cIiBydWxlIFwiJHtuYW1lfVwiLiBgICtcbiAgICAgICAgICAgICAgJ1BsZWFzZSB1c2UgeyBkZXBzOiBbLi4uXSwgdmFsaWRhdGU6IC4uLiB9IGZvcm0uJyxcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgaWYgKChydWxlIGFzIGFueSkuZGVwcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBNaXNzaW5nIGV4cGxpY2l0IGRlcHMgZm9yIGNoZWNrIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIgcnVsZSBcIiR7bmFtZX1cIi4gYCArXG4gICAgICAgICAgICAgICdQbGVhc2UgcHJvdmlkZSBkZXBzOiBbLi4uXS4nLFxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHsgZ3JhcGgsIHBsYW4gfSA9IGJ1aWxkR3JhcGgoZW50cmllcywgbm9kZU1ldGFCeUZpZWxkUGF0aClcblxuICAvLyBSdW4gYSBjeWNsZSBjaGVjayBmb3IgbGluayBlZGdlcyB0byBhdm9pZCBvYnZpb3VzIGNvbmZpZ3VyYXRpb24gZXJyb3JzLlxuICBhc3NlcnROb0xpbmtDeWNsZXMoZ3JhcGguZWRnZXMpXG5cbiAgcmV0dXJuIHtcbiAgICBzdGF0ZVNjaGVtYSxcbiAgICBzcGVjLFxuICAgIGVudHJpZXM6IGVudHJpZXMgYXMgUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PixcbiAgICBncmFwaCxcbiAgICBwbGFuLFxuICAgIGNvbnZlcmdlSXI6IGJ1aWxkQ29udmVyZ2VJcihzdGF0ZVNjaGVtYSBhcyBhbnksIGVudHJpZXMgYXMgUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PiksXG4gICAgc2NoZW1hUGF0aHM6IGNvbGxlY3RTY2hlbWFQYXRocyhlbnRyaWVzIGFzIFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj4pLFxuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBTY2hlbWEgfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgdHlwZSB7IFN0YXRlQXRQYXRoLCBTdGF0ZUZpZWxkUGF0aCB9IGZyb20gJy4vZmllbGQtcGF0aC5qcydcbmltcG9ydCB0eXBlIHsgRGlydHlBbGxSZWFzb24gfSBmcm9tICcuLi9maWVsZC1wYXRoLmpzJ1xuaW1wb3J0ICogYXMgTWV0YSBmcm9tICcuL21ldGEuanMnXG5pbXBvcnQgdHlwZSB7IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeSB9IGZyb20gJy4vY29udmVyZ2UtaXIuanMnXG5pbXBvcnQgdHlwZSB7IENvbnZlcmdlRXhlY0lyIH0gZnJvbSAnLi9jb252ZXJnZS1leGVjLWlyLmpzJ1xuXG4vLyBTdGF0ZVRyYWl0IGNvcmUgbW9kZWwuXG4vLyBLZWVwIHRoZSBmaWVsZCBzZW1hbnRpY3MgYWxpZ25lZCB3aXRoIGRhdGEtbW9kZWwubWQgLyByZWZlcmVuY2VzL3N0YXRlLXRyYWl0LWNvcmUubWQuXG5cbi8qKlxuICogU3RhdGVUcmFpdFNwZWM8Uz5cdUZGMUFcbiAqIC0gVGhlIHN0YW5kYXJkIHNoYXBlIGZvciB0aGUgYHRyYWl0c2Agc2xvdCBpbiBhIE1vZHVsZSBibHVlcHJpbnQuXG4gKiAtIEtleXMgYXJlIGNvbnN0cmFpbmVkIGJ5IFN0YXRlRmllbGRQYXRoPFM+OyB2YWx1ZXMgYXJlIGRlY2xhcmF0aW9ucyBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgc2NvcGUgKEVudHJ5IC8gTm9kZSAvIExpc3QpLlxuICovXG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0U3BlYzxTPiA9IFMgZXh0ZW5kcyBvYmplY3RcbiAgPyB7XG4gICAgICBbUGF0aCBpbiBTdGF0ZUZpZWxkUGF0aDxTPiB8ICckcm9vdCddPzogU3RhdGVUcmFpdFNwZWNWYWx1ZTxTLCBQYXRoPlxuICAgIH1cbiAgOiBuZXZlclxuXG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0S2luZCA9ICdjb21wdXRlZCcgfCAnc291cmNlJyB8ICdsaW5rJyB8ICdleHRlcm5hbFN0b3JlJyB8ICdjaGVjaydcblxuZXhwb3J0IHR5cGUgVHJhaXRMYW5lID0gJ3VyZ2VudCcgfCAnbm9uVXJnZW50J1xuXG4vKipcbiAqIFRyYWl0Q29udmVyZ2VTY2hlZHVsaW5nXHVGRjFBXG4gKiAtIFNjaGVkdWxpbmcgc2VtYW50aWNzIGZvciBjb252ZXJnZS9kaXJ0eS1jaGVjayAoMDQzKTogZGVjaWRlcyB3aGV0aGVyIGEgc3RlcCBtdXN0IGNvbnZlcmdlIHdpdGhpbiBlYWNoIHRyYW5zYWN0aW9uIHdpbmRvdy5cbiAqIC0gRGVmYXVsdCBgaW1tZWRpYXRlYCAoa2VlcHMgbGVnYWN5IGJlaGF2aW9yKTsgYGRlZmVycmVkYCB0YWtlcyBlZmZlY3Qgb25seSB3aXRoIGV4cGxpY2l0IGRlY2xhcmF0aW9uICsgdGltZS1zbGljaW5nIGVuYWJsZWQuXG4gKi9cbmV4cG9ydCB0eXBlIFRyYWl0Q29udmVyZ2VTY2hlZHVsaW5nID0gJ2ltbWVkaWF0ZScgfCAnZGVmZXJyZWQnXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcHV0ZWRNZXRhPFMsIFA+IHtcbiAgLyoqXG4gICAqIEV4cGxpY2l0IGRlcGVuZGVuY3kgZmllbGQgcGF0aHMgKHJlcXVpcmVkKTpcbiAgICpcbiAgICogLSBkZXBzIGlzIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciBkZXBlbmRlbmNpZXM6IEdyYXBoL1JldmVyc2VDbG9zdXJlL2luY3JlbWVudGFsIHNjaGVkdWxpbmcvcGVyZiBvcHRpbWl6YXRpb25zIHJlbHkgb24gZGVwcyBvbmx5LlxuICAgKiAtIEluIHRoZSBEU0wsIGBTdGF0ZVRyYWl0LmNvbXB1dGVkKHsgZGVwcywgZ2V0IH0pYCB1c2VzIGRlcHMtYXMtYXJnczsgaXQgZG9lcyBub3QgZXhwb3NlIGAoc3RhdGUpID0+IC4uLmAuXG4gICAqIC0gRHVyaW5nIGJ1aWxkLCBgZ2V0KC4uLmRlcHNWYWx1ZXMpYCBpcyBsb3dlcmVkIGludG8gYGRlcml2ZShzdGF0ZSlgIGZvciBydW50aW1lIGV4ZWN1dGlvbiwgYnV0IHRoZSBkZXBlbmRlbmN5IHJlYWQtc2V0IHJlbWFpbnMgZGVwcy1iYXNlZC5cbiAgICogLSBJbiBkZXYtbW9kZSwgaWYgYWN0dWFsIHJlYWRzIGluIGBkZXJpdmUoc3RhdGUpYCBkaXNhZ3JlZSB3aXRoIGRlcHMsIGEgYGRlcHNfbWlzbWF0Y2hgIGRpYWdub3N0aWMgd2FybmluZyBpcyBlbWl0dGVkLlxuICAgKlxuICAgKiAtIEZvciByb290IHNjb3BlOiBkZXBzIGFyZSBTdGF0ZUZpZWxkUGF0aDxTdGF0ZT4uXG4gICAqIC0gRm9yIGxpc3QuaXRlbSBzY29wZTogZGVwcyBhcmUgU3RhdGVGaWVsZFBhdGg8SXRlbT4gKHJlbGF0aXZlIHBhdGhzOyBidWlsZCB3aWxsIHByZWZpeCB0aGVtKS5cbiAgICovXG4gIHJlYWRvbmx5IGRlcHM6IFJlYWRvbmx5QXJyYXk8U3RhdGVGaWVsZFBhdGg8Uz4+XG4gIHJlYWRvbmx5IGRlcml2ZTogKHN0YXRlOiBSZWFkb25seTxTPikgPT4gU3RhdGVBdFBhdGg8UywgUD5cbiAgLyoqXG4gICAqIE9wdGlvbmFsOiBlcXVhbGl0eSBwcmVkaWNhdGUgKHVzZWQgdG8gc2tpcCBuby1vcCB3cml0ZWJhY2tzKS5cbiAgICovXG4gIHJlYWRvbmx5IGVxdWFscz86IChwcmV2OiBTdGF0ZUF0UGF0aDxTLCBQPiwgbmV4dDogU3RhdGVBdFBhdGg8UywgUD4pID0+IGJvb2xlYW5cbiAgLyoqXG4gICAqIENvbnZlcmdlIHNjaGVkdWxpbmcgKDA0Myk6IGRlZmF1bHRzIHRvIGltbWVkaWF0ZS5cbiAgICovXG4gIHJlYWRvbmx5IHNjaGVkdWxpbmc/OiBUcmFpdENvbnZlcmdlU2NoZWR1bGluZ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvdXJjZU1ldGE8UywgUD4ge1xuICByZWFkb25seSBkZXBzOiBSZWFkb25seUFycmF5PFN0YXRlRmllbGRQYXRoPFM+PlxuICAvKipcbiAgICogTG9naWNhbCByZXNvdXJjZSBpZGVudGlmaWVyIChlLmcuIFwidXNlci9wcm9maWxlXCIpLlxuICAgKlxuICAgKiAtIEluIHRoZSBTdGF0ZVRyYWl0LnNvdXJjZSBEU0wsIGByZXNvdXJjZWAgaXMgc3RvcmVkIGhlcmUgZHVyaW5nIGJ1aWxkLlxuICAgKiAtIGRhdGEtbW9kZWwubWQgY2FsbHMgaXQgcmVzb3VyY2VJZDsgd2Uga2VlcCB0aGUgRFNMIG5hbWluZyBoZXJlIHRvIGF2b2lkIGNvbmZ1c2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IHJlc291cmNlOiBzdHJpbmdcbiAgLyoqXG4gICAqIFJ1bGUgZm9yIGNvbXB1dGluZyB0aGUga2V5IHJlcXVpcmVkIHRvIGFjY2VzcyB0aGUgcmVzb3VyY2UuXG4gICAqXG4gICAqIC0gZGVwcyBpcyB0aGUgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBmb3IgZGVwZW5kZW5jaWVzOiBHcmFwaC9SZXZlcnNlQ2xvc3VyZS9pbmNyZW1lbnRhbCBzY2hlZHVsaW5nL3BlcmYgb3B0aW1pemF0aW9ucyByZWx5IG9uIGRlcHMgb25seS5cbiAgICogLSBJbiB0aGUgRFNMLCBgU3RhdGVUcmFpdC5zb3VyY2UoeyBkZXBzLCBrZXkgfSlgIHVzZXMgZGVwcy1hcy1hcmdzOyBpdCBkb2VzIG5vdCBleHBvc2UgYChzdGF0ZSkgPT4gLi4uYC5cbiAgICogLSBEdXJpbmcgYnVpbGQsIGBrZXkoLi4uZGVwc1ZhbHVlcylgIGlzIGxvd2VyZWQgaW50byBga2V5KHN0YXRlKWAgZm9yIHJ1bnRpbWUgZXhlY3V0aW9uLCBidXQgdGhlIGRlcGVuZGVuY3kgcmVhZC1zZXQgcmVtYWlucyBkZXBzLWJhc2VkLlxuICAgKlxuICAgKiAtIFJldHVybmluZyB1bmRlZmluZWQgbWVhbnMgdGhlIHJlc291cmNlIGlzIGluYWN0aXZlIHVuZGVyIHRoZSBjdXJyZW50IHN0YXRlIChzaG91bGQgYmUgcmVjeWNsZWQgdG8gaWRsZSkuXG4gICAqL1xuICByZWFkb25seSBrZXk6IChzdGF0ZTogUmVhZG9ubHk8Uz4pID0+IHVua25vd25cbiAgcmVhZG9ubHkgdHJpZ2dlcnM/OiBSZWFkb25seUFycmF5PCdvbk1vdW50JyB8ICdvbktleUNoYW5nZScgfCAnbWFudWFsJz5cbiAgcmVhZG9ubHkgZGVib3VuY2VNcz86IG51bWJlclxuICByZWFkb25seSBjb25jdXJyZW5jeT86ICdzd2l0Y2gnIHwgJ2V4aGF1c3QtdHJhaWxpbmcnXG4gIC8qKlxuICAgKiBTZXJpYWxpemFibGUgbWV0YWRhdGEgZm9yIGRldnRvb2xzL2RvY3MgKHdoaXRlbGlzdGVkIGZpZWxkcykuXG4gICAqL1xuICByZWFkb25seSBtZXRhPzogTWV0YS5UcmFpdE1ldGFcbiAgLyoqXG4gICAqIFJlc2VydmVkOiBidWlsZCBtYXkgcG9wdWxhdGUgdGhlIGZpZWxkIHBhdGggdGhpcyB0cmFpdCBpcyBhdHRhY2hlZCB0bywgZm9yIGVhc2llciBkZWJ1Z2dpbmcuXG4gICAqL1xuICByZWFkb25seSBfZmllbGRQYXRoPzogUFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpbmtNZXRhPFM+IHtcbiAgLyoqXG4gICAqIFNvdXJjZSBmaWVsZCBwYXRoIChhbHNvIGNvbnN0cmFpbmVkIGJ5IFN0YXRlRmllbGRQYXRoPFM+KS5cbiAgICovXG4gIHJlYWRvbmx5IGZyb206IFN0YXRlRmllbGRQYXRoPFM+XG4gIC8qKlxuICAgKiBDb252ZXJnZSBzY2hlZHVsaW5nICgwNDMpOiBkZWZhdWx0cyB0byBpbW1lZGlhdGUuXG4gICAqL1xuICByZWFkb25seSBzY2hlZHVsaW5nPzogVHJhaXRDb252ZXJnZVNjaGVkdWxpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFeHRlcm5hbFN0b3JlTGlrZTxUPiB7XG4gIHJlYWRvbmx5IGdldFNuYXBzaG90OiAoKSA9PiBUXG4gIHJlYWRvbmx5IGdldFNlcnZlclNuYXBzaG90PzogKCkgPT4gVFxuICByZWFkb25seSBzdWJzY3JpYmU6IChsaXN0ZW5lcjogKCkgPT4gdm9pZCkgPT4gKCkgPT4gdm9pZFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVybmFsU3RvcmVNZXRhPFMsIFAsIFQgPSB1bmtub3duPiB7XG4gIHJlYWRvbmx5IHN0b3JlOiBFeHRlcm5hbFN0b3JlTGlrZTxUPlxuICByZWFkb25seSBzZWxlY3Q/OiAoc25hcHNob3Q6IFQpID0+IFN0YXRlQXRQYXRoPFMsIFA+XG4gIHJlYWRvbmx5IGVxdWFscz86IChwcmV2OiBTdGF0ZUF0UGF0aDxTLCBQPiwgbmV4dDogU3RhdGVBdFBhdGg8UywgUD4pID0+IGJvb2xlYW5cbiAgcmVhZG9ubHkgY29hbGVzY2VXaW5kb3dNcz86IG51bWJlclxuICByZWFkb25seSBwcmlvcml0eT86IFRyYWl0TGFuZVxuICByZWFkb25seSBtZXRhPzogTWV0YS5UcmFpdE1ldGFcbiAgcmVhZG9ubHkgX2ZpZWxkUGF0aD86IFBcbn1cblxuZXhwb3J0IHR5cGUgQ2hlY2tSdWxlPElucHV0ID0gdW5rbm93biwgQ3R4ID0gdW5rbm93bj4gPSB7XG4gIHJlYWRvbmx5IGRlcHM6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICAvKipcbiAgICogdmFsaWRhdGVPblx1RkYxQVxuICAgKiAtIEFmZmVjdHMgb25seSBhdXRvIHZhbGlkYXRpb24gcGhhc2VzIChvbkNoYW5nZS9vbkJsdXIpOyBzdWJtaXQvbWFudWFsIGFsd2F5cyBydW4uXG4gICAqIC0gRW1wdHkgYXJyYXkgZGlzYWJsZXMgYXV0byB2YWxpZGF0aW9uIChvbmx5IHN1Ym1pdC9tYW51YWwgcnVuKS5cbiAgICovXG4gIHJlYWRvbmx5IHZhbGlkYXRlT24/OiBSZWFkb25seUFycmF5PCdvbkNoYW5nZScgfCAnb25CbHVyJz5cbiAgcmVhZG9ubHkgdmFsaWRhdGU6IChpbnB1dDogSW5wdXQsIGN0eDogQ3R4KSA9PiB1bmtub3duXG4gIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENoZWNrTWV0YTxJbnB1dCA9IHVua25vd24sIEN0eCA9IHVua25vd24+IHtcbiAgLyoqXG4gICAqIE5hbWVkIHJ1bGUgc2V0ICh1c2VkIGZvciBkZXRlcm1pbmlzdGljIG1lcmdlIGFuZCBkaWFnbm9zdGljcyBkaXNwbGF5KS5cbiAgICovXG4gIHJlYWRvbmx5IHJ1bGVzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBDaGVja1J1bGU8SW5wdXQsIEN0eD4+PlxuICAvKipcbiAgICogRXJyb3ItdHJlZSB3cml0ZWJhY2sgKFBoYXNlIDI6IHN0cnVjdHVyZSBvbmx5OyBjb25jcmV0ZSB3cml0ZWJhY2sgc2VtYW50aWNzIGxhbmQgaW4gbGF0ZXIgcGhhc2VzKS5cbiAgICovXG4gIHJlYWRvbmx5IHdyaXRlYmFjaz86IHtcbiAgICByZWFkb25seSBraW5kOiAnZXJyb3JzJ1xuICAgIHJlYWRvbmx5IHBhdGg/OiBzdHJpbmdcbiAgfVxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRFbnRyeTxTLCBQPlx1RkYxQVxuICogLSBBIHNpbmdsZSBUcmFpdCBjb25maWd1cmF0aW9uIGF0dGFjaGVkIHRvIGEgZmllbGQgcGF0aCBQLlxuICogLSBraW5kIGFuZCBtZXRhIGFsd2F5cyBjb21lIHRvZ2V0aGVyIGFuZCBhcmUgdXNlZCB0byBkaXNwYXRjaCBiZWhhdmlvciBkdXJpbmcgYnVpbGQvaW5zdGFsbC5cbiAqL1xuZXhwb3J0IHR5cGUgU3RhdGVUcmFpdEVudHJ5PFMgPSB1bmtub3duLCBQIGV4dGVuZHMgc3RyaW5nID0gU3RhdGVGaWVsZFBhdGg8Uz4+ID1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdjb21wdXRlZCdcbiAgICAgIHJlYWRvbmx5IG1ldGE6IENvbXB1dGVkTWV0YTxTLCBQPlxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdzb3VyY2UnXG4gICAgICByZWFkb25seSBtZXRhOiBTb3VyY2VNZXRhPFMsIFA+XG4gICAgfVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IGZpZWxkUGF0aDogUFxuICAgICAgcmVhZG9ubHkga2luZDogJ2xpbmsnXG4gICAgICByZWFkb25seSBtZXRhOiBMaW5rTWV0YTxTPlxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdleHRlcm5hbFN0b3JlJ1xuICAgICAgcmVhZG9ubHkgbWV0YTogRXh0ZXJuYWxTdG9yZU1ldGE8UywgUD5cbiAgICB9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgZmllbGRQYXRoOiBQXG4gICAgICByZWFkb25seSBraW5kOiAnY2hlY2snXG4gICAgICByZWFkb25seSBtZXRhOiBDaGVja01ldGE8dW5rbm93biwgdW5rbm93bj5cbiAgICB9XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdE5vZGU8SW5wdXQgPSB1bmtub3duLCBDdHggPSB1bmtub3duPiB7XG4gIHJlYWRvbmx5IF90YWc6ICdTdGF0ZVRyYWl0Tm9kZSdcbiAgcmVhZG9ubHkgY29tcHV0ZWQ/OiBTdGF0ZVRyYWl0RW50cnk8SW5wdXQsIGFueT4gfCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYWl0RW50cnk8SW5wdXQsIGFueT4+PlxuICByZWFkb25seSBzb3VyY2U/OiBTdGF0ZVRyYWl0RW50cnk8SW5wdXQsIGFueT4gfCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYWl0RW50cnk8SW5wdXQsIGFueT4+PlxuICByZWFkb25seSBsaW5rPzogU3RhdGVUcmFpdEVudHJ5PElucHV0LCBhbnk+IHwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgU3RhdGVUcmFpdEVudHJ5PElucHV0LCBhbnk+Pj5cbiAgcmVhZG9ubHkgZXh0ZXJuYWxTdG9yZT86IFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55PiB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55Pj4+XG4gIHJlYWRvbmx5IGNoZWNrPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgQ2hlY2tSdWxlPElucHV0LCBDdHg+Pj5cbiAgcmVhZG9ubHkgbWV0YT86IE1ldGEuVHJhaXRNZXRhXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdExpc3Q8SXRlbSA9IHVua25vd24+IHtcbiAgcmVhZG9ubHkgX3RhZzogJ1N0YXRlVHJhaXRMaXN0J1xuICByZWFkb25seSBpdGVtPzogU3RhdGVUcmFpdE5vZGU8SXRlbSwgYW55PlxuICByZWFkb25seSBsaXN0PzogU3RhdGVUcmFpdE5vZGU8UmVhZG9ubHlBcnJheTxJdGVtPiwgYW55PlxuICByZWFkb25seSBpZGVudGl0eUhpbnQ/OiB7XG4gICAgcmVhZG9ubHkgdHJhY2tCeT86IHN0cmluZ1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRTcGVjVmFsdWU8UywgUCBleHRlbmRzIHN0cmluZz4gPVxuICB8IFN0YXRlVHJhaXRFbnRyeTxTLCBQPlxuICB8IFN0YXRlVHJhaXROb2RlPGFueSwgYW55PlxuICB8IFN0YXRlVHJhaXRMaXN0PGFueT5cblxuLyoqXG4gKiBTdGF0ZVRyYWl0RmllbGRcdUZGMUFcbiAqIC0gUmVwcmVzZW50cyBhIGZpZWxkIG5vZGUgaW4gU3RhdGUgKHdoZXRoZXIgb3Igbm90IHRyYWl0cyBhcmUgYXR0YWNoZWQpLlxuICogLSBOb3JtYWxpemVkIGZyb20gU3RhdGVUcmFpdFNwZWMgZHVyaW5nIGJ1aWxkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRGaWVsZCB7XG4gIHJlYWRvbmx5IGlkOiBzdHJpbmdcbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nXG4gIHJlYWRvbmx5IGRpc3BsYXlOYW1lPzogc3RyaW5nXG4gIHJlYWRvbmx5IHZhbHVlVHlwZT86IHN0cmluZ1xuICByZWFkb25seSB0cmFpdHM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEZpZWxkVHJhaXQ+XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdEZpZWxkVHJhaXRcdUZGMUFcbiAqIC0gQSBzdHJ1Y3R1cmVkIGRlc2NyaXB0aW9uIG9mIGEgZmllbGQgdHJhaXQgKGNvbXB1dGVkIC8gc291cmNlIC8gbGluaykuXG4gKiAtIG1ldGEgbWF0Y2hlcyBTdGF0ZVRyYWl0RW50cnkubWV0YTsgZGVwcyBpcyB0aGUgc2V0IG9mIGZpZWxkIHBhdGhzIHRoaXMgdHJhaXQgZGVwZW5kcyBvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0RmllbGRUcmFpdCB7XG4gIHJlYWRvbmx5IGZpZWxkSWQ6IHN0cmluZ1xuICByZWFkb25seSBraW5kOiBTdGF0ZVRyYWl0S2luZFxuICByZWFkb25seSBtZXRhOlxuICAgIHwgQ29tcHV0ZWRNZXRhPHVua25vd24sIHN0cmluZz5cbiAgICB8IFNvdXJjZU1ldGE8dW5rbm93biwgc3RyaW5nPlxuICAgIHwgTGlua01ldGE8dW5rbm93bj5cbiAgICB8IEV4dGVybmFsU3RvcmVNZXRhPHVua25vd24sIHN0cmluZz5cbiAgICB8IENoZWNrTWV0YTx1bmtub3duLCB1bmtub3duPlxuICByZWFkb25seSBkZXBzOiBSZWFkb25seUFycmF5PHN0cmluZz5cbn1cblxuLyoqXG4gKiBTdGF0ZVRyYWl0UmVzb3VyY2VcdUZGMUFcbiAqIC0gRGVzY3JpYmVzIHRoZSBsb2dpY2FsIHJlc291cmNlIG1ldGFkYXRhIHRoYXQgYSBzb3VyY2UgdHJhaXQgZGVwZW5kcyBvbi5cbiAqIC0gQ29uY3JldGUgUmVzb3VyY2VTcGVjIGltcGxlbWVudGF0aW9uIGxpdmVzIGluIHRoZSBSZXNvdXJjZSBuYW1lc3BhY2U7IHRoaXMga2VlcHMgb25seSB0cmFpdC1wZXJzcGVjdGl2ZSBkZXBlbmRlbmN5IGluZm8uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdFJlc291cmNlIHtcbiAgcmVhZG9ubHkgcmVzb3VyY2VJZDogc3RyaW5nXG4gIHJlYWRvbmx5IGtleVNlbGVjdG9yOiBzdHJpbmdcbiAgcmVhZG9ubHkga2V5RXhhbXBsZT86IHVua25vd25cbiAgcmVhZG9ubHkgb3duZXJGaWVsZHM6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICByZWFkb25seSBtZXRhPzogTWV0YS5UcmFpdE1ldGFcbiAgcmVhZG9ubHkgbWV0YU9yaWdpbj86IHN0cmluZ1xuICByZWFkb25seSBtZXRhQ29uZmxpY3RzPzogUmVhZG9ubHlBcnJheTxNZXRhLlRyYWl0TWV0YUNvbmZsaWN0PlxufVxuXG4vKipcbiAqIEdyYXBoIE5vZGUgLyBFZGdlXHVGRjFBXG4gKiAtIE5vZGVzIHR5cGljYWxseSBjb3JyZXNwb25kIHRvIGZpZWxkcy5cbiAqIC0gRWRnZXMgcmVwcmVzZW50IGRlcGVuZGVuY2llcyBiZXR3ZWVuIGZpZWxkcywgb3IgYmV0d2VlbiBmaWVsZHMgYW5kIHJlc291cmNlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0R3JhcGhOb2RlIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZ1xuICByZWFkb25seSBmaWVsZDogU3RhdGVUcmFpdEZpZWxkXG4gIHJlYWRvbmx5IHRyYWl0czogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RmllbGRUcmFpdD5cbiAgcmVhZG9ubHkgbWV0YT86IE1ldGEuVHJhaXRNZXRhXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdEdyYXBoRWRnZSB7XG4gIHJlYWRvbmx5IGlkOiBzdHJpbmdcbiAgcmVhZG9ubHkgZnJvbTogc3RyaW5nXG4gIHJlYWRvbmx5IHRvOiBzdHJpbmdcbiAgcmVhZG9ubHkga2luZDogJ2NvbXB1dGVkJyB8ICdsaW5rJyB8ICdzb3VyY2UtZGVwJyB8ICdjaGVjay1kZXAnXG59XG5cbi8qKlxuICogU3RhdGVUcmFpdEdyYXBoXHVGRjFBXG4gKiAtIFN0cnVjdHVyYWwgdmlldyBvZiB0aGUgU3RhdGVUcmFpdCBlbmdpbmU6IGEgZ3JhcGggb2Ygbm9kZXMgYW5kIGRlcGVuZGVuY3kgZWRnZXMuXG4gKiAtIFVzZWQgYnkgRGV2dG9vbHMgLyBTdHVkaW8gLyBSdW50aW1lIGZvciBzdHJ1Y3R1cmFsIGFuYWx5c2lzIGFuZCB2aXN1YWxpemF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRHcmFwaCB7XG4gIHJlYWRvbmx5IF90YWc6ICdTdGF0ZVRyYWl0R3JhcGgnXG4gIHJlYWRvbmx5IG5vZGVzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRHcmFwaE5vZGU+XG4gIHJlYWRvbmx5IGVkZ2VzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRHcmFwaEVkZ2U+XG4gIHJlYWRvbmx5IHJlc291cmNlczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0UmVzb3VyY2U+XG4gIHJlYWRvbmx5IG1ldGE/OiB7XG4gICAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgICByZWFkb25seSB2ZXJzaW9uPzogc3RyaW5nXG4gIH1cbn1cblxuLyoqXG4gKiBTdGF0ZVRyYWl0UGxhblN0ZXBcdUZGMUFcbiAqIC0gVGhlIHNtYWxsZXN0IGluc3RydWN0aW9uIHVuaXQgdXNlZCBieSBTdGF0ZVRyYWl0Lmluc3RhbGwgLyBSdW50aW1lIGV4ZWN1dGlvbi5cbiAqIC0gRGVyaXZlZCBmcm9tIHRoZSBncmFwaDsgdXNlZCBhdCBydW50aW1lIHRvIGluc3RhbGwgd2F0Y2hlcnMgb3IgdHJpZ2dlciBleHRlcm5hbCBjYWxscy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0UGxhblN0ZXAge1xuICByZWFkb25seSBpZDogc3RyaW5nXG4gIHJlYWRvbmx5IGtpbmQ6ICdjb21wdXRlZC11cGRhdGUnIHwgJ2xpbmstcHJvcGFnYXRlJyB8ICdzb3VyY2UtcmVmcmVzaCcgfCAnZXh0ZXJuYWwtc3RvcmUtc3luYycgfCAnY2hlY2stdmFsaWRhdGUnXG4gIHJlYWRvbmx5IHRhcmdldEZpZWxkUGF0aD86IHN0cmluZ1xuICByZWFkb25seSBzb3VyY2VGaWVsZFBhdGhzPzogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG4gIHJlYWRvbmx5IHJlc291cmNlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkga2V5U2VsZWN0b3JJZD86IHN0cmluZ1xuICByZWFkb25seSBkZWJ1Z0luZm8/OiB7XG4gICAgcmVhZG9ubHkgZ3JhcGhOb2RlSWQ/OiBzdHJpbmdcbiAgICByZWFkb25seSBncmFwaEVkZ2VJZD86IHN0cmluZ1xuICB9XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdFBsYW5cdUZGMUFcbiAqIC0gRXhlY3V0aW9uIHBsYW4gc3VtbWFyaXppbmcgYWxsIHRyYWl0IGJlaGF2aW9ycyBmb3IgYSBtb2R1bGUuXG4gKiAtIGluc3RhbGwgbW91bnRzIGJlaGF2aW9ycyBvbnRvIEJvdW5kIEFQSSAvIEVmZmVjdE9wIHBpcGVsaW5lcyBhY2NvcmRpbmcgdG8gdGhlIHBsYW4uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdFBsYW4ge1xuICByZWFkb25seSBfdGFnOiAnU3RhdGVUcmFpdFBsYW4nXG4gIHJlYWRvbmx5IG1vZHVsZUlkPzogc3RyaW5nXG4gIHJlYWRvbmx5IHN0ZXBzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRQbGFuU3RlcD5cbiAgcmVhZG9ubHkgbWV0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG59XG5cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRTY2hlbWFQYXRoS2luZCA9ICdmaWVsZFBhdGgnIHwgJ2RlcCcgfCAnbGlua19mcm9tJyB8ICdjaGVja193cml0ZWJhY2snXG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdFNjaGVtYVBhdGhSZWYge1xuICByZWFkb25seSBraW5kOiBTdGF0ZVRyYWl0U2NoZW1hUGF0aEtpbmRcbiAgcmVhZG9ubHkgZW50cnlLaW5kOiBTdGF0ZVRyYWl0S2luZFxuICByZWFkb25seSBlbnRyeUZpZWxkUGF0aDogc3RyaW5nXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZ1xuICByZWFkb25seSBydWxlTmFtZT86IHN0cmluZ1xufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRQcm9ncmFtPFM+XHVGRjFBXG4gKiAtIFByb2dyYW0gb3V0cHV0IG9mIHRoZSBTdGF0ZVRyYWl0IGVuZ2luZTsgdGhlIHVuaWZpZWQgZW50cnlwb2ludCBmb3IgUnVudGltZSAvIERldnRvb2xzLlxuICogLSBzdGF0ZVNjaGVtYSBhbmQgc3BlYyBwcmVzZXJ2ZSBvcmlnaW5hbCBpbnB1dHM7IGdyYXBoL3BsYW4gYXJlIGludGVybmFsIElSLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRQcm9ncmFtPFM+IHtcbiAgcmVhZG9ubHkgc3RhdGVTY2hlbWE6IFNjaGVtYS5TY2hlbWE8UywgYW55PlxuICByZWFkb25seSBzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPlxuICAvKipcbiAgICogUHJvZ3JhbS5lbnRyaWVzXHVGRjFBXG4gICAqIC0gTWluaW1hbCBydWxlIHNldCBub3JtYWxpemVkIGZyb20gc3BlYyAoaW5jbHVkaW5nIG5vZGUvbGlzdC8kcm9vdCkgZHVyaW5nIGJ1aWxkLlxuICAgKiAtIFBoYXNlIDIgZm9jdXNlcyBvbiBhIHJlYWRhYmxlL2RpYWdub3NhYmxlIHN0cnVjdHVyZTsgbGF0ZXIgcGhhc2VzIGFkZCBleGVjdXRpb24gYW5kIGNvbnZlcmdlIHNlbWFudGljcy5cbiAgICovXG4gIHJlYWRvbmx5IGVudHJpZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj5cbiAgcmVhZG9ubHkgZ3JhcGg6IFN0YXRlVHJhaXRHcmFwaFxuICByZWFkb25seSBwbGFuOiBTdGF0ZVRyYWl0UGxhblxuICByZWFkb25seSBjb252ZXJnZUlyPzogQ29udmVyZ2VTdGF0aWNJclJlZ2lzdHJ5XG4gIHJlYWRvbmx5IGNvbnZlcmdlRXhlY0lyPzogQ29udmVyZ2VFeGVjSXJcbiAgLyoqXG4gICAqIHNjaGVtYVBhdGhzXHVGRjFBXG4gICAqIC0gUGF0aCByZWZlcmVuY2VzIHRoYXQgbXVzdCBleGlzdCBpbiBzdGF0ZVNjaGVtYSwgY29sbGVjdGVkIGZyb20gZW50cmllcyBkdXJpbmcgYnVpbGQ7IGRldi1vbmx5IGRpYWdub3N0aWNzIChlLmcuIHNjaGVtYV9taXNtYXRjaCkuXG4gICAqIC0gV2hlbiBkaWFnbm9zdGljcz1vZmYsIHZhbGlkYXRpb24gY2FuIGJlIHNraXBwZWQgZW50aXJlbHkgdG8ga2VlcCBuZWFyLXplcm8gY29zdC5cbiAgICovXG4gIHJlYWRvbmx5IHNjaGVtYVBhdGhzPzogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0U2NoZW1hUGF0aFJlZj5cbn1cblxuLyoqXG4gKiBCdWlsZCBhIG5vcm1hbGl6ZWQgZW50cnkgbGlzdCBmcm9tIFN0YXRlVHJhaXRTcGVjLlxuICpcbiAqIC0gUGhhc2UgMjogc3VwcG9ydHMgc3RydWN0dXJhbCBleHBhbnNpb24gb2Ygbm9kZS9saXN0LyRyb290IGFuZCBmaWxscy9wcmVmaXhlcyBmaWVsZFBhdGgvZGVwcyB3aGVuIG5lY2Vzc2FyeS5cbiAqIC0gTGF0ZXIgcGhhc2VzIG1heSBleHRlbmQgdmFsaWRhdGlvbiBoZXJlIChlLmcuIGRldGVjdGluZyBkdXBsaWNhdGVzLCBvdmVycmlkZSBydWxlcywgZXRjLikuXG4gKi9cbmV4cG9ydCBjb25zdCBub3JtYWxpemVTcGVjID0gPFM+KHNwZWM6IFN0YXRlVHJhaXRTcGVjPFM+KTogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PiA9PiB7XG4gIGNvbnN0IGVudHJpZXM6IEFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+ID0gW11cblxuICBjb25zdCBpc05vZGUgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTdGF0ZVRyYWl0Tm9kZTxhbnksIGFueT4gPT5cbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICh2YWx1ZSBhcyBhbnkpLl90YWcgPT09ICdTdGF0ZVRyYWl0Tm9kZSdcblxuICBjb25zdCBpc0xpc3QgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTdGF0ZVRyYWl0TGlzdDxhbnk+ID0+XG4gICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAodmFsdWUgYXMgYW55KS5fdGFnID09PSAnU3RhdGVUcmFpdExpc3QnXG5cbiAgY29uc3Qgam9pblBhdGggPSAocHJlZml4OiBzdHJpbmcsIHN1ZmZpeDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICBpZiAoIXByZWZpeCkgcmV0dXJuIHN1ZmZpeFxuICAgIGlmICghc3VmZml4KSByZXR1cm4gcHJlZml4XG4gICAgcmV0dXJuIGAke3ByZWZpeH0uJHtzdWZmaXh9YFxuICB9XG5cbiAgY29uc3QgcHJlZml4RGVwcyA9IChkZXBzOiBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWQsIHByZWZpeDogc3RyaW5nKTogUmVhZG9ubHlBcnJheTxzdHJpbmc+ID0+IHtcbiAgICBpZiAoIWRlcHMgfHwgZGVwcy5sZW5ndGggPT09IDApIHJldHVybiBbXVxuICAgIHJldHVybiBkZXBzLm1hcCgoZCkgPT4gKHByZWZpeCA/IGpvaW5QYXRoKHByZWZpeCwgZCkgOiBkKSlcbiAgfVxuXG4gIGNvbnN0IG5vcm1hbGl6ZUVudHJ5ID0gKFxuICAgIGVudHJ5OiBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+LFxuICAgIGZpZWxkUGF0aDogc3RyaW5nLFxuICAgIGRlcFByZWZpeDogc3RyaW5nLFxuICApOiBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+ID0+IHtcbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ2NvbXB1dGVkJykge1xuICAgICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgICBjb25zdCByYXdEZXBzID0gbWV0YS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgY29uc3QgZGVwcyA9IHJhd0RlcHMgIT09IHVuZGVmaW5lZCA/IHByZWZpeERlcHMocmF3RGVwcywgZGVwUHJlZml4KSA6IHVuZGVmaW5lZFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGVudHJ5IGFzIGFueSksXG4gICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgbWV0YTogeyAuLi5tZXRhLCBkZXBzIH0sXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbnRyeS5raW5kID09PSAnc291cmNlJykge1xuICAgICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgICBjb25zdCByYXdEZXBzID0gbWV0YS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgY29uc3QgZGVwcyA9IHJhd0RlcHMgIT09IHVuZGVmaW5lZCA/IHByZWZpeERlcHMocmF3RGVwcywgZGVwUHJlZml4KSA6IHVuZGVmaW5lZFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGVudHJ5IGFzIGFueSksXG4gICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgbWV0YTogeyAuLi5tZXRhLCBkZXBzLCBfZmllbGRQYXRoOiBmaWVsZFBhdGggfSxcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVudHJ5LmtpbmQgPT09ICdleHRlcm5hbFN0b3JlJykge1xuICAgICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi4oZW50cnkgYXMgYW55KSxcbiAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICBtZXRhOiB7IC4uLm1ldGEsIF9maWVsZFBhdGg6IGZpZWxkUGF0aCB9LFxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ2xpbmsnKSB7XG4gICAgICBjb25zdCBtZXRhID0gZW50cnkubWV0YSBhcyBhbnlcbiAgICAgIGNvbnN0IGZyb20gPSBwcmVmaXhEZXBzKFttZXRhLmZyb20gYXMgc3RyaW5nXSwgZGVwUHJlZml4KVswXSA/PyBtZXRhLmZyb21cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLihlbnRyeSBhcyBhbnkpLFxuICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgIG1ldGE6IHsgLi4ubWV0YSwgZnJvbSB9LFxuICAgICAgfVxuICAgIH1cbiAgICAvLyBjaGVjazogUGhhc2UgMiBhZGp1c3RzIGZpZWxkUGF0aCBvbmx5OyBkZXBzIGFyZSBzdGlsbCBjb2xsZWN0ZWQgZnJvbSBtZXRhLnJ1bGVzIGR1cmluZyBidWlsZC5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uKGVudHJ5IGFzIGFueSksXG4gICAgICBmaWVsZFBhdGgsXG4gICAgfVxuICB9XG5cbiAgY29uc3QgZXhwYW5kTm9kZSA9IChcbiAgICBzY29wZUlkOiBzdHJpbmcsXG4gICAgam9pblByZWZpeDogc3RyaW5nLFxuICAgIG5vZGU6IFN0YXRlVHJhaXROb2RlPGFueSwgYW55PixcbiAgICBvcHRpb25zPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBQcmVmaXggZm9yIGNoZWNrIGRlcHM6IGRlZmF1bHQgc2VtYW50aWNzIGZvciBsaXN0LXNjb3BlIGNoZWNrcyAoZGVwcyBhcmUgcmVsYXRpdmUgdG8gYSByb3cgaXRlbSByYXRoZXIgdGhhbiB0aGUgbGlzdCByb290KS5cbiAgICAgICAqXG4gICAgICAgKiAtIGl0ZW0gc2NvcGU6IGRlcHNQcmVmaXggPSBgJHtsaXN0UGF0aH1bXWAgKG1hdGNoZXMgam9pblByZWZpeCkuXG4gICAgICAgKiAtIGxpc3Qgc2NvcGU6IGZpZWxkUGF0aCA9IGAke2xpc3RQYXRofWAsIGJ1dCBkZXBzUHJlZml4IHNob3VsZCBiZSBgJHtsaXN0UGF0aH1bXWAuXG4gICAgICAgKi9cbiAgICAgIHJlYWRvbmx5IGNoZWNrRGVwc1ByZWZpeD86IHN0cmluZ1xuICAgIH0sXG4gICk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGFkZEVudHJ5ID0gKHJlbGF0aXZlVGFyZ2V0OiBzdHJpbmcsIHJhdzogU3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPik6IHZvaWQgPT4ge1xuICAgICAgY29uc3QgcmVsID0gKHJhdyBhcyBhbnkpLmZpZWxkUGF0aCA/PyByZWxhdGl2ZVRhcmdldFxuICAgICAgY29uc3QgZmllbGRQYXRoID0gam9pblByZWZpeCA/IGpvaW5QYXRoKGpvaW5QcmVmaXgsIFN0cmluZyhyZWwpKSA6IFN0cmluZyhyZWwpXG4gICAgICBlbnRyaWVzLnB1c2gobm9ybWFsaXplRW50cnkocmF3LCBmaWVsZFBhdGgsIGpvaW5QcmVmaXgpKVxuICAgIH1cblxuICAgIGNvbnN0IGV4cGFuZE1heWJlUmVjb3JkID0gKFxuICAgICAgdmFsdWU6IFN0YXRlVHJhaXRFbnRyeTxhbnksIGFueT4gfCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYWl0RW50cnk8YW55LCBhbnk+Pj4gfCB1bmRlZmluZWQsXG4gICAgKTogdm9pZCA9PiB7XG4gICAgICBpZiAoIXZhbHVlKSByZXR1cm5cbiAgICAgIGlmICh0eXBlb2YgKHZhbHVlIGFzIGFueSkua2luZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgYWRkRW50cnkoJycsIHZhbHVlIGFzIGFueSlcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBjb25zdCByZWNvcmQgPSB2YWx1ZSBhcyBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYWl0RW50cnk8YW55LCBhbnk+Pj5cbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHJlY29yZCkge1xuICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZWNvcmQsIGtleSkpIGNvbnRpbnVlXG4gICAgICAgIGNvbnN0IGVudHJ5ID0gcmVjb3JkW2tleV1cbiAgICAgICAgaWYgKCFlbnRyeSkgY29udGludWVcbiAgICAgICAgYWRkRW50cnkoa2V5LCBlbnRyeSBhcyBhbnkpXG4gICAgICB9XG4gICAgfVxuXG4gICAgZXhwYW5kTWF5YmVSZWNvcmQobm9kZS5jb21wdXRlZClcbiAgICBleHBhbmRNYXliZVJlY29yZChub2RlLnNvdXJjZSlcbiAgICBleHBhbmRNYXliZVJlY29yZChub2RlLmxpbmspXG4gICAgZXhwYW5kTWF5YmVSZWNvcmQobm9kZS5leHRlcm5hbFN0b3JlKVxuXG4gICAgaWYgKG5vZGUuY2hlY2spIHtcbiAgICAgIGNvbnN0IHJ1bGVzOiBSZWNvcmQ8c3RyaW5nLCBDaGVja1J1bGU8YW55LCBhbnk+PiA9IHt9XG4gICAgICBjb25zdCBjaGVja0RlcHNQcmVmaXggPSBvcHRpb25zPy5jaGVja0RlcHNQcmVmaXggPz8gKGpvaW5QcmVmaXguZW5kc1dpdGgoJ1tdJykgPyBqb2luUHJlZml4IDogJycpXG5cbiAgICAgIGNvbnN0IHByZWZpeENoZWNrRGVwcyA9IChkZXBzOiBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWQpOiBSZWFkb25seUFycmF5PHN0cmluZz4gPT4ge1xuICAgICAgICBpZiAoIWRlcHMgfHwgZGVwcy5sZW5ndGggPT09IDApIHJldHVybiBbXVxuICAgICAgICByZXR1cm4gZGVwcy5tYXAoKGQpID0+IChkID09PSAnJyA/IHNjb3BlSWQgOiBjaGVja0RlcHNQcmVmaXggPyBqb2luUGF0aChjaGVja0RlcHNQcmVmaXgsIGQpIDogZCkpXG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXMobm9kZS5jaGVjaykpIHtcbiAgICAgICAgY29uc3QgcnVsZSA9IChub2RlLmNoZWNrIGFzIGFueSlbbmFtZV0gYXMgQ2hlY2tSdWxlPGFueSwgYW55PlxuICAgICAgICBpZiAodHlwZW9mIHJ1bGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBydWxlc1tuYW1lXSA9IHJ1bGVcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICAgIGlmIChydWxlICYmIHR5cGVvZiBydWxlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGNvbnN0IG1ldGEgPSBNZXRhLnNhbml0aXplKChydWxlIGFzIGFueSkubWV0YSlcbiAgICAgICAgICBydWxlc1tuYW1lXSA9IHtcbiAgICAgICAgICAgIC4uLnJ1bGUsXG4gICAgICAgICAgICBkZXBzOiBwcmVmaXhDaGVja0RlcHMocnVsZS5kZXBzKSxcbiAgICAgICAgICAgIG1ldGEsXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgICAgLy8gSW52YWxpZCBpbnB1dDogaWdub3JlIChsYXRlciBwaGFzZXMgbWF5IHByb21vdGUgdGhpcyBpbnRvIGEgYnVpbGQtdGltZSBjb25maWcgZXJyb3IpLlxuICAgICAgfVxuXG4gICAgICBlbnRyaWVzLnB1c2goe1xuICAgICAgICBmaWVsZFBhdGg6IHNjb3BlSWQsXG4gICAgICAgIGtpbmQ6ICdjaGVjaycsXG4gICAgICAgIG1ldGE6IHtcbiAgICAgICAgICBydWxlcyxcbiAgICAgICAgICB3cml0ZWJhY2s6IHsga2luZDogJ2Vycm9ycycgfSxcbiAgICAgICAgfSxcbiAgICAgIH0gYXMgU3RhdGVUcmFpdEVudHJ5PGFueSwgYW55PilcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjKSB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3BlYywga2V5KSkgY29udGludWVcbiAgICBjb25zdCByYXcgPSBzcGVjW2tleSBhcyBrZXlvZiB0eXBlb2Ygc3BlY10gYXMgU3RhdGVUcmFpdFNwZWNWYWx1ZTxTLCBhbnk+IHwgdW5kZWZpbmVkXG4gICAgaWYgKCFyYXcpIGNvbnRpbnVlXG5cbiAgICBpZiAoaXNMaXN0KHJhdykpIHtcbiAgICAgIGNvbnN0IGxpc3RQYXRoID0ga2V5XG4gICAgICBpZiAocmF3Lml0ZW0pIHtcbiAgICAgICAgZXhwYW5kTm9kZShgJHtsaXN0UGF0aH1bXWAsIGAke2xpc3RQYXRofVtdYCwgcmF3Lml0ZW0pXG4gICAgICB9XG4gICAgICBpZiAocmF3Lmxpc3QpIHtcbiAgICAgICAgZXhwYW5kTm9kZShsaXN0UGF0aCwgbGlzdFBhdGgsIHJhdy5saXN0LCB7XG4gICAgICAgICAgY2hlY2tEZXBzUHJlZml4OiBgJHtsaXN0UGF0aH1bXWAsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmIChpc05vZGUocmF3KSkge1xuICAgICAgaWYgKGtleSA9PT0gJyRyb290Jykge1xuICAgICAgICBleHBhbmROb2RlKCckcm9vdCcsICcnLCByYXcpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleHBhbmROb2RlKGtleSwga2V5LCByYXcpXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGNvbnN0IGVudHJ5ID0gcmF3IGFzIGFueSBhcyBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+XG4gICAgY29uc3QgZmllbGRQYXRoID0gKGVudHJ5IGFzIGFueSkuZmllbGRQYXRoID8/IGtleVxuICAgIGVudHJpZXMucHVzaChub3JtYWxpemVFbnRyeShlbnRyeSwgU3RyaW5nKGZpZWxkUGF0aCksICcnKSlcbiAgfVxuXG4gIHJldHVybiBlbnRyaWVzXG59XG5cbi8qKlxuICogY29sbGVjdE5vZGVNZXRhXHVGRjFBXG4gKiAtIEV4dHJhY3QgU3RhdGVUcmFpdE5vZGUubWV0YSAod2hpdGVsaXN0ZWQgZmllbGRzKSBmcm9tIFN0YXRlVHJhaXRTcGVjIGZvciBkZXZ0b29scyBzdHJ1Y3R1cmFsIGRpc3BsYXkuXG4gKiAtIG1ldGEgaXMgZm9yIGRpYWdub3N0aWNzL2Rpc3BsYXkgb25seSBhbmQgZG9lcyBub3QgcGFydGljaXBhdGUgaW4gcnVudGltZSBzZW1hbnRpY3MuXG4gKi9cbmV4cG9ydCBjb25zdCBjb2xsZWN0Tm9kZU1ldGEgPSA8Uz4oc3BlYzogU3RhdGVUcmFpdFNwZWM8Uz4pOiBSZWFkb25seU1hcDxzdHJpbmcsIE1ldGEuVHJhaXRNZXRhPiA9PiB7XG4gIGNvbnN0IG91dCA9IG5ldyBNYXA8c3RyaW5nLCBNZXRhLlRyYWl0TWV0YT4oKVxuXG4gIGNvbnN0IGlzTm9kZSA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFN0YXRlVHJhaXROb2RlPGFueSwgYW55PiA9PlxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgKHZhbHVlIGFzIGFueSkuX3RhZyA9PT0gJ1N0YXRlVHJhaXROb2RlJ1xuXG4gIGNvbnN0IGlzTGlzdCA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFN0YXRlVHJhaXRMaXN0PGFueT4gPT5cbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICh2YWx1ZSBhcyBhbnkpLl90YWcgPT09ICdTdGF0ZVRyYWl0TGlzdCdcblxuICBjb25zdCBhZGQgPSAoc2NvcGVJZDogc3RyaW5nLCBub2RlOiBTdGF0ZVRyYWl0Tm9kZTxhbnksIGFueT4pOiB2b2lkID0+IHtcbiAgICBjb25zdCBtZXRhID0gTWV0YS5zYW5pdGl6ZShub2RlLm1ldGEpXG4gICAgaWYgKG1ldGEpIG91dC5zZXQoc2NvcGVJZCwgbWV0YSlcbiAgfVxuXG4gIGZvciAoY29uc3Qga2V5IGluIHNwZWMpIHtcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzcGVjLCBrZXkpKSBjb250aW51ZVxuICAgIGNvbnN0IHJhdyA9IHNwZWNba2V5IGFzIGtleW9mIHR5cGVvZiBzcGVjXSBhcyBTdGF0ZVRyYWl0U3BlY1ZhbHVlPFMsIGFueT4gfCB1bmRlZmluZWRcbiAgICBpZiAoIXJhdykgY29udGludWVcblxuICAgIGlmIChpc0xpc3QocmF3KSkge1xuICAgICAgY29uc3QgbGlzdFBhdGggPSBrZXlcbiAgICAgIGlmIChyYXcuaXRlbSkgYWRkKGAke2xpc3RQYXRofVtdYCwgcmF3Lml0ZW0pXG4gICAgICBpZiAocmF3Lmxpc3QpIGFkZChsaXN0UGF0aCwgcmF3Lmxpc3QpXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmIChpc05vZGUocmF3KSkge1xuICAgICAgaWYgKGtleSA9PT0gJyRyb290JykgYWRkKCckcm9vdCcsIHJhdylcbiAgICAgIGVsc2UgYWRkKGtleSwgcmF3KVxuICAgICAgY29udGludWVcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3V0XG59XG5cbi8vIC0tLS0gQ29udmVyZ2UgKDAxMykgZXZpZGVuY2UgbW9kZWwgLS0tLVxuXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlUmVxdWVzdGVkTW9kZSA9ICdhdXRvJyB8ICdmdWxsJyB8ICdkaXJ0eSdcbmV4cG9ydCB0eXBlIFRyYWl0Q29udmVyZ2VFeGVjdXRlZE1vZGUgPSAnZnVsbCcgfCAnZGlydHknXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlT3V0Y29tZSA9ICdDb252ZXJnZWQnIHwgJ05vb3AnIHwgJ0RlZ3JhZGVkJ1xuXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlQ29uZmlnU2NvcGUgPSAncHJvdmlkZXInIHwgJ3J1bnRpbWVfbW9kdWxlJyB8ICdydW50aW1lX2RlZmF1bHQnIHwgJ2J1aWx0aW4nXG5cbmV4cG9ydCB0eXBlIFRyYWl0Q29udmVyZ2VSZWFzb24gPVxuICB8ICdjb2xkX3N0YXJ0J1xuICB8ICdjYWNoZV9oaXQnXG4gIHwgJ2NhY2hlX21pc3MnXG4gIHwgJ2J1ZGdldF9jdXRvZmYnXG4gIHwgJ25lYXJfZnVsbCdcbiAgfCAndW5rbm93bl93cml0ZSdcbiAgfCAnZGlydHlfYWxsJ1xuICB8ICdnZW5lcmF0aW9uX2J1bXBlZCdcbiAgfCAnbG93X2hpdF9yYXRlX3Byb3RlY3Rpb24nXG4gIHwgJ21vZHVsZV9vdmVycmlkZSdcbiAgfCAndGltZV9zbGljaW5nX2ltbWVkaWF0ZSdcbiAgfCAndGltZV9zbGljaW5nX2RlZmVycmVkJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWl0Q29udmVyZ2VTdGVwU3RhdHMge1xuICByZWFkb25seSB0b3RhbFN0ZXBzOiBudW1iZXJcbiAgcmVhZG9ubHkgZXhlY3V0ZWRTdGVwczogbnVtYmVyXG4gIHJlYWRvbmx5IHNraXBwZWRTdGVwczogbnVtYmVyXG4gIHJlYWRvbmx5IGNoYW5nZWRTdGVwczogbnVtYmVyXG4gIHJlYWRvbmx5IGFmZmVjdGVkU3RlcHM/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlRGlydHlTdW1tYXJ5IHtcbiAgcmVhZG9ubHkgZGlydHlBbGw6IGJvb2xlYW5cbiAgcmVhZG9ubHkgcmVhc29uPzogRGlydHlBbGxSZWFzb25cbiAgcmVhZG9ubHkgcm9vdENvdW50PzogbnVtYmVyXG4gIHJlYWRvbmx5IHJvb3RJZHM/OiBSZWFkb25seUFycmF5PG51bWJlcj5cbiAgcmVhZG9ubHkgcm9vdElkc1RydW5jYXRlZD86IGJvb2xlYW5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlUGxhbkNhY2hlRXZpZGVuY2Uge1xuICByZWFkb25seSBjYXBhY2l0eTogbnVtYmVyXG4gIHJlYWRvbmx5IHNpemU6IG51bWJlclxuICByZWFkb25seSBoaXRzOiBudW1iZXJcbiAgcmVhZG9ubHkgbWlzc2VzOiBudW1iZXJcbiAgcmVhZG9ubHkgZXZpY3RzOiBudW1iZXJcbiAgcmVhZG9ubHkgaGl0OiBib29sZWFuXG4gIHJlYWRvbmx5IGtleVNpemU/OiBudW1iZXJcbiAgcmVhZG9ubHkgbWlzc1JlYXNvbj86ICdjb2xkX3N0YXJ0JyB8ICdnZW5lcmF0aW9uX2J1bXBlZCcgfCAnbm90X2NhY2hlZCcgfCAndW5rbm93bidcbiAgcmVhZG9ubHkgZGlzYWJsZWQ/OiBib29sZWFuXG4gIHJlYWRvbmx5IGRpc2FibGVSZWFzb24/OiAnbG93X2hpdF9yYXRlJyB8ICdnZW5lcmF0aW9uX3RocmFzaCcgfCAnbWFudWFsX292ZXJyaWRlJyB8ICd1bmtub3duJ1xufVxuXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlR2VuZXJhdGlvbkJ1bXBSZWFzb24gPVxuICB8ICd3cml0ZXJzX2NoYW5nZWQnXG4gIHwgJ2RlcHNfY2hhbmdlZCdcbiAgfCAnbG9naWNfaW5zdGFsbGVkJ1xuICB8ICdsb2dpY191bmluc3RhbGxlZCdcbiAgfCAnaW1wb3J0c19jaGFuZ2VkJ1xuICB8ICd1bmtub3duJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWl0Q29udmVyZ2VHZW5lcmF0aW9uRXZpZGVuY2Uge1xuICByZWFkb25seSBnZW5lcmF0aW9uOiBudW1iZXJcbiAgcmVhZG9ubHkgZ2VuZXJhdGlvbkJ1bXBDb3VudD86IG51bWJlclxuICByZWFkb25seSBsYXN0QnVtcFJlYXNvbj86IFRyYWl0Q29udmVyZ2VHZW5lcmF0aW9uQnVtcFJlYXNvblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWl0Q29udmVyZ2VTdGF0aWNJckV2aWRlbmNlIHtcbiAgcmVhZG9ubHkgZmllbGRQYXRoQ291bnQ6IG51bWJlclxuICByZWFkb25seSBzdGVwQ291bnQ6IG51bWJlclxuICByZWFkb25seSBidWlsZER1cmF0aW9uTXM/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlSG90c3BvdCB7XG4gIHJlYWRvbmx5IGtpbmQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgc3RlcElkOiBudW1iZXJcbiAgcmVhZG9ubHkgb3V0RmllbGRQYXRoSWQ/OiBudW1iZXJcbiAgcmVhZG9ubHkgZHVyYXRpb25NczogbnVtYmVyXG4gIHJlYWRvbmx5IGNoYW5nZWQ6IGJvb2xlYW5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlVGltZVNsaWNpbmdTdW1tYXJ5IHtcbiAgcmVhZG9ubHkgc2NvcGU6ICdhbGwnIHwgJ2ltbWVkaWF0ZScgfCAnZGVmZXJyZWQnXG4gIHJlYWRvbmx5IGltbWVkaWF0ZVN0ZXBDb3VudDogbnVtYmVyXG4gIHJlYWRvbmx5IGRlZmVycmVkU3RlcENvdW50OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlRGlhZ25vc3RpY3NTYW1wbGluZ1N1bW1hcnkge1xuICAvKipcbiAgICogRGV0ZXJtaW5pc3RpYyBzYW1wbGluZzogdXNlIHN0YWJsZSB0eG5TZXEgYXMgYW4gYW5jaG9yIGFuZCBzYW1wbGUgZXZlcnkgTiB0cmFuc2FjdGlvbnMuXG4gICAqIC0gc2FtcGxlZD10cnVlIG1lYW5zIHRoaXMgaW52b2NhdGlvbiBjYXB0dXJlZCBwZXItc3RlcCB0aW1pbmdzIGFuZCBwcm9kdWNlZCBob3RzcG90cy5cbiAgICovXG4gIHJlYWRvbmx5IHN0cmF0ZWd5OiAndHhuU2VxX2ludGVydmFsJ1xuICByZWFkb25seSBzYW1wbGVFdmVyeU46IG51bWJlclxuICByZWFkb25seSB0b3BLOiBudW1iZXJcbiAgcmVhZG9ubHkgc2FtcGxlZDogYm9vbGVhblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWl0Q29udmVyZ2VEZWNpc2lvblN1bW1hcnkge1xuICByZWFkb25seSByZXF1ZXN0ZWRNb2RlOiBUcmFpdENvbnZlcmdlUmVxdWVzdGVkTW9kZVxuICByZWFkb25seSBleGVjdXRlZE1vZGU6IFRyYWl0Q29udmVyZ2VFeGVjdXRlZE1vZGVcbiAgcmVhZG9ubHkgb3V0Y29tZTogVHJhaXRDb252ZXJnZU91dGNvbWVcbiAgcmVhZG9ubHkgY29uZmlnU2NvcGU6IFRyYWl0Q29udmVyZ2VDb25maWdTY29wZVxuICByZWFkb25seSBzdGF0aWNJckRpZ2VzdDogc3RyaW5nXG4gIHJlYWRvbmx5IGV4ZWN1dGlvbkJ1ZGdldE1zOiBudW1iZXJcbiAgcmVhZG9ubHkgZXhlY3V0aW9uRHVyYXRpb25NczogbnVtYmVyXG4gIHJlYWRvbmx5IGRlY2lzaW9uQnVkZ2V0TXM/OiBudW1iZXJcbiAgcmVhZG9ubHkgZGVjaXNpb25EdXJhdGlvbk1zPzogbnVtYmVyXG4gIHJlYWRvbmx5IHJlYXNvbnM6IFJlYWRvbmx5QXJyYXk8VHJhaXRDb252ZXJnZVJlYXNvbj5cbiAgcmVhZG9ubHkgc3RlcFN0YXRzOiBUcmFpdENvbnZlcmdlU3RlcFN0YXRzXG4gIHJlYWRvbmx5IGRpcnR5PzogVHJhaXRDb252ZXJnZURpcnR5U3VtbWFyeVxuICByZWFkb25seSBjYWNoZT86IFRyYWl0Q29udmVyZ2VQbGFuQ2FjaGVFdmlkZW5jZVxuICByZWFkb25seSBnZW5lcmF0aW9uPzogVHJhaXRDb252ZXJnZUdlbmVyYXRpb25FdmlkZW5jZVxuICByZWFkb25seSBzdGF0aWNJcj86IFRyYWl0Q29udmVyZ2VTdGF0aWNJckV2aWRlbmNlXG4gIHJlYWRvbmx5IHRpbWVTbGljaW5nPzogVHJhaXRDb252ZXJnZVRpbWVTbGljaW5nU3VtbWFyeVxuICByZWFkb25seSB0aHJlc2hvbGRzPzogeyByZWFkb25seSBmbG9vclJhdGlvPzogbnVtYmVyIH1cbiAgcmVhZG9ubHkgZGlhZ25vc3RpY3NTYW1wbGluZz86IFRyYWl0Q29udmVyZ2VEaWFnbm9zdGljc1NhbXBsaW5nU3VtbWFyeVxuICByZWFkb25seSB0b3AzPzogUmVhZG9ubHlBcnJheTxUcmFpdENvbnZlcmdlSG90c3BvdD5cbn1cbiIsICJpbXBvcnQgeyBFZmZlY3QsIEZpYmVyLCBGaWJlclJlZiwgT3B0aW9uIH0gZnJvbSAnZWZmZWN0J1xuaW1wb3J0IHsgY3JlYXRlIH0gZnJvbSAnbXV0YXRpdmUnXG5pbXBvcnQgKiBhcyBFZmZlY3RPcCBmcm9tICcuLi9lZmZlY3Qtb3AuanMnXG5pbXBvcnQgeyBTbmFwc2hvdCwgaW50ZXJuYWwgYXMgUmVzb3VyY2VJbnRlcm5hbCwga2V5SGFzaCBhcyBoYXNoS2V5IH0gZnJvbSAnLi4vcmVzb3VyY2UuanMnXG5pbXBvcnQgKiBhcyBFZmZlY3RPcENvcmUgZnJvbSAnLi4vcnVudGltZS9jb3JlL0VmZmVjdE9wQ29yZS5qcydcbmltcG9ydCAqIGFzIERlYnVnIGZyb20gJy4uL3J1bnRpbWUvY29yZS9EZWJ1Z1NpbmsuanMnXG5pbXBvcnQgKiBhcyBUYXNrUnVubmVyIGZyb20gJy4uL3J1bnRpbWUvY29yZS9UYXNrUnVubmVyLmpzJ1xuaW1wb3J0IHsgaXNEZXZFbnYsIFJlcGxheU1vZGVDb25maWdUYWcgfSBmcm9tICcuLi9ydW50aW1lL2NvcmUvZW52LmpzJ1xuaW1wb3J0ICogYXMgUmVwbGF5TG9nIGZyb20gJy4uL3J1bnRpbWUvY29yZS9SZXBsYXlMb2cuanMnXG5pbXBvcnQgdHlwZSB7IFBhdGNoUmVhc29uIH0gZnJvbSAnLi4vcnVudGltZS9jb3JlL1N0YXRlVHJhbnNhY3Rpb24uanMnXG5pbXBvcnQgdHlwZSB7IEZpZWxkUGF0aCwgRmllbGRQYXRoSWQgfSBmcm9tICcuLi9maWVsZC1wYXRoLmpzJ1xuaW1wb3J0IHsgbm9ybWFsaXplRmllbGRQYXRoIH0gZnJvbSAnLi4vZmllbGQtcGF0aC5qcydcbmltcG9ydCB0eXBlIHsgQm91bmRBcGkgfSBmcm9tICcuLi9ydW50aW1lL2NvcmUvbW9kdWxlLmpzJ1xuaW1wb3J0IHsgZ2V0Qm91bmRJbnRlcm5hbHMgfSBmcm9tICcuLi9ydW50aW1lL2NvcmUvcnVudGltZUludGVybmFsc0FjY2Vzc29yLmpzJ1xuaW1wb3J0IHsgUnVuU2Vzc2lvblRhZyB9IGZyb20gJy4uL29ic2VydmFiaWxpdHkvcnVuU2Vzc2lvbi5qcydcbmltcG9ydCAqIGFzIERlcHNUcmFjZSBmcm9tICcuL2RlcHMtdHJhY2UuanMnXG5pbXBvcnQgKiBhcyBSb3dJZCBmcm9tICcuL3Jvd2lkLmpzJ1xuaW1wb3J0IHR5cGUgeyBTdGF0ZVRyYWl0RW50cnksIFN0YXRlVHJhaXRQbGFuU3RlcCwgU3RhdGVUcmFpdFByb2dyYW0gfSBmcm9tICcuL21vZGVsLmpzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFNvdXJjZVN5bmNDb250ZXh0PFM+IHtcbiAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZ1xuICByZWFkb25seSBnZXREcmFmdDogKCkgPT4gU1xuICByZWFkb25seSBzZXREcmFmdDogKG5leHQ6IFMpID0+IHZvaWRcbiAgcmVhZG9ubHkgcmVjb3JkUGF0Y2g6IChcbiAgICBwYXRoOiBzdHJpbmcgfCBGaWVsZFBhdGggfCBGaWVsZFBhdGhJZCB8IHVuZGVmaW5lZCxcbiAgICByZWFzb246IFBhdGNoUmVhc29uLFxuICAgIGZyb20/OiB1bmtub3duLFxuICAgIHRvPzogdW5rbm93bixcbiAgICB0cmFpdE5vZGVJZD86IHN0cmluZyxcbiAgICBzdGVwSWQ/OiBudW1iZXIsXG4gICkgPT4gdm9pZFxufVxuXG5jb25zdCBvbmNlSW5SdW5TZXNzaW9uID0gKGtleTogc3RyaW5nKTogRWZmZWN0LkVmZmVjdDxib29sZWFuLCBuZXZlciwgYW55PiA9PlxuICBFZmZlY3Quc2VydmljZU9wdGlvbihSdW5TZXNzaW9uVGFnKS5waXBlKFxuICAgIEVmZmVjdC5tYXAoKG1heWJlKSA9PiAoT3B0aW9uLmlzU29tZShtYXliZSkgPyBtYXliZS52YWx1ZS5sb2NhbC5vbmNlKGtleSkgOiB0cnVlKSksXG4gIClcblxuY29uc3QgZm9ybWF0TGlzdCA9IChpdGVtczogUmVhZG9ubHlBcnJheTxzdHJpbmc+LCBsaW1pdCA9IDEwKTogc3RyaW5nID0+IHtcbiAgaWYgKGl0ZW1zLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChpdGVtcy5sZW5ndGggPD0gbGltaXQpIHJldHVybiBpdGVtcy5qb2luKCcsICcpXG4gIHJldHVybiBgJHtpdGVtcy5zbGljZSgwLCBsaW1pdCkuam9pbignLCAnKX0sIFx1MjAyNigrJHtpdGVtcy5sZW5ndGggLSBsaW1pdH0pYFxufVxuXG5jb25zdCBlbWl0RGVwc01pc21hdGNoID0gKHBhcmFtczoge1xuICByZWFkb25seSBtb2R1bGVJZD86IHN0cmluZ1xuICByZWFkb25seSBpbnN0YW5jZUlkPzogc3RyaW5nXG4gIHJlYWRvbmx5IGtpbmQ6ICdjb21wdXRlZCcgfCAnc291cmNlJ1xuICByZWFkb25seSBmaWVsZFBhdGg6IHN0cmluZ1xuICByZWFkb25seSBkaWZmOiBEZXBzVHJhY2UuRGVwc0RpZmZcbn0pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBhbnk+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBrZXkgPSBgJHtwYXJhbXMuaW5zdGFuY2VJZCA/PyAndW5rbm93bid9Ojoke3BhcmFtcy5raW5kfTo6JHtwYXJhbXMuZmllbGRQYXRofWBcbiAgICBjb25zdCBzaG91bGRFbWl0ID0geWllbGQqIG9uY2VJblJ1blNlc3Npb24oYGRlcHNfbWlzbWF0Y2g6JHtrZXl9YClcbiAgICBpZiAoIXNob3VsZEVtaXQpIHJldHVyblxuXG4gICAgeWllbGQqIERlYnVnLnJlY29yZCh7XG4gICAgICB0eXBlOiAnZGlhZ25vc3RpYycsXG4gICAgICBtb2R1bGVJZDogcGFyYW1zLm1vZHVsZUlkLFxuICAgICAgaW5zdGFuY2VJZDogcGFyYW1zLmluc3RhbmNlSWQsXG4gICAgICBjb2RlOiAnc3RhdGVfdHJhaXQ6OmRlcHNfbWlzbWF0Y2gnLFxuICAgICAgc2V2ZXJpdHk6ICd3YXJuaW5nJyxcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIGBbZGVwc10gJHtwYXJhbXMua2luZH0gXCIke3BhcmFtcy5maWVsZFBhdGh9XCIgZGVjbGFyZWQ9WyR7Zm9ybWF0TGlzdChwYXJhbXMuZGlmZi5kZWNsYXJlZCl9XSBgICtcbiAgICAgICAgYHJlYWRzPVske2Zvcm1hdExpc3QocGFyYW1zLmRpZmYucmVhZHMpfV0gbWlzc2luZz1bJHtmb3JtYXRMaXN0KHBhcmFtcy5kaWZmLm1pc3NpbmcpfV0gYCArXG4gICAgICAgIGB1bnVzZWQ9WyR7Zm9ybWF0TGlzdChwYXJhbXMuZGlmZi51bnVzZWQpfV1gLFxuICAgICAgaGludDpcbiAgICAgICAgJ2RlcHMgaXMgdGhlIHNpbmdsZSBzb3VyY2Ugb2YgdHJ1dGggZm9yIGRlcGVuZGVuY2llczogaW5jcmVtZW50YWwgc2NoZWR1bGluZyAvIHJldmVyc2UgY2xvc3VyZXMgLyBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25zIHJlbHkgb24gZGVwcyBvbmx5LiAnICtcbiAgICAgICAgJ0tlZXAgZGVwcyBjb25zaXN0ZW50IHdpdGggYWN0dWFsIHJlYWRzOyBpZiB5b3UgcmVhbGx5IGRlcGVuZCBvbiB0aGUgd2hvbGUgb2JqZWN0LCBkZWNsYXJlIGEgY29hcnNlci1ncmFpbmVkIGRlcCAoZS5nLiBcInByb2ZpbGVcIikgdG8gY292ZXIgc3ViLWZpZWxkIHJlYWRzLicsXG4gICAgICBraW5kOiBgZGVwc19taXNtYXRjaDoke3BhcmFtcy5raW5kfWAsXG4gICAgfSlcbiAgfSlcblxuY29uc3QgZ2V0TWlkZGxld2FyZVN0YWNrID0gKCk6IEVmZmVjdC5FZmZlY3Q8RWZmZWN0T3AuTWlkZGxld2FyZVN0YWNrLCBuZXZlciwgYW55PiA9PlxuICBFZmZlY3Quc2VydmljZU9wdGlvbihFZmZlY3RPcENvcmUuRWZmZWN0T3BNaWRkbGV3YXJlVGFnKS5waXBlKFxuICAgIEVmZmVjdC5tYXAoKG1heWJlKSA9PiAoT3B0aW9uLmlzU29tZShtYXliZSkgPyBtYXliZS52YWx1ZS5zdGFjayA6IFtdKSksXG4gIClcblxuY29uc3QgcmVjb3JkVHJhaXRQYXRjaCA9IChcbiAgYm91bmQ6IEJvdW5kQXBpPGFueSwgYW55PixcbiAgcGF0aDogc3RyaW5nLFxuICByZWFzb246IFBhdGNoUmVhc29uLFxuICBmcm9tPzogdW5rbm93bixcbiAgdG8/OiB1bmtub3duLFxuICB0cmFpdE5vZGVJZD86IHN0cmluZyxcbik6IHZvaWQgPT4ge1xuICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplRmllbGRQYXRoKHBhdGgpID8/IFtdXG4gIHRyeSB7XG4gICAgY29uc3QgaW50ZXJuYWxzID0gZ2V0Qm91bmRJbnRlcm5hbHMoYm91bmQgYXMgYW55KVxuICAgIGludGVybmFscy50eG4ucmVjb3JkU3RhdGVQYXRjaChub3JtYWxpemVkLCByZWFzb24sIGZyb20sIHRvLCB0cmFpdE5vZGVJZClcbiAgfSBjYXRjaCB7XG4gICAgLy8gbm8tb3AgZm9yIGxlZ2FjeS9tb2NrZWQgYm91bmRcbiAgfVxufVxuXG5jb25zdCByZWNvcmRSZXBsYXlFdmVudCA9IChib3VuZDogQm91bmRBcGk8YW55LCBhbnk+LCBldmVudDogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50KTogdm9pZCA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgaW50ZXJuYWxzID0gZ2V0Qm91bmRJbnRlcm5hbHMoYm91bmQgYXMgYW55KVxuICAgIGludGVybmFscy50eG4ucmVjb3JkUmVwbGF5RXZlbnQoZXZlbnQpXG4gIH0gY2F0Y2gge1xuICAgIC8vIG5vLW9wIGZvciBsZWdhY3kvbW9ja2VkIGJvdW5kXG4gIH1cbn1cblxuY29uc3QgZ2V0Qm91bmRTY29wZSA9IChib3VuZDogQm91bmRBcGk8YW55LCBhbnk+KTogeyByZWFkb25seSBtb2R1bGVJZD86IHN0cmluZzsgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZyB9ID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBpbnRlcm5hbHMgPSBnZXRCb3VuZEludGVybmFscyhib3VuZCBhcyBhbnkpXG4gICAgcmV0dXJuIHsgbW9kdWxlSWQ6IGludGVybmFscy5tb2R1bGVJZCwgaW5zdGFuY2VJZDogaW50ZXJuYWxzLmluc3RhbmNlSWQgfVxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4geyBtb2R1bGVJZDogdW5kZWZpbmVkLCBpbnN0YW5jZUlkOiB1bmRlZmluZWQgfVxuICB9XG59XG5cbmNvbnN0IHNldFNuYXBzaG90SW5UeG4gPSAoXG4gIGJvdW5kOiBCb3VuZEFwaTxhbnksIGFueT4sXG4gIGZpZWxkUGF0aDogc3RyaW5nLFxuICBuZXh0OiB1bmtub3duLFxuICByZWFzb246IFBhdGNoUmVhc29uLFxuICBzdGVwSWQ6IHN0cmluZyxcbiAgdHJhaXROb2RlSWQ/OiBzdHJpbmcsXG4pOiBFZmZlY3QuRWZmZWN0PGJvb2xlYW4sIG5ldmVyLCBhbnk+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBsZXQgd3JvdGUgPSBmYWxzZVxuICAgIHlpZWxkKiBib3VuZC5zdGF0ZS5tdXRhdGUoKGRyYWZ0KSA9PiB7XG4gICAgICBjb25zdCBwcmV2ID0gUm93SWQuZ2V0QXRQYXRoKGRyYWZ0LCBmaWVsZFBhdGgpXG4gICAgICBpZiAoT2JqZWN0LmlzKHByZXYsIG5leHQpKSByZXR1cm5cbiAgICAgIHdyb3RlID0gdHJ1ZVxuICAgICAgUm93SWQuc2V0QXRQYXRoTXV0YXRpbmcoZHJhZnQsIGZpZWxkUGF0aCwgbmV4dClcbiAgICAgIHJlY29yZFRyYWl0UGF0Y2goYm91bmQsIGZpZWxkUGF0aCwgcmVhc29uLCBwcmV2LCBuZXh0LCB0cmFpdE5vZGVJZClcbiAgICB9KVxuICAgIHJldHVybiB3cm90ZVxuICB9KVxuXG5jb25zdCB3cml0ZWJhY2tJZkN1cnJlbnRLZXlIYXNoID0gKFxuICBib3VuZDogQm91bmRBcGk8YW55LCBhbnk+LFxuICBmaWVsZFBhdGg6IHN0cmluZyxcbiAga2V5SGFzaDogc3RyaW5nLFxuICBuZXh0OiB1bmtub3duLFxuICByZWFzb246IFBhdGNoUmVhc29uLFxuICBzdGVwSWQ6IHN0cmluZyxcbiAgdHJhaXROb2RlSWQ/OiBzdHJpbmcsXG4gIHJlcGxheUV2ZW50PzogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50LFxuKTogRWZmZWN0LkVmZmVjdDxib29sZWFuLCBuZXZlciwgYW55PiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgbGV0IHdyb3RlID0gZmFsc2VcbiAgICB5aWVsZCogYm91bmQuc3RhdGUubXV0YXRlKChkcmFmdCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudCA9IFJvd0lkLmdldEF0UGF0aChkcmFmdCwgZmllbGRQYXRoKVxuICAgICAgY29uc3QgY3VycmVudEtleUhhc2ggPSBjdXJyZW50ICYmIHR5cGVvZiBjdXJyZW50ID09PSAnb2JqZWN0JyA/IChjdXJyZW50IGFzIGFueSkua2V5SGFzaCA6IHVuZGVmaW5lZFxuICAgICAgaWYgKGN1cnJlbnRLZXlIYXNoICE9PSBrZXlIYXNoKSByZXR1cm5cblxuICAgICAgY29uc3QgcHJldiA9IGN1cnJlbnRcbiAgICAgIGlmIChPYmplY3QuaXMocHJldiwgbmV4dCkpIHJldHVyblxuXG4gICAgICB3cm90ZSA9IHRydWVcbiAgICAgIFJvd0lkLnNldEF0UGF0aE11dGF0aW5nKGRyYWZ0LCBmaWVsZFBhdGgsIG5leHQpXG4gICAgICBpZiAocmVwbGF5RXZlbnQpIHtcbiAgICAgICAgcmVjb3JkUmVwbGF5RXZlbnQoYm91bmQsIHJlcGxheUV2ZW50KVxuICAgICAgfVxuICAgICAgcmVjb3JkVHJhaXRQYXRjaChib3VuZCwgZmllbGRQYXRoLCByZWFzb24sIHByZXYsIG5leHQsIHRyYWl0Tm9kZUlkKVxuICAgIH0pXG4gICAgcmV0dXJuIHdyb3RlXG4gIH0pXG5cbi8qKlxuICogc3luY0lkbGVJblRyYW5zYWN0aW9uXHVGRjFBXG4gKiAtIFN5bmNocm9ub3VzbHkgZXZhbHVhdGUgYWxsIHNvdXJjZS5rZXkoc3RhdGUpIHdpdGhpbiB0aGUgdHJhbnNhY3Rpb24gd2luZG93LlxuICogLSBJZiBhIGtleSBiZWNvbWVzIGVtcHR5ICh1bmRlZmluZWQpLCBzeW5jaHJvbm91c2x5IHJlc2V0IHRoZSBmaWVsZCB0byBhbiBpZGxlIHNuYXBzaG90IChhdm9pZCB0ZWFyaW5nKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHN5bmNJZGxlSW5UcmFuc2FjdGlvbiA9IDxTIGV4dGVuZHMgb2JqZWN0PihcbiAgcHJvZ3JhbTogU3RhdGVUcmFpdFByb2dyYW08Uz4sXG4gIGN0eDogU291cmNlU3luY0NvbnRleHQ8Uz4sXG4pOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+XG4gIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICBjb25zdCBkcmFmdCA9IGN0eC5nZXREcmFmdCgpIGFzIGFueVxuICAgIGNvbnN0IHVwZGF0ZXM6IEFycmF5PHsgcmVhZG9ubHkgZmllbGRQYXRoOiBzdHJpbmc7IHJlYWRvbmx5IHByZXY6IHVua25vd24gfT4gPSBbXVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBwcm9ncmFtLmVudHJpZXMpIHtcbiAgICAgIGlmIChlbnRyeS5raW5kICE9PSAnc291cmNlJykgY29udGludWVcbiAgICAgIGNvbnN0IGZpZWxkUGF0aCA9IGVudHJ5LmZpZWxkUGF0aFxuICAgICAgY29uc3QgbGlzdEl0ZW0gPSBSb3dJZC5wYXJzZUxpc3RJdGVtRmllbGRQYXRoKGZpZWxkUGF0aClcblxuICAgICAgaWYgKGxpc3RJdGVtKSB7XG4gICAgICAgIC8vIGxpc3QuaXRlbSBzY29wZTogZXZhbHVhdGUga2V5IHBlciByb3cgYnkgaW5kZXgsIGFuZCBzeW5jaHJvbm91c2x5IHdyaXRlIGJhY2sgaWRsZSBmb3IgaW5hY3RpdmUgcm93cy5cbiAgICAgICAgY29uc3QgbGlzdFZhbHVlID0gUm93SWQuZ2V0QXRQYXRoKGRyYWZ0LCBsaXN0SXRlbS5saXN0UGF0aClcbiAgICAgICAgY29uc3QgaXRlbXM6IFJlYWRvbmx5QXJyYXk8dW5rbm93bj4gPSBBcnJheS5pc0FycmF5KGxpc3RWYWx1ZSkgPyBsaXN0VmFsdWUgOiBbXVxuXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBpdGVtcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICBjb25zdCBpdGVtID0gaXRlbXNbaW5kZXhdXG5cbiAgICAgICAgICBsZXQga2V5OiB1bmtub3duXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGtleSA9IChlbnRyeS5tZXRhIGFzIGFueSkua2V5KGl0ZW0pXG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChrZXkgIT09IHVuZGVmaW5lZCkgY29udGludWVcblxuICAgICAgICAgIGNvbnN0IGNvbmNyZXRlUGF0aCA9IFJvd0lkLnRvTGlzdEl0ZW1WYWx1ZVBhdGgobGlzdEl0ZW0ubGlzdFBhdGgsIGluZGV4LCBsaXN0SXRlbS5pdGVtUGF0aClcbiAgICAgICAgICBjb25zdCBwcmV2ID0gUm93SWQuZ2V0QXRQYXRoKGRyYWZ0LCBjb25jcmV0ZVBhdGgpXG4gICAgICAgICAgY29uc3QgcHJldlN0YXR1cyA9IHByZXYgJiYgdHlwZW9mIHByZXYgPT09ICdvYmplY3QnID8gKHByZXYgYXMgYW55KS5zdGF0dXMgOiB1bmRlZmluZWRcbiAgICAgICAgICBpZiAocHJldlN0YXR1cyA9PT0gJ2lkbGUnKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0gKHByZXYgYXMgYW55KT8uZGF0YVxuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSAocHJldiBhcyBhbnkpPy5lcnJvclxuICAgICAgICAgICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCAmJiBlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdXBkYXRlcy5wdXNoKHsgZmllbGRQYXRoOiBjb25jcmV0ZVBhdGgsIHByZXYgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGxldCBrZXk6IHVua25vd25cbiAgICAgIHRyeSB7XG4gICAgICAgIGtleSA9IChlbnRyeS5tZXRhIGFzIGFueSkua2V5KGRyYWZ0KVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChrZXkgIT09IHVuZGVmaW5lZCkgY29udGludWVcblxuICAgICAgY29uc3QgcHJldiA9IFJvd0lkLmdldEF0UGF0aChkcmFmdCwgZmllbGRQYXRoKVxuICAgICAgY29uc3QgcHJldlN0YXR1cyA9IHByZXYgJiYgdHlwZW9mIHByZXYgPT09ICdvYmplY3QnID8gKHByZXYgYXMgYW55KS5zdGF0dXMgOiB1bmRlZmluZWRcbiAgICAgIGlmIChwcmV2U3RhdHVzID09PSAnaWRsZScpIHtcbiAgICAgICAgLy8gU3RpbGwgZW5zdXJlIGRhdGEvZXJyb3IgYXJlIGNsZWFyZWQuXG4gICAgICAgIGNvbnN0IGRhdGEgPSAocHJldiBhcyBhbnkpPy5kYXRhXG4gICAgICAgIGNvbnN0IGVycm9yID0gKHByZXYgYXMgYW55KT8uZXJyb3JcbiAgICAgICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCAmJiBlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB1cGRhdGVzLnB1c2goeyBmaWVsZFBhdGgsIHByZXYgfSlcbiAgICB9XG5cbiAgICBpZiAodXBkYXRlcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgY29uc3QgcmVhc29uOiBQYXRjaFJlYXNvbiA9ICdzb3VyY2UtcmVmcmVzaCdcblxuICAgIGNvbnN0IG5leHREcmFmdCA9IGNyZWF0ZShkcmFmdCwgKG5leHQpID0+IHtcbiAgICAgIGZvciAoY29uc3QgdSBvZiB1cGRhdGVzKSB7XG4gICAgICAgIFJvd0lkLnNldEF0UGF0aE11dGF0aW5nKG5leHQsIHUuZmllbGRQYXRoLCBTbmFwc2hvdC5pZGxlKCkpXG4gICAgICB9XG4gICAgfSlcblxuICAgIGN0eC5zZXREcmFmdChuZXh0RHJhZnQgYXMgUylcblxuICAgIGZvciAoY29uc3QgdSBvZiB1cGRhdGVzKSB7XG4gICAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplRmllbGRQYXRoKHUuZmllbGRQYXRoKSA/PyBbXVxuICAgICAgY3R4LnJlY29yZFBhdGNoKG5vcm1hbGl6ZWQsIHJlYXNvbiwgdS5wcmV2LCBTbmFwc2hvdC5pZGxlKCksIGBzb3VyY2U6JHt1LmZpZWxkUGF0aH06aWRsZWApXG4gICAgfVxuICB9KVxuXG4vKipcbiAqIGluc3RhbGxTb3VyY2VSZWZyZXNoXHVGRjFBXG4gKiAtIFJlZ2lzdGVyIHRoZSByZWZyZXNoIGltcGxlbWVudGF0aW9uIGZvciBhIHNpbmdsZSBzb3VyY2UgZmllbGQgKFJlc291cmNlU25hcHNob3QgKyBrZXlIYXNoIGdhdGUgKyBjb25jdXJyZW5jeSkuXG4gKi9cbmV4cG9ydCBjb25zdCBpbnN0YWxsU291cmNlUmVmcmVzaCA9IDxTPihcbiAgYm91bmQ6IEJvdW5kQXBpPGFueSwgYW55PixcbiAgc3RlcDogU3RhdGVUcmFpdFBsYW5TdGVwLFxuICBlbnRyeTogRXh0cmFjdDxTdGF0ZVRyYWl0RW50cnk8Uywgc3RyaW5nPiwgeyByZWFkb25seSBraW5kOiAnc291cmNlJyB9Pixcbik6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIGFueT4gPT4ge1xuICBpZiAoIXN0ZXAudGFyZ2V0RmllbGRQYXRoKSByZXR1cm4gRWZmZWN0LnZvaWRcblxuICBjb25zdCBmaWVsZFBhdGggPSBzdGVwLnRhcmdldEZpZWxkUGF0aFxuICBjb25zdCByZXNvdXJjZUlkID0gc3RlcC5yZXNvdXJjZUlkID8/IGVudHJ5Lm1ldGEucmVzb3VyY2VcbiAgY29uc3QgbGlzdEl0ZW0gPSBSb3dJZC5wYXJzZUxpc3RJdGVtRmllbGRQYXRoKGZpZWxkUGF0aClcblxuICBsZXQgaW50ZXJuYWxzOiBSZXR1cm5UeXBlPHR5cGVvZiBnZXRCb3VuZEludGVybmFscz4gfCB1bmRlZmluZWRcbiAgdHJ5IHtcbiAgICBpbnRlcm5hbHMgPSBnZXRCb3VuZEludGVybmFscyhib3VuZCBhcyBhbnkpXG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICB9XG5cbiAgY29uc3QgcmVnaXN0ZXIgPSBpbnRlcm5hbHMudHJhaXRzLnJlZ2lzdGVyU291cmNlUmVmcmVzaFxuXG4gIGNvbnN0IHJlY29yZFNuYXBzaG90ID0gKFxuICAgIHJlcGxheU1vZGU6ICdsaXZlJyB8ICdyZXBsYXknLFxuICAgIHJlcGxheUxvZzogUmVwbGF5TG9nLlJlcGxheUxvZ1NlcnZpY2UgfCB1bmRlZmluZWQsXG4gICAgaW5wdXQ6XG4gICAgICB8IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudFxuICAgICAgfCB7XG4gICAgICAgICAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgICAgICAgICByZWFkb25seSBpbnN0YW5jZUlkPzogc3RyaW5nXG4gICAgICAgICAgcmVhZG9ubHkgZmllbGRQYXRoOiBzdHJpbmdcbiAgICAgICAgICByZWFkb25seSBrZXlIYXNoPzogc3RyaW5nXG4gICAgICAgICAgcmVhZG9ubHkgY29uY3VycmVuY3k/OiBzdHJpbmdcbiAgICAgICAgICByZWFkb25seSBwaGFzZTogUmVwbGF5TG9nLlJlc291cmNlU25hcHNob3RQaGFzZVxuICAgICAgICAgIHJlYWRvbmx5IHNuYXBzaG90OiB1bmtub3duXG4gICAgICAgIH0sXG4gICk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIGFueT4gPT4ge1xuICAgIGlmICghcmVwbGF5TG9nKSByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICBpZiAocmVwbGF5TW9kZSAhPT0gJ2xpdmUnKSByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICBjb25zdCBldmVudDogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50ID1cbiAgICAgIGlucHV0ICYmIHR5cGVvZiBpbnB1dCA9PT0gJ29iamVjdCcgJiYgKGlucHV0IGFzIGFueSkuX3RhZyA9PT0gJ1Jlc291cmNlU25hcHNob3QnXG4gICAgICAgID8gKGlucHV0IGFzIFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudClcbiAgICAgICAgOiB7XG4gICAgICAgICAgICBfdGFnOiAnUmVzb3VyY2VTbmFwc2hvdCcsXG4gICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgZmllbGRQYXRoOiAoaW5wdXQgYXMgYW55KS5maWVsZFBhdGgsXG4gICAgICAgICAgICBrZXlIYXNoOiAoaW5wdXQgYXMgYW55KS5rZXlIYXNoLFxuICAgICAgICAgICAgY29uY3VycmVuY3k6IChpbnB1dCBhcyBhbnkpLmNvbmN1cnJlbmN5LFxuICAgICAgICAgICAgcGhhc2U6IChpbnB1dCBhcyBhbnkpLnBoYXNlLFxuICAgICAgICAgICAgc25hcHNob3Q6IChpbnB1dCBhcyBhbnkpLnNuYXBzaG90LFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgbW9kdWxlSWQ6IChpbnB1dCBhcyBhbnkpLm1vZHVsZUlkLFxuICAgICAgICAgICAgaW5zdGFuY2VJZDogKGlucHV0IGFzIGFueSkuaW5zdGFuY2VJZCxcbiAgICAgICAgICB9XG4gICAgcmV0dXJuIHJlcGxheUxvZy5yZWNvcmQoZXZlbnQpXG4gIH1cblxuICAvLyBsaXN0Lml0ZW0gc2NvcGU6IGluLWZsaWdodCBnYXRpbmcgYnkgUm93SUQgKGF2b2lkIHdyaXRpbmcgdG8gdGhlIHdyb25nIHJvdyB1bmRlciBpbnNlcnQvcmVtb3ZlL3Jlb3JkZXIpLlxuICBpZiAobGlzdEl0ZW0pIHtcbiAgICBjb25zdCBzdG9yZSA9IGludGVybmFscy50cmFpdHMucm93SWRTdG9yZSBhcyBSb3dJZC5Sb3dJZFN0b3JlIHwgdW5kZWZpbmVkXG4gICAgaWYgKCFzdG9yZSkge1xuICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgfVxuXG4gICAgY29uc3QgbGlzdFBhdGggPSBsaXN0SXRlbS5saXN0UGF0aFxuICAgIGNvbnN0IGl0ZW1QYXRoID0gbGlzdEl0ZW0uaXRlbVBhdGhcbiAgICBpZiAoIWl0ZW1QYXRoKSB7XG4gICAgICAvLyBOZXZlciB3cml0ZSB0aGUgc25hcHNob3QgYmFjayB0byB0aGUgd2hvbGUgaXRlbSAoaXQgd291bGQgb3ZlcndyaXRlIGJ1c2luZXNzIHZhbHVlcykuXG4gICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICB9XG5cbiAgICBjb25zdCBjb25jdXJyZW5jeSA9IChlbnRyeS5tZXRhIGFzIGFueSkuY29uY3VycmVuY3kgYXMgJ3N3aXRjaCcgfCAnZXhoYXVzdC10cmFpbGluZycgfCB1bmRlZmluZWRcbiAgICBjb25zdCBtb2RlID0gY29uY3VycmVuY3kgPz8gJ3N3aXRjaCdcblxuICAgIGNvbnN0IGluRmxpZ2h0ID0gbmV3IE1hcDxcbiAgICAgIFJvd0lkLlJvd0lkLFxuICAgICAge1xuICAgICAgICByZWFkb25seSBnZW46IG51bWJlclxuICAgICAgICByZWFkb25seSBmaWJlcjogRmliZXIuUnVudGltZUZpYmVyPHZvaWQsIG5ldmVyPlxuICAgICAgICByZWFkb25seSBrZXlIYXNoOiBzdHJpbmdcbiAgICAgIH1cbiAgICA+KClcbiAgICBjb25zdCB0cmFpbGluZyA9IG5ldyBNYXA8Um93SWQuUm93SWQsIHsgcmVhZG9ubHkga2V5OiB1bmtub3duOyByZWFkb25seSBrZXlIYXNoOiBzdHJpbmcgfT4oKVxuICAgIGxldCBnZW4gPSAwXG5cbiAgICAvLyBXaGVuIGEgcm93IGlzIHJlbW92ZWQ6IGNsZWFyIHRyYWlsaW5nL2luRmxpZ2h0IHJlZmVyZW5jZXMgdG8gYXZvaWQgd3JvbmcgYXR0cmlidXRpb24gb3IgbWVtb3J5IGxlYWtzLlxuICAgIHN0b3JlLm9uUmVtb3ZlZChsaXN0UGF0aCwgKHJvd0lkKSA9PiB7XG4gICAgICB0cmFpbGluZy5kZWxldGUocm93SWQpXG4gICAgICBpbkZsaWdodC5kZWxldGUocm93SWQpXG4gICAgfSlcblxuICAgIGNvbnN0IHNldFNuYXBzaG90Rm9yUm93SW5UeG4gPSAoXG4gICAgICByb3dJZDogUm93SWQuUm93SWQsXG4gICAgICBuZXh0OiB1bmtub3duLFxuICAgICAgcmVhc29uOiBQYXRjaFJlYXNvbixcbiAgICAgIHN0ZXBJZDogc3RyaW5nLFxuICAgICk6IEVmZmVjdC5FZmZlY3Q8c3RyaW5nIHwgdW5kZWZpbmVkLCBuZXZlciwgYW55PiA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBsZXQgd3JvdGVQYXRoOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgICAgICAgeWllbGQqIGJvdW5kLnN0YXRlLm11dGF0ZSgoZHJhZnQpID0+IHtcbiAgICAgICAgICBjb25zdCBpbmRleCA9IHN0b3JlLmdldEluZGV4KGxpc3RQYXRoLCByb3dJZClcbiAgICAgICAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkgcmV0dXJuXG4gICAgICAgICAgY29uc3QgY29uY3JldGVQYXRoID0gUm93SWQudG9MaXN0SXRlbVZhbHVlUGF0aChsaXN0UGF0aCwgaW5kZXgsIGl0ZW1QYXRoKVxuICAgICAgICAgIGNvbnN0IHByZXYgPSBSb3dJZC5nZXRBdFBhdGgoZHJhZnQsIGNvbmNyZXRlUGF0aClcbiAgICAgICAgICBpZiAoT2JqZWN0LmlzKHByZXYsIG5leHQpKSByZXR1cm5cbiAgICAgICAgICB3cm90ZVBhdGggPSBjb25jcmV0ZVBhdGhcbiAgICAgICAgICBSb3dJZC5zZXRBdFBhdGhNdXRhdGluZyhkcmFmdCwgY29uY3JldGVQYXRoLCBuZXh0KVxuICAgICAgICAgIHJlY29yZFRyYWl0UGF0Y2goYm91bmQsIGNvbmNyZXRlUGF0aCwgcmVhc29uLCBwcmV2LCBuZXh0LCBzdGVwLmRlYnVnSW5mbz8uZ3JhcGhOb2RlSWQpXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiB3cm90ZVBhdGhcbiAgICAgIH0pXG5cbiAgICBjb25zdCB3cml0ZWJhY2tJZkN1cnJlbnRLZXlIYXNoRm9yUm93ID0gKFxuICAgICAgcm93SWQ6IFJvd0lkLlJvd0lkLFxuICAgICAga2V5SGFzaDogc3RyaW5nLFxuICAgICAgbmV4dDogdW5rbm93bixcbiAgICAgIHJlYXNvbjogUGF0Y2hSZWFzb24sXG4gICAgICBzdGVwSWQ6IHN0cmluZyxcbiAgICAgIHBoYXNlPzogUmVwbGF5TG9nLlJlc291cmNlU25hcHNob3RQaGFzZSxcbiAgICApOiBFZmZlY3QuRWZmZWN0PHN0cmluZyB8IHVuZGVmaW5lZCwgbmV2ZXIsIGFueT4gPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgbGV0IHdyb3RlUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gICAgICAgIHlpZWxkKiBib3VuZC5zdGF0ZS5tdXRhdGUoKGRyYWZ0KSA9PiB7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSBzdG9yZS5nZXRJbmRleChsaXN0UGF0aCwgcm93SWQpXG4gICAgICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHJldHVyblxuICAgICAgICAgIGNvbnN0IGNvbmNyZXRlUGF0aCA9IFJvd0lkLnRvTGlzdEl0ZW1WYWx1ZVBhdGgobGlzdFBhdGgsIGluZGV4LCBpdGVtUGF0aClcblxuICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSBSb3dJZC5nZXRBdFBhdGgoZHJhZnQsIGNvbmNyZXRlUGF0aClcbiAgICAgICAgICBjb25zdCBjdXJyZW50S2V5SGFzaCA9IGN1cnJlbnQgJiYgdHlwZW9mIGN1cnJlbnQgPT09ICdvYmplY3QnID8gKGN1cnJlbnQgYXMgYW55KS5rZXlIYXNoIDogdW5kZWZpbmVkXG4gICAgICAgICAgaWYgKGN1cnJlbnRLZXlIYXNoICE9PSBrZXlIYXNoKSByZXR1cm5cblxuICAgICAgICAgIGNvbnN0IHByZXYgPSBjdXJyZW50XG4gICAgICAgICAgaWYgKE9iamVjdC5pcyhwcmV2LCBuZXh0KSkgcmV0dXJuXG5cbiAgICAgICAgICB3cm90ZVBhdGggPSBjb25jcmV0ZVBhdGhcbiAgICAgICAgICBSb3dJZC5zZXRBdFBhdGhNdXRhdGluZyhkcmFmdCwgY29uY3JldGVQYXRoLCBuZXh0KVxuICAgICAgICAgIGlmIChwaGFzZSkge1xuICAgICAgICAgICAgY29uc3QgeyBtb2R1bGVJZCwgaW5zdGFuY2VJZCB9ID0gZ2V0Qm91bmRTY29wZShib3VuZClcbiAgICAgICAgICAgIHJlY29yZFJlcGxheUV2ZW50KGJvdW5kLCB7XG4gICAgICAgICAgICAgIF90YWc6ICdSZXNvdXJjZVNuYXBzaG90JyxcbiAgICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgICAgZmllbGRQYXRoOiBjb25jcmV0ZVBhdGgsXG4gICAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgICAgICBwaGFzZSxcbiAgICAgICAgICAgICAgc25hcHNob3Q6IG5leHQsXG4gICAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgICByZWNvcmRUcmFpdFBhdGNoKGJvdW5kLCBjb25jcmV0ZVBhdGgsIHJlYXNvbiwgcHJldiwgbmV4dCwgc3RlcC5kZWJ1Z0luZm8/LmdyYXBoTm9kZUlkKVxuICAgICAgICB9KVxuICAgICAgICByZXR1cm4gd3JvdGVQYXRoXG4gICAgICB9KVxuXG4gICAgY29uc3Qgc3RhcnRGZXRjaCA9IChcbiAgICAgIHJvd0lkOiBSb3dJZC5Sb3dJZCxcbiAgICAgIGtleTogdW5rbm93bixcbiAgICAgIGtleUhhc2g6IHN0cmluZyxcbiAgICAgIHJlcGxheU1vZGU6ICdsaXZlJyB8ICdyZXBsYXknLFxuICAgICAgcmVwbGF5TG9nOiBSZXBsYXlMb2cuUmVwbGF5TG9nU2VydmljZSB8IHVuZGVmaW5lZCxcbiAgICApOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBhbnk+ID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IHsgbW9kdWxlSWQsIGluc3RhbmNlSWQgfSA9IGdldEJvdW5kU2NvcGUoYm91bmQpXG5cbiAgICAgICAgY29uc3QgaW5kZXhGb3JMb2cgPSBzdG9yZS5nZXRJbmRleChsaXN0UGF0aCwgcm93SWQpXG4gICAgICAgIGNvbnN0IGxvZ0ZpZWxkUGF0aCA9XG4gICAgICAgICAgaW5kZXhGb3JMb2cgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IFJvd0lkLnRvTGlzdEl0ZW1WYWx1ZVBhdGgobGlzdFBhdGgsIGluZGV4Rm9yTG9nLCBpdGVtUGF0aClcblxuICAgICAgICBsZXQgbG9hZGluZ1NuYXBzaG90OiB1bmtub3duID0gU25hcHNob3QubG9hZGluZyh7IGtleUhhc2ggfSlcbiAgICAgICAgaWYgKHJlcGxheU1vZGUgPT09ICdyZXBsYXknICYmIHJlcGxheUxvZyAmJiBsb2dGaWVsZFBhdGgpIHtcbiAgICAgICAgICBjb25zdCByZXBsYXlMb2FkaW5nID0geWllbGQqIHJlcGxheUxvZy5jb25zdW1lTmV4dFJlc291cmNlU25hcHNob3Qoe1xuICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGZpZWxkUGF0aDogbG9nRmllbGRQYXRoLFxuICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgIHBoYXNlOiAnbG9hZGluZycsXG4gICAgICAgICAgfSlcbiAgICAgICAgICBpZiAocmVwbGF5TG9hZGluZykge1xuICAgICAgICAgICAgbG9hZGluZ1NuYXBzaG90ID0gcmVwbGF5TG9hZGluZy5zbmFwc2hvdFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCB3cm90ZUxvYWRpbmdQYXRoID0geWllbGQqIHNldFNuYXBzaG90Rm9yUm93SW5UeG4oXG4gICAgICAgICAgcm93SWQsXG4gICAgICAgICAgbG9hZGluZ1NuYXBzaG90LFxuICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgYHNvdXJjZToke2ZpZWxkUGF0aH06JHtyb3dJZH06bG9hZGluZ2AsXG4gICAgICAgIClcbiAgICAgICAgaWYgKHdyb3RlTG9hZGluZ1BhdGgpIHtcbiAgICAgICAgICBjb25zdCBldmVudDogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50ID0ge1xuICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGZpZWxkUGF0aDogd3JvdGVMb2FkaW5nUGF0aCxcbiAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICBjb25jdXJyZW5jeTogbW9kZSxcbiAgICAgICAgICAgIHBoYXNlOiAnbG9hZGluZycsXG4gICAgICAgICAgICBzbmFwc2hvdDogbG9hZGluZ1NuYXBzaG90LFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgIH1cbiAgICAgICAgICByZWNvcmRSZXBsYXlFdmVudChib3VuZCwgZXZlbnQpXG4gICAgICAgICAgeWllbGQqIHJlY29yZFNuYXBzaG90KHJlcGxheU1vZGUsIHJlcGxheUxvZywgZXZlbnQpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbyA9IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICBpZiAocmVwbGF5TW9kZSA9PT0gJ3JlcGxheScgJiYgcmVwbGF5TG9nKSB7XG4gICAgICAgICAgICAvLyBMZXQgbG9hZGluZyBjb21taXQgYmVjb21lIHZpc2libGUgZmlyc3QsIHRoZW4gcmVwbGF5IHRoZSBzZXR0bGVkIHBoYXNlIChwcmVzZXJ2ZSB0aGUgYXN5bmMtcmVzb3VyY2UgdGltZWxpbmUgc2hhcGUpLlxuICAgICAgICAgICAgeWllbGQqIEVmZmVjdC55aWVsZE5vdygpXG4gICAgICAgICAgICBjb25zdCBjb25zdW1lUGF0aCA9IHdyb3RlTG9hZGluZ1BhdGggPz8gbG9nRmllbGRQYXRoXG4gICAgICAgICAgICBpZiAoIWNvbnN1bWVQYXRoKSByZXR1cm4geWllbGQqIEVmZmVjdC52b2lkXG5cbiAgICAgICAgICAgIGNvbnN0IHJlcGxheWVkID0geWllbGQqIHJlcGxheUxvZy5jb25zdW1lTmV4dFJlc291cmNlU25hcHNob3Qoe1xuICAgICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgICBmaWVsZFBhdGg6IGNvbnN1bWVQYXRoLFxuICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGlmICghcmVwbGF5ZWQpIHJldHVybiB5aWVsZCogRWZmZWN0LnZvaWRcblxuICAgICAgICAgICAgaWYgKHJlcGxheWVkLnBoYXNlID09PSAnc3VjY2VzcycpIHtcbiAgICAgICAgICAgICAgeWllbGQqIHdyaXRlYmFja0lmQ3VycmVudEtleUhhc2hGb3JSb3coXG4gICAgICAgICAgICAgICAgcm93SWQsXG4gICAgICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgICAgICByZXBsYXllZC5zbmFwc2hvdCxcbiAgICAgICAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OiR7cm93SWR9OnN1Y2Nlc3NgLFxuICAgICAgICAgICAgICAgICdzdWNjZXNzJyxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfSBlbHNlIGlmIChyZXBsYXllZC5waGFzZSA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgICB5aWVsZCogd3JpdGViYWNrSWZDdXJyZW50S2V5SGFzaEZvclJvdyhcbiAgICAgICAgICAgICAgICByb3dJZCxcbiAgICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgICAgIHJlcGxheWVkLnNuYXBzaG90LFxuICAgICAgICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgICAgICAgYHNvdXJjZToke2ZpZWxkUGF0aH06JHtyb3dJZH06ZXJyb3JgLFxuICAgICAgICAgICAgICAgICdlcnJvcicsXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3Qudm9pZFxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHN0YWNrID0geWllbGQqIGdldE1pZGRsZXdhcmVTdGFjaygpXG5cbiAgICAgICAgICBjb25zdCByZWdpc3RyeU9wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihSZXNvdXJjZUludGVybmFsLlJlc291cmNlUmVnaXN0cnlUYWcpXG4gICAgICAgICAgY29uc3QgcmVnaXN0cnkgPSBPcHRpb24uaXNTb21lKHJlZ2lzdHJ5T3B0KSA/IHJlZ2lzdHJ5T3B0LnZhbHVlIDogdW5kZWZpbmVkXG4gICAgICAgICAgY29uc3Qgc3BlYyA9IHJlZ2lzdHJ5Py5zcGVjcy5nZXQocmVzb3VyY2VJZClcblxuICAgICAgICAgIGlmICghc3BlYykge1xuICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3Qudm9pZFxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGxvYWRFZmZlY3QgPSAoc3BlYy5sb2FkIGFzIGFueSkoa2V5KSBhcyBFZmZlY3QuRWZmZWN0PGFueSwgYW55LCBhbnk+XG5cbiAgICAgICAgICBjb25zdCBtZXRhOiBhbnkgPSB7XG4gICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgIHJvd0lkLFxuICAgICAgICAgICAgdHJhaXROb2RlSWQ6IHN0ZXAuZGVidWdJbmZvPy5ncmFwaE5vZGVJZCxcbiAgICAgICAgICAgIHN0ZXBJZDogc3RlcC5pZCxcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoISh0eXBlb2YgbWV0YS5vcFNlcSA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKG1ldGEub3BTZXEpKSkge1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbk9wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihSdW5TZXNzaW9uVGFnKVxuICAgICAgICAgICAgaWYgKE9wdGlvbi5pc1NvbWUoc2Vzc2lvbk9wdCkpIHtcbiAgICAgICAgICAgICAgY29uc3Qgc2VxS2V5ID0gaW5zdGFuY2VJZCA/PyAnZ2xvYmFsJ1xuICAgICAgICAgICAgICBtZXRhLm9wU2VxID0gc2Vzc2lvbk9wdC52YWx1ZS5sb2NhbC5uZXh0U2VxKCdvcFNlcScsIHNlcUtleSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBvcCA9IEVmZmVjdE9wLm1ha2U8YW55LCBhbnksIGFueT4oe1xuICAgICAgICAgICAga2luZDogJ3NlcnZpY2UnLFxuICAgICAgICAgICAgbmFtZTogcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGVmZmVjdDogbG9hZEVmZmVjdCxcbiAgICAgICAgICAgIG1ldGEsXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGNvbnN0IGV4aXQgPSB5aWVsZCogRWZmZWN0LmV4aXQoRWZmZWN0T3AucnVuKG9wLCBzdGFjaykpXG5cbiAgICAgICAgICBpZiAoZXhpdC5fdGFnID09PSAnU3VjY2VzcycpIHtcbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NTbmFwc2hvdCA9IFNuYXBzaG90LnN1Y2Nlc3MoeyBrZXlIYXNoLCBkYXRhOiBleGl0LnZhbHVlIH0pXG4gICAgICAgICAgICBjb25zdCB3cm90ZVN1Y2Nlc3NQYXRoID0geWllbGQqIHdyaXRlYmFja0lmQ3VycmVudEtleUhhc2hGb3JSb3coXG4gICAgICAgICAgICAgIHJvd0lkLFxuICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgICBzdWNjZXNzU25hcHNob3QsXG4gICAgICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OiR7cm93SWR9OnN1Y2Nlc3NgLFxuICAgICAgICAgICAgICAnc3VjY2VzcycsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBpZiAod3JvdGVTdWNjZXNzUGF0aCkge1xuICAgICAgICAgICAgICB5aWVsZCogcmVjb3JkU25hcHNob3QocmVwbGF5TW9kZSwgcmVwbGF5TG9nLCB7XG4gICAgICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgICAgICAgZmllbGRQYXRoOiB3cm90ZVN1Y2Nlc3NQYXRoLFxuICAgICAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICAgICAgY29uY3VycmVuY3k6IG1vZGUsXG4gICAgICAgICAgICAgICAgcGhhc2U6ICdzdWNjZXNzJyxcbiAgICAgICAgICAgICAgICBzbmFwc2hvdDogc3VjY2Vzc1NuYXBzaG90LFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvclNuYXBzaG90ID0gU25hcHNob3QuZXJyb3IoeyBrZXlIYXNoLCBlcnJvcjogZXhpdC5jYXVzZSB9KVxuICAgICAgICAgICAgY29uc3Qgd3JvdGVFcnJvclBhdGggPSB5aWVsZCogd3JpdGViYWNrSWZDdXJyZW50S2V5SGFzaEZvclJvdyhcbiAgICAgICAgICAgICAgcm93SWQsXG4gICAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICAgIGVycm9yU25hcHNob3QsXG4gICAgICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OiR7cm93SWR9OmVycm9yYCxcbiAgICAgICAgICAgICAgJ2Vycm9yJyxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGlmICh3cm90ZUVycm9yUGF0aCkge1xuICAgICAgICAgICAgICB5aWVsZCogcmVjb3JkU25hcHNob3QocmVwbGF5TW9kZSwgcmVwbGF5TG9nLCB7XG4gICAgICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgICAgICAgZmllbGRQYXRoOiB3cm90ZUVycm9yUGF0aCxcbiAgICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgICAgICAgIHBoYXNlOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgIHNuYXBzaG90OiBlcnJvclNuYXBzaG90LFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSkucGlwZShFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoKSA9PiBFZmZlY3Qudm9pZCkpXG5cbiAgICAgICAgLy8gbGlzdC5pdGVtOiBJTyBmaWJlcnMgbXVzdCBkZXRhY2ggZnJvbSB0aGUgc3luYy10cmFuc2FjdGlvbiBGaWJlclJlZjsgb3RoZXJ3aXNlIHRoZXknZCBiZSBtaXNjbGFzc2lmaWVkIGFzIFwiaW4gdHhuIHdpbmRvd1wiXG4gICAgICAgIC8vIGFuZCBibG9jayBzdWJzZXF1ZW50IHdyaXRlYmFjayBlbnRyeXBvaW50cy5cbiAgICAgICAgY29uc3QgZmliZXIgPSB5aWVsZCogRWZmZWN0LmZvcmtTY29wZWQoRWZmZWN0LmxvY2FsbHkoVGFza1J1bm5lci5pblN5bmNUcmFuc2FjdGlvbkZpYmVyLCBmYWxzZSkoaW8pKVxuICAgICAgICBjb25zdCBteUdlbiA9IChnZW4gKz0gMSlcbiAgICAgICAgaW5GbGlnaHQuc2V0KHJvd0lkLCB7IGdlbjogbXlHZW4sIGZpYmVyLCBrZXlIYXNoIH0pXG5cbiAgICAgICAgeWllbGQqIEVmZmVjdC5mb3JrU2NvcGVkKFxuICAgICAgICAgIEVmZmVjdC5sb2NhbGx5KFxuICAgICAgICAgICAgVGFza1J1bm5lci5pblN5bmNUcmFuc2FjdGlvbkZpYmVyLFxuICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgKShcbiAgICAgICAgICAgIEZpYmVyLmF3YWl0KGZpYmVyKS5waXBlKFxuICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQoXG4gICAgICAgICAgICAgICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudCA9IGluRmxpZ2h0LmdldChyb3dJZClcbiAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ICYmIGN1cnJlbnQuZ2VuID09PSBteUdlbikge1xuICAgICAgICAgICAgICAgICAgICBpbkZsaWdodC5kZWxldGUocm93SWQpXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIEVmZmVjdC56aXBSaWdodChcbiAgICAgICAgICAgICAgICBtb2RlID09PSAnZXhoYXVzdC10cmFpbGluZydcbiAgICAgICAgICAgICAgICAgID8gRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHQgPSB0cmFpbGluZy5nZXQocm93SWQpXG4gICAgICAgICAgICAgICAgICAgICAgdHJhaWxpbmcuZGVsZXRlKHJvd0lkKVxuICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB5aWVsZCogc3RhcnRGZXRjaChyb3dJZCwgbmV4dC5rZXksIG5leHQua2V5SGFzaCwgcmVwbGF5TW9kZSwgcmVwbGF5TG9nKVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgIDogRWZmZWN0LnZvaWQsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIEVmZmVjdC5jYXRjaEFsbENhdXNlKCgpID0+IEVmZmVjdC52b2lkKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKSxcbiAgICAgICAgKVxuICAgICAgfSlcblxuICAgIHJlZ2lzdGVyKGZpZWxkUGF0aCwgKHN0YXRlOiBhbnkpID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IHsgbW9kdWxlSWQsIGluc3RhbmNlSWQgfSA9IGdldEJvdW5kU2NvcGUoYm91bmQpXG4gICAgICAgIGNvbnN0IHJlcGxheU1vZGVPcHQgPSB5aWVsZCogRWZmZWN0LnNlcnZpY2VPcHRpb24oUmVwbGF5TW9kZUNvbmZpZ1RhZylcbiAgICAgICAgY29uc3QgcmVwbGF5TW9kZSA9IE9wdGlvbi5pc1NvbWUocmVwbGF5TW9kZU9wdCkgPyByZXBsYXlNb2RlT3B0LnZhbHVlLm1vZGUgOiAnbGl2ZSdcbiAgICAgICAgY29uc3QgcmVwbGF5TG9nT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKFJlcGxheUxvZy5SZXBsYXlMb2cpXG4gICAgICAgIGNvbnN0IHJlcGxheUxvZyA9IE9wdGlvbi5pc1NvbWUocmVwbGF5TG9nT3B0KSA/IHJlcGxheUxvZ09wdC52YWx1ZSA6IHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBmb3JjZSA9IHlpZWxkKiBGaWJlclJlZi5nZXQoVGFza1J1bm5lci5mb3JjZVNvdXJjZVJlZnJlc2gpXG5cbiAgICAgICAgY29uc3QgbGlzdFZhbHVlID0gUm93SWQuZ2V0QXRQYXRoKHN0YXRlLCBsaXN0UGF0aClcbiAgICAgICAgY29uc3QgaXRlbXM6IFJlYWRvbmx5QXJyYXk8dW5rbm93bj4gPSBBcnJheS5pc0FycmF5KGxpc3RWYWx1ZSkgPyBsaXN0VmFsdWUgOiBbXVxuICAgICAgICBjb25zdCBpZHMgPSBzdG9yZS5lbnN1cmVMaXN0KGxpc3RQYXRoLCBpdGVtcylcblxuICAgICAgICAvLyBkZXYtbW9kZTogdHJhY2UgZGVwcyBvbmNlIGZvciB0aGUgZmlyc3Qgcm93IChkaWFnbm9zdGljcyBvbmx5OyBkb2VzIG5vdCBhZmZlY3QgZXhlY3V0aW9uIHNlbWFudGljcykuXG4gICAgICAgIGNvbnN0IHRyYWNlS2V5ID0gYCR7aW5zdGFuY2VJZCA/PyAndW5rbm93bid9Ojpzb3VyY2U6OiR7ZmllbGRQYXRofWBcbiAgICAgICAgaWYgKGlzRGV2RW52KCkgJiYgKHlpZWxkKiBvbmNlSW5SdW5TZXNzaW9uKGBkZXBzX3RyYWNlX3NldHRsZWQ6JHt0cmFjZUtleX1gKSkpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc2FtcGxlID0gaXRlbXNbMF1cbiAgICAgICAgICAgIGlmIChzYW1wbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICBjb25zdCB0cmFjZWQgPSBEZXBzVHJhY2UudHJhY2UoKHMpID0+IChlbnRyeS5tZXRhIGFzIGFueSkua2V5KHMpLCBzYW1wbGUgYXMgYW55KVxuICAgICAgICAgICAgICBjb25zdCBwcmVmaXhlZFJlYWRzID0gdHJhY2VkLnJlYWRzLm1hcCgocikgPT4gKHIgPyBgJHtsaXN0UGF0aH1bXS4ke3J9YCA6IGAke2xpc3RQYXRofVtdYCkpXG4gICAgICAgICAgICAgIGNvbnN0IGRpZmYgPSBEZXBzVHJhY2UuZGlmZkRlcHMoKChlbnRyeS5tZXRhIGFzIGFueSkuZGVwcyA/PyBbXSkgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+LCBwcmVmaXhlZFJlYWRzKVxuICAgICAgICAgICAgICBpZiAoZGlmZikge1xuICAgICAgICAgICAgICAgIHlpZWxkKiBlbWl0RGVwc01pc21hdGNoKHtcbiAgICAgICAgICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgICAgIGtpbmQ6ICdzb3VyY2UnLFxuICAgICAgICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAgICAgICAgZGlmZixcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyB0cmFjaW5nIGZhaWx1cmUgc2hvdWxkIG5ldmVyIGJyZWFrIHJlZnJlc2ggZmxvd1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBpdGVtcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICBjb25zdCByb3dJZCA9IGlkc1tpbmRleF1cbiAgICAgICAgICBpZiAoIXJvd0lkKSBjb250aW51ZVxuXG4gICAgICAgICAgY29uc3QgY29uY3JldGVQYXRoID0gUm93SWQudG9MaXN0SXRlbVZhbHVlUGF0aChsaXN0UGF0aCwgaW5kZXgsIGl0ZW1QYXRoKVxuICAgICAgICAgIGNvbnN0IHByZXZTbmFwc2hvdCA9IFJvd0lkLmdldEF0UGF0aChzdGF0ZSwgY29uY3JldGVQYXRoKSBhcyBhbnlcblxuICAgICAgICAgIGxldCBrZXk6IHVua25vd25cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAga2V5ID0gKGVudHJ5Lm1ldGEgYXMgYW55KS5rZXkoaXRlbXNbaW5kZXhdKVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAga2V5ID0gdW5kZWZpbmVkXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY3VycmVudCA9IGluRmxpZ2h0LmdldChyb3dJZClcblxuICAgICAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdHJhaWxpbmcuZGVsZXRlKHJvd0lkKVxuICAgICAgICAgICAgaW5GbGlnaHQuZGVsZXRlKHJvd0lkKVxuXG4gICAgICAgICAgICAvLyBJZiBpdCdzIGFscmVhZHkgY2xlYW4gaWRsZSwgYXZvaWQgcmVkdW5kYW50IHdyaXRlYmFjayAocHJldmVudHMgbWVhbmluZ2xlc3MgcGF0Y2hlcyBhbmQgVUkgaml0dGVyKS5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgcHJldlNuYXBzaG90ICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBwcmV2U25hcHNob3QgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICAgIHByZXZTbmFwc2hvdC5zdGF0dXMgPT09ICdpZGxlJyAmJlxuICAgICAgICAgICAgICBwcmV2U25hcHNob3QuZGF0YSA9PT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgIHByZXZTbmFwc2hvdC5lcnJvciA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgaWRsZVNuYXBzaG90ID0gU25hcHNob3QuaWRsZSgpXG4gICAgICAgICAgICBjb25zdCB3cm90ZUlkbGVQYXRoID0geWllbGQqIHNldFNuYXBzaG90Rm9yUm93SW5UeG4oXG4gICAgICAgICAgICAgIHJvd0lkLFxuICAgICAgICAgICAgICBpZGxlU25hcHNob3QsXG4gICAgICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OiR7cm93SWR9OmlkbGVgLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgaWYgKHdyb3RlSWRsZVBhdGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXZlbnQ6IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudCA9IHtcbiAgICAgICAgICAgICAgICBfdGFnOiAnUmVzb3VyY2VTbmFwc2hvdCcsXG4gICAgICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBmaWVsZFBhdGg6IHdyb3RlSWRsZVBhdGgsXG4gICAgICAgICAgICAgICAga2V5SGFzaDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgICAgICAgIHBoYXNlOiAnaWRsZScsXG4gICAgICAgICAgICAgICAgc25hcHNob3Q6IGlkbGVTbmFwc2hvdCxcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZWNvcmRSZXBsYXlFdmVudChib3VuZCwgZXZlbnQpXG4gICAgICAgICAgICAgIHlpZWxkKiByZWNvcmRTbmFwc2hvdChyZXBsYXlNb2RlLCByZXBsYXlMb2csIGV2ZW50KVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBoID0gaGFzaEtleShrZXkpXG5cbiAgICAgICAgICAvLyBrZXlIYXNoIHVuY2hhbmdlZDogYXZvaWQgcmVkdW5kYW50IHJlZnJlc2ggd2hpbGUga2VlcGluZyBpbi1mbGlnaHQuXG4gICAgICAgICAgaWYgKCFmb3JjZSAmJiBjdXJyZW50ICYmIGN1cnJlbnQua2V5SGFzaCA9PT0gaCkge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBOb3QgaW4tZmxpZ2h0OiBpZiBzbmFwc2hvdC5rZXlIYXNoIGFscmVhZHkgbWF0Y2hlcywgdHJlYXQgaXQgYXMgYWxyZWFkeSB1cC10by1kYXRlIChhdm9pZCBmdWxsIHJlZnJlc2ggYW5kIHJvdyBqaXR0ZXIpLlxuICAgICAgICAgIGNvbnN0IHByZXZLZXlIYXNoID1cbiAgICAgICAgICAgIHByZXZTbmFwc2hvdCAmJiB0eXBlb2YgcHJldlNuYXBzaG90ID09PSAnb2JqZWN0JyA/IChwcmV2U25hcHNob3QgYXMgYW55KS5rZXlIYXNoIDogdW5kZWZpbmVkXG4gICAgICAgICAgaWYgKCFmb3JjZSAmJiAhY3VycmVudCAmJiBwcmV2S2V5SGFzaCA9PT0gaCkge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobW9kZSA9PT0gJ2V4aGF1c3QtdHJhaWxpbmcnICYmIGN1cnJlbnQpIHtcbiAgICAgICAgICAgIHRyYWlsaW5nLnNldChyb3dJZCwgeyBrZXksIGtleUhhc2g6IGggfSlcbiAgICAgICAgICAgIGNvbnN0IGxvYWRpbmdTbmFwc2hvdCA9IFNuYXBzaG90LmxvYWRpbmcoeyBrZXlIYXNoOiBoIH0pXG4gICAgICAgICAgICBjb25zdCB3cm90ZUxvYWRpbmdQYXRoID0geWllbGQqIHNldFNuYXBzaG90Rm9yUm93SW5UeG4oXG4gICAgICAgICAgICAgIHJvd0lkLFxuICAgICAgICAgICAgICBsb2FkaW5nU25hcHNob3QsXG4gICAgICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OiR7cm93SWR9OmxvYWRpbmdgLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgaWYgKHdyb3RlTG9hZGluZ1BhdGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXZlbnQ6IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudCA9IHtcbiAgICAgICAgICAgICAgICBfdGFnOiAnUmVzb3VyY2VTbmFwc2hvdCcsXG4gICAgICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBmaWVsZFBhdGg6IHdyb3RlTG9hZGluZ1BhdGgsXG4gICAgICAgICAgICAgICAga2V5SGFzaDogaCxcbiAgICAgICAgICAgICAgICBjb25jdXJyZW5jeTogbW9kZSxcbiAgICAgICAgICAgICAgICBwaGFzZTogJ2xvYWRpbmcnLFxuICAgICAgICAgICAgICAgIHNuYXBzaG90OiBsb2FkaW5nU25hcHNob3QsXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVjb3JkUmVwbGF5RXZlbnQoYm91bmQsIGV2ZW50KVxuICAgICAgICAgICAgICB5aWVsZCogcmVjb3JkU25hcHNob3QocmVwbGF5TW9kZSwgcmVwbGF5TG9nLCBldmVudClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG1vZGUgPT09ICdzd2l0Y2gnICYmIGN1cnJlbnQpIHtcbiAgICAgICAgICAgIC8vIERvIG5vdCByZWx5IG9uIGNhbmNlbGxhdGlvbiBjb3JyZWN0bmVzczogc3RhbGUgd3JpdGViYWNrcyBhcmUgZHJvcHBlZCBieSB0aGUga2V5SGFzaCBnYXRlLlxuICAgICAgICAgICAgdHJhaWxpbmcuZGVsZXRlKHJvd0lkKVxuICAgICAgICAgICAgaW5GbGlnaHQuZGVsZXRlKHJvd0lkKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHlpZWxkKiBzdGFydEZldGNoKHJvd0lkLCBrZXksIGgsIHJlcGxheU1vZGUsIHJlcGxheUxvZylcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgKVxuXG4gICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gIH1cblxuICAvLyBpbi1mbGlnaHQgc3RhdGUgKHBlciBmaWVsZClcbiAgbGV0IGluRmxpZ2h0OlxuICAgIHwge1xuICAgICAgICByZWFkb25seSBnZW46IG51bWJlclxuICAgICAgICByZWFkb25seSBmaWJlcjogRmliZXIuUnVudGltZUZpYmVyPHZvaWQsIG5ldmVyPlxuICAgICAgICByZWFkb25seSBrZXlIYXNoOiBzdHJpbmdcbiAgICAgIH1cbiAgICB8IHVuZGVmaW5lZFxuICBsZXQgZ2VuID0gMFxuICBsZXQgdHJhaWxpbmc6IHsgcmVhZG9ubHkga2V5OiB1bmtub3duOyByZWFkb25seSBrZXlIYXNoOiBzdHJpbmcgfSB8IHVuZGVmaW5lZFxuXG4gIGNvbnN0IGNvbmN1cnJlbmN5ID0gKGVudHJ5Lm1ldGEgYXMgYW55KS5jb25jdXJyZW5jeSBhcyAnc3dpdGNoJyB8ICdleGhhdXN0LXRyYWlsaW5nJyB8IHVuZGVmaW5lZFxuICBjb25zdCBtb2RlID0gY29uY3VycmVuY3kgPz8gJ3N3aXRjaCdcblxuICBjb25zdCBzdGFydEZldGNoID0gKFxuICAgIGtleTogdW5rbm93bixcbiAgICBrZXlIYXNoOiBzdHJpbmcsXG4gICAgcmVwbGF5TW9kZTogJ2xpdmUnIHwgJ3JlcGxheScsXG4gICAgcmVwbGF5TG9nOiBSZXBsYXlMb2cuUmVwbGF5TG9nU2VydmljZSB8IHVuZGVmaW5lZCxcbiAgKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgYW55PiA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IHsgbW9kdWxlSWQsIGluc3RhbmNlSWQgfSA9IGdldEJvdW5kU2NvcGUoYm91bmQpXG5cbiAgICAgIC8vIDEpIHBlbmRpbmc6IHN5bmNocm9ub3VzbHkgd3JpdGUgYSBsb2FkaW5nIHNuYXBzaG90ICh3aXRoaW4gdGhlIGN1cnJlbnQgdHJhbnNhY3Rpb24gd2luZG93KS5cbiAgICAgIGxldCBsb2FkaW5nU25hcHNob3Q6IHVua25vd24gPSBTbmFwc2hvdC5sb2FkaW5nKHsga2V5SGFzaCB9KVxuICAgICAgaWYgKHJlcGxheU1vZGUgPT09ICdyZXBsYXknICYmIHJlcGxheUxvZykge1xuICAgICAgICBjb25zdCByZXBsYXlMb2FkaW5nID0geWllbGQqIHJlcGxheUxvZy5jb25zdW1lTmV4dFJlc291cmNlU25hcHNob3Qoe1xuICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgcGhhc2U6ICdsb2FkaW5nJyxcbiAgICAgICAgfSlcbiAgICAgICAgaWYgKHJlcGxheUxvYWRpbmcpIHtcbiAgICAgICAgICBsb2FkaW5nU25hcHNob3QgPSByZXBsYXlMb2FkaW5nLnNuYXBzaG90XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IHdyb3RlTG9hZGluZyA9IHlpZWxkKiBzZXRTbmFwc2hvdEluVHhuKFxuICAgICAgICBib3VuZCxcbiAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICBsb2FkaW5nU25hcHNob3QsXG4gICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OmxvYWRpbmdgLFxuICAgICAgICBzdGVwLmRlYnVnSW5mbz8uZ3JhcGhOb2RlSWQsXG4gICAgICApXG4gICAgICBpZiAod3JvdGVMb2FkaW5nKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50OiBSZXBsYXlMb2cuUmVwbGF5TG9nRXZlbnQgPSB7XG4gICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgY29uY3VycmVuY3k6IG1vZGUsXG4gICAgICAgICAgcGhhc2U6ICdsb2FkaW5nJyxcbiAgICAgICAgICBzbmFwc2hvdDogbG9hZGluZ1NuYXBzaG90LFxuICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICB9XG4gICAgICAgIHJlY29yZFJlcGxheUV2ZW50KGJvdW5kLCBldmVudClcbiAgICAgICAgeWllbGQqIHJlY29yZFNuYXBzaG90KHJlcGxheU1vZGUsIHJlcGxheUxvZywgZXZlbnQpXG4gICAgICB9XG5cbiAgICAgIC8vIDIpIElPOiBydW4gaW4gYSBiYWNrZ3JvdW5kIGZpYmVyIChhdm9pZCBibG9ja2luZyB0aGUgY3VycmVudCB0cmFuc2FjdGlvbikuXG4gICAgICBjb25zdCBpbyA9IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgaWYgKHJlcGxheU1vZGUgPT09ICdyZXBsYXknICYmIHJlcGxheUxvZykge1xuICAgICAgICAgIC8vIExldCBsb2FkaW5nIGNvbW1pdCBiZWNvbWUgdmlzaWJsZSBmaXJzdCwgdGhlbiByZXBsYXkgdGhlIHNldHRsZWQgcGhhc2UgKHByZXNlcnZlIHRoZSBhc3luYy1yZXNvdXJjZSB0aW1lbGluZSBzaGFwZSkuXG4gICAgICAgICAgeWllbGQqIEVmZmVjdC55aWVsZE5vdygpXG4gICAgICAgICAgY29uc3QgcmVwbGF5ZWQgPSB5aWVsZCogcmVwbGF5TG9nLmNvbnN1bWVOZXh0UmVzb3VyY2VTbmFwc2hvdCh7XG4gICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICB9KVxuICAgICAgICAgIGlmICghcmVwbGF5ZWQpIHJldHVybiB5aWVsZCogRWZmZWN0LnZvaWRcblxuICAgICAgICAgIGlmIChyZXBsYXllZC5waGFzZSA9PT0gJ3N1Y2Nlc3MnKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudDogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50ID0ge1xuICAgICAgICAgICAgICBfdGFnOiAnUmVzb3VyY2VTbmFwc2hvdCcsXG4gICAgICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgICAgY29uY3VycmVuY3k6IG1vZGUsXG4gICAgICAgICAgICAgIHBoYXNlOiAnc3VjY2VzcycsXG4gICAgICAgICAgICAgIHNuYXBzaG90OiByZXBsYXllZC5zbmFwc2hvdCxcbiAgICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHlpZWxkKiB3cml0ZWJhY2tJZkN1cnJlbnRLZXlIYXNoKFxuICAgICAgICAgICAgICBib3VuZCxcbiAgICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgICByZXBsYXllZC5zbmFwc2hvdCxcbiAgICAgICAgICAgICAgJ3NvdXJjZS1yZWZyZXNoJyxcbiAgICAgICAgICAgICAgYHNvdXJjZToke2ZpZWxkUGF0aH06c3VjY2Vzc2AsXG4gICAgICAgICAgICAgIHN0ZXAuZGVidWdJbmZvPy5ncmFwaE5vZGVJZCxcbiAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICApXG4gICAgICAgICAgfSBlbHNlIGlmIChyZXBsYXllZC5waGFzZSA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQ6IFJlcGxheUxvZy5SZXBsYXlMb2dFdmVudCA9IHtcbiAgICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgICAgICBwaGFzZTogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgc25hcHNob3Q6IHJlcGxheWVkLnNuYXBzaG90LFxuICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeWllbGQqIHdyaXRlYmFja0lmQ3VycmVudEtleUhhc2goXG4gICAgICAgICAgICAgIGJvdW5kLFxuICAgICAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgICAgIHJlcGxheWVkLnNuYXBzaG90LFxuICAgICAgICAgICAgICAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofTplcnJvcmAsXG4gICAgICAgICAgICAgIHN0ZXAuZGVidWdJbmZvPy5ncmFwaE5vZGVJZCxcbiAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICApXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3Qudm9pZFxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3RhY2sgPSB5aWVsZCogZ2V0TWlkZGxld2FyZVN0YWNrKClcblxuICAgICAgICBjb25zdCByZWdpc3RyeU9wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihSZXNvdXJjZUludGVybmFsLlJlc291cmNlUmVnaXN0cnlUYWcpXG4gICAgICAgIGNvbnN0IHJlZ2lzdHJ5ID0gT3B0aW9uLmlzU29tZShyZWdpc3RyeU9wdCkgPyByZWdpc3RyeU9wdC52YWx1ZSA6IHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBzcGVjID0gcmVnaXN0cnk/LnNwZWNzLmdldChyZXNvdXJjZUlkKVxuXG4gICAgICAgIGlmICghc3BlYykge1xuICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LnZvaWRcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxvYWRFZmZlY3QgPSAoc3BlYy5sb2FkIGFzIGFueSkoa2V5KSBhcyBFZmZlY3QuRWZmZWN0PGFueSwgYW55LCBhbnk+XG5cbiAgICAgICAgY29uc3QgbWV0YTogYW55ID0ge1xuICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAga2V5LFxuICAgICAgICAgIGtleUhhc2gsXG4gICAgICAgICAgdHJhaXROb2RlSWQ6IHN0ZXAuZGVidWdJbmZvPy5ncmFwaE5vZGVJZCxcbiAgICAgICAgICBzdGVwSWQ6IHN0ZXAuaWQsXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISh0eXBlb2YgbWV0YS5vcFNlcSA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKG1ldGEub3BTZXEpKSkge1xuICAgICAgICAgIGNvbnN0IHNlc3Npb25PcHQgPSB5aWVsZCogRWZmZWN0LnNlcnZpY2VPcHRpb24oUnVuU2Vzc2lvblRhZylcbiAgICAgICAgICBpZiAoT3B0aW9uLmlzU29tZShzZXNzaW9uT3B0KSkge1xuICAgICAgICAgICAgY29uc3Qgc2VxS2V5ID0gaW5zdGFuY2VJZCA/PyAnZ2xvYmFsJ1xuICAgICAgICAgICAgbWV0YS5vcFNlcSA9IHNlc3Npb25PcHQudmFsdWUubG9jYWwubmV4dFNlcSgnb3BTZXEnLCBzZXFLZXkpXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3AgPSBFZmZlY3RPcC5tYWtlPGFueSwgYW55LCBhbnk+KHtcbiAgICAgICAgICBraW5kOiAndHJhaXQtc291cmNlJyxcbiAgICAgICAgICBuYW1lOiByZXNvdXJjZUlkLFxuICAgICAgICAgIGVmZmVjdDogbG9hZEVmZmVjdCxcbiAgICAgICAgICBtZXRhLFxuICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IGV4aXQgPSB5aWVsZCogRWZmZWN0LmV4aXQoRWZmZWN0T3AucnVuKG9wLCBzdGFjaykpXG5cbiAgICAgICAgLy8gMykgd3JpdGViYWNrOiB1c2UgYSBrZXlIYXNoIGdhdGUgdG8gcHJldmVudCBzdGFsZSByZXN1bHRzIGZyb20gd3JpdGluZyBiYWNrIG9udG8gYSBuZXcga2V5LlxuICAgICAgICBpZiAoZXhpdC5fdGFnID09PSAnU3VjY2VzcycpIHtcbiAgICAgICAgICBjb25zdCBzdWNjZXNzU25hcHNob3QgPSBTbmFwc2hvdC5zdWNjZXNzKHsga2V5SGFzaCwgZGF0YTogZXhpdC52YWx1ZSB9KVxuICAgICAgICAgIGNvbnN0IGV2ZW50OiBSZXBsYXlMb2cuUmVwbGF5TG9nRXZlbnQgPSB7XG4gICAgICAgICAgICBfdGFnOiAnUmVzb3VyY2VTbmFwc2hvdCcsXG4gICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgICAgcGhhc2U6ICdzdWNjZXNzJyxcbiAgICAgICAgICAgIHNuYXBzaG90OiBzdWNjZXNzU25hcHNob3QsXG4gICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgIGluc3RhbmNlSWQsXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHdyb3RlU3VjY2VzcyA9IHlpZWxkKiB3cml0ZWJhY2tJZkN1cnJlbnRLZXlIYXNoKFxuICAgICAgICAgICAgYm91bmQsXG4gICAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgc3VjY2Vzc1NuYXBzaG90LFxuICAgICAgICAgICAgJ3NvdXJjZS1yZWZyZXNoJyxcbiAgICAgICAgICAgIGBzb3VyY2U6JHtmaWVsZFBhdGh9OnN1Y2Nlc3NgLFxuICAgICAgICAgICAgc3RlcC5kZWJ1Z0luZm8/LmdyYXBoTm9kZUlkLFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgKVxuICAgICAgICAgIGlmICh3cm90ZVN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIHlpZWxkKiByZWNvcmRTbmFwc2hvdChyZXBsYXlNb2RlLCByZXBsYXlMb2csIGV2ZW50KVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBlcnJvclNuYXBzaG90ID0gU25hcHNob3QuZXJyb3IoeyBrZXlIYXNoLCBlcnJvcjogZXhpdC5jYXVzZSB9KVxuICAgICAgICAgIGNvbnN0IGV2ZW50OiBSZXBsYXlMb2cuUmVwbGF5TG9nRXZlbnQgPSB7XG4gICAgICAgICAgICBfdGFnOiAnUmVzb3VyY2VTbmFwc2hvdCcsXG4gICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAga2V5SGFzaCxcbiAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBtb2RlLFxuICAgICAgICAgICAgcGhhc2U6ICdlcnJvcicsXG4gICAgICAgICAgICBzbmFwc2hvdDogZXJyb3JTbmFwc2hvdCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgd3JvdGVFcnJvciA9IHlpZWxkKiB3cml0ZWJhY2tJZkN1cnJlbnRLZXlIYXNoKFxuICAgICAgICAgICAgYm91bmQsXG4gICAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgICBrZXlIYXNoLFxuICAgICAgICAgICAgZXJyb3JTbmFwc2hvdCxcbiAgICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofTplcnJvcmAsXG4gICAgICAgICAgICBzdGVwLmRlYnVnSW5mbz8uZ3JhcGhOb2RlSWQsXG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICApXG4gICAgICAgICAgaWYgKHdyb3RlRXJyb3IpIHtcbiAgICAgICAgICAgIHlpZWxkKiByZWNvcmRTbmFwc2hvdChyZXBsYXlNb2RlLCByZXBsYXlMb2csIGV2ZW50KVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSkucGlwZShFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoKSA9PiBFZmZlY3Qudm9pZCkpXG5cbiAgICAgIC8vIERvIG5vdCB3YWl0IGZvciBJTyBjb21wbGV0aW9uOiBmb3JrU2NvcGVkIGludG8gdGhlIHJ1bnRpbWUgc2NvcGUgc28gdW5tb3VudCB3aWxsIGludGVycnVwdCBhdXRvbWF0aWNhbGx5LlxuICAgICAgY29uc3QgZmliZXIgPSB5aWVsZCogRWZmZWN0LmZvcmtTY29wZWQoRWZmZWN0LmxvY2FsbHkoVGFza1J1bm5lci5pblN5bmNUcmFuc2FjdGlvbkZpYmVyLCBmYWxzZSkoaW8pKVxuICAgICAgY29uc3QgbXlHZW4gPSAoZ2VuICs9IDEpXG4gICAgICBpbkZsaWdodCA9IHsgZ2VuOiBteUdlbiwgZmliZXIsIGtleUhhc2ggfVxuXG4gICAgICAvLyBBZnRlciBpbi1mbGlnaHQgY29tcGxldGVzLCBjbGVhbiB1cDsgaW4gZXhoYXVzdC10cmFpbGluZyBtb2RlLCBydW4gb25lIHRyYWlsaW5nIGZldGNoIGlmIHByZXNlbnQuXG4gICAgICB5aWVsZCogRWZmZWN0LmZvcmtTY29wZWQoXG4gICAgICAgIEVmZmVjdC5sb2NhbGx5KFxuICAgICAgICAgIFRhc2tSdW5uZXIuaW5TeW5jVHJhbnNhY3Rpb25GaWJlcixcbiAgICAgICAgICBmYWxzZSxcbiAgICAgICAgKShcbiAgICAgICAgICBGaWJlci5hd2FpdChmaWJlcikucGlwZShcbiAgICAgICAgICAgIEVmZmVjdC56aXBSaWdodChcbiAgICAgICAgICAgICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpbkZsaWdodCAmJiBpbkZsaWdodC5nZW4gPT09IG15R2VuKSB7XG4gICAgICAgICAgICAgICAgICBpbkZsaWdodCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgRWZmZWN0LnppcFJpZ2h0KFxuICAgICAgICAgICAgICBtb2RlID09PSAnZXhoYXVzdC10cmFpbGluZydcbiAgICAgICAgICAgICAgICA/IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dCA9IHRyYWlsaW5nXG4gICAgICAgICAgICAgICAgICAgIHRyYWlsaW5nID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgeWllbGQqIHN0YXJ0RmV0Y2gobmV4dC5rZXksIG5leHQua2V5SGFzaCwgcmVwbGF5TW9kZSwgcmVwbGF5TG9nKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIDogRWZmZWN0LnZvaWQsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgRWZmZWN0LmNhdGNoQWxsQ2F1c2UoKCkgPT4gRWZmZWN0LnZvaWQpLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApXG4gICAgfSlcblxuICByZWdpc3RlcihmaWVsZFBhdGgsIChzdGF0ZTogYW55KSA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IHsgbW9kdWxlSWQsIGluc3RhbmNlSWQgfSA9IGdldEJvdW5kU2NvcGUoYm91bmQpXG4gICAgICBjb25zdCByZXBsYXlNb2RlT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKFJlcGxheU1vZGVDb25maWdUYWcpXG4gICAgICBjb25zdCByZXBsYXlNb2RlID0gT3B0aW9uLmlzU29tZShyZXBsYXlNb2RlT3B0KSA/IHJlcGxheU1vZGVPcHQudmFsdWUubW9kZSA6ICdsaXZlJ1xuICAgICAgY29uc3QgcmVwbGF5TG9nT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKFJlcGxheUxvZy5SZXBsYXlMb2cpXG4gICAgICBjb25zdCByZXBsYXlMb2cgPSBPcHRpb24uaXNTb21lKHJlcGxheUxvZ09wdCkgPyByZXBsYXlMb2dPcHQudmFsdWUgOiB1bmRlZmluZWRcbiAgICAgIGNvbnN0IGZvcmNlID0geWllbGQqIEZpYmVyUmVmLmdldChUYXNrUnVubmVyLmZvcmNlU291cmNlUmVmcmVzaClcblxuICAgICAgbGV0IGtleTogdW5rbm93blxuICAgICAgdHJ5IHtcbiAgICAgICAga2V5ID0gKGVudHJ5Lm1ldGEgYXMgYW55KS5rZXkoc3RhdGUpXG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAga2V5ID0gdW5kZWZpbmVkXG4gICAgICB9XG5cbiAgICAgIC8vIGRldi1tb2RlOiBkZXRlY3QgbWlzbWF0Y2ggYmV0d2VlbiBhY3R1YWwgcmVhZHMgaW4ga2V5U2VsZWN0b3IgYW5kIGRlY2xhcmVkIGRlcHMgKGRpYWdub3N0aWNzIG9ubHk7IGRvZXMgbm90IGFmZmVjdCBleGVjdXRpb24gc2VtYW50aWNzKS5cbiAgICAgIGNvbnN0IHRyYWNlS2V5ID0gYCR7aW5zdGFuY2VJZCA/PyAndW5rbm93bid9Ojpzb3VyY2U6OiR7ZmllbGRQYXRofWBcbiAgICAgIGlmIChpc0RldkVudigpICYmICh5aWVsZCogb25jZUluUnVuU2Vzc2lvbihgZGVwc190cmFjZV9zZXR0bGVkOiR7dHJhY2VLZXl9YCkpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgdHJhY2VkID0gRGVwc1RyYWNlLnRyYWNlKChzKSA9PiAoZW50cnkubWV0YSBhcyBhbnkpLmtleShzKSwgc3RhdGUpXG4gICAgICAgICAgY29uc3QgZGlmZiA9IERlcHNUcmFjZS5kaWZmRGVwcygoKGVudHJ5Lm1ldGEgYXMgYW55KS5kZXBzID8/IFtdKSBhcyBSZWFkb25seUFycmF5PHN0cmluZz4sIHRyYWNlZC5yZWFkcylcbiAgICAgICAgICBpZiAoZGlmZikge1xuICAgICAgICAgICAgeWllbGQqIGVtaXREZXBzTWlzbWF0Y2goe1xuICAgICAgICAgICAgICBtb2R1bGVJZCxcbiAgICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAga2luZDogJ3NvdXJjZScsXG4gICAgICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICAgICAgZGlmZixcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAvLyB0cmFjaW5nIGZhaWx1cmUgc2hvdWxkIG5ldmVyIGJyZWFrIHJlZnJlc2ggZmxvd1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEtleSBiZWNvbWVzIGVtcHR5OiBzeW5jaHJvbm91c2x5IGNsZWFyIHRvIGlkbGUgKGFuZCBpbnRlcnJ1cHQgaW4tZmxpZ2h0KS5cbiAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoaW5GbGlnaHQpIHtcbiAgICAgICAgICB5aWVsZCogRmliZXIuaW50ZXJydXB0Rm9yayhpbkZsaWdodC5maWJlcilcbiAgICAgICAgICBpbkZsaWdodCA9IHVuZGVmaW5lZFxuICAgICAgICB9XG4gICAgICAgIHRyYWlsaW5nID0gdW5kZWZpbmVkXG5cbiAgICAgICAgY29uc3QgaWRsZVNuYXBzaG90ID0gU25hcHNob3QuaWRsZSgpXG4gICAgICAgIGNvbnN0IHdyb3RlSWRsZSA9IHlpZWxkKiBzZXRTbmFwc2hvdEluVHhuKFxuICAgICAgICAgIGJvdW5kLFxuICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICBpZGxlU25hcHNob3QsXG4gICAgICAgICAgJ3NvdXJjZS1yZWZyZXNoJyxcbiAgICAgICAgICBgc291cmNlOiR7ZmllbGRQYXRofTppZGxlYCxcbiAgICAgICAgICBzdGVwLmRlYnVnSW5mbz8uZ3JhcGhOb2RlSWQsXG4gICAgICAgIClcbiAgICAgICAgaWYgKHdyb3RlSWRsZSkge1xuICAgICAgICAgIGNvbnN0IGV2ZW50OiBSZXBsYXlMb2cuUmVwbGF5TG9nRXZlbnQgPSB7XG4gICAgICAgICAgICBfdGFnOiAnUmVzb3VyY2VTbmFwc2hvdCcsXG4gICAgICAgICAgICByZXNvdXJjZUlkLFxuICAgICAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICAgICAga2V5SGFzaDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY29uY3VycmVuY3k6IG1vZGUsXG4gICAgICAgICAgICBwaGFzZTogJ2lkbGUnLFxuICAgICAgICAgICAgc25hcHNob3Q6IGlkbGVTbmFwc2hvdCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIG1vZHVsZUlkLFxuICAgICAgICAgICAgaW5zdGFuY2VJZCxcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVjb3JkUmVwbGF5RXZlbnQoYm91bmQsIGV2ZW50KVxuICAgICAgICAgIHlpZWxkKiByZWNvcmRTbmFwc2hvdChyZXBsYXlNb2RlLCByZXBsYXlMb2csIGV2ZW50KVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBjb25zdCBoID0gaGFzaEtleShrZXkpXG5cbiAgICAgIC8vIERlZmF1bHQgc2VtYW50aWNzOiB3aGVuIGEgbm9uLWlkbGUgc25hcHNob3QgYWxyZWFkeSBleGlzdHMgZm9yIHRoZSBzYW1lIGtleUhhc2gsIHJlZnJlc2ggc2hvdWxkIGJlIGEgbm8tb3Agd2hlbiBwb3NzaWJsZVxuICAgICAgLy8gKGF2b2lkIGR1cGxpY2F0ZSBJTy93cml0ZWJhY2spLiBFeHBsaWNpdCByZWZyZXNoL2ludmFsaWRhdGUgY2FuIGJ5cGFzcyB2aWEgZm9yY2UuXG4gICAgICBpZiAoIWZvcmNlKSB7XG4gICAgICAgIGlmIChpbkZsaWdodCAmJiBpbkZsaWdodC5rZXlIYXNoID09PSBoKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjdXJyZW50U25hcHNob3QgPSBSb3dJZC5nZXRBdFBhdGgoc3RhdGUsIGZpZWxkUGF0aCkgYXMgYW55XG4gICAgICAgIGNvbnN0IGN1cnJlbnRLZXlIYXNoID1cbiAgICAgICAgICBjdXJyZW50U25hcHNob3QgJiYgdHlwZW9mIGN1cnJlbnRTbmFwc2hvdCA9PT0gJ29iamVjdCcgPyAoY3VycmVudFNuYXBzaG90IGFzIGFueSkua2V5SGFzaCA6IHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBjdXJyZW50U3RhdHVzID1cbiAgICAgICAgICBjdXJyZW50U25hcHNob3QgJiYgdHlwZW9mIGN1cnJlbnRTbmFwc2hvdCA9PT0gJ29iamVjdCcgPyAoY3VycmVudFNuYXBzaG90IGFzIGFueSkuc3RhdHVzIDogdW5kZWZpbmVkXG4gICAgICAgIGlmIChjdXJyZW50U3RhdHVzICYmIGN1cnJlbnRTdGF0dXMgIT09ICdpZGxlJyAmJiBjdXJyZW50S2V5SGFzaCA9PT0gaCkge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RlID09PSAnZXhoYXVzdC10cmFpbGluZycgJiYgaW5GbGlnaHQpIHtcbiAgICAgICAgLy8gQnVzeTogcmVjb3JkIHRyYWlsaW5nIGFuZCB1cGRhdGUgbG9hZGluZyBpbW1lZGlhdGVseTsgc3RhbGUgaW4tZmxpZ2h0IHdyaXRlYmFja3Mgd2lsbCBiZSBibG9ja2VkIGJ5IHRoZSBrZXlIYXNoIGdhdGUuXG4gICAgICAgIHRyYWlsaW5nID0geyBrZXksIGtleUhhc2g6IGggfVxuICAgICAgICBjb25zdCBsb2FkaW5nU25hcHNob3QgPSBTbmFwc2hvdC5sb2FkaW5nKHsga2V5SGFzaDogaCB9KVxuICAgICAgICBjb25zdCB3cm90ZUxvYWRpbmcgPSB5aWVsZCogc2V0U25hcHNob3RJblR4bihcbiAgICAgICAgICBib3VuZCxcbiAgICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgICAgbG9hZGluZ1NuYXBzaG90LFxuICAgICAgICAgICdzb3VyY2UtcmVmcmVzaCcsXG4gICAgICAgICAgYHNvdXJjZToke2ZpZWxkUGF0aH06bG9hZGluZ2AsXG4gICAgICAgICAgc3RlcC5kZWJ1Z0luZm8/LmdyYXBoTm9kZUlkLFxuICAgICAgICApXG4gICAgICAgIGlmICh3cm90ZUxvYWRpbmcpIHtcbiAgICAgICAgICBjb25zdCBldmVudDogUmVwbGF5TG9nLlJlcGxheUxvZ0V2ZW50ID0ge1xuICAgICAgICAgICAgX3RhZzogJ1Jlc291cmNlU25hcHNob3QnLFxuICAgICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgICAgIGtleUhhc2g6IGgsXG4gICAgICAgICAgICBjb25jdXJyZW5jeTogbW9kZSxcbiAgICAgICAgICAgIHBoYXNlOiAnbG9hZGluZycsXG4gICAgICAgICAgICBzbmFwc2hvdDogbG9hZGluZ1NuYXBzaG90LFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICAgIH1cbiAgICAgICAgICByZWNvcmRSZXBsYXlFdmVudChib3VuZCwgZXZlbnQpXG4gICAgICAgICAgeWllbGQqIHJlY29yZFNuYXBzaG90KHJlcGxheU1vZGUsIHJlcGxheUxvZywgZXZlbnQpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RlID09PSAnc3dpdGNoJyAmJiBpbkZsaWdodCkge1xuICAgICAgICB5aWVsZCogRmliZXIuaW50ZXJydXB0Rm9yayhpbkZsaWdodC5maWJlcilcbiAgICAgICAgaW5GbGlnaHQgPSB1bmRlZmluZWRcbiAgICAgICAgdHJhaWxpbmcgPSB1bmRlZmluZWRcbiAgICAgIH1cblxuICAgICAgLy8gc3RhcnQgZmV0Y2ggKHBlbmRpbmcgdHggKyBmb3JrIElPKVxuICAgICAgeWllbGQqIHN0YXJ0RmV0Y2goa2V5LCBoLCByZXBsYXlNb2RlLCByZXBsYXlMb2cpXG4gICAgfSksXG4gIClcblxuICByZXR1cm4gRWZmZWN0LnZvaWRcbn1cbiIsICJleHBvcnQgaW50ZXJmYWNlIERlcHNUcmFjZVJlc3VsdDxUPiB7XG4gIHJlYWRvbmx5IHZhbHVlOiBUXG4gIHJlYWRvbmx5IHJlYWRzOiBSZWFkb25seUFycmF5PHN0cmluZz5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZXBzRGlmZiB7XG4gIHJlYWRvbmx5IHJlYWRzOiBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgcmVhZG9ubHkgZGVjbGFyZWQ6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICByZWFkb25seSBtaXNzaW5nOiBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgcmVhZG9ubHkgdW51c2VkOiBSZWFkb25seUFycmF5PHN0cmluZz5cbn1cblxuY29uc3QgaXNUcmFjZWFibGVPYmplY3QgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBvYmplY3QgPT4ge1xuICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHJldHVybiBmYWxzZVxuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB0cnVlXG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHJldHVybiBmYWxzZVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBSZWdFeHApIHJldHVybiBmYWxzZVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIGZhbHNlXG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE1hcCkgcmV0dXJuIGZhbHNlXG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFNldCkgcmV0dXJuIGZhbHNlXG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFdlYWtNYXApIHJldHVybiBmYWxzZVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBXZWFrU2V0KSByZXR1cm4gZmFsc2VcbiAgcmV0dXJuIHRydWVcbn1cblxuY29uc3Qgc2hvdWxkSWdub3JlS2V5ID0gKGtleTogc3RyaW5nKTogYm9vbGVhbiA9PiBrZXkgPT09ICdfX3Byb3RvX18nIHx8IGtleSA9PT0gJ3Byb3RvdHlwZScgfHwga2V5ID09PSAnY29uc3RydWN0b3InXG5cbmNvbnN0IG5vcm1hbGl6ZVJlYWRzID0gKHJlYWRzOiBSZWFkb25seVNldDxzdHJpbmc+KTogUmVhZG9ubHlBcnJheTxzdHJpbmc+ID0+IHtcbiAgY29uc3QgYWxsID0gQXJyYXkuZnJvbShyZWFkcykuZmlsdGVyKChwKSA9PiB0eXBlb2YgcCA9PT0gJ3N0cmluZycgJiYgcC5sZW5ndGggPiAwKVxuICBhbGwuc29ydCgpXG5cbiAgLy8gRHJvcCBzdHJpY3QgcHJlZml4IHBhdGhzIChlLmcuIGlmIGJvdGggcHJvZmlsZSBhbmQgcHJvZmlsZS5pZCBhcmUgcmVhZCwga2VlcCBvbmx5IHRoZSBtb3JlIHNwZWNpZmljIHByb2ZpbGUuaWQpLlxuICBjb25zdCBpc1ByZWZpeCA9IChwcmVmaXg6IHN0cmluZywgZnVsbDogc3RyaW5nKTogYm9vbGVhbiA9PiBmdWxsICE9PSBwcmVmaXggJiYgZnVsbC5zdGFydHNXaXRoKHByZWZpeCArICcuJylcblxuICBjb25zdCBwcnVuZWQ6IEFycmF5PHN0cmluZz4gPSBbXVxuICBmb3IgKGNvbnN0IHAgb2YgYWxsKSB7XG4gICAgbGV0IGhhc01vcmVTcGVjaWZpYyA9IGZhbHNlXG4gICAgZm9yIChjb25zdCBvdGhlciBvZiBhbGwpIHtcbiAgICAgIGlmIChpc1ByZWZpeChwLCBvdGhlcikpIHtcbiAgICAgICAgaGFzTW9yZVNwZWNpZmljID0gdHJ1ZVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWhhc01vcmVTcGVjaWZpYykge1xuICAgICAgcHJ1bmVkLnB1c2gocClcbiAgICB9XG4gIH1cblxuICBwcnVuZWQuc29ydCgpXG4gIHJldHVybiBwcnVuZWRcbn1cblxuY29uc3QgY292ZXJzID0gKGRlY2xhcmVkOiBzdHJpbmcsIHJlYWQ6IHN0cmluZyk6IGJvb2xlYW4gPT4gZGVjbGFyZWQgPT09IHJlYWQgfHwgcmVhZC5zdGFydHNXaXRoKGRlY2xhcmVkICsgJy4nKVxuXG5leHBvcnQgY29uc3QgZGlmZkRlcHMgPSAoZGVjbGFyZWQ6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiwgcmVhZHM6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPik6IERlcHNEaWZmIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgZGVjbGFyZWRMaXN0ID0gQXJyYXkuZnJvbShuZXcgU2V0KGRlY2xhcmVkKSkuZmlsdGVyKChwKSA9PiB0eXBlb2YgcCA9PT0gJ3N0cmluZycgJiYgcC5sZW5ndGggPiAwKVxuICBkZWNsYXJlZExpc3Quc29ydCgpXG4gIGNvbnN0IHJlYWRMaXN0ID0gQXJyYXkuZnJvbShuZXcgU2V0KHJlYWRzKSkuZmlsdGVyKChwKSA9PiB0eXBlb2YgcCA9PT0gJ3N0cmluZycgJiYgcC5sZW5ndGggPiAwKVxuICByZWFkTGlzdC5zb3J0KClcblxuICBjb25zdCBtaXNzaW5nID0gcmVhZExpc3QuZmlsdGVyKChyKSA9PiBkZWNsYXJlZExpc3QuZXZlcnkoKGQpID0+ICFjb3ZlcnMoZCwgcikpKVxuICBjb25zdCB1bnVzZWQgPSBkZWNsYXJlZExpc3QuZmlsdGVyKChkKSA9PiByZWFkTGlzdC5ldmVyeSgocikgPT4gIWNvdmVycyhkLCByKSkpXG5cbiAgaWYgKG1pc3NpbmcubGVuZ3RoID09PSAwICYmIHVudXNlZC5sZW5ndGggPT09IDApIHJldHVybiB1bmRlZmluZWRcblxuICByZXR1cm4ge1xuICAgIHJlYWRzOiByZWFkTGlzdCxcbiAgICBkZWNsYXJlZDogZGVjbGFyZWRMaXN0LFxuICAgIG1pc3NpbmcsXG4gICAgdW51c2VkLFxuICB9XG59XG5cbmV4cG9ydCBjb25zdCB0cmFjZSA9IDxUPihmbjogKHN0YXRlOiBhbnkpID0+IFQsIHN0YXRlOiB1bmtub3duKTogRGVwc1RyYWNlUmVzdWx0PFQ+ID0+IHtcbiAgaWYgKCFpc1RyYWNlYWJsZU9iamVjdChzdGF0ZSkpIHtcbiAgICByZXR1cm4geyB2YWx1ZTogZm4oc3RhdGUgYXMgYW55KSwgcmVhZHM6IFtdIH1cbiAgfVxuXG4gIGNvbnN0IHJlYWRzID0gbmV3IFNldDxzdHJpbmc+KClcblxuICAvLyBwZXItdHJhY2UgY2FjaGVzIHRvIHByZXNlcnZlIHJlZmVyZW5jZSBpZGVudGl0eSB3aXRoaW4gdGhlIHRyYWNlZCBjYWxsLlxuICBjb25zdCBwcm94eUNhY2hlID0gbmV3IFdlYWtNYXA8b2JqZWN0LCBNYXA8c3RyaW5nLCBhbnk+PigpXG4gIGNvbnN0IHByb3h5VG9UYXJnZXQgPSBuZXcgV2Vha01hcDxvYmplY3QsIG9iamVjdD4oKVxuXG4gIGNvbnN0IHdyYXAgPSAodmFsdWU6IHVua25vd24sIHBhdGg6IHN0cmluZyk6IHVua25vd24gPT4ge1xuICAgIGlmICghaXNUcmFjZWFibGVPYmplY3QodmFsdWUpKSByZXR1cm4gdmFsdWVcbiAgICByZXR1cm4gZ2V0UHJveHkodmFsdWUgYXMgYW55LCBwYXRoKVxuICB9XG5cbiAgY29uc3QgdW53cmFwID0gPFY+KHZhbHVlOiBWKTogViA9PiB7XG4gICAgaWYgKHZhbHVlICYmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IHByb3h5VG9UYXJnZXQuZ2V0KHZhbHVlIGFzIGFueSlcbiAgICAgIGlmICh0YXJnZXQpIHJldHVybiB0YXJnZXQgYXMgYW55IGFzIFZcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICBjb25zdCBnZXRQcm94eSA9ICh0YXJnZXQ6IG9iamVjdCwgYmFzZVBhdGg6IHN0cmluZyk6IGFueSA9PiB7XG4gICAgbGV0IGJ5UGF0aCA9IHByb3h5Q2FjaGUuZ2V0KHRhcmdldClcbiAgICBpZiAoIWJ5UGF0aCkge1xuICAgICAgYnlQYXRoID0gbmV3IE1hcCgpXG4gICAgICBwcm94eUNhY2hlLnNldCh0YXJnZXQsIGJ5UGF0aClcbiAgICB9XG5cbiAgICBjb25zdCBjYWNoZWQgPSBieVBhdGguZ2V0KGJhc2VQYXRoKVxuICAgIGlmIChjYWNoZWQpIHJldHVybiBjYWNoZWRcblxuICAgIGNvbnN0IHJlY29yZCA9IChwYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmIChwYXRoKSByZWFkcy5hZGQocGF0aClcbiAgICB9XG5cbiAgICBjb25zdCBwcm94eSA9IG5ldyBQcm94eSh0YXJnZXQgYXMgYW55LCB7XG4gICAgICBnZXQ6ICh0LCBwcm9wLCByZWNlaXZlcikgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHByb3AgPT09ICdzeW1ib2wnKSB7XG4gICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHQsIHByb3AsIHJlY2VpdmVyKVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleSA9IFN0cmluZyhwcm9wKVxuICAgICAgICBpZiAoc2hvdWxkSWdub3JlS2V5KGtleSkpIHtcbiAgICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQodCwgcHJvcCwgcmVjZWl2ZXIpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBuZXh0UGF0aCA9IGJhc2VQYXRoID8gYCR7YmFzZVBhdGh9LiR7a2V5fWAgOiBrZXlcbiAgICAgICAgcmVjb3JkKG5leHRQYXRoKVxuXG4gICAgICAgIGNvbnN0IHZhbHVlID0gUmVmbGVjdC5nZXQodCwgcHJvcCwgcmVjZWl2ZXIpIGFzIHVua25vd25cbiAgICAgICAgcmV0dXJuIHdyYXAodmFsdWUsIG5leHRQYXRoKVxuICAgICAgfSxcbiAgICAgIGhhczogKHQsIHByb3ApID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnc3ltYm9sJykgcmV0dXJuIFJlZmxlY3QuaGFzKHQsIHByb3ApXG4gICAgICAgIGNvbnN0IGtleSA9IFN0cmluZyhwcm9wKVxuICAgICAgICBpZiAoIXNob3VsZElnbm9yZUtleShrZXkpKSB7XG4gICAgICAgICAgY29uc3QgbmV4dFBhdGggPSBiYXNlUGF0aCA/IGAke2Jhc2VQYXRofS4ke2tleX1gIDoga2V5XG4gICAgICAgICAgcmVjb3JkKG5leHRQYXRoKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWZsZWN0Lmhhcyh0LCBwcm9wKVxuICAgICAgfSxcbiAgICAgIG93bktleXM6ICh0KSA9PiB7XG4gICAgICAgIGlmIChiYXNlUGF0aCkgcmVjb3JkKGJhc2VQYXRoKVxuICAgICAgICByZXR1cm4gUmVmbGVjdC5vd25LZXlzKHQpXG4gICAgICB9LFxuICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAodCwgcHJvcCkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHByb3AgPT09ICdzeW1ib2wnKSB7XG4gICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHQsIHByb3ApXG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qga2V5ID0gU3RyaW5nKHByb3ApXG4gICAgICAgIGlmICghc2hvdWxkSWdub3JlS2V5KGtleSkpIHtcbiAgICAgICAgICBjb25zdCBuZXh0UGF0aCA9IGJhc2VQYXRoID8gYCR7YmFzZVBhdGh9LiR7a2V5fWAgOiBrZXlcbiAgICAgICAgICByZWNvcmQobmV4dFBhdGgpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHQsIHByb3ApXG4gICAgICB9LFxuICAgICAgc2V0OiAoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnW2RlcHMtdHJhY2VdIEF0dGVtcHRlZCB0byBtdXRhdGUgc3RhdGUgZHVyaW5nIGRlcHMgdHJhY2luZyAoc3RhdGUgaXMgcmVhZG9ubHkgaW4gZGV2LW1vZGUgZGlhZ25vc3RpY3MpLicsXG4gICAgICAgIClcbiAgICAgIH0sXG4gICAgICBkZWZpbmVQcm9wZXJ0eTogKCkgPT4ge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ1tkZXBzLXRyYWNlXSBBdHRlbXB0ZWQgdG8gZGVmaW5lIHByb3BlcnR5IG9uIHN0YXRlIGR1cmluZyBkZXBzIHRyYWNpbmcgKHN0YXRlIGlzIHJlYWRvbmx5IGluIGRldi1tb2RlIGRpYWdub3N0aWNzKS4nLFxuICAgICAgICApXG4gICAgICB9LFxuICAgICAgZGVsZXRlUHJvcGVydHk6ICgpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdbZGVwcy10cmFjZV0gQXR0ZW1wdGVkIHRvIGRlbGV0ZSBwcm9wZXJ0eSBvbiBzdGF0ZSBkdXJpbmcgZGVwcyB0cmFjaW5nIChzdGF0ZSBpcyByZWFkb25seSBpbiBkZXYtbW9kZSBkaWFnbm9zdGljcykuJyxcbiAgICAgICAgKVxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgYnlQYXRoLnNldChiYXNlUGF0aCwgcHJveHkpXG4gICAgcHJveHlUb1RhcmdldC5zZXQocHJveHksIHRhcmdldClcbiAgICByZXR1cm4gcHJveHlcbiAgfVxuXG4gIGNvbnN0IHJvb3QgPSBnZXRQcm94eShzdGF0ZSBhcyBhbnksICcnKVxuICBjb25zdCB2YWx1ZSA9IHVud3JhcChmbihyb290KSlcblxuICByZXR1cm4ge1xuICAgIHZhbHVlLFxuICAgIHJlYWRzOiBub3JtYWxpemVSZWFkcyhyZWFkcyksXG4gIH1cbn1cbiIsICJpbXBvcnQgeyBFZmZlY3QsIEZpYmVyUmVmLCBPcHRpb24gfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgKiBhcyBTY2hlbWFBU1QgZnJvbSAnZWZmZWN0L1NjaGVtYUFTVCdcbmltcG9ydCAqIGFzIERlYnVnIGZyb20gJy4uL3J1bnRpbWUvY29yZS9EZWJ1Z1NpbmsuanMnXG5pbXBvcnQgeyBpc0RldkVudiB9IGZyb20gJy4uL3J1bnRpbWUvY29yZS9lbnYuanMnXG5pbXBvcnQgeyBSdW5TZXNzaW9uVGFnIH0gZnJvbSAnLi4vb2JzZXJ2YWJpbGl0eS9ydW5TZXNzaW9uLmpzJ1xuaW1wb3J0IHsgbm9ybWFsaXplRmllbGRQYXRoIH0gZnJvbSAnLi4vZmllbGQtcGF0aC5qcydcbmltcG9ydCAqIGFzIERlcHNUcmFjZSBmcm9tICcuL2RlcHMtdHJhY2UuanMnXG5pbXBvcnQgdHlwZSB7IENvbnZlcmdlQ29udGV4dCB9IGZyb20gJy4vY29udmVyZ2UudHlwZXMuanMnXG5pbXBvcnQgdHlwZSB7IFN0YXRlVHJhaXRQcm9ncmFtLCBTdGF0ZVRyYWl0U2NoZW1hUGF0aFJlZiB9IGZyb20gJy4vbW9kZWwuanMnXG5cbmNvbnN0IG9uY2VLZXlzRmFsbGJhY2sgPSBuZXcgU2V0PHN0cmluZz4oKVxuXG5leHBvcnQgY29uc3Qgb25jZUluUnVuU2Vzc2lvbiA9IChrZXk6IHN0cmluZyk6IEVmZmVjdC5FZmZlY3Q8Ym9vbGVhbj4gPT5cbiAgRWZmZWN0LnNlcnZpY2VPcHRpb24oUnVuU2Vzc2lvblRhZykucGlwZShcbiAgICBFZmZlY3QubWFwKChtYXliZSkgPT4ge1xuICAgICAgaWYgKE9wdGlvbi5pc1NvbWUobWF5YmUpKSB7XG4gICAgICAgIHJldHVybiBtYXliZS52YWx1ZS5sb2NhbC5vbmNlKGtleSlcbiAgICAgIH1cbiAgICAgIGlmIChvbmNlS2V5c0ZhbGxiYWNrLmhhcyhrZXkpKSByZXR1cm4gZmFsc2VcbiAgICAgIG9uY2VLZXlzRmFsbGJhY2suYWRkKGtleSlcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfSksXG4gIClcblxuY29uc3QgZm9ybWF0TGlzdCA9IChpdGVtczogUmVhZG9ubHlBcnJheTxzdHJpbmc+LCBsaW1pdCA9IDEwKTogc3RyaW5nID0+IHtcbiAgaWYgKGl0ZW1zLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChpdGVtcy5sZW5ndGggPD0gbGltaXQpIHJldHVybiBpdGVtcy5qb2luKCcsICcpXG4gIHJldHVybiBgJHtpdGVtcy5zbGljZSgwLCBsaW1pdCkuam9pbignLCAnKX0sIFx1MjAyNigrJHtpdGVtcy5sZW5ndGggLSBsaW1pdH0pYFxufVxuXG5leHBvcnQgY29uc3QgZW1pdERlcHNNaXNtYXRjaCA9IChwYXJhbXM6IHtcbiAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZ1xuICByZWFkb25seSBraW5kOiAnY29tcHV0ZWQnIHwgJ3NvdXJjZSdcbiAgcmVhZG9ubHkgZmllbGRQYXRoOiBzdHJpbmdcbiAgcmVhZG9ubHkgZGlmZjogRGVwc1RyYWNlLkRlcHNEaWZmXG59KTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PiB7XG4gIHJldHVybiBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3Qga2V5ID0gYCR7cGFyYW1zLm1vZHVsZUlkID8/ICd1bmtub3duJ306OiR7cGFyYW1zLmluc3RhbmNlSWQgPz8gJ3Vua25vd24nfTo6JHtwYXJhbXMua2luZH06OiR7cGFyYW1zLmZpZWxkUGF0aH1gXG4gICAgY29uc3Qgc2hvdWxkRW1pdCA9IHlpZWxkKiBvbmNlSW5SdW5TZXNzaW9uKGBkZXBzX21pc21hdGNoOiR7a2V5fWApXG4gICAgaWYgKCFzaG91bGRFbWl0KSByZXR1cm5cblxuICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgdHlwZTogJ2RpYWdub3N0aWMnLFxuICAgICAgbW9kdWxlSWQ6IHBhcmFtcy5tb2R1bGVJZCxcbiAgICAgIGluc3RhbmNlSWQ6IHBhcmFtcy5pbnN0YW5jZUlkLFxuICAgICAgY29kZTogJ3N0YXRlX3RyYWl0OjpkZXBzX21pc21hdGNoJyxcbiAgICAgIHNldmVyaXR5OiAnd2FybmluZycsXG4gICAgICBtZXNzYWdlOlxuICAgICAgICBgW2RlcHNdICR7cGFyYW1zLmtpbmR9IFwiJHtwYXJhbXMuZmllbGRQYXRofVwiIGRlY2xhcmVkPVske2Zvcm1hdExpc3QocGFyYW1zLmRpZmYuZGVjbGFyZWQpfV0gYCArXG4gICAgICAgIGByZWFkcz1bJHtmb3JtYXRMaXN0KHBhcmFtcy5kaWZmLnJlYWRzKX1dIG1pc3Npbmc9WyR7Zm9ybWF0TGlzdChwYXJhbXMuZGlmZi5taXNzaW5nKX1dIGAgK1xuICAgICAgICBgdW51c2VkPVske2Zvcm1hdExpc3QocGFyYW1zLmRpZmYudW51c2VkKX1dYCxcbiAgICAgIGhpbnQ6XG4gICAgICAgICdkZXBzIGlzIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciBkZXBlbmRlbmNpZXM6IGluY3JlbWVudGFsIHNjaGVkdWxpbmcgLyByZXZlcnNlIGNsb3N1cmVzIC8gcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9ucyByZWx5IG9uIGRlcHMgb25seS4gJyArXG4gICAgICAgICdLZWVwIGRlcHMgY29uc2lzdGVudCB3aXRoIGFjdHVhbCByZWFkczsgaWYgeW91IHJlYWxseSBkZXBlbmQgb24gdGhlIHdob2xlIG9iamVjdCwgZGVjbGFyZSBhIGNvYXJzZXItZ3JhaW5lZCBkZXAgKGUuZy4gXCJwcm9maWxlXCIpIHRvIGNvdmVyIHN1Yi1maWVsZCByZWFkcy4nLFxuICAgICAga2luZDogYGRlcHNfbWlzbWF0Y2g6JHtwYXJhbXMua2luZH1gLFxuICAgIH0pXG4gIH0pXG59XG5cbmNvbnN0IHNjaGVtYUhhc1BhdGggPSAoXG4gIGFzdDogU2NoZW1hQVNULkFTVCxcbiAgc2VnbWVudHM6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPixcbiAgc2VlbjogU2V0PFNjaGVtYUFTVC5BU1Q+ID0gbmV3IFNldCgpLFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmIChzZWdtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB0cnVlXG5cbiAgbGV0IGN1cnJlbnQgPSBhc3RcblxuICAvLyB1bndyYXAgU3VzcGVuZC9SZWZpbmVtZW50IChjb21tb24gZm9yIHJlY3Vyc2l2ZSBzY2hlbWFzIGFuZCBicmFuZGVkIHNjaGVtYXMpXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKFNjaGVtYUFTVC5pc1N1c3BlbmQoY3VycmVudCkpIHtcbiAgICAgIGlmIChzZWVuLmhhcyhjdXJyZW50KSkge1xuICAgICAgICAvLyBSZWN1cnNpb246IGlmIHdlIGNhbid0IHN0YXRpY2FsbHkgZGVjaWRlIGZ1cnRoZXIsIGFsbG93IGNvbnNlcnZhdGl2ZWx5IHRvIGF2b2lkIGZhbHNlIHBvc2l0aXZlcy5cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICAgIHNlZW4uYWRkKGN1cnJlbnQpXG4gICAgICBjdXJyZW50ID0gY3VycmVudC5mKClcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChTY2hlbWFBU1QuaXNSZWZpbmVtZW50KGN1cnJlbnQpKSB7XG4gICAgICBjdXJyZW50ID0gY3VycmVudC5mcm9tXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBicmVha1xuICB9XG5cbiAgLy8gVHJhbnNmb3JtYXRpb246IHByZWZlciBgdG9gIChkZWNvZGVkIHNoYXBlKSwgYnV0IGFsc28gYWxsb3cgYGZyb21gIHRvIHJlZHVjZSBmYWxzZSBwb3NpdGl2ZXMuXG4gIGlmIChTY2hlbWFBU1QuaXNUcmFuc2Zvcm1hdGlvbihjdXJyZW50KSkge1xuICAgIHJldHVybiBzY2hlbWFIYXNQYXRoKGN1cnJlbnQudG8sIHNlZ21lbnRzLCBzZWVuKSB8fCBzY2hlbWFIYXNQYXRoKGN1cnJlbnQuZnJvbSwgc2VnbWVudHMsIHNlZW4pXG4gIH1cblxuICBpZiAoU2NoZW1hQVNULmlzVW5pb24oY3VycmVudCkpIHtcbiAgICByZXR1cm4gY3VycmVudC50eXBlcy5zb21lKCh0KSA9PiBzY2hlbWFIYXNQYXRoKHQsIHNlZ21lbnRzLCBzZWVuKSlcbiAgfVxuXG4gIGlmIChTY2hlbWFBU1QuaXNUdXBsZVR5cGUoY3VycmVudCkpIHtcbiAgICBjb25zdCBjYW5kaWRhdGVzOiBBcnJheTxTY2hlbWFBU1QuQVNUPiA9IFtdXG4gICAgZm9yIChjb25zdCBlIG9mIGN1cnJlbnQuZWxlbWVudHMpIGNhbmRpZGF0ZXMucHVzaChlLnR5cGUpXG4gICAgZm9yIChjb25zdCByIG9mIGN1cnJlbnQucmVzdCkgY2FuZGlkYXRlcy5wdXNoKHIudHlwZSlcbiAgICBpZiAoY2FuZGlkYXRlcy5sZW5ndGggPT09IDApIHJldHVybiB0cnVlXG4gICAgcmV0dXJuIGNhbmRpZGF0ZXMuc29tZSgodCkgPT4gc2NoZW1hSGFzUGF0aCh0LCBzZWdtZW50cywgc2VlbikpXG4gIH1cblxuICBpZiAoU2NoZW1hQVNULmlzVHlwZUxpdGVyYWwoY3VycmVudCkpIHtcbiAgICBjb25zdCBbaGVhZCwgLi4udGFpbF0gPSBzZWdtZW50c1xuXG4gICAgZm9yIChjb25zdCBwcyBvZiBjdXJyZW50LnByb3BlcnR5U2lnbmF0dXJlcykge1xuICAgICAgaWYgKFN0cmluZyhwcy5uYW1lKSAhPT0gaGVhZCkgY29udGludWVcbiAgICAgIHJldHVybiBzY2hlbWFIYXNQYXRoKHBzLnR5cGUsIHRhaWwsIHNlZW4pXG4gICAgfVxuXG4gICAgLy8gaW5kZXggc2lnbmF0dXJlOiBvcGVuIG9iamVjdHMgbGlrZSBSZWNvcmQ8c3RyaW5nLCBUPiBhbGxvdyBhbnkga2V5XG4gICAgZm9yIChjb25zdCBzaWcgb2YgY3VycmVudC5pbmRleFNpZ25hdHVyZXMpIHtcbiAgICAgIGxldCBwYXJhbTogU2NoZW1hQVNULkFTVCA9IHNpZy5wYXJhbWV0ZXIgYXMgdW5rbm93biBhcyBTY2hlbWFBU1QuQVNUXG4gICAgICB3aGlsZSAoU2NoZW1hQVNULmlzUmVmaW5lbWVudChwYXJhbSkpIHtcbiAgICAgICAgcGFyYW0gPSBwYXJhbS5mcm9tXG4gICAgICB9XG4gICAgICBjb25zdCB0YWcgPSAocGFyYW0gYXMgYW55KT8uX3RhZ1xuICAgICAgaWYgKHRhZyA9PT0gJ1N0cmluZ0tleXdvcmQnIHx8IHRhZyA9PT0gJ1RlbXBsYXRlTGl0ZXJhbCcpIHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYUhhc1BhdGgoc2lnLnR5cGUsIHRhaWwsIHNlZW4pXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBjb25zdCB0YWcgPSAoY3VycmVudCBhcyBhbnkpPy5fdGFnXG4gIGlmICh0YWcgPT09ICdBbnlLZXl3b3JkJyB8fCB0YWcgPT09ICdVbmtub3duS2V5d29yZCcgfHwgdGFnID09PSAnT2JqZWN0S2V5d29yZCcgfHwgdGFnID09PSAnRGVjbGFyYXRpb24nKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIHJldHVybiBmYWxzZVxufVxuXG5jb25zdCBzY2hlbWFIYXNGaWVsZFBhdGggPSAoc3RhdGVTY2hlbWFBc3Q6IFNjaGVtYUFTVC5BU1QsIHBhdGg6IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xuICBpZiAoIXBhdGgpIHJldHVybiB0cnVlXG4gIGlmIChwYXRoID09PSAnJHJvb3QnKSByZXR1cm4gdHJ1ZVxuXG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVGaWVsZFBhdGgocGF0aClcbiAgaWYgKCFub3JtYWxpemVkKSByZXR1cm4gZmFsc2VcblxuICBjb25zdCBzZWdzID0gbm9ybWFsaXplZFswXSA9PT0gJyRyb290JyA/IG5vcm1hbGl6ZWQuc2xpY2UoMSkgOiBub3JtYWxpemVkXG4gIHJldHVybiBzY2hlbWFIYXNQYXRoKHN0YXRlU2NoZW1hQXN0LCBzZWdzKVxufVxuXG5jb25zdCBmb3JtYXRTY2hlbWFNaXNtYXRjaExpbmUgPSAocmVmOiBTdGF0ZVRyYWl0U2NoZW1hUGF0aFJlZik6IHN0cmluZyA9PiB7XG4gIGlmIChyZWYua2luZCA9PT0gJ2ZpZWxkUGF0aCcpIHtcbiAgICByZXR1cm4gYC0gJHtyZWYuZW50cnlLaW5kfSBcIiR7cmVmLmVudHJ5RmllbGRQYXRofVwiIGZpZWxkUGF0aD1cIiR7cmVmLnBhdGh9XCJgXG4gIH1cbiAgaWYgKHJlZi5raW5kID09PSAnZGVwJykge1xuICAgIGNvbnN0IHJ1bGUgPSByZWYucnVsZU5hbWUgPyBgIHJ1bGU9XCIke3JlZi5ydWxlTmFtZX1cImAgOiAnJ1xuICAgIHJldHVybiBgLSAke3JlZi5lbnRyeUtpbmR9IFwiJHtyZWYuZW50cnlGaWVsZFBhdGh9XCIgZGVwcz1cIiR7cmVmLnBhdGh9XCIke3J1bGV9YFxuICB9XG4gIGlmIChyZWYua2luZCA9PT0gJ2xpbmtfZnJvbScpIHtcbiAgICByZXR1cm4gYC0gbGluayBcIiR7cmVmLmVudHJ5RmllbGRQYXRofVwiIGZyb209XCIke3JlZi5wYXRofVwiYFxuICB9XG4gIGlmIChyZWYua2luZCA9PT0gJ2NoZWNrX3dyaXRlYmFjaycpIHtcbiAgICByZXR1cm4gYC0gY2hlY2sgXCIke3JlZi5lbnRyeUZpZWxkUGF0aH1cIiB3cml0ZWJhY2s9XCIke3JlZi5wYXRofVwiYFxuICB9XG4gIHJldHVybiBgLSAke3JlZi5lbnRyeUtpbmR9IFwiJHtyZWYuZW50cnlGaWVsZFBhdGh9XCIgcGF0aD1cIiR7cmVmLnBhdGh9XCJgXG59XG5cbmV4cG9ydCBjb25zdCBlbWl0U2NoZW1hTWlzbWF0Y2ggPSA8UyBleHRlbmRzIG9iamVjdD4oXG4gIHByb2dyYW06IFN0YXRlVHJhaXRQcm9ncmFtPFM+LFxuICBjdHg6IFBpY2s8Q29udmVyZ2VDb250ZXh0PFM+LCAnbW9kdWxlSWQnIHwgJ2luc3RhbmNlSWQnPixcbik6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGlmICghaXNEZXZFbnYoKSkgcmV0dXJuXG5cbiAgICBjb25zdCBsZXZlbCA9IHlpZWxkKiBGaWJlclJlZi5nZXQoRGVidWcuY3VycmVudERpYWdub3N0aWNzTGV2ZWwpXG4gICAgaWYgKGxldmVsID09PSAnb2ZmJykgcmV0dXJuXG5cbiAgICBjb25zdCBrZXkgPSBgJHtjdHgubW9kdWxlSWQgPz8gJ3Vua25vd24nfTo6JHtjdHguaW5zdGFuY2VJZH1gXG4gICAgY29uc3Qgc2hvdWxkRW1pdCA9IHlpZWxkKiBvbmNlSW5SdW5TZXNzaW9uKGBzY2hlbWFfbWlzbWF0Y2g6JHtrZXl9YClcbiAgICBpZiAoIXNob3VsZEVtaXQpIHJldHVyblxuXG4gICAgY29uc3QgcmVmcyA9IChwcm9ncmFtLnNjaGVtYVBhdGhzID8/IFtdKSBhcyBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRTY2hlbWFQYXRoUmVmPlxuICAgIGlmIChyZWZzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBjb25zdCBzdGF0ZVNjaGVtYUFzdCA9IHByb2dyYW0uc3RhdGVTY2hlbWEuYXN0IGFzIHVua25vd24gYXMgU2NoZW1hQVNULkFTVFxuXG4gICAgY29uc3QgbWlzbWF0Y2hlczogQXJyYXk8U3RhdGVUcmFpdFNjaGVtYVBhdGhSZWY+ID0gW11cbiAgICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KClcblxuICAgIGZvciAoY29uc3QgcmVmIG9mIHJlZnMpIHtcbiAgICAgIGlmIChzY2hlbWFIYXNGaWVsZFBhdGgoc3RhdGVTY2hlbWFBc3QsIHJlZi5wYXRoKSkgY29udGludWVcbiAgICAgIGNvbnN0IGsgPSBgJHtyZWYua2luZH18JHtyZWYuZW50cnlLaW5kfXwke3JlZi5lbnRyeUZpZWxkUGF0aH18JHtyZWYucnVsZU5hbWUgPz8gJyd9fCR7cmVmLnBhdGh9YFxuICAgICAgaWYgKHNlZW4uaGFzKGspKSBjb250aW51ZVxuICAgICAgc2Vlbi5hZGQoaylcbiAgICAgIG1pc21hdGNoZXMucHVzaChyZWYpXG4gICAgfVxuXG4gICAgaWYgKG1pc21hdGNoZXMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgIGNvbnN0IGxpbWl0ID0gbGV2ZWwgPT09ICdsaWdodCcgPyA4IDogMjRcbiAgICBjb25zdCBsaW5lcyA9IG1pc21hdGNoZXMuc2xpY2UoMCwgbGltaXQpLm1hcChmb3JtYXRTY2hlbWFNaXNtYXRjaExpbmUpXG4gICAgaWYgKG1pc21hdGNoZXMubGVuZ3RoID4gbGltaXQpIHtcbiAgICAgIGxpbmVzLnB1c2goYC0gXHUyMDI2KCske21pc21hdGNoZXMubGVuZ3RoIC0gbGltaXR9KWApXG4gICAgfVxuXG4gICAgeWllbGQqIERlYnVnLnJlY29yZCh7XG4gICAgICB0eXBlOiAnZGlhZ25vc3RpYycsXG4gICAgICBtb2R1bGVJZDogY3R4Lm1vZHVsZUlkLFxuICAgICAgaW5zdGFuY2VJZDogY3R4Lmluc3RhbmNlSWQsXG4gICAgICBjb2RlOiAnc3RhdGVfdHJhaXQ6OnNjaGVtYV9taXNtYXRjaCcsXG4gICAgICBzZXZlcml0eTogJ3dhcm5pbmcnLFxuICAgICAgbWVzc2FnZTogYFtzY2hlbWFdIFRoZSBmb2xsb3dpbmcgcGF0aHMgYXJlIG5vdCBkZWNsYXJlZCBpbiBzdGF0ZVNjaGVtYSAodG90YWwgJHttaXNtYXRjaGVzLmxlbmd0aH0pOlxcbiR7bGluZXMuam9pbignXFxuJyl9YCxcbiAgICAgIGhpbnQ6ICdTdGF0ZVRyYWl0IHdyaXRlYmFjayB3aWxsIGNyZWF0ZSBtaXNzaW5nIG9iamVjdHMvZmllbGRzLiBEZWNsYXJlIGFsbCBmaWVsZFBhdGgvZGVwcy9saW5rLmZyb20gYW5kIGVycm9ycy4qIHdyaXRlYmFjayBwYXRocyBpbiBzdGF0ZVNjaGVtYSwgb3IgZml4IHR5cG9zIGluIHRyYWl0IHBhdGhzLicsXG4gICAgICBraW5kOiAnc2NoZW1hX21pc21hdGNoJyxcbiAgICB9KVxuICB9KVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EsWUFBWSxlQUFlOzs7QUM0VnBCLElBQU0sZ0JBQWdCLENBQUksU0FBeUU7QUFDeEcsUUFBTSxVQUErQyxDQUFDO0FBRXRELFFBQU0sU0FBUyxDQUFDLFVBQ2QsT0FBTyxVQUFVLFlBQVksVUFBVSxRQUFTLE1BQWMsU0FBUztBQUV6RSxRQUFNLFNBQVMsQ0FBQyxVQUNkLE9BQU8sVUFBVSxZQUFZLFVBQVUsUUFBUyxNQUFjLFNBQVM7QUFFekUsUUFBTSxXQUFXLENBQUMsUUFBZ0IsV0FBMkI7QUFDM0QsUUFBSSxDQUFDLE9BQVEsUUFBTztBQUNwQixRQUFJLENBQUMsT0FBUSxRQUFPO0FBQ3BCLFdBQU8sR0FBRyxNQUFNLElBQUksTUFBTTtBQUFBLEVBQzVCO0FBRUEsUUFBTSxhQUFhLENBQUMsTUFBeUMsV0FBMEM7QUFDckcsUUFBSSxDQUFDLFFBQVEsS0FBSyxXQUFXLEVBQUcsUUFBTyxDQUFDO0FBQ3hDLFdBQU8sS0FBSyxJQUFJLENBQUMsTUFBTyxTQUFTLFNBQVMsUUFBUSxDQUFDLElBQUksQ0FBRTtBQUFBLEVBQzNEO0FBRUEsUUFBTSxpQkFBaUIsQ0FDckIsT0FDQSxXQUNBLGNBQ2lDO0FBQ2pDLFFBQUksTUFBTSxTQUFTLFlBQVk7QUFDN0IsWUFBTSxPQUFPLE1BQU07QUFDbkIsWUFBTSxVQUFVLEtBQUs7QUFDckIsWUFBTSxPQUFPLFlBQVksU0FBWSxXQUFXLFNBQVMsU0FBUyxJQUFJO0FBQ3RFLGFBQU87QUFBQSxRQUNMLEdBQUk7QUFBQSxRQUNKO0FBQUEsUUFD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QUMsRUFBRztBQUNqQixTQUFLLElBQUksQ0FBQztBQUNWLGVBQVcsS0FBSyxHQUFHO0FBQUEsRUFDckI7QUFFQSxNQUFJLFdBQVcsV0FBVyxFQUFHO0FBRTdCLFFBQU0sUUFBUSxVQUFVLFVBQVUsSUFBSTtBQUN0QyxRQUFNLFFBQVEsV0FBVyxNQUFNLEdBQUcsS0FBSyxFQUFFLElBQUksd0JBQXdCO0FBQ3JFLE1BQUksV0FBVyxTQUFTLE9BQU87QUFDN0IsVUFBTSxLQUFLLGFBQVEsV0FBVyxTQUFTLEtBQUssR0FBRztBQUFBLEVBQ2pEO0FBRUEsU0FBYSxPQUFPO0FBQUEsSUFDbEIsTUFBTTtBQUFBLElBQ04sVUFBVSxJQUFJO0FBQUEsSUFDZCxZQUFZLElBQUk7QUFBQSxJQUNoQixNQUFNO0FBQUEsSUFDTixVQUFVO0FBQUEsSUFDVixTQUFTLHVFQUF1RSxXQUFXLE1BQU07QUFBQSxFQUFPLE1BQU0sS0FBSyxJQUFJLENBQUM7QUFBQSxJQUN4SCxNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsRUFDUixDQUFDO0FBQ0gsQ0FBQzsiLAogICJuYW1lcyI6IFsicmVjb3JkIiwgInZhbHVlIiwgInJlY29yZCIsICJrZXlIYXNoIiwgImtleSIsICJwcmV2IiwgInByZXZTdGF0dXMiLCAiY29uY3VycmVuY3kiLCAibW9kZSIsICJpbkZsaWdodCIsICJ0cmFpbGluZyIsICJnZW4iLCAic3RhcnRGZXRjaCIsICJFZmZlY3QiLCAiRmliZXJSZWYiLCAiT3B0aW9uIiwgIlNjaGVtYUFTVCIsICJvbmNlSW5SdW5TZXNzaW9uIiwgIkVmZmVjdCIsICJPcHRpb24iLCAiZm9ybWF0TGlzdCIsICJlbWl0RGVwc01pc21hdGNoIiwgInRhZyIsICJGaWJlclJlZiJdCn0K