@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.
- package/LICENSE +201 -0
- package/package.json +3 -1
- package/public/sandbox/chunks/chunk-2AUQRESB.js +1114 -0
- package/public/sandbox/chunks/chunk-2F72LQKW.js +194 -0
- package/public/sandbox/chunks/chunk-2PYDGDD3.js +4071 -0
- package/public/sandbox/chunks/chunk-2UGKSXDZ.js +16 -0
- package/public/sandbox/chunks/chunk-2XVE7F26.js +153 -0
- package/public/sandbox/chunks/chunk-3A7TFNZN.js +219 -0
- package/public/sandbox/chunks/chunk-3BHC6JAV.js +1070 -0
- package/public/sandbox/chunks/chunk-3U4CAKCX.js +61 -0
- package/public/sandbox/chunks/chunk-3VU3JLZO.js +272 -0
- package/public/sandbox/chunks/chunk-4CPONKWY.js +1170 -0
- package/public/sandbox/chunks/chunk-4GMUQTWH.js +850 -0
- package/public/sandbox/chunks/chunk-4KIYG5E4.js +749 -0
- package/public/sandbox/chunks/chunk-4MY35XR3.js +175 -0
- package/public/sandbox/chunks/chunk-5DNHJMHA.js +69 -0
- package/public/sandbox/chunks/chunk-5EC4S7X6.js +42 -0
- package/public/sandbox/chunks/chunk-5FB7QFSH.js +227 -0
- package/public/sandbox/chunks/chunk-5GEYCJW2.js +206 -0
- package/public/sandbox/chunks/chunk-5PT7Q5SS.js +373 -0
- package/public/sandbox/chunks/chunk-5WN5IGKA.js +166 -0
- package/public/sandbox/chunks/chunk-5XOBKSOT.js +213 -0
- package/public/sandbox/chunks/chunk-67RVISUC.js +313 -0
- package/public/sandbox/chunks/chunk-6ELJEKZS.js +12 -0
- package/public/sandbox/chunks/chunk-6FKWRVP4.js +85 -0
- package/public/sandbox/chunks/chunk-6JRP52YT.js +34 -0
- package/public/sandbox/chunks/chunk-6JYAC3G6.js +42 -0
- package/public/sandbox/chunks/chunk-6TUOP63Q.js +86 -0
- package/public/sandbox/chunks/{chunk-A6JFUNQQ.js → chunk-74C5VW7Z.js} +2 -2
- package/public/sandbox/chunks/chunk-75DQFC5M.js +16 -0
- package/public/sandbox/chunks/{chunk-UCFEP3BH.js → chunk-7GPAF2UK.js} +1 -1
- package/public/sandbox/chunks/chunk-7KQFTS2Y.js +135 -0
- package/public/sandbox/chunks/chunk-7POKWYE3.js +112 -0
- package/public/sandbox/chunks/chunk-7VUEF5F3.js +395 -0
- package/public/sandbox/chunks/chunk-7W5APZS2.js +77 -0
- package/public/sandbox/chunks/chunk-A6OFCXDQ.js +397 -0
- package/public/sandbox/chunks/chunk-A7HLOSO6.js +216 -0
- package/public/sandbox/chunks/chunk-AGF4RRCB.js +408 -0
- package/public/sandbox/chunks/chunk-ASJSJAAL.js +122 -0
- package/public/sandbox/chunks/chunk-ASVMK364.js +283 -0
- package/public/sandbox/chunks/chunk-AUDTI2BQ.js +895 -0
- package/public/sandbox/chunks/chunk-B2SZTA3M.js +16 -0
- package/public/sandbox/chunks/chunk-B6YS2UMV.js +372 -0
- package/public/sandbox/chunks/chunk-BCEO3MGD.js +244 -0
- package/public/sandbox/chunks/chunk-BCOO65D4.js +373 -0
- package/public/sandbox/chunks/chunk-BJOWSSEL.js +38 -0
- package/public/sandbox/chunks/chunk-BS2WBFW4.js +373 -0
- package/public/sandbox/chunks/chunk-BUVHG3NJ.js +439 -0
- package/public/sandbox/chunks/chunk-BVE33AN6.js +42 -0
- package/public/sandbox/chunks/chunk-BWTGJZVP.js +19 -0
- package/public/sandbox/chunks/chunk-BXD7GZC3.js +1025 -0
- package/public/sandbox/chunks/chunk-BZH4EUUD.js +164 -0
- package/public/sandbox/chunks/{chunk-HFV5GJPK.js → chunk-C2MYMMO4.js} +3 -3
- package/public/sandbox/chunks/chunk-CRE4NJJ6.js +271 -0
- package/public/sandbox/chunks/chunk-CVZPRIDB.js +706 -0
- package/public/sandbox/chunks/chunk-CWOXD5NG.js +991 -0
- package/public/sandbox/chunks/chunk-D6DOC3BJ.js +373 -0
- package/public/sandbox/chunks/chunk-DEPSGFSY.js +1698 -0
- package/public/sandbox/chunks/chunk-DM7C5NP5.js +819 -0
- package/public/sandbox/chunks/chunk-DN33LMOF.js +1112 -0
- package/public/sandbox/chunks/{chunk-S46P7MC6.js → chunk-DT7YIIWE.js} +2 -2
- package/public/sandbox/chunks/chunk-DVB5WRCI.js +260 -0
- package/public/sandbox/chunks/{chunk-TOHCFMQS.js → chunk-E3EVW7NR.js} +11 -18
- package/public/sandbox/chunks/chunk-E5BV567Q.js +417 -0
- package/public/sandbox/chunks/chunk-E7BIWMQQ.js +203 -0
- package/public/sandbox/chunks/chunk-EAKGPSOQ.js +83 -0
- package/public/sandbox/chunks/chunk-EGUYL2ER.js +75 -0
- package/public/sandbox/chunks/chunk-EP5GQYZ5.js +85 -0
- package/public/sandbox/chunks/chunk-ET6CJEHC.js +221 -0
- package/public/sandbox/chunks/chunk-EU67YZHZ.js +1070 -0
- package/public/sandbox/chunks/{chunk-PTSJJANP.js → chunk-EYNDQLSB.js} +1 -1
- package/public/sandbox/chunks/{chunk-CEGSWZ5S.js → chunk-EZTMVCJF.js} +1 -1
- package/public/sandbox/chunks/chunk-F5CLVIS6.js +907 -0
- package/public/sandbox/chunks/chunk-F743SKYD.js +85 -0
- package/public/sandbox/chunks/chunk-FEGFZ5OX.js +86 -0
- package/public/sandbox/chunks/chunk-FG5B7ZX3.js +373 -0
- package/public/sandbox/chunks/chunk-FKZPYMDG.js +373 -0
- package/public/sandbox/chunks/chunk-FNLXHWIU.js +220 -0
- package/public/sandbox/chunks/chunk-FQRUTYAD.js +1991 -0
- package/public/sandbox/chunks/{chunk-VLYP4WUS.js → chunk-FY5A73NK.js} +5 -5
- package/public/sandbox/chunks/chunk-G7FAOG3O.js +221 -0
- package/public/sandbox/chunks/chunk-GFXHUC7Y.js +73 -0
- package/public/sandbox/chunks/chunk-GIPXUIZQ.js +534 -0
- package/public/sandbox/chunks/chunk-GP37MEGJ.js +52 -0
- package/public/sandbox/chunks/chunk-GXL5QCMF.js +4511 -0
- package/public/sandbox/chunks/chunk-GZ2NSE6A.js +177 -0
- package/public/sandbox/chunks/chunk-GZATW4YD.js +69 -0
- package/public/sandbox/chunks/chunk-H4EBXROQ.js +166 -0
- package/public/sandbox/chunks/chunk-HETCPK6Z.js +153 -0
- package/public/sandbox/chunks/chunk-HGUFQ2QC.js +4431 -0
- package/public/sandbox/chunks/chunk-HGV3VNH3.js +255 -0
- package/public/sandbox/chunks/chunk-HIJ67QWR.js +5397 -0
- package/public/sandbox/chunks/chunk-IDHERBKW.js +1114 -0
- package/public/sandbox/chunks/chunk-IDTK4FIY.js +102 -0
- package/public/sandbox/chunks/chunk-ILFVY7H5.js +164 -0
- package/public/sandbox/chunks/chunk-ISGSRYGO.js +57 -0
- package/public/sandbox/chunks/chunk-J45VPU24.js +408 -0
- package/public/sandbox/chunks/chunk-JAUIM3O5.js +42 -0
- package/public/sandbox/chunks/chunk-JB7OQEM6.js +373 -0
- package/public/sandbox/chunks/chunk-JCKW6NHD.js +15 -0
- package/public/sandbox/chunks/chunk-JMA7GY7Z.js +221 -0
- package/public/sandbox/chunks/chunk-JY46J6IL.js +836 -0
- package/public/sandbox/chunks/{chunk-X72PZOFA.js → chunk-K2MQ66O7.js} +1 -1
- package/public/sandbox/chunks/chunk-KA7PZA6F.js +464 -0
- package/public/sandbox/chunks/chunk-KDEQTUID.js +102 -0
- package/public/sandbox/chunks/chunk-KDJR27JV.js +1696 -0
- package/public/sandbox/chunks/chunk-KFE3JO6N.js +77 -0
- package/public/sandbox/chunks/chunk-KLDSYWT5.js +536 -0
- package/public/sandbox/chunks/chunk-KQWWFYBF.js +203 -0
- package/public/sandbox/chunks/chunk-KTFZSXOW.js +6473 -0
- package/public/sandbox/chunks/chunk-KXVIC55U.js +108 -0
- package/public/sandbox/chunks/{chunk-HNEDTEGQ.js → chunk-L4PNO2H6.js} +1 -1
- package/public/sandbox/chunks/{chunk-WE4STGO2.js → chunk-L4ZNW5DI.js} +2 -2
- package/public/sandbox/chunks/chunk-LBUINGZ4.js +836 -0
- package/public/sandbox/chunks/chunk-LIYPPU6I.js +112 -0
- package/public/sandbox/chunks/chunk-LJHTOJXW.js +221 -0
- package/public/sandbox/chunks/{chunk-BWSNPKO5.js → chunk-LQL23SWJ.js} +2 -2
- package/public/sandbox/chunks/chunk-LTFCYZQ6.js +46 -0
- package/public/sandbox/chunks/chunk-LTWLVCKQ.js +166 -0
- package/public/sandbox/chunks/chunk-LWI7BXFN.js +395 -0
- package/public/sandbox/chunks/chunk-LYBBX6WM.js +225 -0
- package/public/sandbox/chunks/chunk-MXE7HIBM.js +474 -0
- package/public/sandbox/chunks/chunk-MYBDYNK4.js +6004 -0
- package/public/sandbox/chunks/chunk-NC2MIWZX.js +732 -0
- package/public/sandbox/chunks/chunk-NE447XAF.js +597 -0
- package/public/sandbox/chunks/chunk-NEAYV5C2.js +255 -0
- package/public/sandbox/chunks/chunk-NMGFJZ4I.js +26 -0
- package/public/sandbox/chunks/chunk-NWCJJZNQ.js +71 -0
- package/public/sandbox/chunks/chunk-O57OZBDR.js +214 -0
- package/public/sandbox/chunks/chunk-OJJT664Q.js +731 -0
- package/public/sandbox/chunks/chunk-OKTBUTCH.js +1175 -0
- package/public/sandbox/chunks/chunk-OQ4SYV5D.js +534 -0
- package/public/sandbox/chunks/chunk-OTVVIHJD.js +219 -0
- package/public/sandbox/chunks/chunk-OWTMSCF7.js +1052 -0
- package/public/sandbox/chunks/chunk-P5ZQNFC3.js +122 -0
- package/public/sandbox/chunks/chunk-PBPT2U2N.js +1698 -0
- package/public/sandbox/chunks/chunk-PHBJLCP3.js +836 -0
- package/public/sandbox/chunks/chunk-PHV4HYHB.js +397 -0
- package/public/sandbox/chunks/chunk-PIXQ6SOX.js +4071 -0
- package/public/sandbox/chunks/chunk-PKJL6YLK.js +73 -0
- package/public/sandbox/chunks/chunk-PKPOITIU.js +221 -0
- package/public/sandbox/chunks/{chunk-NQW73ACJ.js → chunk-PMXBOYQI.js} +1 -1
- package/public/sandbox/chunks/chunk-PQLZD7NR.js +836 -0
- package/public/sandbox/chunks/chunk-QEESVOZU.js +16 -0
- package/public/sandbox/chunks/chunk-QGIM3FQK.js +159 -0
- package/public/sandbox/chunks/chunk-QL5JNEDO.js +69 -0
- package/public/sandbox/chunks/chunk-QQOZ3RMH.js +867 -0
- package/public/sandbox/chunks/chunk-QUMEVT2F.js +194 -0
- package/public/sandbox/chunks/chunk-QVZBXYVY.js +102 -0
- package/public/sandbox/chunks/chunk-R5HQS6RB.js +135 -0
- package/public/sandbox/chunks/chunk-R75Q2CTT.js +900 -0
- package/public/sandbox/chunks/chunk-RBB6SHW2.js +253 -0
- package/public/sandbox/chunks/chunk-RDHNRWQP.js +383 -0
- package/public/sandbox/chunks/chunk-RIWOEI3T.js +1101 -0
- package/public/sandbox/chunks/chunk-RS5FFPUV.js +103 -0
- package/public/sandbox/chunks/chunk-RYSSJBGX.js +203 -0
- package/public/sandbox/chunks/chunk-S3KBAE5Z.js +1114 -0
- package/public/sandbox/chunks/chunk-S6ZZHV6G.js +244 -0
- package/public/sandbox/chunks/chunk-SFXJ24HY.js +499 -0
- package/public/sandbox/chunks/chunk-SH7TP5CJ.js +1109 -0
- package/public/sandbox/chunks/chunk-SI5OKFFY.js +317 -0
- package/public/sandbox/chunks/chunk-SIXNQNIR.js +86 -0
- package/public/sandbox/chunks/chunk-ST353BOX.js +42 -0
- package/public/sandbox/chunks/chunk-SYEHKMLP.js +1140 -0
- package/public/sandbox/chunks/chunk-SZ4KQUJU.js +69 -0
- package/public/sandbox/chunks/{chunk-5SOP6EKV.js → chunk-SZI65PSP.js} +5 -10
- package/public/sandbox/chunks/chunk-T7RLTSMX.js +78 -0
- package/public/sandbox/chunks/chunk-TJ2RLUTW.js +57 -0
- package/public/sandbox/chunks/chunk-TJB73XPN.js +4071 -0
- package/public/sandbox/chunks/chunk-TXJCYO56.js +4046 -0
- package/public/sandbox/chunks/chunk-U5J3LCYI.js +731 -0
- package/public/sandbox/chunks/chunk-UABFN3NH.js +208 -0
- package/public/sandbox/chunks/chunk-UBMUY7WO.js +13 -0
- package/public/sandbox/chunks/chunk-UC27CE32.js +69 -0
- package/public/sandbox/chunks/chunk-UJGVDFZN.js +147 -0
- package/public/sandbox/chunks/chunk-UNVLTK4N.js +122 -0
- package/public/sandbox/chunks/chunk-UQKQ6V3V.js +208 -0
- package/public/sandbox/chunks/chunk-UZZBHWIO.js +703 -0
- package/public/sandbox/chunks/chunk-VKZIJERL.js +1114 -0
- package/public/sandbox/chunks/chunk-VQQEAGID.js +372 -0
- package/public/sandbox/chunks/{chunk-3LX3KIQQ.js → chunk-W365QUZ5.js} +3 -5
- package/public/sandbox/chunks/chunk-WJY2LSWG.js +1052 -0
- package/public/sandbox/chunks/chunk-WNOBN3DX.js +391 -0
- package/public/sandbox/chunks/chunk-X2Z5VYG3.js +245 -0
- package/public/sandbox/chunks/chunk-X74KU74D.js +959 -0
- package/public/sandbox/chunks/chunk-XE7ULSGQ.js +46 -0
- package/public/sandbox/chunks/chunk-XRXUJZ3X.js +431 -0
- package/public/sandbox/chunks/chunk-XWHIN7CC.js +85 -0
- package/public/sandbox/chunks/chunk-Y2TVGGVL.js +527 -0
- package/public/sandbox/chunks/chunk-YMVMZA3U.js +1395 -0
- package/public/sandbox/chunks/chunk-YOBLFWDV.js +431 -0
- package/public/sandbox/chunks/chunk-YR2RFEZA.js +11 -0
- package/public/sandbox/chunks/chunk-YTD6A35P.js +836 -0
- package/public/sandbox/chunks/chunk-Z5L7EZXS.js +81 -0
- package/public/sandbox/chunks/chunk-Z65I5ET2.js +108 -0
- package/public/sandbox/chunks/chunk-Z6LV34RO.js +390 -0
- package/public/sandbox/chunks/chunk-ZAKUP6QG.js +1634 -0
- package/public/sandbox/chunks/chunk-ZHNYE2YH.js +731 -0
- package/public/sandbox/chunks/chunk-ZHQX3B3Y.js +867 -0
- package/public/sandbox/chunks/chunk-ZIXDFRHJ.js +731 -0
- package/public/sandbox/chunks/chunk-ZPZ2MZ4D.js +528 -0
- package/public/sandbox/chunks/chunk-ZQD6NZXB.js +373 -0
- package/public/sandbox/chunks/chunk-ZVVBP7ON.js +16 -0
- package/public/sandbox/chunks/chunk-ZWE3P6X2.js +11 -0
- package/public/sandbox/logix-core/Bound.js +14 -14
- package/public/sandbox/logix-core/Debug.js +12 -10
- package/public/sandbox/logix-core/EffectOp.js +3 -4
- package/public/sandbox/logix-core/Env.js +5 -2
- package/public/sandbox/logix-core/ExternalStore.js +239 -0
- package/public/sandbox/logix-core/Flow.js +7 -8
- package/public/sandbox/logix-core/Kernel.js +7 -4
- package/public/sandbox/logix-core/Link.js +33 -25
- package/public/sandbox/logix-core/Middleware.js +13 -11
- package/public/sandbox/logix-core/Module.js +93 -30
- package/public/sandbox/logix-core/ModuleTag.js +28 -25
- package/public/sandbox/logix-core/Observability.js +21 -19
- package/public/sandbox/logix-core/Process.js +27 -22
- package/public/sandbox/logix-core/ReadQuery.js +7 -11
- package/public/sandbox/logix-core/Reflection.js +173 -53
- package/public/sandbox/logix-core/Resource.js +6 -3
- package/public/sandbox/logix-core/Root.js +7 -3
- package/public/sandbox/logix-core/Runtime.js +54 -40
- package/public/sandbox/logix-core/ScopeRegistry.js +6 -3
- package/public/sandbox/logix-core/StateTrait.js +17 -14
- package/public/sandbox/logix-core/TraitLifecycle.js +8 -8
- package/public/sandbox/logix-core/Workflow.js +332 -0
- package/public/sandbox/logix-core.js +11133 -6622
- package/public/sandbox/logix-core.manifest.json +4 -2
- package/public/sandbox/worker.js +3 -3
- package/public/sandbox/chunks/chunk-4LRLOTMA.js +0 -1698
- package/public/sandbox/chunks/chunk-CDLXJHXY.js +0 -120
- package/public/sandbox/chunks/chunk-CZRI7MHA.js +0 -46
- package/public/sandbox/chunks/chunk-EJDFUZ4B.js +0 -408
- package/public/sandbox/chunks/chunk-IP63FME6.js +0 -282
- package/public/sandbox/chunks/chunk-JIXTOQXJ.js +0 -1103
- package/public/sandbox/chunks/chunk-MPUSOFJ3.js +0 -1928
- package/public/sandbox/chunks/chunk-ON2LY6HJ.js +0 -135
- package/public/sandbox/chunks/chunk-POIBXAH5.js +0 -995
- package/public/sandbox/chunks/chunk-PQ652ULI.js +0 -6359
- package/public/sandbox/chunks/chunk-RJQ4PG2F.js +0 -77
- package/public/sandbox/chunks/chunk-S4EXG3OS.js +0 -533
- package/public/sandbox/chunks/chunk-SUXDGXVE.js +0 -390
- package/public/sandbox/chunks/chunk-TOQ6SJ6O.js +0 -244
- package/public/sandbox/chunks/chunk-UKYAF3NL.js +0 -1036
- package/public/sandbox/chunks/chunk-UMVN3AWO.js +0 -395
- package/public/sandbox/chunks/chunk-WFV5PPWJ.js +0 -194
- package/public/sandbox/chunks/chunk-YF6IO732.js +0 -206
- package/public/sandbox/chunks/chunk-ZUBABAAO.js +0 -86
|
@@ -0,0 +1,1395 @@
|
|
|
1
|
+
// @logixjs/core subpath bundles for @logixjs/sandbox
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getGlobalHostScheduler
|
|
5
|
+
} from "./chunk-UJGVDFZN.js";
|
|
6
|
+
import {
|
|
7
|
+
clearRuntimeDebugEventSeq,
|
|
8
|
+
currentDiagnosticsLevel,
|
|
9
|
+
record,
|
|
10
|
+
toRuntimeDebugEventRef
|
|
11
|
+
} from "./chunk-SH7TP5CJ.js";
|
|
12
|
+
import {
|
|
13
|
+
OBSERVABILITY_PROTOCOL_VERSION,
|
|
14
|
+
exportEvidencePackage
|
|
15
|
+
} from "./chunk-SI5OKFFY.js";
|
|
16
|
+
|
|
17
|
+
// ../logix-core/src/internal/runtime/core/DevtoolsHub.ts
|
|
18
|
+
import { Effect, FiberRef } from "../effect.js";
|
|
19
|
+
var instances = /* @__PURE__ */ new Map();
|
|
20
|
+
var latestStates = /* @__PURE__ */ new Map();
|
|
21
|
+
var latestTraitSummaries = /* @__PURE__ */ new Map();
|
|
22
|
+
var instanceLabels = /* @__PURE__ */ new Map();
|
|
23
|
+
var convergeStaticIrByDigest = /* @__PURE__ */ new Map();
|
|
24
|
+
var liveInstanceKeys = /* @__PURE__ */ new Set();
|
|
25
|
+
var exportBudget = {
|
|
26
|
+
dropped: 0,
|
|
27
|
+
oversized: 0
|
|
28
|
+
};
|
|
29
|
+
var lastRunTs = 0;
|
|
30
|
+
var lastRunTsSeq = 0;
|
|
31
|
+
var nextRunId = () => {
|
|
32
|
+
const ts = Date.now();
|
|
33
|
+
if (ts === lastRunTs) {
|
|
34
|
+
lastRunTsSeq += 1;
|
|
35
|
+
} else {
|
|
36
|
+
lastRunTs = ts;
|
|
37
|
+
lastRunTsSeq = 0;
|
|
38
|
+
}
|
|
39
|
+
return lastRunTsSeq === 0 ? `run-${ts}` : `run-${ts}.${lastRunTsSeq}`;
|
|
40
|
+
};
|
|
41
|
+
var currentRunId = nextRunId();
|
|
42
|
+
var nextSeq = 1;
|
|
43
|
+
var bufferSize = 500;
|
|
44
|
+
var ringBuffer = [];
|
|
45
|
+
var ringBufferSeq = [];
|
|
46
|
+
var snapshotToken = 0;
|
|
47
|
+
var ensureRingBufferSize = () => {
|
|
48
|
+
if (bufferSize <= 0) {
|
|
49
|
+
ringBuffer.length = 0;
|
|
50
|
+
ringBufferSeq.length = 0;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (ringBuffer.length <= bufferSize) return;
|
|
54
|
+
const excess = ringBuffer.length - bufferSize;
|
|
55
|
+
ringBuffer.splice(0, excess);
|
|
56
|
+
ringBufferSeq.splice(0, excess);
|
|
57
|
+
};
|
|
58
|
+
var trimRingBufferIfNeeded = () => {
|
|
59
|
+
if (bufferSize <= 0) {
|
|
60
|
+
ringBuffer.length = 0;
|
|
61
|
+
ringBufferSeq.length = 0;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (bufferSize <= 64) {
|
|
65
|
+
ensureRingBufferSize();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const slack = Math.min(1024, Math.floor(bufferSize / 2));
|
|
69
|
+
const threshold = bufferSize + Math.max(1, slack);
|
|
70
|
+
if (ringBuffer.length <= threshold) return;
|
|
71
|
+
const excess = ringBuffer.length - bufferSize;
|
|
72
|
+
ringBuffer.splice(0, excess);
|
|
73
|
+
ringBufferSeq.splice(0, excess);
|
|
74
|
+
};
|
|
75
|
+
var currentSnapshot = {
|
|
76
|
+
snapshotToken,
|
|
77
|
+
instances,
|
|
78
|
+
events: ringBuffer,
|
|
79
|
+
latestStates,
|
|
80
|
+
latestTraitSummaries,
|
|
81
|
+
exportBudget
|
|
82
|
+
};
|
|
83
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
84
|
+
var notifyScheduled = false;
|
|
85
|
+
var scheduleNotify = () => {
|
|
86
|
+
if (listeners.size === 0) return;
|
|
87
|
+
if (notifyScheduled) return;
|
|
88
|
+
notifyScheduled = true;
|
|
89
|
+
getGlobalHostScheduler().scheduleMicrotask(() => {
|
|
90
|
+
notifyScheduled = false;
|
|
91
|
+
for (const listener of listeners) {
|
|
92
|
+
listener();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
var devtoolsEnabled = false;
|
|
97
|
+
var bumpSnapshotToken = () => {
|
|
98
|
+
snapshotToken += 1;
|
|
99
|
+
currentSnapshot.snapshotToken = snapshotToken;
|
|
100
|
+
};
|
|
101
|
+
var markSnapshotChanged = () => {
|
|
102
|
+
bumpSnapshotToken();
|
|
103
|
+
scheduleNotify();
|
|
104
|
+
};
|
|
105
|
+
var configureDevtoolsHub = (options) => {
|
|
106
|
+
devtoolsEnabled = true;
|
|
107
|
+
if (typeof options?.bufferSize === "number" && Number.isFinite(options.bufferSize)) {
|
|
108
|
+
const next = Math.floor(options.bufferSize);
|
|
109
|
+
const nextBufferSize = next >= 0 ? next : 0;
|
|
110
|
+
if (nextBufferSize !== bufferSize) {
|
|
111
|
+
bufferSize = nextBufferSize;
|
|
112
|
+
ensureRingBufferSize();
|
|
113
|
+
markSnapshotChanged();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
var isDevtoolsEnabled = () => devtoolsEnabled;
|
|
118
|
+
var getDevtoolsSnapshot = () => currentSnapshot;
|
|
119
|
+
var getDevtoolsSnapshotToken = () => snapshotToken;
|
|
120
|
+
var subscribeDevtoolsSnapshot = (listener) => {
|
|
121
|
+
listeners.add(listener);
|
|
122
|
+
return () => {
|
|
123
|
+
listeners.delete(listener);
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
var getDevtoolsRunId = () => currentRunId;
|
|
127
|
+
var setDevtoolsRunId = (runId) => {
|
|
128
|
+
if (typeof runId !== "string" || runId.length === 0) return;
|
|
129
|
+
if (runId !== currentRunId) {
|
|
130
|
+
currentRunId = runId;
|
|
131
|
+
markSnapshotChanged();
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
var startDevtoolsRun = (runId) => {
|
|
135
|
+
currentRunId = typeof runId === "string" && runId.length > 0 ? runId : nextRunId();
|
|
136
|
+
nextSeq = 1;
|
|
137
|
+
clearRuntimeDebugEventSeq();
|
|
138
|
+
clearDevtoolsEvents();
|
|
139
|
+
return currentRunId;
|
|
140
|
+
};
|
|
141
|
+
var clearDevtoolsEvents = () => {
|
|
142
|
+
ringBuffer.length = 0;
|
|
143
|
+
ringBufferSeq.length = 0;
|
|
144
|
+
exportBudget.dropped = 0;
|
|
145
|
+
exportBudget.oversized = 0;
|
|
146
|
+
markSnapshotChanged();
|
|
147
|
+
};
|
|
148
|
+
var setInstanceLabel = (instanceId, label) => {
|
|
149
|
+
instanceLabels.set(instanceId, label);
|
|
150
|
+
markSnapshotChanged();
|
|
151
|
+
};
|
|
152
|
+
var getInstanceLabel = (instanceId) => instanceLabels.get(instanceId);
|
|
153
|
+
var registerConvergeStaticIr = (ir) => {
|
|
154
|
+
convergeStaticIrByDigest.set(ir.staticIrDigest, ir);
|
|
155
|
+
};
|
|
156
|
+
var devtoolsHubConvergeStaticIrCollector = {
|
|
157
|
+
register: registerConvergeStaticIr
|
|
158
|
+
};
|
|
159
|
+
var exportDevtoolsEvidencePackage = (options) => {
|
|
160
|
+
const protocolVersion = options?.protocolVersion ?? OBSERVABILITY_PROTOCOL_VERSION;
|
|
161
|
+
const runId = options?.runId ?? currentRunId;
|
|
162
|
+
const source = options?.source ?? { host: "unknown" };
|
|
163
|
+
const events = ringBuffer.map((payload, i) => ({
|
|
164
|
+
protocolVersion,
|
|
165
|
+
runId,
|
|
166
|
+
seq: ringBufferSeq[i] ?? i + 1,
|
|
167
|
+
timestamp: payload.timestamp,
|
|
168
|
+
type: "debug:event",
|
|
169
|
+
payload
|
|
170
|
+
}));
|
|
171
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
172
|
+
const convergeDigests = /* @__PURE__ */ new Set();
|
|
173
|
+
let sawFullConverge = false;
|
|
174
|
+
for (const ref of ringBuffer) {
|
|
175
|
+
if (ref.kind !== "trait:converge") continue;
|
|
176
|
+
const meta = ref.meta;
|
|
177
|
+
if (!isRecord(meta)) continue;
|
|
178
|
+
const digest = meta.staticIrDigest;
|
|
179
|
+
if (typeof digest === "string" && digest.length > 0) {
|
|
180
|
+
convergeDigests.add(digest);
|
|
181
|
+
}
|
|
182
|
+
const dirty = meta.dirty;
|
|
183
|
+
if (isRecord(dirty) && typeof dirty.rootCount === "number") {
|
|
184
|
+
sawFullConverge = true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
let summary;
|
|
188
|
+
if (sawFullConverge && convergeDigests.size > 0) {
|
|
189
|
+
const staticIrByDigest = {};
|
|
190
|
+
for (const digest of convergeDigests) {
|
|
191
|
+
const ir = convergeStaticIrByDigest.get(digest);
|
|
192
|
+
if (ir) {
|
|
193
|
+
staticIrByDigest[digest] = ir;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (Object.keys(staticIrByDigest).length > 0) {
|
|
197
|
+
summary = { converge: { staticIrByDigest } };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return exportEvidencePackage({
|
|
201
|
+
protocolVersion,
|
|
202
|
+
runId,
|
|
203
|
+
source,
|
|
204
|
+
events,
|
|
205
|
+
summary
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
var devtoolsHubSink = {
|
|
209
|
+
record: (event) => Effect.gen(function* () {
|
|
210
|
+
const level = yield* FiberRef.get(currentDiagnosticsLevel);
|
|
211
|
+
let changed = false;
|
|
212
|
+
if (event.type === "trace:instanceLabel") {
|
|
213
|
+
const instanceId = event.instanceId;
|
|
214
|
+
const data = event.data;
|
|
215
|
+
const label = data && typeof data === "object" && "label" in data ? String(data.label) : void 0;
|
|
216
|
+
if (instanceId && label) {
|
|
217
|
+
instanceLabels.set(instanceId, label);
|
|
218
|
+
changed = true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (event.type === "module:init" || event.type === "module:destroy") {
|
|
222
|
+
const moduleId = event.moduleId ?? "unknown";
|
|
223
|
+
const runtimeLabel = event.runtimeLabel ?? "unknown";
|
|
224
|
+
const instanceId = event.instanceId;
|
|
225
|
+
const key = `${runtimeLabel}::${moduleId}`;
|
|
226
|
+
const prev = instances.get(key) ?? 0;
|
|
227
|
+
if (event.type === "module:init") {
|
|
228
|
+
instances.set(key, prev + 1);
|
|
229
|
+
changed = true;
|
|
230
|
+
if (instanceId) {
|
|
231
|
+
const instanceKey = `${runtimeLabel}::${moduleId}::${instanceId}`;
|
|
232
|
+
liveInstanceKeys.add(instanceKey);
|
|
233
|
+
if (latestStates.delete(instanceKey)) changed = true;
|
|
234
|
+
if (latestTraitSummaries.delete(instanceKey)) changed = true;
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
const next = prev - 1;
|
|
238
|
+
if (next <= 0) {
|
|
239
|
+
if (instances.delete(key)) changed = true;
|
|
240
|
+
} else {
|
|
241
|
+
instances.set(key, next);
|
|
242
|
+
changed = true;
|
|
243
|
+
}
|
|
244
|
+
if (instanceId) {
|
|
245
|
+
const instanceKey = `${runtimeLabel}::${moduleId}::${instanceId}`;
|
|
246
|
+
liveInstanceKeys.delete(instanceKey);
|
|
247
|
+
if (latestStates.delete(instanceKey)) changed = true;
|
|
248
|
+
if (latestTraitSummaries.delete(instanceKey)) changed = true;
|
|
249
|
+
if (instanceLabels.delete(instanceId)) changed = true;
|
|
250
|
+
changed = true;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
let exportBudgetChanged = false;
|
|
255
|
+
const ref = toRuntimeDebugEventRef(event, {
|
|
256
|
+
diagnosticsLevel: level,
|
|
257
|
+
resolveConvergeStaticIr: (staticIrDigest) => convergeStaticIrByDigest.get(staticIrDigest),
|
|
258
|
+
onMetaProjection: ({ stats }) => {
|
|
259
|
+
if (stats.dropped !== 0 || stats.oversized !== 0) {
|
|
260
|
+
exportBudgetChanged = true;
|
|
261
|
+
}
|
|
262
|
+
exportBudget.dropped += stats.dropped;
|
|
263
|
+
exportBudget.oversized += stats.oversized;
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
if (exportBudgetChanged) {
|
|
267
|
+
changed = true;
|
|
268
|
+
}
|
|
269
|
+
if (!ref) {
|
|
270
|
+
if (changed) {
|
|
271
|
+
markSnapshotChanged();
|
|
272
|
+
}
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (ref.kind === "state" && ref.label === "state:update") {
|
|
276
|
+
const runtimeLabel = ref.runtimeLabel ?? "unknown";
|
|
277
|
+
const key = `${runtimeLabel}::${ref.moduleId}::${ref.instanceId}`;
|
|
278
|
+
if (liveInstanceKeys.has(key)) {
|
|
279
|
+
if (ref.meta && typeof ref.meta === "object" && !Array.isArray(ref.meta)) {
|
|
280
|
+
const anyMeta = ref.meta;
|
|
281
|
+
if ("state" in anyMeta) {
|
|
282
|
+
latestStates.set(key, anyMeta.state);
|
|
283
|
+
changed = true;
|
|
284
|
+
}
|
|
285
|
+
if ("traitSummary" in anyMeta && anyMeta.traitSummary !== void 0) {
|
|
286
|
+
latestTraitSummaries.set(key, anyMeta.traitSummary);
|
|
287
|
+
changed = true;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (bufferSize > 0) {
|
|
293
|
+
const seq = nextSeq++;
|
|
294
|
+
ringBuffer.push(ref);
|
|
295
|
+
ringBufferSeq.push(seq);
|
|
296
|
+
trimRingBufferIfNeeded();
|
|
297
|
+
changed = true;
|
|
298
|
+
}
|
|
299
|
+
if (changed) {
|
|
300
|
+
markSnapshotChanged();
|
|
301
|
+
}
|
|
302
|
+
})
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// ../logix-core/src/internal/runtime/core/TickScheduler.ts
|
|
306
|
+
import { Effect as Effect5, FiberRef as FiberRef3 } from "../effect.js";
|
|
307
|
+
|
|
308
|
+
// ../logix-core/src/internal/runtime/core/JobQueue.ts
|
|
309
|
+
var maxPriority = (a, b) => a === "normal" || b === "normal" ? "normal" : "low";
|
|
310
|
+
var makeJobQueue = () => {
|
|
311
|
+
let pendingModules = /* @__PURE__ */ new Map();
|
|
312
|
+
let pendingDirtyTopics = /* @__PURE__ */ new Map();
|
|
313
|
+
const hasPending = () => pendingModules.size > 0 || pendingDirtyTopics.size > 0;
|
|
314
|
+
const enqueueModuleCommit = (commit) => {
|
|
315
|
+
const prev = pendingModules.get(commit.moduleInstanceKey);
|
|
316
|
+
if (!prev) {
|
|
317
|
+
pendingModules.set(commit.moduleInstanceKey, commit);
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
pendingModules.set(commit.moduleInstanceKey, {
|
|
321
|
+
...commit,
|
|
322
|
+
meta: {
|
|
323
|
+
...commit.meta,
|
|
324
|
+
priority: maxPriority(prev.meta.priority, commit.meta.priority)
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
return true;
|
|
328
|
+
};
|
|
329
|
+
const markTopicDirty = (topicKey, priority) => {
|
|
330
|
+
const prev = pendingDirtyTopics.get(topicKey);
|
|
331
|
+
pendingDirtyTopics.set(topicKey, prev ? maxPriority(prev, priority) : priority);
|
|
332
|
+
return prev != null;
|
|
333
|
+
};
|
|
334
|
+
const drain = () => {
|
|
335
|
+
if (!hasPending()) return void 0;
|
|
336
|
+
const drained = {
|
|
337
|
+
modules: pendingModules,
|
|
338
|
+
dirtyTopics: pendingDirtyTopics
|
|
339
|
+
};
|
|
340
|
+
pendingModules = /* @__PURE__ */ new Map();
|
|
341
|
+
pendingDirtyTopics = /* @__PURE__ */ new Map();
|
|
342
|
+
return drained;
|
|
343
|
+
};
|
|
344
|
+
const requeue = (drain2) => {
|
|
345
|
+
for (const [, commit] of drain2.modules) {
|
|
346
|
+
enqueueModuleCommit(commit);
|
|
347
|
+
}
|
|
348
|
+
for (const [k, p] of drain2.dirtyTopics) {
|
|
349
|
+
markTopicDirty(k, p);
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
return {
|
|
353
|
+
hasPending,
|
|
354
|
+
enqueueModuleCommit,
|
|
355
|
+
markTopicDirty,
|
|
356
|
+
drain,
|
|
357
|
+
requeue
|
|
358
|
+
};
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// ../logix-core/src/internal/runtime/core/TaskRunner.ts
|
|
362
|
+
import { Cause, Effect as Effect4, Fiber, FiberRef as FiberRef2, Ref, Stream } from "../effect.js";
|
|
363
|
+
|
|
364
|
+
// ../logix-core/src/internal/runtime/core/env.ts
|
|
365
|
+
import { Context, Effect as Effect3, Layer } from "../effect.js";
|
|
366
|
+
|
|
367
|
+
// ../logix-core/src/internal/runtime/core/RuntimeStore.ts
|
|
368
|
+
var makeModuleInstanceKey = (moduleId, instanceId) => `${moduleId}::${instanceId}`;
|
|
369
|
+
var makeReadQueryTopicKey = (moduleInstanceKey, selectorId) => `${moduleInstanceKey}::rq:${selectorId}`;
|
|
370
|
+
var parseTopicKey = (topicKey) => {
|
|
371
|
+
const idx = topicKey.indexOf("::");
|
|
372
|
+
if (idx <= 0) return void 0;
|
|
373
|
+
const moduleId = topicKey.slice(0, idx);
|
|
374
|
+
const rest = topicKey.slice(idx + 2);
|
|
375
|
+
if (rest.length === 0) return void 0;
|
|
376
|
+
const idx2 = rest.indexOf("::");
|
|
377
|
+
if (idx2 < 0) {
|
|
378
|
+
return { kind: "module", moduleInstanceKey: `${moduleId}::${rest}` };
|
|
379
|
+
}
|
|
380
|
+
const instanceId = rest.slice(0, idx2);
|
|
381
|
+
const suffix = rest.slice(idx2 + 2);
|
|
382
|
+
if (suffix.startsWith("rq:")) {
|
|
383
|
+
const selectorId = suffix.slice("rq:".length);
|
|
384
|
+
if (selectorId.length === 0) return void 0;
|
|
385
|
+
return {
|
|
386
|
+
kind: "readQuery",
|
|
387
|
+
moduleInstanceKey: `${moduleId}::${instanceId}`,
|
|
388
|
+
selectorId
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
return { kind: "module", moduleInstanceKey: `${moduleId}::${instanceId}` };
|
|
392
|
+
};
|
|
393
|
+
var makeRuntimeStore = () => {
|
|
394
|
+
let tickSeq = 0;
|
|
395
|
+
const moduleStates = /* @__PURE__ */ new Map();
|
|
396
|
+
const topicVersions = /* @__PURE__ */ new Map();
|
|
397
|
+
const topicPriorities = /* @__PURE__ */ new Map();
|
|
398
|
+
const listenersByTopic = /* @__PURE__ */ new Map();
|
|
399
|
+
const subscriberCountByModule = /* @__PURE__ */ new Map();
|
|
400
|
+
const getTopicVersion = (topicKey) => topicVersions.get(topicKey) ?? 0;
|
|
401
|
+
const getTopicPriority = (topicKey) => topicPriorities.get(topicKey) ?? "normal";
|
|
402
|
+
const commitTopicBump = (topicKey, priority) => {
|
|
403
|
+
const prev = topicVersions.get(topicKey) ?? 0;
|
|
404
|
+
topicVersions.set(topicKey, prev + 1);
|
|
405
|
+
topicPriorities.set(topicKey, priority);
|
|
406
|
+
};
|
|
407
|
+
const subscribeTopic = (topicKey, listener) => {
|
|
408
|
+
const info = parseTopicKey(topicKey);
|
|
409
|
+
const existing = listenersByTopic.get(topicKey);
|
|
410
|
+
const set = existing ?? /* @__PURE__ */ new Set();
|
|
411
|
+
const alreadyHas = set.has(listener);
|
|
412
|
+
if (!alreadyHas) {
|
|
413
|
+
set.add(listener);
|
|
414
|
+
}
|
|
415
|
+
if (!existing) {
|
|
416
|
+
listenersByTopic.set(topicKey, set);
|
|
417
|
+
}
|
|
418
|
+
if (!alreadyHas && info) {
|
|
419
|
+
const prev = subscriberCountByModule.get(info.moduleInstanceKey) ?? 0;
|
|
420
|
+
subscriberCountByModule.set(info.moduleInstanceKey, prev + 1);
|
|
421
|
+
}
|
|
422
|
+
return () => {
|
|
423
|
+
const current = listenersByTopic.get(topicKey);
|
|
424
|
+
if (!current) return;
|
|
425
|
+
const deleted = current.delete(listener);
|
|
426
|
+
if (deleted && info) {
|
|
427
|
+
const prev = subscriberCountByModule.get(info.moduleInstanceKey) ?? 0;
|
|
428
|
+
const next = prev - 1;
|
|
429
|
+
if (next <= 0) {
|
|
430
|
+
subscriberCountByModule.delete(info.moduleInstanceKey);
|
|
431
|
+
} else {
|
|
432
|
+
subscriberCountByModule.set(info.moduleInstanceKey, next);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if (current.size === 0) {
|
|
436
|
+
listenersByTopic.delete(topicKey);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
};
|
|
440
|
+
const getTopicSubscriberCount = (topicKey) => listenersByTopic.get(topicKey)?.size ?? 0;
|
|
441
|
+
const getModuleSubscriberCount = (moduleInstanceKey) => subscriberCountByModule.get(moduleInstanceKey) ?? 0;
|
|
442
|
+
const registerModuleInstance = (args) => {
|
|
443
|
+
moduleStates.set(args.moduleInstanceKey, args.initialState);
|
|
444
|
+
if (!topicVersions.has(args.moduleInstanceKey)) {
|
|
445
|
+
topicVersions.set(args.moduleInstanceKey, 0);
|
|
446
|
+
topicPriorities.set(args.moduleInstanceKey, "normal");
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
const unregisterModuleInstance = (moduleInstanceKey) => {
|
|
450
|
+
moduleStates.delete(moduleInstanceKey);
|
|
451
|
+
};
|
|
452
|
+
const commitTick = (args) => {
|
|
453
|
+
tickSeq = args.tickSeq;
|
|
454
|
+
for (const [key, commit] of args.accepted.modules) {
|
|
455
|
+
moduleStates.set(key, commit.state);
|
|
456
|
+
}
|
|
457
|
+
const changedTopics = /* @__PURE__ */ new Map();
|
|
458
|
+
for (const [topicKey, priority] of args.accepted.dirtyTopics) {
|
|
459
|
+
commitTopicBump(topicKey, priority);
|
|
460
|
+
const listeners2 = Array.from(listenersByTopic.get(topicKey) ?? []);
|
|
461
|
+
if (listeners2.length > 0) {
|
|
462
|
+
changedTopics.set(topicKey, { priority, listeners: listeners2 });
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return { changedTopics };
|
|
466
|
+
};
|
|
467
|
+
const getModuleState = (moduleInstanceKey) => moduleStates.get(moduleInstanceKey);
|
|
468
|
+
const dispose = () => {
|
|
469
|
+
moduleStates.clear();
|
|
470
|
+
topicVersions.clear();
|
|
471
|
+
topicPriorities.clear();
|
|
472
|
+
listenersByTopic.clear();
|
|
473
|
+
subscriberCountByModule.clear();
|
|
474
|
+
};
|
|
475
|
+
return {
|
|
476
|
+
getTickSeq: () => tickSeq,
|
|
477
|
+
getModuleState,
|
|
478
|
+
getTopicVersion,
|
|
479
|
+
getTopicPriority,
|
|
480
|
+
subscribeTopic,
|
|
481
|
+
getTopicSubscriberCount,
|
|
482
|
+
getModuleSubscriberCount,
|
|
483
|
+
registerModuleInstance,
|
|
484
|
+
unregisterModuleInstance,
|
|
485
|
+
commitTick,
|
|
486
|
+
dispose
|
|
487
|
+
};
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
// ../logix-core/src/internal/runtime/core/DeclarativeLinkRuntime.ts
|
|
491
|
+
import { Effect as Effect2 } from "../effect.js";
|
|
492
|
+
var makeDeclarativeLinkRuntime = () => {
|
|
493
|
+
const moduleAsSourceById = /* @__PURE__ */ new Map();
|
|
494
|
+
const moduleAsSourceIdsBySource = /* @__PURE__ */ new Map();
|
|
495
|
+
const declarativeById = /* @__PURE__ */ new Map();
|
|
496
|
+
const declarativeReadNodesBySource = /* @__PURE__ */ new Map();
|
|
497
|
+
const registerModuleAsSourceLink = (link) => {
|
|
498
|
+
const stored = {
|
|
499
|
+
...link,
|
|
500
|
+
hasValue: false,
|
|
501
|
+
lastValue: void 0
|
|
502
|
+
};
|
|
503
|
+
moduleAsSourceById.set(link.id, stored);
|
|
504
|
+
const set = moduleAsSourceIdsBySource.get(link.sourceModuleInstanceKey) ?? /* @__PURE__ */ new Set();
|
|
505
|
+
set.add(link.id);
|
|
506
|
+
moduleAsSourceIdsBySource.set(link.sourceModuleInstanceKey, set);
|
|
507
|
+
return () => {
|
|
508
|
+
moduleAsSourceById.delete(link.id);
|
|
509
|
+
const current = moduleAsSourceIdsBySource.get(link.sourceModuleInstanceKey);
|
|
510
|
+
if (!current) return;
|
|
511
|
+
current.delete(link.id);
|
|
512
|
+
if (current.size === 0) {
|
|
513
|
+
moduleAsSourceIdsBySource.delete(link.sourceModuleInstanceKey);
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
};
|
|
517
|
+
const registerDeclarativeLink = (link) => {
|
|
518
|
+
const readNodeById = /* @__PURE__ */ new Map();
|
|
519
|
+
for (const n of link.readNodes) {
|
|
520
|
+
readNodeById.set(n.nodeId, n);
|
|
521
|
+
}
|
|
522
|
+
const dispatchNodeById = /* @__PURE__ */ new Map();
|
|
523
|
+
for (const n of link.dispatchNodes) {
|
|
524
|
+
dispatchNodeById.set(n.nodeId, n);
|
|
525
|
+
}
|
|
526
|
+
const incomingByDispatch = /* @__PURE__ */ new Map();
|
|
527
|
+
for (const e of link.ir.edges) {
|
|
528
|
+
const to = e.to;
|
|
529
|
+
const isDispatch = dispatchNodeById.has(to);
|
|
530
|
+
if (!isDispatch) continue;
|
|
531
|
+
incomingByDispatch.set(to, (incomingByDispatch.get(to) ?? 0) + 1);
|
|
532
|
+
const count = incomingByDispatch.get(to) ?? 0;
|
|
533
|
+
if (count > 1) {
|
|
534
|
+
throw new Error(
|
|
535
|
+
`[DeclarativeLinkRuntime] Invalid DeclarativeLinkIR: dispatch node has multiple incoming edges (linkId=${link.linkId}, nodeId=${to}).`
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
const dispatchTargetsByReadNode = /* @__PURE__ */ new Map();
|
|
540
|
+
for (const e of link.ir.edges) {
|
|
541
|
+
const from = e.from;
|
|
542
|
+
const to = e.to;
|
|
543
|
+
if (!readNodeById.has(from)) continue;
|
|
544
|
+
if (!dispatchNodeById.has(to)) continue;
|
|
545
|
+
const list = dispatchTargetsByReadNode.get(from) ?? [];
|
|
546
|
+
list.push(to);
|
|
547
|
+
dispatchTargetsByReadNode.set(from, list);
|
|
548
|
+
}
|
|
549
|
+
const stored = {
|
|
550
|
+
...link,
|
|
551
|
+
readNodeById,
|
|
552
|
+
dispatchNodeById,
|
|
553
|
+
dispatchTargetsByReadNode,
|
|
554
|
+
readNodeState: /* @__PURE__ */ new Map()
|
|
555
|
+
};
|
|
556
|
+
declarativeById.set(link.linkId, stored);
|
|
557
|
+
for (const n of link.readNodes) {
|
|
558
|
+
const list = declarativeReadNodesBySource.get(n.moduleInstanceKey) ?? [];
|
|
559
|
+
list.push({ linkId: link.linkId, nodeId: n.nodeId });
|
|
560
|
+
declarativeReadNodesBySource.set(n.moduleInstanceKey, list);
|
|
561
|
+
}
|
|
562
|
+
return () => {
|
|
563
|
+
declarativeById.delete(link.linkId);
|
|
564
|
+
for (const n of link.readNodes) {
|
|
565
|
+
const list = declarativeReadNodesBySource.get(n.moduleInstanceKey);
|
|
566
|
+
if (!list) continue;
|
|
567
|
+
const next = list.filter((x) => !(x.linkId === link.linkId && x.nodeId === n.nodeId));
|
|
568
|
+
if (next.length === 0) {
|
|
569
|
+
declarativeReadNodesBySource.delete(n.moduleInstanceKey);
|
|
570
|
+
} else {
|
|
571
|
+
declarativeReadNodesBySource.set(n.moduleInstanceKey, next);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
};
|
|
576
|
+
const applyForSources = (args) => Effect2.gen(function* () {
|
|
577
|
+
let scheduled = false;
|
|
578
|
+
for (const sourceKey of args.changedModuleInstanceKeys) {
|
|
579
|
+
const ids = moduleAsSourceIdsBySource.get(sourceKey);
|
|
580
|
+
if (!ids || ids.size === 0) continue;
|
|
581
|
+
const commit = args.acceptedModules.get(sourceKey);
|
|
582
|
+
if (!commit) continue;
|
|
583
|
+
for (const id of ids) {
|
|
584
|
+
const link = moduleAsSourceById.get(id);
|
|
585
|
+
if (!link) continue;
|
|
586
|
+
let selected;
|
|
587
|
+
try {
|
|
588
|
+
selected = link.readQuery.select(commit.state);
|
|
589
|
+
} catch {
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const nextValue = link.computeValue(selected);
|
|
593
|
+
if (link.hasValue && link.equalsValue(link.lastValue, nextValue)) {
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
link.hasValue = true;
|
|
597
|
+
link.lastValue = nextValue;
|
|
598
|
+
scheduled = true;
|
|
599
|
+
yield* link.applyValue(nextValue);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
for (const sourceKey of args.changedModuleInstanceKeys) {
|
|
603
|
+
const refs = declarativeReadNodesBySource.get(sourceKey);
|
|
604
|
+
if (!refs || refs.length === 0) continue;
|
|
605
|
+
const commit = args.acceptedModules.get(sourceKey);
|
|
606
|
+
if (!commit) continue;
|
|
607
|
+
for (const ref of refs) {
|
|
608
|
+
const link = declarativeById.get(ref.linkId);
|
|
609
|
+
if (!link) continue;
|
|
610
|
+
const readNode = link.readNodeById.get(ref.nodeId);
|
|
611
|
+
if (!readNode) continue;
|
|
612
|
+
let value;
|
|
613
|
+
try {
|
|
614
|
+
value = readNode.readQuery.select(commit.state);
|
|
615
|
+
} catch {
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
const state = link.readNodeState.get(ref.nodeId) ?? { hasValue: false, lastValue: void 0 };
|
|
619
|
+
const changed = !state.hasValue || !Object.is(state.lastValue, value);
|
|
620
|
+
if (!changed) continue;
|
|
621
|
+
state.hasValue = true;
|
|
622
|
+
state.lastValue = value;
|
|
623
|
+
link.readNodeState.set(ref.nodeId, state);
|
|
624
|
+
const targets = link.dispatchTargetsByReadNode.get(ref.nodeId) ?? [];
|
|
625
|
+
for (const dispatchNodeId of targets) {
|
|
626
|
+
const node = link.dispatchNodeById.get(dispatchNodeId);
|
|
627
|
+
if (!node) continue;
|
|
628
|
+
scheduled = true;
|
|
629
|
+
yield* node.dispatch(value);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
return { scheduled };
|
|
634
|
+
});
|
|
635
|
+
return {
|
|
636
|
+
registerModuleAsSourceLink,
|
|
637
|
+
registerDeclarativeLink,
|
|
638
|
+
applyForSources
|
|
639
|
+
};
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
// ../logix-core/src/internal/runtime/core/env.ts
|
|
643
|
+
var getNodeEnv = () => {
|
|
644
|
+
try {
|
|
645
|
+
const env = globalThis?.process?.env;
|
|
646
|
+
return typeof env?.NODE_ENV === "string" ? env.NODE_ENV : void 0;
|
|
647
|
+
} catch {
|
|
648
|
+
return void 0;
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
var isDevEnv = () => getNodeEnv() !== "production";
|
|
652
|
+
var getDefaultStateTxnInstrumentation = () => isDevEnv() ? "full" : "light";
|
|
653
|
+
var StateTransactionConfigTagImpl = class extends Context.Tag("@logixjs/core/StateTransactionRuntimeConfig")() {
|
|
654
|
+
};
|
|
655
|
+
var StateTransactionConfigTag = StateTransactionConfigTagImpl;
|
|
656
|
+
var ReadQueryStrictGateConfigTagImpl = class extends Context.Tag("@logixjs/core/ReadQueryStrictGateRuntimeConfig")() {
|
|
657
|
+
};
|
|
658
|
+
var ReadQueryStrictGateConfigTag = ReadQueryStrictGateConfigTagImpl;
|
|
659
|
+
var ReplayModeConfigTagImpl = class extends Context.Tag("@logixjs/core/ReplayModeConfig")() {
|
|
660
|
+
};
|
|
661
|
+
var ReplayModeConfigTag = ReplayModeConfigTagImpl;
|
|
662
|
+
var StateTransactionOverridesTagImpl = class extends Context.Tag("@logixjs/core/StateTransactionOverrides")() {
|
|
663
|
+
};
|
|
664
|
+
var StateTransactionOverridesTag = StateTransactionOverridesTagImpl;
|
|
665
|
+
var ConcurrencyPolicyTagImpl = class extends Context.Tag("@logixjs/core/ConcurrencyPolicy")() {
|
|
666
|
+
};
|
|
667
|
+
var ConcurrencyPolicyTag = ConcurrencyPolicyTagImpl;
|
|
668
|
+
var ConcurrencyPolicyOverridesTagImpl = class extends Context.Tag("@logixjs/core/ConcurrencyPolicyOverrides")() {
|
|
669
|
+
};
|
|
670
|
+
var ConcurrencyPolicyOverridesTag = ConcurrencyPolicyOverridesTagImpl;
|
|
671
|
+
var RuntimeStoreTag = class extends Context.Tag("@logixjs/core/RuntimeStore")() {
|
|
672
|
+
};
|
|
673
|
+
var runtimeStoreLayer = Layer.scoped(
|
|
674
|
+
RuntimeStoreTag,
|
|
675
|
+
Effect3.acquireRelease(
|
|
676
|
+
Effect3.sync(() => makeRuntimeStore()),
|
|
677
|
+
(store) => Effect3.sync(() => store.dispose())
|
|
678
|
+
)
|
|
679
|
+
);
|
|
680
|
+
var HostSchedulerTag = class extends Context.Tag("@logixjs/core/HostScheduler")() {
|
|
681
|
+
};
|
|
682
|
+
var hostSchedulerLayer = Layer.succeed(
|
|
683
|
+
HostSchedulerTag,
|
|
684
|
+
getGlobalHostScheduler()
|
|
685
|
+
);
|
|
686
|
+
var DeclarativeLinkRuntimeTag = class extends Context.Tag("@logixjs/core/DeclarativeLinkRuntime")() {
|
|
687
|
+
};
|
|
688
|
+
var declarativeLinkRuntimeLayer = Layer.succeed(
|
|
689
|
+
DeclarativeLinkRuntimeTag,
|
|
690
|
+
makeDeclarativeLinkRuntime()
|
|
691
|
+
);
|
|
692
|
+
var TickSchedulerTag = class extends Context.Tag("@logixjs/core/TickScheduler")() {
|
|
693
|
+
};
|
|
694
|
+
var tickSchedulerLayer = (config) => Layer.effect(
|
|
695
|
+
TickSchedulerTag,
|
|
696
|
+
Effect3.gen(function* () {
|
|
697
|
+
const store = yield* RuntimeStoreTag;
|
|
698
|
+
const declarativeLinkRuntime = yield* DeclarativeLinkRuntimeTag;
|
|
699
|
+
const hostScheduler = yield* HostSchedulerTag;
|
|
700
|
+
return makeTickScheduler({ runtimeStore: store, declarativeLinkRuntime, hostScheduler, config });
|
|
701
|
+
})
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
// ../logix-core/src/internal/runtime/core/TaskRunner.ts
|
|
705
|
+
var inSyncTransactionFiber = FiberRef2.unsafeMake(false);
|
|
706
|
+
var forceSourceRefresh = FiberRef2.unsafeMake(false);
|
|
707
|
+
var inSyncTransactionGlobalDepth = 0;
|
|
708
|
+
var enterSyncTransaction = () => {
|
|
709
|
+
inSyncTransactionGlobalDepth += 1;
|
|
710
|
+
};
|
|
711
|
+
var exitSyncTransaction = () => {
|
|
712
|
+
inSyncTransactionGlobalDepth = Math.max(0, inSyncTransactionGlobalDepth - 1);
|
|
713
|
+
};
|
|
714
|
+
var isInSyncTransaction = () => inSyncTransactionGlobalDepth > 0;
|
|
715
|
+
var resolve = (eff, payload) => typeof eff === "function" ? eff(payload) : eff;
|
|
716
|
+
var defaultOrigins = (triggerName) => ({
|
|
717
|
+
pending: {
|
|
718
|
+
kind: "task:pending",
|
|
719
|
+
name: triggerName
|
|
720
|
+
},
|
|
721
|
+
success: {
|
|
722
|
+
kind: "service-callback",
|
|
723
|
+
name: "task:success"
|
|
724
|
+
},
|
|
725
|
+
failure: {
|
|
726
|
+
kind: "service-callback",
|
|
727
|
+
name: "task:failure"
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
var shouldNoopInSyncTransactionFiber = (options) => Effect4.gen(function* () {
|
|
731
|
+
const inTxn = yield* FiberRef2.get(inSyncTransactionFiber);
|
|
732
|
+
if (!inTxn) {
|
|
733
|
+
return false;
|
|
734
|
+
}
|
|
735
|
+
if (isDevEnv()) {
|
|
736
|
+
yield* record({
|
|
737
|
+
type: "diagnostic",
|
|
738
|
+
moduleId: options.moduleId,
|
|
739
|
+
instanceId: options.instanceId,
|
|
740
|
+
code: options.code,
|
|
741
|
+
severity: options.severity,
|
|
742
|
+
message: options.message,
|
|
743
|
+
hint: options.hint,
|
|
744
|
+
actionTag: options.actionTag,
|
|
745
|
+
kind: options.kind
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
return true;
|
|
749
|
+
});
|
|
750
|
+
var resolveConcurrencyLimit = (runtime) => runtime.resolveConcurrencyPolicy ? runtime.resolveConcurrencyPolicy().pipe(Effect4.map((p) => p.concurrencyLimit)) : Effect4.succeed(16);
|
|
751
|
+
var runTaskLifecycle = (payload, runtime, config, getCanWriteBack) => Effect4.gen(function* () {
|
|
752
|
+
const noop = yield* shouldNoopInSyncTransactionFiber({
|
|
753
|
+
moduleId: runtime.moduleId,
|
|
754
|
+
instanceId: runtime.instanceId,
|
|
755
|
+
code: "logic::invalid_usage",
|
|
756
|
+
severity: "error",
|
|
757
|
+
message: "run*Task is not allowed inside a synchronous StateTransaction body (it may deadlock the txnQueue).",
|
|
758
|
+
hint: "Call run*Task from the run section of a watcher (e.g. $.onAction/$.onState/$.on); do not call it directly inside a reducer / trait.run / synchronous transaction body. For long-lived flows, use a multi-entry pattern (pending \u2192 IO \u2192 writeback).",
|
|
759
|
+
kind: "run_task_in_transaction"
|
|
760
|
+
});
|
|
761
|
+
if (noop) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
const defaults = defaultOrigins(config.triggerName);
|
|
765
|
+
const origins = {
|
|
766
|
+
pending: config.origin?.pending ?? defaults.pending,
|
|
767
|
+
success: config.origin?.success ?? defaults.success,
|
|
768
|
+
failure: config.origin?.failure ?? defaults.failure
|
|
769
|
+
};
|
|
770
|
+
const pending = config.pending;
|
|
771
|
+
if (pending) {
|
|
772
|
+
yield* Effect4.uninterruptible(
|
|
773
|
+
runtime.runWithStateTransaction(origins.pending, () => Effect4.asVoid(resolve(pending, payload)))
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
const io = resolve(config.effect, payload);
|
|
777
|
+
const exit = yield* Effect4.exit(io);
|
|
778
|
+
if (getCanWriteBack) {
|
|
779
|
+
const ok = yield* getCanWriteBack;
|
|
780
|
+
if (!ok) {
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
if (exit._tag === "Success") {
|
|
785
|
+
const success = config.success;
|
|
786
|
+
if (success) {
|
|
787
|
+
yield* runtime.runWithStateTransaction(origins.success, () => Effect4.asVoid(success(exit.value, payload)));
|
|
788
|
+
}
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const cause = exit.cause;
|
|
792
|
+
if (Cause.isInterrupted(cause)) {
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
const failure = config.failure;
|
|
796
|
+
if (failure) {
|
|
797
|
+
yield* runtime.runWithStateTransaction(origins.failure, () => Effect4.asVoid(failure(cause, payload)));
|
|
798
|
+
}
|
|
799
|
+
}).pipe(
|
|
800
|
+
// Watchers must not crash as a whole due to a single task failure: swallow errors, but keep them diagnosable.
|
|
801
|
+
Effect4.catchAllCause(
|
|
802
|
+
(cause) => record({
|
|
803
|
+
type: "diagnostic",
|
|
804
|
+
moduleId: runtime.moduleId,
|
|
805
|
+
instanceId: runtime.instanceId,
|
|
806
|
+
code: "task_runner::unhandled_failure",
|
|
807
|
+
severity: "error",
|
|
808
|
+
message: "TaskRunner encountered an unhandled failure (pending/IO/writeback).",
|
|
809
|
+
hint: "Add a failure writeback for this task or handle errors explicitly upstream; avoid fire-and-forget swallowing errors.",
|
|
810
|
+
actionTag: config.triggerName,
|
|
811
|
+
kind: "task_runner_unhandled_failure",
|
|
812
|
+
trigger: {
|
|
813
|
+
kind: "task",
|
|
814
|
+
name: config.triggerName
|
|
815
|
+
}
|
|
816
|
+
}).pipe(Effect4.zipRight(Effect4.logError("TaskRunner error", cause)))
|
|
817
|
+
)
|
|
818
|
+
);
|
|
819
|
+
var makeTaskRunner = (stream, mode, runtime, config) => {
|
|
820
|
+
if (mode === "latest") {
|
|
821
|
+
return Effect4.gen(function* () {
|
|
822
|
+
const taskIdRef = yield* Ref.make(0);
|
|
823
|
+
const currentFiberRef = yield* Ref.make(void 0);
|
|
824
|
+
const start = (payload) => Effect4.gen(function* () {
|
|
825
|
+
const taskId = yield* Ref.updateAndGet(taskIdRef, (n) => n + 1);
|
|
826
|
+
const prev = yield* Ref.get(currentFiberRef);
|
|
827
|
+
if (prev) {
|
|
828
|
+
yield* Fiber.interruptFork(prev);
|
|
829
|
+
}
|
|
830
|
+
const canWriteBack = Ref.get(taskIdRef).pipe(Effect4.map((current) => current === taskId));
|
|
831
|
+
const fiber = yield* Effect4.fork(
|
|
832
|
+
runTaskLifecycle(payload, runtime, config, canWriteBack)
|
|
833
|
+
);
|
|
834
|
+
yield* Ref.set(currentFiberRef, fiber);
|
|
835
|
+
});
|
|
836
|
+
return yield* Stream.runForEach(stream, start);
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
if (mode === "exhaust") {
|
|
840
|
+
return Effect4.gen(function* () {
|
|
841
|
+
const concurrency = yield* resolveConcurrencyLimit(runtime);
|
|
842
|
+
const busyRef = yield* Ref.make(false);
|
|
843
|
+
const mapper = (payload) => Effect4.gen(function* () {
|
|
844
|
+
const acquired = yield* Ref.modify(
|
|
845
|
+
busyRef,
|
|
846
|
+
(busy) => busy ? [false, busy] : [true, true]
|
|
847
|
+
);
|
|
848
|
+
if (!acquired) {
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
try {
|
|
852
|
+
yield* runTaskLifecycle(payload, runtime, config);
|
|
853
|
+
} finally {
|
|
854
|
+
yield* Ref.set(busyRef, false);
|
|
855
|
+
}
|
|
856
|
+
});
|
|
857
|
+
return yield* Stream.runDrain(stream.pipe(Stream.mapEffect(mapper, { concurrency })));
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
if (mode === "parallel") {
|
|
861
|
+
return Effect4.gen(function* () {
|
|
862
|
+
const concurrency = yield* resolveConcurrencyLimit(runtime);
|
|
863
|
+
return yield* Stream.runDrain(
|
|
864
|
+
stream.pipe(
|
|
865
|
+
Stream.mapEffect((payload) => runTaskLifecycle(payload, runtime, config), {
|
|
866
|
+
concurrency
|
|
867
|
+
})
|
|
868
|
+
)
|
|
869
|
+
);
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
return Stream.runForEach(
|
|
873
|
+
stream,
|
|
874
|
+
(payload) => runTaskLifecycle(payload, runtime, config)
|
|
875
|
+
);
|
|
876
|
+
};
|
|
877
|
+
|
|
878
|
+
// ../logix-core/src/internal/runtime/core/TickScheduler.ts
|
|
879
|
+
var batchDepth = 0;
|
|
880
|
+
var batchWaiters = /* @__PURE__ */ new Set();
|
|
881
|
+
var enterRuntimeBatch = () => {
|
|
882
|
+
batchDepth += 1;
|
|
883
|
+
};
|
|
884
|
+
var exitRuntimeBatch = () => {
|
|
885
|
+
batchDepth = Math.max(0, batchDepth - 1);
|
|
886
|
+
if (batchDepth !== 0) return;
|
|
887
|
+
const waiters = Array.from(batchWaiters);
|
|
888
|
+
batchWaiters.clear();
|
|
889
|
+
for (const w of waiters) {
|
|
890
|
+
try {
|
|
891
|
+
w.resolve();
|
|
892
|
+
} catch {
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
var waitForBatchEndIfNeeded = () => batchDepth === 0 ? Effect5.void : Effect5.async((resume, signal) => {
|
|
897
|
+
let done = false;
|
|
898
|
+
const cleanup = () => {
|
|
899
|
+
if (done) return;
|
|
900
|
+
done = true;
|
|
901
|
+
batchWaiters.delete(waiter);
|
|
902
|
+
try {
|
|
903
|
+
signal.removeEventListener("abort", onAbort);
|
|
904
|
+
} catch {
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
const onAbort = () => {
|
|
908
|
+
cleanup();
|
|
909
|
+
};
|
|
910
|
+
const waiter = {
|
|
911
|
+
resolve: () => {
|
|
912
|
+
cleanup();
|
|
913
|
+
resume(Effect5.void);
|
|
914
|
+
}
|
|
915
|
+
};
|
|
916
|
+
batchWaiters.add(waiter);
|
|
917
|
+
try {
|
|
918
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
919
|
+
} catch {
|
|
920
|
+
}
|
|
921
|
+
});
|
|
922
|
+
var clampSampleRate = (sampleRate) => {
|
|
923
|
+
if (typeof sampleRate !== "number" || !Number.isFinite(sampleRate)) return 0;
|
|
924
|
+
if (sampleRate <= 0) return 0;
|
|
925
|
+
if (sampleRate >= 1) return 1;
|
|
926
|
+
return sampleRate;
|
|
927
|
+
};
|
|
928
|
+
var shouldSampleTick = (tickSeq, sampleRate) => {
|
|
929
|
+
if (sampleRate <= 0) return false;
|
|
930
|
+
if (sampleRate >= 1) return true;
|
|
931
|
+
const x = tickSeq >>> 0;
|
|
932
|
+
const h = Math.imul(x ^ 2654435769, 2246822507) >>> 0;
|
|
933
|
+
return h / 4294967295 < sampleRate;
|
|
934
|
+
};
|
|
935
|
+
var toTriggerKind = (originKind) => {
|
|
936
|
+
if (originKind === "action") return "dispatch";
|
|
937
|
+
if (originKind === "trait-external-store") return "externalStore";
|
|
938
|
+
if (originKind?.includes("timer")) return "timer";
|
|
939
|
+
return "unknown";
|
|
940
|
+
};
|
|
941
|
+
var toLane = (priority) => priority === "low" ? "nonUrgent" : "urgent";
|
|
942
|
+
var maxPriority2 = (a, b) => a === "normal" || b === "normal" ? "normal" : "low";
|
|
943
|
+
var mergeDrain = (base, next) => {
|
|
944
|
+
const modules = new Map(base.modules);
|
|
945
|
+
for (const [k, commit] of next.modules) {
|
|
946
|
+
const prev = modules.get(k);
|
|
947
|
+
if (!prev) {
|
|
948
|
+
modules.set(k, commit);
|
|
949
|
+
} else {
|
|
950
|
+
modules.set(k, {
|
|
951
|
+
...commit,
|
|
952
|
+
meta: {
|
|
953
|
+
...commit.meta,
|
|
954
|
+
priority: maxPriority2(prev.meta.priority, commit.meta.priority)
|
|
955
|
+
}
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
const dirtyTopics = new Map(base.dirtyTopics);
|
|
960
|
+
for (const [k, p] of next.dirtyTopics) {
|
|
961
|
+
const prev = dirtyTopics.get(k);
|
|
962
|
+
dirtyTopics.set(k, prev ? maxPriority2(prev, p) : p);
|
|
963
|
+
}
|
|
964
|
+
return { modules, dirtyTopics };
|
|
965
|
+
};
|
|
966
|
+
var emptyDrain = () => ({ modules: /* @__PURE__ */ new Map(), dirtyTopics: /* @__PURE__ */ new Map() });
|
|
967
|
+
var makeTickScheduler = (args) => {
|
|
968
|
+
const store = args.runtimeStore;
|
|
969
|
+
const hostScheduler = args.hostScheduler;
|
|
970
|
+
const declarativeLinks = args.declarativeLinkRuntime;
|
|
971
|
+
const queue = args.queue ?? makeJobQueue();
|
|
972
|
+
const config = {
|
|
973
|
+
maxSteps: args.config?.maxSteps ?? 64,
|
|
974
|
+
urgentStepCap: args.config?.urgentStepCap ?? 512,
|
|
975
|
+
maxDrainRounds: args.config?.maxDrainRounds ?? 8,
|
|
976
|
+
microtaskChainDepthLimit: args.config?.microtaskChainDepthLimit ?? 32
|
|
977
|
+
};
|
|
978
|
+
const telemetry = args.config?.telemetry;
|
|
979
|
+
const telemetrySampleRate = clampSampleRate(telemetry?.sampleRate);
|
|
980
|
+
let tickSeq = 0;
|
|
981
|
+
let scheduled = false;
|
|
982
|
+
let microtaskChainDepth = 0;
|
|
983
|
+
let nextForcedReason;
|
|
984
|
+
let coalescedModules = 0;
|
|
985
|
+
let coalescedTopics = 0;
|
|
986
|
+
const yieldMicrotask = Effect5.async((resume) => {
|
|
987
|
+
hostScheduler.scheduleMicrotask(() => resume(Effect5.void));
|
|
988
|
+
});
|
|
989
|
+
const yieldMacrotask = Effect5.async((resume, signal) => {
|
|
990
|
+
const cancel = hostScheduler.scheduleMacrotask(() => resume(Effect5.void));
|
|
991
|
+
try {
|
|
992
|
+
signal.addEventListener(
|
|
993
|
+
"abort",
|
|
994
|
+
() => {
|
|
995
|
+
cancel();
|
|
996
|
+
},
|
|
997
|
+
{ once: true }
|
|
998
|
+
);
|
|
999
|
+
} catch {
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
const scheduleTick = () => Effect5.gen(function* () {
|
|
1003
|
+
if (scheduled) return;
|
|
1004
|
+
scheduled = true;
|
|
1005
|
+
const waitedForBatch = batchDepth > 0;
|
|
1006
|
+
const forcedReason = nextForcedReason;
|
|
1007
|
+
nextForcedReason = void 0;
|
|
1008
|
+
const shouldYieldForStarvation = forcedReason == null && microtaskChainDepth >= Math.max(1, config.microtaskChainDepthLimit);
|
|
1009
|
+
const reason = forcedReason ?? (shouldYieldForStarvation ? "microtask_starvation" : void 0);
|
|
1010
|
+
const boundary = reason ? "macrotask" : "microtask";
|
|
1011
|
+
const startedAs = waitedForBatch ? "batch" : boundary;
|
|
1012
|
+
const depthAtSchedule = microtaskChainDepth;
|
|
1013
|
+
yield* Effect5.forkDaemon(
|
|
1014
|
+
Effect5.locally(inSyncTransactionFiber, false)(
|
|
1015
|
+
Effect5.gen(function* () {
|
|
1016
|
+
try {
|
|
1017
|
+
yield* waitForBatchEndIfNeeded();
|
|
1018
|
+
if (boundary === "microtask") {
|
|
1019
|
+
yield* yieldMicrotask;
|
|
1020
|
+
microtaskChainDepth += 1;
|
|
1021
|
+
} else {
|
|
1022
|
+
yield* yieldMacrotask;
|
|
1023
|
+
microtaskChainDepth = 0;
|
|
1024
|
+
}
|
|
1025
|
+
const schedule = {
|
|
1026
|
+
startedAs,
|
|
1027
|
+
microtaskChainDepth: boundary === "macrotask" ? depthAtSchedule : microtaskChainDepth,
|
|
1028
|
+
...boundary === "macrotask" ? { forcedMacrotask: true, reason: reason ?? "unknown" } : {}
|
|
1029
|
+
};
|
|
1030
|
+
const outcome = yield* flushTick(schedule);
|
|
1031
|
+
if (!outcome.stable) {
|
|
1032
|
+
nextForcedReason = outcome.degradeReason === "budget_steps" ? "budget" : outcome.degradeReason === "cycle_detected" ? "cycle_detected" : "unknown";
|
|
1033
|
+
}
|
|
1034
|
+
} finally {
|
|
1035
|
+
scheduled = false;
|
|
1036
|
+
if (queue.hasPending()) {
|
|
1037
|
+
yield* scheduleTick();
|
|
1038
|
+
} else {
|
|
1039
|
+
microtaskChainDepth = 0;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
})
|
|
1043
|
+
)
|
|
1044
|
+
);
|
|
1045
|
+
});
|
|
1046
|
+
const flushTick = (schedule) => Effect5.gen(function* () {
|
|
1047
|
+
if (!queue.hasPending()) {
|
|
1048
|
+
return { stable: true };
|
|
1049
|
+
}
|
|
1050
|
+
tickSeq += 1;
|
|
1051
|
+
const currentTickSeq = tickSeq;
|
|
1052
|
+
const diagnosticsLevel = yield* FiberRef3.get(currentDiagnosticsLevel);
|
|
1053
|
+
const shouldEmitTrace = isDevtoolsEnabled() && diagnosticsLevel !== "off";
|
|
1054
|
+
const captured = {
|
|
1055
|
+
drainRounds: 0,
|
|
1056
|
+
stable: true,
|
|
1057
|
+
accepted: emptyDrain()
|
|
1058
|
+
};
|
|
1059
|
+
while (captured.drainRounds < config.maxDrainRounds) {
|
|
1060
|
+
const drained = queue.drain();
|
|
1061
|
+
if (!drained) break;
|
|
1062
|
+
captured.drainRounds += 1;
|
|
1063
|
+
captured.accepted = mergeDrain(captured.accepted, drained);
|
|
1064
|
+
if (declarativeLinks && drained.modules.size > 0) {
|
|
1065
|
+
const changedModuleInstanceKeys = Array.from(drained.modules.keys());
|
|
1066
|
+
yield* declarativeLinks.applyForSources({
|
|
1067
|
+
tickSeq: currentTickSeq,
|
|
1068
|
+
acceptedModules: captured.accepted.modules,
|
|
1069
|
+
changedModuleInstanceKeys
|
|
1070
|
+
});
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
if (queue.hasPending()) {
|
|
1074
|
+
captured.stable = false;
|
|
1075
|
+
captured.degradeReason = "cycle_detected";
|
|
1076
|
+
}
|
|
1077
|
+
const urgentModules = [];
|
|
1078
|
+
const nonUrgentModules = [];
|
|
1079
|
+
for (const commit of captured.accepted.modules.values()) {
|
|
1080
|
+
if (toLane(commit.meta.priority) === "urgent") {
|
|
1081
|
+
urgentModules.push(commit);
|
|
1082
|
+
} else {
|
|
1083
|
+
nonUrgentModules.push(commit);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
const urgentCapExceeded = urgentModules.length > config.urgentStepCap;
|
|
1087
|
+
const urgentAccepted = urgentCapExceeded ? urgentModules.slice(0, config.urgentStepCap) : urgentModules;
|
|
1088
|
+
const urgentDeferred = urgentCapExceeded ? urgentModules.slice(config.urgentStepCap) : [];
|
|
1089
|
+
const nonUrgentBudget = Math.max(0, config.maxSteps);
|
|
1090
|
+
const nonUrgentAccepted = urgentCapExceeded ? [] : nonUrgentModules.slice(0, nonUrgentBudget);
|
|
1091
|
+
const nonUrgentDeferred = urgentCapExceeded ? nonUrgentModules : nonUrgentModules.slice(nonUrgentBudget);
|
|
1092
|
+
if (urgentCapExceeded) {
|
|
1093
|
+
captured.stable = false;
|
|
1094
|
+
captured.degradeReason = "cycle_detected";
|
|
1095
|
+
} else if (nonUrgentDeferred.length > 0) {
|
|
1096
|
+
captured.stable = false;
|
|
1097
|
+
captured.degradeReason = captured.degradeReason ?? "budget_steps";
|
|
1098
|
+
}
|
|
1099
|
+
const acceptedModules = /* @__PURE__ */ new Map();
|
|
1100
|
+
const deferredModules = /* @__PURE__ */ new Map();
|
|
1101
|
+
for (const c of urgentAccepted) acceptedModules.set(c.moduleInstanceKey, c);
|
|
1102
|
+
for (const c of nonUrgentAccepted) acceptedModules.set(c.moduleInstanceKey, c);
|
|
1103
|
+
for (const c of urgentDeferred) deferredModules.set(c.moduleInstanceKey, c);
|
|
1104
|
+
for (const c of nonUrgentDeferred) deferredModules.set(c.moduleInstanceKey, c);
|
|
1105
|
+
const acceptedTopics = /* @__PURE__ */ new Map();
|
|
1106
|
+
const deferredTopics = /* @__PURE__ */ new Map();
|
|
1107
|
+
for (const [topicKey, priority] of captured.accepted.dirtyTopics) {
|
|
1108
|
+
const info = storeTopicToModuleInstanceKey(topicKey);
|
|
1109
|
+
if (!info) continue;
|
|
1110
|
+
if (acceptedModules.has(info)) {
|
|
1111
|
+
acceptedTopics.set(topicKey, priority);
|
|
1112
|
+
} else if (deferredModules.has(info)) {
|
|
1113
|
+
deferredTopics.set(topicKey, priority);
|
|
1114
|
+
} else {
|
|
1115
|
+
acceptedTopics.set(topicKey, priority);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
const acceptedDrain = {
|
|
1119
|
+
modules: acceptedModules,
|
|
1120
|
+
dirtyTopics: acceptedTopics
|
|
1121
|
+
};
|
|
1122
|
+
const deferredDrain = deferredModules.size > 0 || deferredTopics.size > 0 ? {
|
|
1123
|
+
modules: deferredModules,
|
|
1124
|
+
dirtyTopics: deferredTopics
|
|
1125
|
+
} : void 0;
|
|
1126
|
+
captured.deferred = deferredDrain;
|
|
1127
|
+
let startedAtMs;
|
|
1128
|
+
let triggerSummary;
|
|
1129
|
+
let anchor;
|
|
1130
|
+
let backlog;
|
|
1131
|
+
let result;
|
|
1132
|
+
if (shouldEmitTrace) {
|
|
1133
|
+
startedAtMs = Date.now();
|
|
1134
|
+
triggerSummary = (() => {
|
|
1135
|
+
const triggers = Array.from(captured.accepted.modules.values());
|
|
1136
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1137
|
+
let primary = void 0;
|
|
1138
|
+
for (const t of triggers) {
|
|
1139
|
+
const kind = toTriggerKind(t.meta.originKind);
|
|
1140
|
+
counts.set(kind, (counts.get(kind) ?? 0) + 1);
|
|
1141
|
+
if (!primary) {
|
|
1142
|
+
primary = {
|
|
1143
|
+
kind,
|
|
1144
|
+
moduleId: t.moduleId,
|
|
1145
|
+
instanceId: t.instanceId,
|
|
1146
|
+
fieldPath: kind === "externalStore" ? t.meta.originName : void 0,
|
|
1147
|
+
actionTag: kind === "dispatch" ? t.meta.originName : void 0
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
return {
|
|
1152
|
+
total: triggers.length,
|
|
1153
|
+
kinds: Array.from(counts.entries()).map(([kind, count]) => ({ kind, count })),
|
|
1154
|
+
primary,
|
|
1155
|
+
coalescedCount: {
|
|
1156
|
+
modules: coalescedModules,
|
|
1157
|
+
topics: coalescedTopics
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
})();
|
|
1161
|
+
anchor = (() => {
|
|
1162
|
+
const first = captured.accepted.modules.values().next().value;
|
|
1163
|
+
if (!first) return void 0;
|
|
1164
|
+
return {
|
|
1165
|
+
moduleId: first.moduleId,
|
|
1166
|
+
instanceId: first.instanceId,
|
|
1167
|
+
txnSeq: first.meta.txnSeq,
|
|
1168
|
+
txnId: first.meta.txnId,
|
|
1169
|
+
...typeof first.opSeq === "number" ? { opSeq: first.opSeq } : null
|
|
1170
|
+
};
|
|
1171
|
+
})();
|
|
1172
|
+
backlog = (() => {
|
|
1173
|
+
const deferredWork = captured.deferred;
|
|
1174
|
+
if (!deferredWork) return void 0;
|
|
1175
|
+
const pendingDeferredWork = deferredWork.modules.size + deferredWork.dirtyTopics.size;
|
|
1176
|
+
const deferredModulesList = Array.from(deferredWork.modules.values());
|
|
1177
|
+
const pendingExternalInputs = deferredModulesList.filter((m) => toTriggerKind(m.meta.originKind) === "externalStore").length;
|
|
1178
|
+
const primaryDeferred = deferredModulesList.find((m) => toTriggerKind(m.meta.originKind) === "externalStore") ?? deferredModulesList[0];
|
|
1179
|
+
const kind = primaryDeferred ? toTriggerKind(primaryDeferred.meta.originKind) : "unknown";
|
|
1180
|
+
const deferredPrimary = primaryDeferred != null ? {
|
|
1181
|
+
kind: kind === "externalStore" ? "externalStore" : "unknown",
|
|
1182
|
+
moduleId: primaryDeferred.moduleId,
|
|
1183
|
+
instanceId: primaryDeferred.instanceId,
|
|
1184
|
+
fieldPath: kind === "externalStore" ? primaryDeferred.meta.originName : void 0,
|
|
1185
|
+
storeId: void 0
|
|
1186
|
+
} : void 0;
|
|
1187
|
+
return {
|
|
1188
|
+
pendingExternalInputs,
|
|
1189
|
+
pendingDeferredWork,
|
|
1190
|
+
deferredPrimary
|
|
1191
|
+
};
|
|
1192
|
+
})();
|
|
1193
|
+
result = {
|
|
1194
|
+
stable: captured.stable,
|
|
1195
|
+
...captured.stable ? null : { degradeReason: captured.degradeReason ?? "unknown" }
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
if (shouldEmitTrace && schedule.forcedMacrotask && schedule.reason === "microtask_starvation") {
|
|
1199
|
+
yield* record({
|
|
1200
|
+
type: "warn:microtask-starvation",
|
|
1201
|
+
moduleId: anchor?.moduleId,
|
|
1202
|
+
instanceId: anchor?.instanceId,
|
|
1203
|
+
tickSeq: currentTickSeq,
|
|
1204
|
+
microtaskChainDepth: schedule.microtaskChainDepth
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
if (shouldEmitTrace) {
|
|
1208
|
+
yield* record({
|
|
1209
|
+
type: "trace:tick",
|
|
1210
|
+
moduleId: anchor?.moduleId,
|
|
1211
|
+
instanceId: anchor?.instanceId,
|
|
1212
|
+
data: {
|
|
1213
|
+
tickSeq: currentTickSeq,
|
|
1214
|
+
phase: "start",
|
|
1215
|
+
timestampMs: startedAtMs,
|
|
1216
|
+
schedule,
|
|
1217
|
+
triggerSummary,
|
|
1218
|
+
anchors: anchor,
|
|
1219
|
+
budget: {
|
|
1220
|
+
maxSteps: config.maxSteps,
|
|
1221
|
+
elapsedMs: 0,
|
|
1222
|
+
steps: 0,
|
|
1223
|
+
txnCount: acceptedModules.size
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
});
|
|
1227
|
+
}
|
|
1228
|
+
if (!captured.stable && shouldEmitTrace) {
|
|
1229
|
+
yield* record({
|
|
1230
|
+
type: "trace:tick",
|
|
1231
|
+
moduleId: anchor?.moduleId,
|
|
1232
|
+
instanceId: anchor?.instanceId,
|
|
1233
|
+
data: {
|
|
1234
|
+
tickSeq: currentTickSeq,
|
|
1235
|
+
phase: "budgetExceeded",
|
|
1236
|
+
timestampMs: Date.now(),
|
|
1237
|
+
schedule,
|
|
1238
|
+
triggerSummary,
|
|
1239
|
+
anchors: anchor,
|
|
1240
|
+
budget: {
|
|
1241
|
+
maxSteps: config.maxSteps,
|
|
1242
|
+
elapsedMs: Math.max(0, Date.now() - startedAtMs),
|
|
1243
|
+
steps: config.maxSteps,
|
|
1244
|
+
txnCount: acceptedModules.size
|
|
1245
|
+
},
|
|
1246
|
+
backlog,
|
|
1247
|
+
result
|
|
1248
|
+
}
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
if (deferredDrain) {
|
|
1252
|
+
queue.requeue(deferredDrain);
|
|
1253
|
+
}
|
|
1254
|
+
const committed = store.commitTick({
|
|
1255
|
+
tickSeq: currentTickSeq,
|
|
1256
|
+
accepted: acceptedDrain
|
|
1257
|
+
});
|
|
1258
|
+
for (const { listeners: listeners2 } of committed.changedTopics.values()) {
|
|
1259
|
+
for (const listener of listeners2) {
|
|
1260
|
+
try {
|
|
1261
|
+
listener();
|
|
1262
|
+
} catch {
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
if (!captured.stable && shouldEmitTrace && backlog?.deferredPrimary) {
|
|
1267
|
+
const primary = backlog.deferredPrimary;
|
|
1268
|
+
if (primary.kind === "externalStore") {
|
|
1269
|
+
const moduleInstanceKey = primary.moduleId && primary.instanceId ? `${primary.moduleId}::${primary.instanceId}` : void 0;
|
|
1270
|
+
if (moduleInstanceKey && store.getModuleSubscriberCount(moduleInstanceKey) > 0) {
|
|
1271
|
+
yield* record({
|
|
1272
|
+
type: "warn:priority-inversion",
|
|
1273
|
+
moduleId: primary.moduleId,
|
|
1274
|
+
instanceId: primary.instanceId,
|
|
1275
|
+
tickSeq: currentTickSeq,
|
|
1276
|
+
reason: "deferredBacklog"
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
if (shouldEmitTrace) {
|
|
1282
|
+
yield* record({
|
|
1283
|
+
type: "trace:tick",
|
|
1284
|
+
moduleId: anchor?.moduleId,
|
|
1285
|
+
instanceId: anchor?.instanceId,
|
|
1286
|
+
data: {
|
|
1287
|
+
tickSeq: currentTickSeq,
|
|
1288
|
+
phase: "settled",
|
|
1289
|
+
timestampMs: Date.now(),
|
|
1290
|
+
schedule,
|
|
1291
|
+
triggerSummary,
|
|
1292
|
+
anchors: anchor,
|
|
1293
|
+
budget: {
|
|
1294
|
+
maxSteps: config.maxSteps,
|
|
1295
|
+
elapsedMs: Math.max(0, Date.now() - startedAtMs),
|
|
1296
|
+
steps: acceptedModules.size,
|
|
1297
|
+
txnCount: acceptedModules.size
|
|
1298
|
+
},
|
|
1299
|
+
backlog,
|
|
1300
|
+
result
|
|
1301
|
+
}
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
if (telemetry?.onTickDegraded && (schedule.forcedMacrotask || !captured.stable) && shouldSampleTick(currentTickSeq, telemetrySampleRate)) {
|
|
1305
|
+
try {
|
|
1306
|
+
telemetry.onTickDegraded({
|
|
1307
|
+
tickSeq: currentTickSeq,
|
|
1308
|
+
stable: captured.stable,
|
|
1309
|
+
degradeReason: captured.stable ? void 0 : captured.degradeReason ?? "unknown",
|
|
1310
|
+
forcedMacrotask: schedule.forcedMacrotask,
|
|
1311
|
+
scheduleReason: schedule.reason,
|
|
1312
|
+
microtaskChainDepth: schedule.microtaskChainDepth,
|
|
1313
|
+
deferredWorkCount: deferredDrain ? deferredDrain.modules.size + deferredDrain.dirtyTopics.size : 0
|
|
1314
|
+
});
|
|
1315
|
+
} catch {
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
coalescedModules = 0;
|
|
1319
|
+
coalescedTopics = 0;
|
|
1320
|
+
return { stable: captured.stable, degradeReason: captured.degradeReason };
|
|
1321
|
+
});
|
|
1322
|
+
const flushNow = flushTick({ startedAs: "unknown" }).pipe(Effect5.asVoid);
|
|
1323
|
+
const storeTopicToModuleInstanceKey = (topicKey) => {
|
|
1324
|
+
const idx = topicKey.indexOf("::rq:");
|
|
1325
|
+
if (idx > 0) {
|
|
1326
|
+
return topicKey.slice(0, idx);
|
|
1327
|
+
}
|
|
1328
|
+
if (topicKey.includes("::")) {
|
|
1329
|
+
return topicKey;
|
|
1330
|
+
}
|
|
1331
|
+
return void 0;
|
|
1332
|
+
};
|
|
1333
|
+
const onSelectorChanged = ({ moduleInstanceKey, selectorId, priority }) => {
|
|
1334
|
+
const coalesced = queue.markTopicDirty(makeReadQueryTopicKey(moduleInstanceKey, selectorId), priority);
|
|
1335
|
+
if (coalesced) coalescedTopics += 1;
|
|
1336
|
+
};
|
|
1337
|
+
const onModuleCommit = (commit) => Effect5.gen(function* () {
|
|
1338
|
+
const coalescedCommit = queue.enqueueModuleCommit(commit);
|
|
1339
|
+
if (coalescedCommit) coalescedModules += 1;
|
|
1340
|
+
const coalescedTopic = queue.markTopicDirty(commit.moduleInstanceKey, commit.meta.priority);
|
|
1341
|
+
if (coalescedTopic) coalescedTopics += 1;
|
|
1342
|
+
yield* scheduleTick();
|
|
1343
|
+
});
|
|
1344
|
+
return {
|
|
1345
|
+
getTickSeq: () => tickSeq,
|
|
1346
|
+
onModuleCommit,
|
|
1347
|
+
onSelectorChanged,
|
|
1348
|
+
flushNow
|
|
1349
|
+
};
|
|
1350
|
+
};
|
|
1351
|
+
|
|
1352
|
+
export {
|
|
1353
|
+
makeModuleInstanceKey,
|
|
1354
|
+
configureDevtoolsHub,
|
|
1355
|
+
isDevtoolsEnabled,
|
|
1356
|
+
getDevtoolsSnapshot,
|
|
1357
|
+
getDevtoolsSnapshotToken,
|
|
1358
|
+
subscribeDevtoolsSnapshot,
|
|
1359
|
+
getDevtoolsRunId,
|
|
1360
|
+
setDevtoolsRunId,
|
|
1361
|
+
startDevtoolsRun,
|
|
1362
|
+
clearDevtoolsEvents,
|
|
1363
|
+
setInstanceLabel,
|
|
1364
|
+
getInstanceLabel,
|
|
1365
|
+
devtoolsHubConvergeStaticIrCollector,
|
|
1366
|
+
exportDevtoolsEvidencePackage,
|
|
1367
|
+
devtoolsHubSink,
|
|
1368
|
+
enterRuntimeBatch,
|
|
1369
|
+
exitRuntimeBatch,
|
|
1370
|
+
getNodeEnv,
|
|
1371
|
+
isDevEnv,
|
|
1372
|
+
getDefaultStateTxnInstrumentation,
|
|
1373
|
+
StateTransactionConfigTag,
|
|
1374
|
+
ReadQueryStrictGateConfigTag,
|
|
1375
|
+
ReplayModeConfigTag,
|
|
1376
|
+
StateTransactionOverridesTag,
|
|
1377
|
+
ConcurrencyPolicyTag,
|
|
1378
|
+
ConcurrencyPolicyOverridesTag,
|
|
1379
|
+
RuntimeStoreTag,
|
|
1380
|
+
runtimeStoreLayer,
|
|
1381
|
+
HostSchedulerTag,
|
|
1382
|
+
hostSchedulerLayer,
|
|
1383
|
+
DeclarativeLinkRuntimeTag,
|
|
1384
|
+
declarativeLinkRuntimeLayer,
|
|
1385
|
+
TickSchedulerTag,
|
|
1386
|
+
tickSchedulerLayer,
|
|
1387
|
+
inSyncTransactionFiber,
|
|
1388
|
+
forceSourceRefresh,
|
|
1389
|
+
enterSyncTransaction,
|
|
1390
|
+
exitSyncTransaction,
|
|
1391
|
+
isInSyncTransaction,
|
|
1392
|
+
shouldNoopInSyncTransactionFiber,
|
|
1393
|
+
makeTaskRunner
|
|
1394
|
+
};
|
|
1395
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL0RldnRvb2xzSHViLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9UaWNrU2NoZWR1bGVyLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9Kb2JRdWV1ZS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvVGFza1J1bm5lci50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvZW52LnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9SdW50aW1lU3RvcmUudHMiLCAiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL0RlY2xhcmF0aXZlTGlua1J1bnRpbWUudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7IEVmZmVjdCwgRmliZXJSZWYgfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgdHlwZSB7IEpzb25WYWx1ZSB9IGZyb20gJy4uLy4uL29ic2VydmFiaWxpdHkvanNvblZhbHVlLmpzJ1xuaW1wb3J0IHR5cGUgeyBFdmlkZW5jZVBhY2thZ2UsIEV2aWRlbmNlUGFja2FnZVNvdXJjZSB9IGZyb20gJy4uLy4uL29ic2VydmFiaWxpdHkvZXZpZGVuY2UuanMnXG5pbXBvcnQgeyBleHBvcnRFdmlkZW5jZVBhY2thZ2UsIE9CU0VSVkFCSUxJVFlfUFJPVE9DT0xfVkVSU0lPTiB9IGZyb20gJy4uLy4uL29ic2VydmFiaWxpdHkvZXZpZGVuY2UuanMnXG5pbXBvcnQgdHlwZSB7IENvbnZlcmdlU3RhdGljSXJFeHBvcnQgfSBmcm9tICcuLi8uLi9zdGF0ZS10cmFpdC9jb252ZXJnZS1pci5qcydcbmltcG9ydCB0eXBlIHsgQ29udmVyZ2VTdGF0aWNJckNvbGxlY3RvciB9IGZyb20gJy4vQ29udmVyZ2VTdGF0aWNJckNvbGxlY3Rvci5qcydcbmltcG9ydCB7XG4gIGN1cnJlbnREaWFnbm9zdGljc0xldmVsLFxuICBjbGVhclJ1bnRpbWVEZWJ1Z0V2ZW50U2VxLFxuICB0b1J1bnRpbWVEZWJ1Z0V2ZW50UmVmLFxuICB0eXBlIEV2ZW50LFxuICB0eXBlIFJ1bnRpbWVEZWJ1Z0V2ZW50UmVmLFxuICB0eXBlIFNpbmssXG59IGZyb20gJy4vRGVidWdTaW5rLmpzJ1xuaW1wb3J0IHsgZ2V0R2xvYmFsSG9zdFNjaGVkdWxlciB9IGZyb20gJy4vSG9zdFNjaGVkdWxlci5qcydcblxuLyoqXG4gKiBEZXZ0b29sc0h1Ylx1RkYxQVxuICogLSBQcm9jZXNzL3BhZ2UtbGV2ZWwgRGVidWcgZXZlbnQgYWdncmVnYXRvciAoZ2xvYmFsIHNpbmdsZXRvbikuXG4gKlxuICogTm90ZTogdGhpcyBodWIgaXMgb25seSBhcHBlbmRlZCB0byBEZWJ1ZyBzaW5rcyB3aGVuIGRldnRvb2xzSHViTGF5ZXIgaXMgZXhwbGljaXRseSBlbmFibGVkLlxuICogVGhlIFNuYXBzaG90IEFQSSBpcyBhbHdheXMgYXZhaWxhYmxlIChyZXR1cm5zIGVtcHR5IHNuYXBzaG90cyB3aGVuIGRpc2FibGVkKS5cbiAqXG4gKiBQZXJmb3JtYW5jZTpcbiAqIC0gRGV2dG9vbHMgRGVidWcgZXZlbnRzIGNhbiBiZSBleHRyZW1lbHkgZGVuc2UgaW4gaG90IHBhdGhzIChFZmZlY3RPcCAvIFRyYWl0IC8gU3RhdGVUeG4sIGV0Yy4pLlxuICogLSBUaGUgcHJldmlvdXMgaW1wbGVtZW50YXRpb24gY29waWVkIHJpbmdCdWZmZXIgYW5kIE1hcHMgcGVyIGV2ZW50IHRvIGJ1aWxkIGFuIFwiaW1tdXRhYmxlIHNuYXBzaG90XCIgKE8oYnVmZmVyU2l6ZSkpLlxuICogLSBUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBsZXRzIFNuYXBzaG90IHJlZmVyZW5jZSBpbnRlcm5hbCBNYXAvQXJyYXkgZGlyZWN0bHkgKHJlYWQtb25seSBjb252ZW50aW9uKSBhbmQgYmF0Y2hlc1xuICogICBzdWJzY3JpYmVyIG5vdGlmaWNhdGlvbnMgaW4gbWljcm90YXNrcywgYXZvaWRpbmcgcGVyLWV2ZW50IGNvcGllcyBhbmQgcmVkdWNpbmcgbWFpbi10aHJlYWQgaW50ZXJmZXJlbmNlLlxuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgRGV2dG9vbHNTbmFwc2hvdCB7XG4gIC8qKlxuICAgKiBTbmFwc2hvdFRva2VuXHVGRjFBXG4gICAqIC0gTW9ub3RvbmljIHNuYXBzaG90IGNoYW5nZSB0b2tlbiAoYSBzdWJzY3JpcHRpb24tc2FmZSBzb3VyY2Ugb2YgdHJ1dGgpLlxuICAgKiAtIEFueSBleHRlcm5hbGx5IHZpc2libGUgY2hhbmdlIG11c3QgYWR2YW5jZSB0aGUgdG9rZW4uXG4gICAqIC0gSWYgdGhlIHRva2VuIGRvZXMgbm90IGNoYW5nZSwgZXh0ZXJuYWxseSB2aXNpYmxlIHNuYXBzaG90IGZpZWxkcyBtdXN0IG5vdCBjaGFuZ2UgKGF2b2lkIHRlYXJpbmcgLyBtaXNzZWQgdXBkYXRlcykuXG4gICAqL1xuICByZWFkb25seSBzbmFwc2hvdFRva2VuOiBTbmFwc2hvdFRva2VuXG4gIHJlYWRvbmx5IGluc3RhbmNlczogUmVhZG9ubHlNYXA8c3RyaW5nLCBudW1iZXI+XG4gIHJlYWRvbmx5IGV2ZW50czogUmVhZG9ubHlBcnJheTxSdW50aW1lRGVidWdFdmVudFJlZj5cbiAgcmVhZG9ubHkgbGF0ZXN0U3RhdGVzOiBSZWFkb25seU1hcDxzdHJpbmcsIEpzb25WYWx1ZT5cbiAgcmVhZG9ubHkgbGF0ZXN0VHJhaXRTdW1tYXJpZXM6IFJlYWRvbmx5TWFwPHN0cmluZywgSnNvblZhbHVlPlxuICAvKipcbiAgICogZXhwb3J0QnVkZ2V0XHVGRjFBXG4gICAqIC0gVHJhY2tzIFwiZGVncmFkZSBjb3VudHNcIiBjYXVzZWQgYnkgZXhwb3J0IGJvdW5kYXJpZXMgKEpzb25WYWx1ZSBwcm9qZWN0aW9uL3RyaW1taW5nKSwgZm9yIGV4cGxhaW5hYmlsaXR5LlxuICAgKiAtIENvdW50cyBhcmUgY3VtdWxhdGl2ZSAobWF5IGRpZmZlciBmcm9tIHRoZSByaW5nIGJ1ZmZlciB3aW5kb3cpOyBjbGVhckRldnRvb2xzRXZlbnRzIHJlc2V0cyB0aGVtLlxuICAgKi9cbiAgcmVhZG9ubHkgZXhwb3J0QnVkZ2V0OiB7XG4gICAgcmVhZG9ubHkgZHJvcHBlZDogbnVtYmVyXG4gICAgcmVhZG9ubHkgb3ZlcnNpemVkOiBudW1iZXJcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERldnRvb2xzSHViT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGJ1ZmZlclNpemU/OiBudW1iZXJcbn1cblxuZXhwb3J0IHR5cGUgU25hcHNob3RUb2tlbiA9IG51bWJlclxuXG4vLyAtLS0tIEdsb2JhbCBtdXRhYmxlIHN0YXRlIChzaW5nbGV0b24pIC0tLS1cblxuY29uc3QgaW5zdGFuY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKVxuY29uc3QgbGF0ZXN0U3RhdGVzID0gbmV3IE1hcDxzdHJpbmcsIEpzb25WYWx1ZT4oKVxuY29uc3QgbGF0ZXN0VHJhaXRTdW1tYXJpZXMgPSBuZXcgTWFwPHN0cmluZywgSnNvblZhbHVlPigpXG5jb25zdCBpbnN0YW5jZUxhYmVscyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KClcbmNvbnN0IGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdCA9IG5ldyBNYXA8c3RyaW5nLCBDb252ZXJnZVN0YXRpY0lyRXhwb3J0PigpXG5jb25zdCBsaXZlSW5zdGFuY2VLZXlzID0gbmV3IFNldDxzdHJpbmc+KClcblxuY29uc3QgZXhwb3J0QnVkZ2V0ID0ge1xuICBkcm9wcGVkOiAwLFxuICBvdmVyc2l6ZWQ6IDAsXG59XG5cbmxldCBsYXN0UnVuVHMgPSAwXG5sZXQgbGFzdFJ1blRzU2VxID0gMFxuXG5jb25zdCBuZXh0UnVuSWQgPSAoKTogc3RyaW5nID0+IHtcbiAgY29uc3QgdHMgPSBEYXRlLm5vdygpXG4gIGlmICh0cyA9PT0gbGFzdFJ1blRzKSB7XG4gICAgbGFzdFJ1blRzU2VxICs9IDFcbiAgfSBlbHNlIHtcbiAgICBsYXN0UnVuVHMgPSB0c1xuICAgIGxhc3RSdW5Uc1NlcSA9IDBcbiAgfVxuXG4gIHJldHVybiBsYXN0UnVuVHNTZXEgPT09IDAgPyBgcnVuLSR7dHN9YCA6IGBydW4tJHt0c30uJHtsYXN0UnVuVHNTZXF9YFxufVxuXG5sZXQgY3VycmVudFJ1bklkID0gbmV4dFJ1bklkKClcbmxldCBuZXh0U2VxID0gMVxuXG5sZXQgYnVmZmVyU2l6ZSA9IDUwMFxuY29uc3QgcmluZ0J1ZmZlcjogUnVudGltZURlYnVnRXZlbnRSZWZbXSA9IFtdXG5jb25zdCByaW5nQnVmZmVyU2VxOiBudW1iZXJbXSA9IFtdXG5cbmxldCBzbmFwc2hvdFRva2VuOiBTbmFwc2hvdFRva2VuID0gMFxuXG5jb25zdCBlbnN1cmVSaW5nQnVmZmVyU2l6ZSA9ICgpOiB2b2lkID0+IHtcbiAgaWYgKGJ1ZmZlclNpemUgPD0gMCkge1xuICAgIHJpbmdCdWZmZXIubGVuZ3RoID0gMFxuICAgIHJpbmdCdWZmZXJTZXEubGVuZ3RoID0gMFxuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKHJpbmdCdWZmZXIubGVuZ3RoIDw9IGJ1ZmZlclNpemUpIHJldHVyblxuICBjb25zdCBleGNlc3MgPSByaW5nQnVmZmVyLmxlbmd0aCAtIGJ1ZmZlclNpemVcbiAgcmluZ0J1ZmZlci5zcGxpY2UoMCwgZXhjZXNzKVxuICByaW5nQnVmZmVyU2VxLnNwbGljZSgwLCBleGNlc3MpXG59XG5cbmNvbnN0IHRyaW1SaW5nQnVmZmVySWZOZWVkZWQgPSAoKTogdm9pZCA9PiB7XG4gIGlmIChidWZmZXJTaXplIDw9IDApIHtcbiAgICByaW5nQnVmZmVyLmxlbmd0aCA9IDBcbiAgICByaW5nQnVmZmVyU2VxLmxlbmd0aCA9IDBcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8vIFNtYWxsIHdpbmRvd3Mga2VlcCBhIHN0cmljdCB1cHBlciBib3VuZCB0byBhdm9pZCBcInNpemU9NSBidXQgZXZlbnRzLmxlbmd0aCBicmllZmx5ID4gNVwiIHN1cnByaXNlcy5cbiAgLy8gTGFyZ2Ugd2luZG93cyBhbGxvdyBzaG9ydCBidXJzdHMgKyBiYXRjaCB0cmltbWluZyB0byBhdm9pZCBsaW5lYXIgc2hpZnQoKSBjb3N0cyB1bmRlciBzdXN0YWluZWQgbG9hZC5cbiAgaWYgKGJ1ZmZlclNpemUgPD0gNjQpIHtcbiAgICBlbnN1cmVSaW5nQnVmZmVyU2l6ZSgpXG4gICAgcmV0dXJuXG4gIH1cblxuICBjb25zdCBzbGFjayA9IE1hdGgubWluKDEwMjQsIE1hdGguZmxvb3IoYnVmZmVyU2l6ZSAvIDIpKVxuICBjb25zdCB0aHJlc2hvbGQgPSBidWZmZXJTaXplICsgTWF0aC5tYXgoMSwgc2xhY2spXG4gIGlmIChyaW5nQnVmZmVyLmxlbmd0aCA8PSB0aHJlc2hvbGQpIHJldHVyblxuXG4gIGNvbnN0IGV4Y2VzcyA9IHJpbmdCdWZmZXIubGVuZ3RoIC0gYnVmZmVyU2l6ZVxuICByaW5nQnVmZmVyLnNwbGljZSgwLCBleGNlc3MpXG4gIHJpbmdCdWZmZXJTZXEuc3BsaWNlKDAsIGV4Y2Vzcylcbn1cblxuLy8gU25hcHNob3QgcmVmZXJlbmNlcyBpbnRlcm5hbCBzdHJ1Y3R1cmVzIGRpcmVjdGx5IChyZWFkLW9ubHkgY29udmVudGlvbikgdG8gYXZvaWQgY29weSBjb3N0cyBpbiBob3QgcGF0aHMuXG5jb25zdCBjdXJyZW50U25hcHNob3Q6IERldnRvb2xzU25hcHNob3QgPSB7XG4gIHNuYXBzaG90VG9rZW4sXG4gIGluc3RhbmNlcyxcbiAgZXZlbnRzOiByaW5nQnVmZmVyLFxuICBsYXRlc3RTdGF0ZXMsXG4gIGxhdGVzdFRyYWl0U3VtbWFyaWVzLFxuICBleHBvcnRCdWRnZXQsXG59XG5cbmNvbnN0IGxpc3RlbmVycyA9IG5ldyBTZXQ8KCkgPT4gdm9pZD4oKVxuXG5sZXQgbm90aWZ5U2NoZWR1bGVkID0gZmFsc2VcbmNvbnN0IHNjaGVkdWxlTm90aWZ5ID0gKCkgPT4ge1xuICBpZiAobGlzdGVuZXJzLnNpemUgPT09IDApIHJldHVyblxuICBpZiAobm90aWZ5U2NoZWR1bGVkKSByZXR1cm5cbiAgbm90aWZ5U2NoZWR1bGVkID0gdHJ1ZVxuICBnZXRHbG9iYWxIb3N0U2NoZWR1bGVyKCkuc2NoZWR1bGVNaWNyb3Rhc2soKCkgPT4ge1xuICAgIG5vdGlmeVNjaGVkdWxlZCA9IGZhbHNlXG4gICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgIGxpc3RlbmVyKClcbiAgICB9XG4gIH0pXG59XG5cbmxldCBkZXZ0b29sc0VuYWJsZWQgPSBmYWxzZVxuXG5jb25zdCBidW1wU25hcHNob3RUb2tlbiA9ICgpOiB2b2lkID0+IHtcbiAgc25hcHNob3RUb2tlbiArPSAxXG4gIDsoY3VycmVudFNuYXBzaG90IGFzIGFueSkuc25hcHNob3RUb2tlbiA9IHNuYXBzaG90VG9rZW5cbn1cblxuY29uc3QgbWFya1NuYXBzaG90Q2hhbmdlZCA9ICgpOiB2b2lkID0+IHtcbiAgYnVtcFNuYXBzaG90VG9rZW4oKVxuICBzY2hlZHVsZU5vdGlmeSgpXG59XG5cbmV4cG9ydCBjb25zdCBjb25maWd1cmVEZXZ0b29sc0h1YiA9IChvcHRpb25zPzogRGV2dG9vbHNIdWJPcHRpb25zKSA9PiB7XG4gIGRldnRvb2xzRW5hYmxlZCA9IHRydWVcbiAgaWYgKHR5cGVvZiBvcHRpb25zPy5idWZmZXJTaXplID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUob3B0aW9ucy5idWZmZXJTaXplKSkge1xuICAgIGNvbnN0IG5leHQgPSBNYXRoLmZsb29yKG9wdGlvbnMuYnVmZmVyU2l6ZSlcbiAgICBjb25zdCBuZXh0QnVmZmVyU2l6ZSA9IG5leHQgPj0gMCA/IG5leHQgOiAwXG4gICAgaWYgKG5leHRCdWZmZXJTaXplICE9PSBidWZmZXJTaXplKSB7XG4gICAgICBidWZmZXJTaXplID0gbmV4dEJ1ZmZlclNpemVcbiAgICAgIGVuc3VyZVJpbmdCdWZmZXJTaXplKClcbiAgICAgIG1hcmtTbmFwc2hvdENoYW5nZWQoKVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgaXNEZXZ0b29sc0VuYWJsZWQgPSAoKTogYm9vbGVhbiA9PiBkZXZ0b29sc0VuYWJsZWRcblxuLy8gLS0tLSBTbmFwc2hvdCBwdWJsaWMgaGVscGVycyAtLS0tXG5cbmV4cG9ydCBjb25zdCBnZXREZXZ0b29sc1NuYXBzaG90ID0gKCk6IERldnRvb2xzU25hcHNob3QgPT4gY3VycmVudFNuYXBzaG90XG5leHBvcnQgY29uc3QgZ2V0RGV2dG9vbHNTbmFwc2hvdFRva2VuID0gKCk6IFNuYXBzaG90VG9rZW4gPT4gc25hcHNob3RUb2tlblxuXG5leHBvcnQgY29uc3Qgc3Vic2NyaWJlRGV2dG9vbHNTbmFwc2hvdCA9IChsaXN0ZW5lcjogKCkgPT4gdm9pZCk6ICgoKSA9PiB2b2lkKSA9PiB7XG4gIGxpc3RlbmVycy5hZGQobGlzdGVuZXIpXG4gIHJldHVybiAoKSA9PiB7XG4gICAgbGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcilcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZ2V0RGV2dG9vbHNSdW5JZCA9ICgpOiBzdHJpbmcgPT4gY3VycmVudFJ1bklkXG5cbmV4cG9ydCBjb25zdCBzZXREZXZ0b29sc1J1bklkID0gKHJ1bklkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgaWYgKHR5cGVvZiBydW5JZCAhPT0gJ3N0cmluZycgfHwgcnVuSWQubGVuZ3RoID09PSAwKSByZXR1cm5cbiAgaWYgKHJ1bklkICE9PSBjdXJyZW50UnVuSWQpIHtcbiAgICBjdXJyZW50UnVuSWQgPSBydW5JZFxuICAgIG1hcmtTbmFwc2hvdENoYW5nZWQoKVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzdGFydERldnRvb2xzUnVuID0gKHJ1bklkPzogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgY3VycmVudFJ1bklkID0gdHlwZW9mIHJ1bklkID09PSAnc3RyaW5nJyAmJiBydW5JZC5sZW5ndGggPiAwID8gcnVuSWQgOiBuZXh0UnVuSWQoKVxuICBuZXh0U2VxID0gMVxuICBjbGVhclJ1bnRpbWVEZWJ1Z0V2ZW50U2VxKClcbiAgY2xlYXJEZXZ0b29sc0V2ZW50cygpXG4gIHJldHVybiBjdXJyZW50UnVuSWRcbn1cblxuZXhwb3J0IGNvbnN0IGNsZWFyRGV2dG9vbHNFdmVudHMgPSAoKTogdm9pZCA9PiB7XG4gIHJpbmdCdWZmZXIubGVuZ3RoID0gMFxuICByaW5nQnVmZmVyU2VxLmxlbmd0aCA9IDBcbiAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgPSAwXG4gIGV4cG9ydEJ1ZGdldC5vdmVyc2l6ZWQgPSAwXG4gIG1hcmtTbmFwc2hvdENoYW5nZWQoKVxufVxuXG5leHBvcnQgY29uc3Qgc2V0SW5zdGFuY2VMYWJlbCA9IChpbnN0YW5jZUlkOiBzdHJpbmcsIGxhYmVsOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgaW5zdGFuY2VMYWJlbHMuc2V0KGluc3RhbmNlSWQsIGxhYmVsKVxuICBtYXJrU25hcHNob3RDaGFuZ2VkKClcbn1cblxuZXhwb3J0IGNvbnN0IGdldEluc3RhbmNlTGFiZWwgPSAoaW5zdGFuY2VJZDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IGluc3RhbmNlTGFiZWxzLmdldChpbnN0YW5jZUlkKVxuXG5jb25zdCByZWdpc3RlckNvbnZlcmdlU3RhdGljSXIgPSAoaXI6IENvbnZlcmdlU3RhdGljSXJFeHBvcnQpOiB2b2lkID0+IHtcbiAgY29udmVyZ2VTdGF0aWNJckJ5RGlnZXN0LnNldChpci5zdGF0aWNJckRpZ2VzdCwgaXIpXG59XG5cbmV4cG9ydCBjb25zdCBkZXZ0b29sc0h1YkNvbnZlcmdlU3RhdGljSXJDb2xsZWN0b3I6IENvbnZlcmdlU3RhdGljSXJDb2xsZWN0b3IgPSB7XG4gIHJlZ2lzdGVyOiByZWdpc3RlckNvbnZlcmdlU3RhdGljSXIsXG59XG5cbmV4cG9ydCBjb25zdCBleHBvcnREZXZ0b29sc0V2aWRlbmNlUGFja2FnZSA9IChvcHRpb25zPzoge1xuICByZWFkb25seSBydW5JZD86IHN0cmluZ1xuICByZWFkb25seSBzb3VyY2U/OiBFdmlkZW5jZVBhY2thZ2VTb3VyY2VcbiAgcmVhZG9ubHkgcHJvdG9jb2xWZXJzaW9uPzogc3RyaW5nXG59KTogRXZpZGVuY2VQYWNrYWdlID0+IHtcbiAgY29uc3QgcHJvdG9jb2xWZXJzaW9uID0gb3B0aW9ucz8ucHJvdG9jb2xWZXJzaW9uID8/IE9CU0VSVkFCSUxJVFlfUFJPVE9DT0xfVkVSU0lPTlxuICBjb25zdCBydW5JZCA9IG9wdGlvbnM/LnJ1bklkID8/IGN1cnJlbnRSdW5JZFxuICBjb25zdCBzb3VyY2UgPSBvcHRpb25zPy5zb3VyY2UgPz8geyBob3N0OiAndW5rbm93bicgfVxuXG4gIGNvbnN0IGV2ZW50cyA9IHJpbmdCdWZmZXIubWFwKChwYXlsb2FkLCBpKSA9PiAoe1xuICAgIHByb3RvY29sVmVyc2lvbixcbiAgICBydW5JZCxcbiAgICBzZXE6IHJpbmdCdWZmZXJTZXFbaV0gPz8gaSArIDEsXG4gICAgdGltZXN0YW1wOiBwYXlsb2FkLnRpbWVzdGFtcCxcbiAgICB0eXBlOiAnZGVidWc6ZXZlbnQnLFxuICAgIHBheWxvYWQ6IHBheWxvYWQgYXMgdW5rbm93biBhcyBKc29uVmFsdWUsXG4gIH0pKVxuXG4gIGNvbnN0IGlzUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT5cbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKVxuXG4gIC8vIEluIGZ1bGwgZGlhZ25vc3RpY3M6IGRlLWR1cGxpY2F0ZSBieSBzdGF0aWNJckRpZ2VzdCBhbmQgZXhwb3J0IG1hdGNoaW5nIENvbnZlcmdlU3RhdGljSVIgKGZvciBvZmZsaW5lIGV4cGxhbmF0aW9uL3JlcGxheSkuXG4gIGNvbnN0IGNvbnZlcmdlRGlnZXN0cyA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gIGxldCBzYXdGdWxsQ29udmVyZ2UgPSBmYWxzZVxuXG4gIGZvciAoY29uc3QgcmVmIG9mIHJpbmdCdWZmZXIpIHtcbiAgICBpZiAocmVmLmtpbmQgIT09ICd0cmFpdDpjb252ZXJnZScpIGNvbnRpbnVlXG4gICAgY29uc3QgbWV0YSA9IHJlZi5tZXRhXG4gICAgaWYgKCFpc1JlY29yZChtZXRhKSkgY29udGludWVcblxuICAgIGNvbnN0IGRpZ2VzdCA9IG1ldGEuc3RhdGljSXJEaWdlc3RcbiAgICBpZiAodHlwZW9mIGRpZ2VzdCA9PT0gJ3N0cmluZycgJiYgZGlnZXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnZlcmdlRGlnZXN0cy5hZGQoZGlnZXN0KVxuICAgIH1cblxuICAgIGNvbnN0IGRpcnR5ID0gbWV0YS5kaXJ0eVxuICAgIGlmIChpc1JlY29yZChkaXJ0eSkgJiYgdHlwZW9mIGRpcnR5LnJvb3RDb3VudCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHNhd0Z1bGxDb252ZXJnZSA9IHRydWVcbiAgICB9XG4gIH1cblxuICBsZXQgc3VtbWFyeTogSnNvblZhbHVlIHwgdW5kZWZpbmVkXG4gIGlmIChzYXdGdWxsQ29udmVyZ2UgJiYgY29udmVyZ2VEaWdlc3RzLnNpemUgPiAwKSB7XG4gICAgY29uc3Qgc3RhdGljSXJCeURpZ2VzdDogUmVjb3JkPHN0cmluZywgSnNvblZhbHVlPiA9IHt9XG4gICAgZm9yIChjb25zdCBkaWdlc3Qgb2YgY29udmVyZ2VEaWdlc3RzKSB7XG4gICAgICBjb25zdCBpciA9IGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdC5nZXQoZGlnZXN0KVxuICAgICAgaWYgKGlyKSB7XG4gICAgICAgIHN0YXRpY0lyQnlEaWdlc3RbZGlnZXN0XSA9IGlyIGFzIHVua25vd24gYXMgSnNvblZhbHVlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyhzdGF0aWNJckJ5RGlnZXN0KS5sZW5ndGggPiAwKSB7XG4gICAgICBzdW1tYXJ5ID0geyBjb252ZXJnZTogeyBzdGF0aWNJckJ5RGlnZXN0IH0gfSBhcyB1bmtub3duIGFzIEpzb25WYWx1ZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleHBvcnRFdmlkZW5jZVBhY2thZ2Uoe1xuICAgIHByb3RvY29sVmVyc2lvbixcbiAgICBydW5JZCxcbiAgICBzb3VyY2UsXG4gICAgZXZlbnRzLFxuICAgIHN1bW1hcnksXG4gIH0pXG59XG5cbi8vIC0tLS0gSHViIFNpbmsgLS0tLVxuXG5leHBvcnQgY29uc3QgZGV2dG9vbHNIdWJTaW5rOiBTaW5rID0ge1xuICByZWNvcmQ6IChldmVudDogRXZlbnQpID0+XG4gICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgLy8gTk9URTogdGhlIGh1YiBpcyBhIGdsb2JhbCBzaW5nbGV0b24sIGJ1dCB3aGV0aGVyIGV2ZW50cyBhcmUgZXhwb3J0YWJsZS93cml0dGVuIHRvIHRoZSBidWZmZXIgaXMgY29udHJvbGxlZCBieSBGaWJlclJlZixcbiAgICAgIC8vIGVuYWJsaW5nIGRpZmZlcmVudCBwZXJmIGJhc2VsaW5lcy9kaWFnbm9zdGljcyB0aWVycyBhY3Jvc3Mgc2NvcGVzIHdpdGhpbiB0aGUgc2FtZSBwcm9jZXNzLlxuICAgICAgY29uc3QgbGV2ZWwgPSB5aWVsZCogRmliZXJSZWYuZ2V0KGN1cnJlbnREaWFnbm9zdGljc0xldmVsKVxuXG4gICAgICBsZXQgY2hhbmdlZCA9IGZhbHNlXG5cbiAgICAgIC8vIHRyYWNlOmluc3RhbmNlTGFiZWw6IHNldCBhIGh1bWFuLXJlYWRhYmxlIGxhYmVsIGZvciBhIHJ1bnRpbWUgaW5zdGFuY2UuXG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ3RyYWNlOmluc3RhbmNlTGFiZWwnKSB7XG4gICAgICAgIGNvbnN0IGluc3RhbmNlSWQgPSAoZXZlbnQgYXMgYW55KS5pbnN0YW5jZUlkIGFzIHN0cmluZyB8IHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBkYXRhID0gKGV2ZW50IGFzIGFueSkuZGF0YVxuICAgICAgICBjb25zdCBsYWJlbCA9IGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICdvYmplY3QnICYmICdsYWJlbCcgaW4gZGF0YSA/IFN0cmluZygoZGF0YSBhcyBhbnkpLmxhYmVsKSA6IHVuZGVmaW5lZFxuICAgICAgICBpZiAoaW5zdGFuY2VJZCAmJiBsYWJlbCkge1xuICAgICAgICAgIGluc3RhbmNlTGFiZWxzLnNldChpbnN0YW5jZUlkLCBsYWJlbClcbiAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEluc3RhbmNlIGNvdW50ZXJzOiBtYWludGFpbiBhY3RpdmUgaW5zdGFuY2UgY291bnRzIGJ5IHJ1bnRpbWVMYWJlbDo6bW9kdWxlSWQuXG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ21vZHVsZTppbml0JyB8fCBldmVudC50eXBlID09PSAnbW9kdWxlOmRlc3Ryb3knKSB7XG4gICAgICAgIGNvbnN0IG1vZHVsZUlkID0gKGV2ZW50IGFzIGFueSkubW9kdWxlSWQgPz8gJ3Vua25vd24nXG4gICAgICAgIGNvbnN0IHJ1bnRpbWVMYWJlbCA9IChldmVudCBhcyBhbnkpLnJ1bnRpbWVMYWJlbCA/PyAndW5rbm93bidcbiAgICAgICAgY29uc3QgaW5zdGFuY2VJZCA9IChldmVudCBhcyBhbnkpLmluc3RhbmNlSWQgYXMgc3RyaW5nIHwgdW5kZWZpbmVkXG4gICAgICAgIGNvbnN0IGtleSA9IGAke3J1bnRpbWVMYWJlbH06OiR7bW9kdWxlSWR9YFxuICAgICAgICBjb25zdCBwcmV2ID0gaW5zdGFuY2VzLmdldChrZXkpID8/IDBcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICdtb2R1bGU6aW5pdCcpIHtcbiAgICAgICAgICBpbnN0YW5jZXMuc2V0KGtleSwgcHJldiArIDEpXG4gICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgICBpZiAoaW5zdGFuY2VJZCkge1xuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2VLZXkgPSBgJHtydW50aW1lTGFiZWx9Ojoke21vZHVsZUlkfTo6JHtpbnN0YW5jZUlkfWBcbiAgICAgICAgICAgIGxpdmVJbnN0YW5jZUtleXMuYWRkKGluc3RhbmNlS2V5KVxuICAgICAgICAgICAgLy8gSWYgaW5zdGFuY2VJZCBpcyByZXVzZWQsIGVuc3VyZSBkZXJpdmVkIGNhY2hlcyBkbyBub3QgY2FycnkgbGVmdG92ZXJzIGZyb20gdGhlIHByZXZpb3VzIGxpZmV0aW1lLlxuICAgICAgICAgICAgaWYgKGxhdGVzdFN0YXRlcy5kZWxldGUoaW5zdGFuY2VLZXkpKSBjaGFuZ2VkID0gdHJ1ZVxuICAgICAgICAgICAgaWYgKGxhdGVzdFRyYWl0U3VtbWFyaWVzLmRlbGV0ZShpbnN0YW5jZUtleSkpIGNoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IG5leHQgPSBwcmV2IC0gMVxuICAgICAgICAgIGlmIChuZXh0IDw9IDApIHtcbiAgICAgICAgICAgIGlmIChpbnN0YW5jZXMuZGVsZXRlKGtleSkpIGNoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluc3RhbmNlcy5zZXQoa2V5LCBuZXh0KVxuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaW5zdGFuY2VJZCkge1xuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2VLZXkgPSBgJHtydW50aW1lTGFiZWx9Ojoke21vZHVsZUlkfTo6JHtpbnN0YW5jZUlkfWBcbiAgICAgICAgICAgIGxpdmVJbnN0YW5jZUtleXMuZGVsZXRlKGluc3RhbmNlS2V5KVxuICAgICAgICAgICAgaWYgKGxhdGVzdFN0YXRlcy5kZWxldGUoaW5zdGFuY2VLZXkpKSBjaGFuZ2VkID0gdHJ1ZVxuICAgICAgICAgICAgaWYgKGxhdGVzdFRyYWl0U3VtbWFyaWVzLmRlbGV0ZShpbnN0YW5jZUtleSkpIGNoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgICBpZiAoaW5zdGFuY2VMYWJlbHMuZGVsZXRlKGluc3RhbmNlSWQpKSBjaGFuZ2VkID0gdHJ1ZVxuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGV0IGV4cG9ydEJ1ZGdldENoYW5nZWQgPSBmYWxzZVxuICAgICAgY29uc3QgcmVmID0gdG9SdW50aW1lRGVidWdFdmVudFJlZihldmVudCwge1xuICAgICAgICBkaWFnbm9zdGljc0xldmVsOiBsZXZlbCxcbiAgICAgICAgcmVzb2x2ZUNvbnZlcmdlU3RhdGljSXI6IChzdGF0aWNJckRpZ2VzdCkgPT4gY29udmVyZ2VTdGF0aWNJckJ5RGlnZXN0LmdldChzdGF0aWNJckRpZ2VzdCksXG4gICAgICAgIG9uTWV0YVByb2plY3Rpb246ICh7IHN0YXRzIH0pID0+IHtcbiAgICAgICAgICBpZiAoc3RhdHMuZHJvcHBlZCAhPT0gMCB8fCBzdGF0cy5vdmVyc2l6ZWQgIT09IDApIHtcbiAgICAgICAgICAgIGV4cG9ydEJ1ZGdldENoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICAgIGV4cG9ydEJ1ZGdldC5kcm9wcGVkICs9IHN0YXRzLmRyb3BwZWRcbiAgICAgICAgICBleHBvcnRCdWRnZXQub3ZlcnNpemVkICs9IHN0YXRzLm92ZXJzaXplZFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIGlmIChleHBvcnRCdWRnZXRDaGFuZ2VkKSB7XG4gICAgICAgIGNoYW5nZWQgPSB0cnVlXG4gICAgICB9XG4gICAgICBpZiAoIXJlZikge1xuICAgICAgICAvLyBvZmYgdGllcjogZG8gbm90IHdyaXRlIHJpbmcgYnVmZmVyIC8gbGF0ZXN0U3RhdGVzLCBidXQga2VlcCBtaW5pbWFsIGNvdW50ZXJzL2xhYmVscyAoaW5jbHVkaW5nIG1vZHVsZTpkZXN0cm95IGNsZWFudXApLlxuICAgICAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgICAgIG1hcmtTbmFwc2hvdENoYW5nZWQoKVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICAvLyBsYXRlc3RTdGF0ZXMgLyBsYXRlc3RUcmFpdFN1bW1hcmllczogcmVjb3JkIGxhdGVzdCBzbmFwc2hvdHMgYnkgcnVudGltZUxhYmVsOjptb2R1bGVJZDo6aW5zdGFuY2VJZC5cbiAgICAgIGlmIChyZWYua2luZCA9PT0gJ3N0YXRlJyAmJiByZWYubGFiZWwgPT09ICdzdGF0ZTp1cGRhdGUnKSB7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVMYWJlbCA9IHJlZi5ydW50aW1lTGFiZWwgPz8gJ3Vua25vd24nXG4gICAgICAgIGNvbnN0IGtleSA9IGAke3J1bnRpbWVMYWJlbH06OiR7cmVmLm1vZHVsZUlkfTo6JHtyZWYuaW5zdGFuY2VJZH1gXG5cbiAgICAgICAgLy8gTGF0ZS9yZXBsYXllZCBldmVudHMgYWZ0ZXIgbW9kdWxlOmRlc3Ryb3k6IGFsbG93IGVudGVyaW5nIHRoZSB3aW5kb3cgZm9yIHJlcGxheSwgYnV0IGRvIG5vdCByZWJ1aWxkIGxhdGVzdCogY2FjaGVzLlxuICAgICAgICBpZiAobGl2ZUluc3RhbmNlS2V5cy5oYXMoa2V5KSkge1xuICAgICAgICAgIGlmIChyZWYubWV0YSAmJiB0eXBlb2YgcmVmLm1ldGEgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHJlZi5tZXRhKSkge1xuICAgICAgICAgICAgY29uc3QgYW55TWV0YSA9IHJlZi5tZXRhIGFzIGFueVxuICAgICAgICAgICAgaWYgKCdzdGF0ZScgaW4gYW55TWV0YSkge1xuICAgICAgICAgICAgICBsYXRlc3RTdGF0ZXMuc2V0KGtleSwgYW55TWV0YS5zdGF0ZSBhcyBKc29uVmFsdWUpXG4gICAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoJ3RyYWl0U3VtbWFyeScgaW4gYW55TWV0YSAmJiBhbnlNZXRhLnRyYWl0U3VtbWFyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGxhdGVzdFRyYWl0U3VtbWFyaWVzLnNldChrZXksIGFueU1ldGEudHJhaXRTdW1tYXJ5IGFzIEpzb25WYWx1ZSlcbiAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gcmluZyBidWZmZXI6IGtlZXAgdGhlIG1vc3QgcmVjZW50IGJ1ZmZlclNpemUgUnVudGltZURlYnVnRXZlbnRSZWZzLlxuICAgICAgaWYgKGJ1ZmZlclNpemUgPiAwKSB7XG4gICAgICAgIGNvbnN0IHNlcSA9IG5leHRTZXErK1xuICAgICAgICByaW5nQnVmZmVyLnB1c2gocmVmKVxuICAgICAgICByaW5nQnVmZmVyU2VxLnB1c2goc2VxKVxuICAgICAgICB0cmltUmluZ0J1ZmZlcklmTmVlZGVkKClcbiAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgIH1cblxuICAgICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgICAgbWFya1NuYXBzaG90Q2hhbmdlZCgpXG4gICAgICB9XG4gICAgfSksXG59XG4iLCAiaW1wb3J0IHsgRWZmZWN0LCBGaWJlclJlZiB9IGZyb20gJ2VmZmVjdCdcbmltcG9ydCAqIGFzIERlYnVnIGZyb20gJy4vRGVidWdTaW5rLmpzJ1xuaW1wb3J0ICogYXMgRGV2dG9vbHNIdWIgZnJvbSAnLi9EZXZ0b29sc0h1Yi5qcydcbmltcG9ydCB0eXBlIHsgRGVjbGFyYXRpdmVMaW5rUnVudGltZSB9IGZyb20gJy4vRGVjbGFyYXRpdmVMaW5rUnVudGltZS5qcydcbmltcG9ydCB0eXBlIHsgSG9zdFNjaGVkdWxlciB9IGZyb20gJy4vSG9zdFNjaGVkdWxlci5qcydcbmltcG9ydCB7IG1ha2VKb2JRdWV1ZSwgdHlwZSBKb2JRdWV1ZSB9IGZyb20gJy4vSm9iUXVldWUuanMnXG5pbXBvcnQgKiBhcyBUYXNrUnVubmVyIGZyb20gJy4vVGFza1J1bm5lci5qcydcbmltcG9ydCB7XG4gIG1ha2VSZWFkUXVlcnlUb3BpY0tleSxcbiAgdHlwZSBNb2R1bGVJbnN0YW5jZUtleSxcbiAgdHlwZSBSdW50aW1lU3RvcmUsXG4gIHR5cGUgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0LFxuICB0eXBlIFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbixcbn0gZnJvbSAnLi9SdW50aW1lU3RvcmUuanMnXG5pbXBvcnQgdHlwZSB7IFN0YXRlQ29tbWl0UHJpb3JpdHkgfSBmcm9tICcuL21vZHVsZS5qcydcblxuZXhwb3J0IHR5cGUgVGlja0xhbmUgPSAndXJnZW50JyB8ICdub25VcmdlbnQnXG5cbmV4cG9ydCB0eXBlIFRpY2tEZWdyYWRlUmVhc29uID0gJ2J1ZGdldF9zdGVwcycgfCAnY3ljbGVfZGV0ZWN0ZWQnIHwgJ3Vua25vd24nXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGlja1NjaGVkdWxlckNvbmZpZyB7XG4gIC8qKlxuICAgKiBGaXhwb2ludCBzdGVwIGNhcDpcbiAgICogLSBTdGVwcyBjb3VudCBcIndvcmsgYWNjZXB0YW5jZSB1bml0c1wiIHdpdGhpbiBhIHNpbmdsZSB0aWNrLCBub3QgdGltZS5cbiAgICogLSBFeGNlZWRpbmcgdGhlIGJ1ZGdldCB0cmlnZ2VycyBhIHNvZnQgZGVncmFkZSAoc3RhYmxlPWZhbHNlKSwgZGVmZXJyaW5nIG5vblVyZ2VudCBiYWNrbG9nIHRvIHRoZSBuZXh0IHRpY2suXG4gICAqL1xuICByZWFkb25seSBtYXhTdGVwcz86IG51bWJlclxuICAvKipcbiAgICogVXJnZW50IHNhZmV0eSBjYXA6XG4gICAqIC0gRXZlbiB1cmdlbnQgd29yayBtYXkgYmUgY3V0IHdoZW4gdGhlIHN5c3RlbSBhcHBlYXJzIHRvIGJlIGluIGEgY3ljbGUgKGF2b2lkIGZyZWV6aW5nKS5cbiAgICovXG4gIHJlYWRvbmx5IHVyZ2VudFN0ZXBDYXA/OiBudW1iZXJcbiAgLyoqXG4gICAqIERyYWluLXJvdW5kIGNhcDpcbiAgICogLSBCb3VuZHMgdGhlIG51bWJlciBvZiBkcmFpbiByb3VuZHMgd2hpbGUgY2FwdHVyaW5nIGNvbmN1cnJlbnQgY29tbWl0cyBiZWZvcmUgY29tbWl0dGluZyB0aGUgdGljayBzbmFwc2hvdC5cbiAgICogLSBFeGNlZWRpbmcgdGhlIGNhcCBpcyB0cmVhdGVkIGFzIGEgY3ljbGUgKHN0YWJsZT1mYWxzZSwgZGVncmFkZVJlYXNvbj1jeWNsZV9kZXRlY3RlZCkuXG4gICAqL1xuICByZWFkb25seSBtYXhEcmFpblJvdW5kcz86IG51bWJlclxuICAvKipcbiAgICogTWljcm90YXNrIHN0YXJ2YXRpb24gcHJvdGVjdGlvbiB0aHJlc2hvbGQ6XG4gICAqIC0gQ291bnRzIGNvbnNlY3V0aXZlIHRpY2tzIHNjaGVkdWxlZCBvbiBtaWNyb3Rhc2sgYm91bmRhcmllcyB3aXRob3V0IHlpZWxkaW5nIHRvIGhvc3QgKGJlc3QtZWZmb3J0KS5cbiAgICogLSBFeGNlZWRpbmcgdGhlIGxpbWl0IGZvcmNlcyB0aGUgbmV4dCB0aWNrIHRvIHN0YXJ0IG9uIGEgbWFjcm90YXNrIGJvdW5kYXJ5LlxuICAgKi9cbiAgcmVhZG9ubHkgbWljcm90YXNrQ2hhaW5EZXB0aExpbWl0PzogbnVtYmVyXG4gIC8qKlxuICAgKiBPcHRpb25hbCBkZWdyYWRlZC10aWNrIHRlbGVtZXRyeSAob3B0LWluLCBzYW1wbGVkKTpcbiAgICogLSBSdW5zIGV2ZW4gd2hlbiBkaWFnbm9zdGljcz1vZmYgKERldnRvb2xzIGRpc2FibGVkKS5cbiAgICogLSBJbnRlbmRlZCBmb3IgcHJvZHVjdGlvbiBoZWFsdGggc2lnbmFscyAoZnJlcXVlbmN5IG9mIHN0YWJsZT1mYWxzZSAvIGZvcmNlZCB5aWVsZCkuXG4gICAqL1xuICByZWFkb25seSB0ZWxlbWV0cnk/OiBUaWNrU2NoZWR1bGVyVGVsZW1ldHJ5Q29uZmlnXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGlja1NjaGVkdWxlclRlbGVtZXRyeUV2ZW50IHtcbiAgcmVhZG9ubHkgdGlja1NlcTogbnVtYmVyXG4gIHJlYWRvbmx5IHN0YWJsZTogYm9vbGVhblxuICByZWFkb25seSBkZWdyYWRlUmVhc29uPzogVGlja0RlZ3JhZGVSZWFzb25cbiAgcmVhZG9ubHkgZm9yY2VkTWFjcm90YXNrPzogYm9vbGVhblxuICByZWFkb25seSBzY2hlZHVsZVJlYXNvbj86IFRpY2tTY2hlZHVsZVJlYXNvblxuICByZWFkb25seSBtaWNyb3Rhc2tDaGFpbkRlcHRoPzogbnVtYmVyXG4gIHJlYWRvbmx5IGRlZmVycmVkV29ya0NvdW50PzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGlja1NjaGVkdWxlclRlbGVtZXRyeUNvbmZpZyB7XG4gIC8qKiBTYW1wbGUgcmF0ZSBpbiBbMCwgMV0uIERlZmF1bHQ6IDAgKGRpc2FibGVkKS4gKi9cbiAgcmVhZG9ubHkgc2FtcGxlUmF0ZT86IG51bWJlclxuICAvKiogQ2FsbGVkIGZvciB0aWNrcyB0aGF0IGFyZSBkZWdyYWRlZCAoc3RhYmxlPWZhbHNlKSBhbmQvb3Igc3RhcnRlZCBvbiBhIGZvcmNlZCBtYWNyb3Rhc2sgYm91bmRhcnkuICovXG4gIHJlYWRvbmx5IG9uVGlja0RlZ3JhZGVkPzogKGV2ZW50OiBUaWNrU2NoZWR1bGVyVGVsZW1ldHJ5RXZlbnQpID0+IHZvaWRcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUaWNrU2NoZWR1bGVyIHtcbiAgcmVhZG9ubHkgZ2V0VGlja1NlcTogKCkgPT4gbnVtYmVyXG4gIHJlYWRvbmx5IG9uTW9kdWxlQ29tbWl0OiAoY29tbWl0OiBSdW50aW1lU3RvcmVNb2R1bGVDb21taXQpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIG5ldmVyPlxuICByZWFkb25seSBvblNlbGVjdG9yQ2hhbmdlZDogKGFyZ3M6IHtcbiAgICByZWFkb25seSBtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXlcbiAgICByZWFkb25seSBzZWxlY3RvcklkOiBzdHJpbmdcbiAgICByZWFkb25seSBwcmlvcml0eTogU3RhdGVDb21taXRQcmlvcml0eVxuICB9KSA9PiB2b2lkXG4gIHJlYWRvbmx5IGZsdXNoTm93OiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBuZXZlcj5cbn1cblxuLy8gLS0tLSBSdW50aW1lLmJhdGNoIChzeW5jIGJvdW5kYXJ5KSAtLS0tXG5cbnR5cGUgQmF0Y2hXYWl0ZXIgPSB7IHJlYWRvbmx5IHJlc29sdmU6ICgpID0+IHZvaWQgfVxuXG5sZXQgYmF0Y2hEZXB0aCA9IDBcbmNvbnN0IGJhdGNoV2FpdGVycyA9IG5ldyBTZXQ8QmF0Y2hXYWl0ZXI+KClcblxuZXhwb3J0IGNvbnN0IGVudGVyUnVudGltZUJhdGNoID0gKCk6IHZvaWQgPT4ge1xuICBiYXRjaERlcHRoICs9IDFcbn1cblxuZXhwb3J0IGNvbnN0IGV4aXRSdW50aW1lQmF0Y2ggPSAoKTogdm9pZCA9PiB7XG4gIGJhdGNoRGVwdGggPSBNYXRoLm1heCgwLCBiYXRjaERlcHRoIC0gMSlcbiAgaWYgKGJhdGNoRGVwdGggIT09IDApIHJldHVyblxuICBjb25zdCB3YWl0ZXJzID0gQXJyYXkuZnJvbShiYXRjaFdhaXRlcnMpXG4gIGJhdGNoV2FpdGVycy5jbGVhcigpXG4gIGZvciAoY29uc3QgdyBvZiB3YWl0ZXJzKSB7XG4gICAgdHJ5IHtcbiAgICAgIHcucmVzb2x2ZSgpXG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBiZXN0LWVmZm9ydFxuICAgIH1cbiAgfVxufVxuXG5jb25zdCB3YWl0Rm9yQmF0Y2hFbmRJZk5lZWRlZCA9ICgpOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBuZXZlcj4gPT5cbiAgYmF0Y2hEZXB0aCA9PT0gMFxuICAgID8gRWZmZWN0LnZvaWRcbiAgICA6IEVmZmVjdC5hc3luYzx2b2lkLCBuZXZlcj4oKHJlc3VtZSwgc2lnbmFsKSA9PiB7XG5cbiAgICBsZXQgZG9uZSA9IGZhbHNlXG4gICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgIGlmIChkb25lKSByZXR1cm5cbiAgICAgIGRvbmUgPSB0cnVlXG4gICAgICBiYXRjaFdhaXRlcnMuZGVsZXRlKHdhaXRlcilcbiAgICAgIHRyeSB7XG4gICAgICAgIHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQpXG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gYmVzdC1lZmZvcnRcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBvbkFib3J0ID0gKCkgPT4ge1xuICAgICAgY2xlYW51cCgpXG4gICAgfVxuXG4gICAgY29uc3Qgd2FpdGVyOiBCYXRjaFdhaXRlciA9IHtcbiAgICAgIHJlc29sdmU6ICgpID0+IHtcbiAgICAgICAgY2xlYW51cCgpXG4gICAgICAgIHJlc3VtZShFZmZlY3Qudm9pZClcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgYmF0Y2hXYWl0ZXJzLmFkZCh3YWl0ZXIpXG4gICAgdHJ5IHtcbiAgICAgIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQsIHsgb25jZTogdHJ1ZSB9KVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gYmVzdC1lZmZvcnRcbiAgICB9XG4gIH0pXG5cbi8vIC0tLS0gVGlja1NjaGVkdWxlciBpbXBsZW1lbnRhdGlvbiAtLS0tXG5cbnR5cGUgVHJpZ2dlcktpbmQgPSAnZXh0ZXJuYWxTdG9yZScgfCAnZGlzcGF0Y2gnIHwgJ3RpbWVyJyB8ICd1bmtub3duJ1xuXG50eXBlIFRpY2tTY2hlZHVsZVN0YXJ0ZWRBcyA9ICdtaWNyb3Rhc2snIHwgJ21hY3JvdGFzaycgfCAnYmF0Y2gnIHwgJ3Vua25vd24nXG50eXBlIFRpY2tTY2hlZHVsZVJlYXNvbiA9ICdidWRnZXQnIHwgJ2N5Y2xlX2RldGVjdGVkJyB8ICdtaWNyb3Rhc2tfc3RhcnZhdGlvbicgfCAndW5rbm93bidcblxudHlwZSBUaWNrU2NoZWR1bGUgPSB7XG4gIHJlYWRvbmx5IHN0YXJ0ZWRBcz86IFRpY2tTY2hlZHVsZVN0YXJ0ZWRBc1xuICByZWFkb25seSBtaWNyb3Rhc2tDaGFpbkRlcHRoPzogbnVtYmVyXG4gIHJlYWRvbmx5IGZvcmNlZE1hY3JvdGFzaz86IGJvb2xlYW5cbiAgcmVhZG9ubHkgcmVhc29uPzogVGlja1NjaGVkdWxlUmVhc29uXG59XG5cbmNvbnN0IGNsYW1wU2FtcGxlUmF0ZSA9IChzYW1wbGVSYXRlOiBudW1iZXIgfCB1bmRlZmluZWQpOiBudW1iZXIgPT4ge1xuICBpZiAodHlwZW9mIHNhbXBsZVJhdGUgIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNGaW5pdGUoc2FtcGxlUmF0ZSkpIHJldHVybiAwXG4gIGlmIChzYW1wbGVSYXRlIDw9IDApIHJldHVybiAwXG4gIGlmIChzYW1wbGVSYXRlID49IDEpIHJldHVybiAxXG4gIHJldHVybiBzYW1wbGVSYXRlXG59XG5cbmNvbnN0IHNob3VsZFNhbXBsZVRpY2sgPSAodGlja1NlcTogbnVtYmVyLCBzYW1wbGVSYXRlOiBudW1iZXIpOiBib29sZWFuID0+IHtcbiAgaWYgKHNhbXBsZVJhdGUgPD0gMCkgcmV0dXJuIGZhbHNlXG4gIGlmIChzYW1wbGVSYXRlID49IDEpIHJldHVybiB0cnVlXG4gIC8vIERldGVybWluaXN0aWMgc2FtcGxpbmc6IHN0YWJsZSBhY3Jvc3MgcnVucywgYXZvaWRzIE1hdGgucmFuZG9tKCkgYW5kIGtlZXBzIG92ZXJoZWFkIG1pbmltYWwuXG4gIGNvbnN0IHggPSB0aWNrU2VxID4+PiAwXG4gIGNvbnN0IGggPSBNYXRoLmltdWwoeCBeIDB4OWUzNzc5YjksIDB4ODVlYmNhNmIpID4+PiAwXG4gIHJldHVybiBoIC8gMHhmZmZmZmZmZiA8IHNhbXBsZVJhdGVcbn1cblxuY29uc3QgdG9UcmlnZ2VyS2luZCA9IChvcmlnaW5LaW5kOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBUcmlnZ2VyS2luZCA9PiB7XG4gIGlmIChvcmlnaW5LaW5kID09PSAnYWN0aW9uJykgcmV0dXJuICdkaXNwYXRjaCdcbiAgaWYgKG9yaWdpbktpbmQgPT09ICd0cmFpdC1leHRlcm5hbC1zdG9yZScpIHJldHVybiAnZXh0ZXJuYWxTdG9yZSdcbiAgaWYgKG9yaWdpbktpbmQ/LmluY2x1ZGVzKCd0aW1lcicpKSByZXR1cm4gJ3RpbWVyJ1xuICByZXR1cm4gJ3Vua25vd24nXG59XG5cbmNvbnN0IHRvTGFuZSA9IChwcmlvcml0eTogU3RhdGVDb21taXRQcmlvcml0eSk6IFRpY2tMYW5lID0+IChwcmlvcml0eSA9PT0gJ2xvdycgPyAnbm9uVXJnZW50JyA6ICd1cmdlbnQnKVxuXG5jb25zdCBtYXhQcmlvcml0eSA9IChhOiBTdGF0ZUNvbW1pdFByaW9yaXR5LCBiOiBTdGF0ZUNvbW1pdFByaW9yaXR5KTogU3RhdGVDb21taXRQcmlvcml0eSA9PlxuICBhID09PSAnbm9ybWFsJyB8fCBiID09PSAnbm9ybWFsJyA/ICdub3JtYWwnIDogJ2xvdydcblxuY29uc3QgbWVyZ2VEcmFpbiA9IChiYXNlOiBSdW50aW1lU3RvcmVQZW5kaW5nRHJhaW4sIG5leHQ6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbik6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbiA9PiB7XG4gIGNvbnN0IG1vZHVsZXMgPSBuZXcgTWFwKGJhc2UubW9kdWxlcylcbiAgZm9yIChjb25zdCBbaywgY29tbWl0XSBvZiBuZXh0Lm1vZHVsZXMpIHtcbiAgICBjb25zdCBwcmV2ID0gbW9kdWxlcy5nZXQoaylcbiAgICBpZiAoIXByZXYpIHtcbiAgICAgIG1vZHVsZXMuc2V0KGssIGNvbW1pdClcbiAgICB9IGVsc2Uge1xuICAgICAgbW9kdWxlcy5zZXQoaywge1xuICAgICAgICAuLi5jb21taXQsXG4gICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAuLi5jb21taXQubWV0YSxcbiAgICAgICAgICBwcmlvcml0eTogbWF4UHJpb3JpdHkocHJldi5tZXRhLnByaW9yaXR5LCBjb21taXQubWV0YS5wcmlvcml0eSksXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGRpcnR5VG9waWNzID0gbmV3IE1hcChiYXNlLmRpcnR5VG9waWNzKVxuICBmb3IgKGNvbnN0IFtrLCBwXSBvZiBuZXh0LmRpcnR5VG9waWNzKSB7XG4gICAgY29uc3QgcHJldiA9IGRpcnR5VG9waWNzLmdldChrKVxuICAgIGRpcnR5VG9waWNzLnNldChrLCBwcmV2ID8gbWF4UHJpb3JpdHkocHJldiwgcCkgOiBwKVxuICB9XG5cbiAgcmV0dXJuIHsgbW9kdWxlcywgZGlydHlUb3BpY3MgfVxufVxuXG5jb25zdCBlbXB0eURyYWluID0gKCk6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbiA9PiAoeyBtb2R1bGVzOiBuZXcgTWFwKCksIGRpcnR5VG9waWNzOiBuZXcgTWFwKCkgfSlcblxuZXhwb3J0IGNvbnN0IG1ha2VUaWNrU2NoZWR1bGVyID0gKGFyZ3M6IHtcbiAgcmVhZG9ubHkgcnVudGltZVN0b3JlOiBSdW50aW1lU3RvcmVcbiAgcmVhZG9ubHkgcXVldWU/OiBKb2JRdWV1ZVxuICByZWFkb25seSBob3N0U2NoZWR1bGVyOiBIb3N0U2NoZWR1bGVyXG4gIHJlYWRvbmx5IGNvbmZpZz86IFRpY2tTY2hlZHVsZXJDb25maWdcbiAgcmVhZG9ubHkgZGVjbGFyYXRpdmVMaW5rUnVudGltZT86IERlY2xhcmF0aXZlTGlua1J1bnRpbWVcbn0pOiBUaWNrU2NoZWR1bGVyID0+IHtcbiAgY29uc3Qgc3RvcmUgPSBhcmdzLnJ1bnRpbWVTdG9yZVxuICBjb25zdCBob3N0U2NoZWR1bGVyID0gYXJncy5ob3N0U2NoZWR1bGVyXG4gIGNvbnN0IGRlY2xhcmF0aXZlTGlua3MgPSBhcmdzLmRlY2xhcmF0aXZlTGlua1J1bnRpbWVcbiAgY29uc3QgcXVldWUgPSBhcmdzLnF1ZXVlID8/IG1ha2VKb2JRdWV1ZSgpXG5cbiAgY29uc3QgY29uZmlnOiBSZXF1aXJlZDxQaWNrPFRpY2tTY2hlZHVsZXJDb25maWcsICdtYXhTdGVwcycgfCAndXJnZW50U3RlcENhcCcgfCAnbWF4RHJhaW5Sb3VuZHMnIHwgJ21pY3JvdGFza0NoYWluRGVwdGhMaW1pdCc+PiA9IHtcbiAgICBtYXhTdGVwczogYXJncy5jb25maWc/Lm1heFN0ZXBzID8/IDY0LFxuICAgIHVyZ2VudFN0ZXBDYXA6IGFyZ3MuY29uZmlnPy51cmdlbnRTdGVwQ2FwID8/IDUxMixcbiAgICBtYXhEcmFpblJvdW5kczogYXJncy5jb25maWc/Lm1heERyYWluUm91bmRzID8/IDgsXG4gICAgbWljcm90YXNrQ2hhaW5EZXB0aExpbWl0OiBhcmdzLmNvbmZpZz8ubWljcm90YXNrQ2hhaW5EZXB0aExpbWl0ID8/IDMyLFxuICB9XG4gIGNvbnN0IHRlbGVtZXRyeSA9IGFyZ3MuY29uZmlnPy50ZWxlbWV0cnlcbiAgY29uc3QgdGVsZW1ldHJ5U2FtcGxlUmF0ZSA9IGNsYW1wU2FtcGxlUmF0ZSh0ZWxlbWV0cnk/LnNhbXBsZVJhdGUpXG5cbiAgbGV0IHRpY2tTZXEgPSAwXG4gIGxldCBzY2hlZHVsZWQgPSBmYWxzZVxuICBsZXQgbWljcm90YXNrQ2hhaW5EZXB0aCA9IDBcbiAgbGV0IG5leHRGb3JjZWRSZWFzb246IFRpY2tTY2hlZHVsZVJlYXNvbiB8IHVuZGVmaW5lZFxuXG4gIGxldCBjb2FsZXNjZWRNb2R1bGVzID0gMFxuICBsZXQgY29hbGVzY2VkVG9waWNzID0gMFxuXG4gIGNvbnN0IHlpZWxkTWljcm90YXNrID0gRWZmZWN0LmFzeW5jPHZvaWQsIG5ldmVyPigocmVzdW1lKSA9PiB7XG4gICAgaG9zdFNjaGVkdWxlci5zY2hlZHVsZU1pY3JvdGFzaygoKSA9PiByZXN1bWUoRWZmZWN0LnZvaWQpKVxuICB9KVxuICBjb25zdCB5aWVsZE1hY3JvdGFzayA9IEVmZmVjdC5hc3luYzx2b2lkLCBuZXZlcj4oKHJlc3VtZSwgc2lnbmFsKSA9PiB7XG4gICAgY29uc3QgY2FuY2VsID0gaG9zdFNjaGVkdWxlci5zY2hlZHVsZU1hY3JvdGFzaygoKSA9PiByZXN1bWUoRWZmZWN0LnZvaWQpKVxuICAgIHRyeSB7XG4gICAgICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgJ2Fib3J0JyxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGNhbmNlbCgpXG4gICAgICAgIH0sXG4gICAgICAgIHsgb25jZTogdHJ1ZSB9LFxuICAgICAgKVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gYmVzdC1lZmZvcnRcbiAgICB9XG4gIH0pXG5cbiAgY29uc3Qgc2NoZWR1bGVUaWNrID0gKCk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIG5ldmVyPiA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGlmIChzY2hlZHVsZWQpIHJldHVyblxuICAgICAgc2NoZWR1bGVkID0gdHJ1ZVxuXG4gICAgICBjb25zdCB3YWl0ZWRGb3JCYXRjaCA9IGJhdGNoRGVwdGggPiAwXG5cbiAgICAgIGNvbnN0IGZvcmNlZFJlYXNvbiA9IG5leHRGb3JjZWRSZWFzb25cbiAgICAgIG5leHRGb3JjZWRSZWFzb24gPSB1bmRlZmluZWRcblxuICAgICAgY29uc3Qgc2hvdWxkWWllbGRGb3JTdGFydmF0aW9uID1cbiAgICAgICAgZm9yY2VkUmVhc29uID09IG51bGwgJiYgbWljcm90YXNrQ2hhaW5EZXB0aCA+PSBNYXRoLm1heCgxLCBjb25maWcubWljcm90YXNrQ2hhaW5EZXB0aExpbWl0KVxuXG4gICAgICBjb25zdCByZWFzb246IFRpY2tTY2hlZHVsZVJlYXNvbiB8IHVuZGVmaW5lZCA9IGZvcmNlZFJlYXNvbiA/PyAoc2hvdWxkWWllbGRGb3JTdGFydmF0aW9uID8gJ21pY3JvdGFza19zdGFydmF0aW9uJyA6IHVuZGVmaW5lZClcbiAgICAgIGNvbnN0IGJvdW5kYXJ5OiAnbWljcm90YXNrJyB8ICdtYWNyb3Rhc2snID0gcmVhc29uID8gJ21hY3JvdGFzaycgOiAnbWljcm90YXNrJ1xuICAgICAgY29uc3Qgc3RhcnRlZEFzOiBUaWNrU2NoZWR1bGVTdGFydGVkQXMgPSB3YWl0ZWRGb3JCYXRjaCA/ICdiYXRjaCcgOiBib3VuZGFyeVxuICAgICAgY29uc3QgZGVwdGhBdFNjaGVkdWxlID0gbWljcm90YXNrQ2hhaW5EZXB0aFxuXG4gICAgICB5aWVsZCogRWZmZWN0LmZvcmtEYWVtb24oXG4gICAgICAgIEVmZmVjdC5sb2NhbGx5KFRhc2tSdW5uZXIuaW5TeW5jVHJhbnNhY3Rpb25GaWJlciwgZmFsc2UpKFxuICAgICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHlpZWxkKiB3YWl0Rm9yQmF0Y2hFbmRJZk5lZWRlZCgpXG4gICAgICAgICAgICAgIGlmIChib3VuZGFyeSA9PT0gJ21pY3JvdGFzaycpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCogeWllbGRNaWNyb3Rhc2tcbiAgICAgICAgICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoICs9IDFcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB5aWVsZCogeWllbGRNYWNyb3Rhc2tcbiAgICAgICAgICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoID0gMFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3Qgc2NoZWR1bGU6IFRpY2tTY2hlZHVsZSA9IHtcbiAgICAgICAgICAgICAgICBzdGFydGVkQXMsXG4gICAgICAgICAgICAgICAgbWljcm90YXNrQ2hhaW5EZXB0aDogYm91bmRhcnkgPT09ICdtYWNyb3Rhc2snID8gZGVwdGhBdFNjaGVkdWxlIDogbWljcm90YXNrQ2hhaW5EZXB0aCxcbiAgICAgICAgICAgICAgICAuLi4oYm91bmRhcnkgPT09ICdtYWNyb3Rhc2snID8geyBmb3JjZWRNYWNyb3Rhc2s6IHRydWUsIHJlYXNvbjogcmVhc29uID8/ICd1bmtub3duJyB9IDoge30pLFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3Qgb3V0Y29tZSA9IHlpZWxkKiBmbHVzaFRpY2soc2NoZWR1bGUpXG4gICAgICAgICAgICAgIGlmICghb3V0Y29tZS5zdGFibGUpIHtcbiAgICAgICAgICAgICAgICBuZXh0Rm9yY2VkUmVhc29uID1cbiAgICAgICAgICAgICAgICAgIG91dGNvbWUuZGVncmFkZVJlYXNvbiA9PT0gJ2J1ZGdldF9zdGVwcydcbiAgICAgICAgICAgICAgICAgICAgPyAnYnVkZ2V0J1xuICAgICAgICAgICAgICAgICAgICA6IG91dGNvbWUuZGVncmFkZVJlYXNvbiA9PT0gJ2N5Y2xlX2RldGVjdGVkJ1xuICAgICAgICAgICAgICAgICAgICAgID8gJ2N5Y2xlX2RldGVjdGVkJ1xuICAgICAgICAgICAgICAgICAgICAgIDogJ3Vua25vd24nXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgIHNjaGVkdWxlZCA9IGZhbHNlXG4gICAgICAgICAgICAgIC8vIElmIHNvbWV0aGluZyB3YXMgcmUtcXVldWVkIG9yIGFycml2ZWQgYWZ0ZXIgY29tbWl0LCBzY2hlZHVsZSB0aGUgbmV4dCB0aWNrIChiZXN0LWVmZm9ydCkuXG4gICAgICAgICAgICAgIGlmIChxdWV1ZS5oYXNQZW5kaW5nKCkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCogc2NoZWR1bGVUaWNrKClcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNldCBjaGFpbiBkZXB0aCB3aGVuIHRoZSBzeXN0ZW0gYmVjb21lcyBpZGxlIChhdm9pZCBmb3JjaW5nIGEgbWFjcm90YXNrIG9uIHRoZSBuZXh0IHVucmVsYXRlZCB0aWNrKS5cbiAgICAgICAgICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoID0gMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICApXG4gICAgfSlcblxuICBjb25zdCBmbHVzaFRpY2sgPSAoc2NoZWR1bGU6IFRpY2tTY2hlZHVsZSk6IEVmZmVjdC5FZmZlY3Q8eyBzdGFibGU6IGJvb2xlYW47IGRlZ3JhZGVSZWFzb24/OiBUaWNrRGVncmFkZVJlYXNvbiB9LCBuZXZlciwgbmV2ZXI+ID0+XG4gICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGlmICghcXVldWUuaGFzUGVuZGluZygpKSB7XG4gICAgICByZXR1cm4geyBzdGFibGU6IHRydWUgfVxuICAgIH1cblxuICAgIHRpY2tTZXEgKz0gMVxuICAgIGNvbnN0IGN1cnJlbnRUaWNrU2VxID0gdGlja1NlcVxuXG4gICAgY29uc3QgZGlhZ25vc3RpY3NMZXZlbCA9IHlpZWxkKiBGaWJlclJlZi5nZXQoRGVidWcuY3VycmVudERpYWdub3N0aWNzTGV2ZWwpXG4gICAgY29uc3Qgc2hvdWxkRW1pdFRyYWNlID0gRGV2dG9vbHNIdWIuaXNEZXZ0b29sc0VuYWJsZWQoKSAmJiBkaWFnbm9zdGljc0xldmVsICE9PSAnb2ZmJ1xuXG4gICAgY29uc3QgY2FwdHVyZWQ6IHtcbiAgICAgIGRyYWluUm91bmRzOiBudW1iZXJcbiAgICAgIHN0YWJsZTogYm9vbGVhblxuICAgICAgZGVncmFkZVJlYXNvbj86IFRpY2tEZWdyYWRlUmVhc29uXG4gICAgICBkZWZlcnJlZD86IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpblxuICAgICAgYWNjZXB0ZWQ6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpblxuICAgIH0gPSB7XG4gICAgICBkcmFpblJvdW5kczogMCxcbiAgICAgIHN0YWJsZTogdHJ1ZSxcbiAgICAgIGFjY2VwdGVkOiBlbXB0eURyYWluKCksXG4gICAgfVxuXG4gICAgLy8gRml4cG9pbnQgY2FwdHVyZTogZHJhaW4gLT4gYXBwbHkgZGVjbGFyYXRpdmUgbGlua3MgLT4gZHJhaW4gKGJvdW5kZWQgYnkgbWF4RHJhaW5Sb3VuZHMpLlxuICAgIHdoaWxlIChjYXB0dXJlZC5kcmFpblJvdW5kcyA8IGNvbmZpZy5tYXhEcmFpblJvdW5kcykge1xuICAgICAgY29uc3QgZHJhaW5lZCA9IHF1ZXVlLmRyYWluKClcbiAgICAgIGlmICghZHJhaW5lZCkgYnJlYWtcbiAgICAgIGNhcHR1cmVkLmRyYWluUm91bmRzICs9IDFcbiAgICAgIGNhcHR1cmVkLmFjY2VwdGVkID0gbWVyZ2VEcmFpbihjYXB0dXJlZC5hY2NlcHRlZCwgZHJhaW5lZClcblxuICAgICAgaWYgKGRlY2xhcmF0aXZlTGlua3MgJiYgZHJhaW5lZC5tb2R1bGVzLnNpemUgPiAwKSB7XG4gICAgICAgIGNvbnN0IGNoYW5nZWRNb2R1bGVJbnN0YW5jZUtleXMgPSBBcnJheS5mcm9tKGRyYWluZWQubW9kdWxlcy5rZXlzKCkpXG4gICAgICAgIHlpZWxkKiBkZWNsYXJhdGl2ZUxpbmtzLmFwcGx5Rm9yU291cmNlcyh7XG4gICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgYWNjZXB0ZWRNb2R1bGVzOiBjYXB0dXJlZC5hY2NlcHRlZC5tb2R1bGVzLFxuICAgICAgICAgIGNoYW5nZWRNb2R1bGVJbnN0YW5jZUtleXMsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHF1ZXVlLmhhc1BlbmRpbmcoKSkge1xuICAgICAgY2FwdHVyZWQuc3RhYmxlID0gZmFsc2VcbiAgICAgIGNhcHR1cmVkLmRlZ3JhZGVSZWFzb24gPSAnY3ljbGVfZGV0ZWN0ZWQnXG4gICAgfVxuXG4gICAgLy8gQnVkZ2V0IGVuZm9yY2VtZW50IChkZWZlciBub25VcmdlbnQgb25seTsgdXJnZW50IG1heSBiZSBjdXQgb25seSBpbiBjeWNsZSBzYWZldHktYnJlYWspLlxuICAgIGNvbnN0IHVyZ2VudE1vZHVsZXM6IEFycmF5PFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdD4gPSBbXVxuICAgIGNvbnN0IG5vblVyZ2VudE1vZHVsZXM6IEFycmF5PFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdD4gPSBbXVxuXG4gICAgZm9yIChjb25zdCBjb21taXQgb2YgY2FwdHVyZWQuYWNjZXB0ZWQubW9kdWxlcy52YWx1ZXMoKSkge1xuICAgICAgaWYgKHRvTGFuZShjb21taXQubWV0YS5wcmlvcml0eSkgPT09ICd1cmdlbnQnKSB7XG4gICAgICAgIHVyZ2VudE1vZHVsZXMucHVzaChjb21taXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub25VcmdlbnRNb2R1bGVzLnB1c2goY29tbWl0KVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHVyZ2VudENhcEV4Y2VlZGVkID0gdXJnZW50TW9kdWxlcy5sZW5ndGggPiBjb25maWcudXJnZW50U3RlcENhcFxuICAgIGNvbnN0IHVyZ2VudEFjY2VwdGVkID0gdXJnZW50Q2FwRXhjZWVkZWQgPyB1cmdlbnRNb2R1bGVzLnNsaWNlKDAsIGNvbmZpZy51cmdlbnRTdGVwQ2FwKSA6IHVyZ2VudE1vZHVsZXNcbiAgICBjb25zdCB1cmdlbnREZWZlcnJlZCA9IHVyZ2VudENhcEV4Y2VlZGVkID8gdXJnZW50TW9kdWxlcy5zbGljZShjb25maWcudXJnZW50U3RlcENhcCkgOiBbXVxuXG4gICAgY29uc3Qgbm9uVXJnZW50QnVkZ2V0ID0gTWF0aC5tYXgoMCwgY29uZmlnLm1heFN0ZXBzKVxuICAgIGNvbnN0IG5vblVyZ2VudEFjY2VwdGVkID0gdXJnZW50Q2FwRXhjZWVkZWQgPyBbXSA6IG5vblVyZ2VudE1vZHVsZXMuc2xpY2UoMCwgbm9uVXJnZW50QnVkZ2V0KVxuICAgIGNvbnN0IG5vblVyZ2VudERlZmVycmVkID0gdXJnZW50Q2FwRXhjZWVkZWQgPyBub25VcmdlbnRNb2R1bGVzIDogbm9uVXJnZW50TW9kdWxlcy5zbGljZShub25VcmdlbnRCdWRnZXQpXG5cbiAgICBpZiAodXJnZW50Q2FwRXhjZWVkZWQpIHtcbiAgICAgIGNhcHR1cmVkLnN0YWJsZSA9IGZhbHNlXG4gICAgICBjYXB0dXJlZC5kZWdyYWRlUmVhc29uID0gJ2N5Y2xlX2RldGVjdGVkJ1xuICAgIH0gZWxzZSBpZiAobm9uVXJnZW50RGVmZXJyZWQubGVuZ3RoID4gMCkge1xuICAgICAgY2FwdHVyZWQuc3RhYmxlID0gZmFsc2VcbiAgICAgIGNhcHR1cmVkLmRlZ3JhZGVSZWFzb24gPSBjYXB0dXJlZC5kZWdyYWRlUmVhc29uID8/ICdidWRnZXRfc3RlcHMnXG4gICAgfVxuXG4gICAgY29uc3QgYWNjZXB0ZWRNb2R1bGVzID0gbmV3IE1hcDxNb2R1bGVJbnN0YW5jZUtleSwgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0PigpXG4gICAgY29uc3QgZGVmZXJyZWRNb2R1bGVzID0gbmV3IE1hcDxNb2R1bGVJbnN0YW5jZUtleSwgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0PigpXG5cbiAgICBmb3IgKGNvbnN0IGMgb2YgdXJnZW50QWNjZXB0ZWQpIGFjY2VwdGVkTW9kdWxlcy5zZXQoYy5tb2R1bGVJbnN0YW5jZUtleSwgYylcbiAgICBmb3IgKGNvbnN0IGMgb2Ygbm9uVXJnZW50QWNjZXB0ZWQpIGFjY2VwdGVkTW9kdWxlcy5zZXQoYy5tb2R1bGVJbnN0YW5jZUtleSwgYylcblxuICAgIGZvciAoY29uc3QgYyBvZiB1cmdlbnREZWZlcnJlZCkgZGVmZXJyZWRNb2R1bGVzLnNldChjLm1vZHVsZUluc3RhbmNlS2V5LCBjKVxuICAgIGZvciAoY29uc3QgYyBvZiBub25VcmdlbnREZWZlcnJlZCkgZGVmZXJyZWRNb2R1bGVzLnNldChjLm1vZHVsZUluc3RhbmNlS2V5LCBjKVxuXG4gICAgY29uc3QgYWNjZXB0ZWRUb3BpY3MgPSBuZXcgTWFwPHN0cmluZywgU3RhdGVDb21taXRQcmlvcml0eT4oKVxuICAgIGNvbnN0IGRlZmVycmVkVG9waWNzID0gbmV3IE1hcDxzdHJpbmcsIFN0YXRlQ29tbWl0UHJpb3JpdHk+KClcblxuICAgIGZvciAoY29uc3QgW3RvcGljS2V5LCBwcmlvcml0eV0gb2YgY2FwdHVyZWQuYWNjZXB0ZWQuZGlydHlUb3BpY3MpIHtcbiAgICAgIGNvbnN0IGluZm8gPSBzdG9yZVRvcGljVG9Nb2R1bGVJbnN0YW5jZUtleSh0b3BpY0tleSlcbiAgICAgIGlmICghaW5mbykgY29udGludWVcbiAgICAgIGlmIChhY2NlcHRlZE1vZHVsZXMuaGFzKGluZm8pKSB7XG4gICAgICAgIGFjY2VwdGVkVG9waWNzLnNldCh0b3BpY0tleSwgcHJpb3JpdHkpXG4gICAgICB9IGVsc2UgaWYgKGRlZmVycmVkTW9kdWxlcy5oYXMoaW5mbykpIHtcbiAgICAgICAgZGVmZXJyZWRUb3BpY3Muc2V0KHRvcGljS2V5LCBwcmlvcml0eSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIENvbnNlcnZhdGl2ZSBkZWZhdWx0OiB0cmVhdCB1bmtub3duIHRvcGljcyBhcyBhY2NlcHRlZC5cbiAgICAgICAgYWNjZXB0ZWRUb3BpY3Muc2V0KHRvcGljS2V5LCBwcmlvcml0eSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBhY2NlcHRlZERyYWluOiBSdW50aW1lU3RvcmVQZW5kaW5nRHJhaW4gPSB7XG4gICAgICBtb2R1bGVzOiBhY2NlcHRlZE1vZHVsZXMsXG4gICAgICBkaXJ0eVRvcGljczogYWNjZXB0ZWRUb3BpY3MsXG4gICAgfVxuXG4gICAgY29uc3QgZGVmZXJyZWREcmFpbjogUnVudGltZVN0b3JlUGVuZGluZ0RyYWluIHwgdW5kZWZpbmVkID1cbiAgICAgIGRlZmVycmVkTW9kdWxlcy5zaXplID4gMCB8fCBkZWZlcnJlZFRvcGljcy5zaXplID4gMFxuICAgICAgICA/IHtcbiAgICAgICAgICAgIG1vZHVsZXM6IGRlZmVycmVkTW9kdWxlcyxcbiAgICAgICAgICAgIGRpcnR5VG9waWNzOiBkZWZlcnJlZFRvcGljcyxcbiAgICAgICAgICB9XG4gICAgICAgIDogdW5kZWZpbmVkXG5cbiAgICBjYXB0dXJlZC5kZWZlcnJlZCA9IGRlZmVycmVkRHJhaW5cblxuICAgIGxldCBzdGFydGVkQXRNczogbnVtYmVyIHwgdW5kZWZpbmVkXG4gICAgbGV0IHRyaWdnZXJTdW1tYXJ5OiBhbnkgfCB1bmRlZmluZWRcbiAgICBsZXQgYW5jaG9yOiBhbnkgfCB1bmRlZmluZWRcbiAgICBsZXQgYmFja2xvZzogYW55IHwgdW5kZWZpbmVkXG4gICAgbGV0IHJlc3VsdDogYW55IHwgdW5kZWZpbmVkXG5cbiAgICBpZiAoc2hvdWxkRW1pdFRyYWNlKSB7XG4gICAgICBzdGFydGVkQXRNcyA9IERhdGUubm93KClcblxuICAgICAgdHJpZ2dlclN1bW1hcnkgPSAoKCkgPT4ge1xuICAgICAgICBjb25zdCB0cmlnZ2VycyA9IEFycmF5LmZyb20oY2FwdHVyZWQuYWNjZXB0ZWQubW9kdWxlcy52YWx1ZXMoKSlcbiAgICAgICAgY29uc3QgY291bnRzID0gbmV3IE1hcDxUcmlnZ2VyS2luZCwgbnVtYmVyPigpXG4gICAgICAgIGxldCBwcmltYXJ5OiBhbnkgPSB1bmRlZmluZWRcbiAgICAgICAgZm9yIChjb25zdCB0IG9mIHRyaWdnZXJzKSB7XG4gICAgICAgICAgY29uc3Qga2luZCA9IHRvVHJpZ2dlcktpbmQodC5tZXRhLm9yaWdpbktpbmQpXG4gICAgICAgICAgY291bnRzLnNldChraW5kLCAoY291bnRzLmdldChraW5kKSA/PyAwKSArIDEpXG4gICAgICAgICAgaWYgKCFwcmltYXJ5KSB7XG4gICAgICAgICAgICBwcmltYXJ5ID0ge1xuICAgICAgICAgICAgICBraW5kLFxuICAgICAgICAgICAgICBtb2R1bGVJZDogdC5tb2R1bGVJZCxcbiAgICAgICAgICAgICAgaW5zdGFuY2VJZDogdC5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgICBmaWVsZFBhdGg6IGtpbmQgPT09ICdleHRlcm5hbFN0b3JlJyA/IHQubWV0YS5vcmlnaW5OYW1lIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBhY3Rpb25UYWc6IGtpbmQgPT09ICdkaXNwYXRjaCcgPyB0Lm1ldGEub3JpZ2luTmFtZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0b3RhbDogdHJpZ2dlcnMubGVuZ3RoLFxuICAgICAgICAgIGtpbmRzOiBBcnJheS5mcm9tKGNvdW50cy5lbnRyaWVzKCkpLm1hcCgoW2tpbmQsIGNvdW50XSkgPT4gKHsga2luZCwgY291bnQgfSkpLFxuICAgICAgICAgIHByaW1hcnksXG4gICAgICAgICAgY29hbGVzY2VkQ291bnQ6IHtcbiAgICAgICAgICAgIG1vZHVsZXM6IGNvYWxlc2NlZE1vZHVsZXMsXG4gICAgICAgICAgICB0b3BpY3M6IGNvYWxlc2NlZFRvcGljcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICB9KSgpXG5cbiAgICAgIGFuY2hvciA9ICgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpcnN0ID0gY2FwdHVyZWQuYWNjZXB0ZWQubW9kdWxlcy52YWx1ZXMoKS5uZXh0KCkudmFsdWUgYXMgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0IHwgdW5kZWZpbmVkXG4gICAgICAgIGlmICghZmlyc3QpIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBtb2R1bGVJZDogZmlyc3QubW9kdWxlSWQsXG4gICAgICAgICAgaW5zdGFuY2VJZDogZmlyc3QuaW5zdGFuY2VJZCxcbiAgICAgICAgICB0eG5TZXE6IGZpcnN0Lm1ldGEudHhuU2VxLFxuICAgICAgICAgIHR4bklkOiBmaXJzdC5tZXRhLnR4bklkLFxuICAgICAgICAgIC4uLih0eXBlb2YgZmlyc3Qub3BTZXEgPT09ICdudW1iZXInID8geyBvcFNlcTogZmlyc3Qub3BTZXEgfSA6IG51bGwpLFxuICAgICAgICB9XG4gICAgICB9KSgpXG5cbiAgICAgIGJhY2tsb2cgPSAoKCkgPT4ge1xuICAgICAgICBjb25zdCBkZWZlcnJlZFdvcmsgPSBjYXB0dXJlZC5kZWZlcnJlZFxuICAgICAgICBpZiAoIWRlZmVycmVkV29yaykgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBwZW5kaW5nRGVmZXJyZWRXb3JrID0gZGVmZXJyZWRXb3JrLm1vZHVsZXMuc2l6ZSArIGRlZmVycmVkV29yay5kaXJ0eVRvcGljcy5zaXplXG5cbiAgICAgICAgY29uc3QgZGVmZXJyZWRNb2R1bGVzTGlzdCA9IEFycmF5LmZyb20oZGVmZXJyZWRXb3JrLm1vZHVsZXMudmFsdWVzKCkpXG4gICAgICAgIGNvbnN0IHBlbmRpbmdFeHRlcm5hbElucHV0cyA9IGRlZmVycmVkTW9kdWxlc0xpc3QuZmlsdGVyKChtKSA9PiB0b1RyaWdnZXJLaW5kKG0ubWV0YS5vcmlnaW5LaW5kKSA9PT0gJ2V4dGVybmFsU3RvcmUnKS5sZW5ndGhcblxuICAgICAgICBjb25zdCBwcmltYXJ5RGVmZXJyZWQgPVxuICAgICAgICAgIGRlZmVycmVkTW9kdWxlc0xpc3QuZmluZCgobSkgPT4gdG9UcmlnZ2VyS2luZChtLm1ldGEub3JpZ2luS2luZCkgPT09ICdleHRlcm5hbFN0b3JlJykgPz8gZGVmZXJyZWRNb2R1bGVzTGlzdFswXVxuICAgICAgICBjb25zdCBraW5kID0gcHJpbWFyeURlZmVycmVkID8gdG9UcmlnZ2VyS2luZChwcmltYXJ5RGVmZXJyZWQubWV0YS5vcmlnaW5LaW5kKSA6ICd1bmtub3duJ1xuXG4gICAgICAgIGNvbnN0IGRlZmVycmVkUHJpbWFyeSA9XG4gICAgICAgICAgcHJpbWFyeURlZmVycmVkICE9IG51bGxcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIGtpbmQ6IGtpbmQgPT09ICdleHRlcm5hbFN0b3JlJyA/ICgnZXh0ZXJuYWxTdG9yZScgYXMgY29uc3QpIDogKCd1bmtub3duJyBhcyBjb25zdCksXG4gICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHByaW1hcnlEZWZlcnJlZC5tb2R1bGVJZCxcbiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBwcmltYXJ5RGVmZXJyZWQuaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgICBmaWVsZFBhdGg6IGtpbmQgPT09ICdleHRlcm5hbFN0b3JlJyA/IHByaW1hcnlEZWZlcnJlZC5tZXRhLm9yaWdpbk5hbWUgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgc3RvcmVJZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGVuZGluZ0V4dGVybmFsSW5wdXRzLFxuICAgICAgICAgIHBlbmRpbmdEZWZlcnJlZFdvcmssXG4gICAgICAgICAgZGVmZXJyZWRQcmltYXJ5LFxuICAgICAgICB9XG4gICAgICB9KSgpXG5cbiAgICAgIHJlc3VsdCA9IHtcbiAgICAgICAgc3RhYmxlOiBjYXB0dXJlZC5zdGFibGUsXG4gICAgICAgIC4uLihjYXB0dXJlZC5zdGFibGUgPyBudWxsIDogeyBkZWdyYWRlUmVhc29uOiBjYXB0dXJlZC5kZWdyYWRlUmVhc29uID8/ICd1bmtub3duJyB9KSxcbiAgICAgIH0gYXMgY29uc3RcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkRW1pdFRyYWNlICYmIHNjaGVkdWxlLmZvcmNlZE1hY3JvdGFzayAmJiBzY2hlZHVsZS5yZWFzb24gPT09ICdtaWNyb3Rhc2tfc3RhcnZhdGlvbicpIHtcbiAgICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICB0eXBlOiAnd2FybjptaWNyb3Rhc2stc3RhcnZhdGlvbicsXG4gICAgICAgIG1vZHVsZUlkOiBhbmNob3I/Lm1vZHVsZUlkLFxuICAgICAgICBpbnN0YW5jZUlkOiBhbmNob3I/Lmluc3RhbmNlSWQsXG4gICAgICAgIHRpY2tTZXE6IGN1cnJlbnRUaWNrU2VxLFxuICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoOiBzY2hlZHVsZS5taWNyb3Rhc2tDaGFpbkRlcHRoLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkRW1pdFRyYWNlKSB7XG4gICAgICB5aWVsZCogRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogJ3RyYWNlOnRpY2snLFxuICAgICAgICBtb2R1bGVJZDogYW5jaG9yPy5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogYW5jaG9yPy5pbnN0YW5jZUlkLFxuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgcGhhc2U6ICdzdGFydCcsXG4gICAgICAgICAgdGltZXN0YW1wTXM6IHN0YXJ0ZWRBdE1zISxcbiAgICAgICAgICBzY2hlZHVsZSxcbiAgICAgICAgICB0cmlnZ2VyU3VtbWFyeSxcbiAgICAgICAgICBhbmNob3JzOiBhbmNob3IsXG4gICAgICAgICAgYnVkZ2V0OiB7XG4gICAgICAgICAgICBtYXhTdGVwczogY29uZmlnLm1heFN0ZXBzLFxuICAgICAgICAgICAgZWxhcHNlZE1zOiAwLFxuICAgICAgICAgICAgc3RlcHM6IDAsXG4gICAgICAgICAgICB0eG5Db3VudDogYWNjZXB0ZWRNb2R1bGVzLnNpemUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgaWYgKCFjYXB0dXJlZC5zdGFibGUgJiYgc2hvdWxkRW1pdFRyYWNlKSB7XG4gICAgICB5aWVsZCogRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogJ3RyYWNlOnRpY2snLFxuICAgICAgICBtb2R1bGVJZDogYW5jaG9yPy5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogYW5jaG9yPy5pbnN0YW5jZUlkLFxuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgcGhhc2U6ICdidWRnZXRFeGNlZWRlZCcsXG4gICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgc2NoZWR1bGUsXG4gICAgICAgICAgdHJpZ2dlclN1bW1hcnksXG4gICAgICAgICAgYW5jaG9yczogYW5jaG9yLFxuICAgICAgICAgIGJ1ZGdldDoge1xuICAgICAgICAgICAgbWF4U3RlcHM6IGNvbmZpZy5tYXhTdGVwcyxcbiAgICAgICAgICAgIGVsYXBzZWRNczogTWF0aC5tYXgoMCwgRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdE1zISksXG4gICAgICAgICAgICBzdGVwczogY29uZmlnLm1heFN0ZXBzLFxuICAgICAgICAgICAgdHhuQ291bnQ6IGFjY2VwdGVkTW9kdWxlcy5zaXplLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYmFja2xvZyxcbiAgICAgICAgICByZXN1bHQsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8vIFJlcXVldWUgZGVmZXJyZWQgYmFja2xvZyBiZWZvcmUgY29tbWl0dGluZyB0aGUgdGljaywgc28gdGhlIG5leHQgdGljayBjYW4gcGljayBpdCB1cC5cbiAgICBpZiAoZGVmZXJyZWREcmFpbikge1xuICAgICAgcXVldWUucmVxdWV1ZShkZWZlcnJlZERyYWluKVxuICAgIH1cblxuICAgIGNvbnN0IGNvbW1pdHRlZCA9IHN0b3JlLmNvbW1pdFRpY2soe1xuICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICBhY2NlcHRlZDogYWNjZXB0ZWREcmFpbixcbiAgICB9KVxuXG4gICAgLy8gTm90aWZ5IGNoYW5nZWQgdG9waWNzIGFmdGVyIGNvbW1pdHRpbmcgdGhlIHNuYXBzaG90IHRva2VuLlxuICAgIGZvciAoY29uc3QgeyBsaXN0ZW5lcnMgfSBvZiBjb21taXR0ZWQuY2hhbmdlZFRvcGljcy52YWx1ZXMoKSkge1xuICAgICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsaXN0ZW5lcigpXG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIGJlc3QtZWZmb3J0OiBuZXZlciBsZXQgYSBzdWJzY3JpYmVyIGJyZWFrIHRoZSB0aWNrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWNhcHR1cmVkLnN0YWJsZSAmJiBzaG91bGRFbWl0VHJhY2UgJiYgYmFja2xvZz8uZGVmZXJyZWRQcmltYXJ5KSB7XG4gICAgICBjb25zdCBwcmltYXJ5ID0gYmFja2xvZy5kZWZlcnJlZFByaW1hcnlcbiAgICAgIGlmIChwcmltYXJ5LmtpbmQgPT09ICdleHRlcm5hbFN0b3JlJykge1xuICAgICAgICBjb25zdCBtb2R1bGVJbnN0YW5jZUtleSA9XG4gICAgICAgICAgcHJpbWFyeS5tb2R1bGVJZCAmJiBwcmltYXJ5Lmluc3RhbmNlSWQgPyAoYCR7cHJpbWFyeS5tb2R1bGVJZH06OiR7cHJpbWFyeS5pbnN0YW5jZUlkfWAgYXMgTW9kdWxlSW5zdGFuY2VLZXkpIDogdW5kZWZpbmVkXG4gICAgICAgIGlmIChtb2R1bGVJbnN0YW5jZUtleSAmJiBzdG9yZS5nZXRNb2R1bGVTdWJzY3JpYmVyQ291bnQobW9kdWxlSW5zdGFuY2VLZXkpID4gMCkge1xuICAgICAgICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICAgICAgdHlwZTogJ3dhcm46cHJpb3JpdHktaW52ZXJzaW9uJyxcbiAgICAgICAgICAgIG1vZHVsZUlkOiBwcmltYXJ5Lm1vZHVsZUlkLFxuICAgICAgICAgICAgaW5zdGFuY2VJZDogcHJpbWFyeS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgICByZWFzb246ICdkZWZlcnJlZEJhY2tsb2cnLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkRW1pdFRyYWNlKSB7XG4gICAgICB5aWVsZCogRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogJ3RyYWNlOnRpY2snLFxuICAgICAgICBtb2R1bGVJZDogYW5jaG9yPy5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogYW5jaG9yPy5pbnN0YW5jZUlkLFxuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgcGhhc2U6ICdzZXR0bGVkJyxcbiAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgICBzY2hlZHVsZSxcbiAgICAgICAgICB0cmlnZ2VyU3VtbWFyeSxcbiAgICAgICAgICBhbmNob3JzOiBhbmNob3IsXG4gICAgICAgICAgYnVkZ2V0OiB7XG4gICAgICAgICAgICBtYXhTdGVwczogY29uZmlnLm1heFN0ZXBzLFxuICAgICAgICAgICAgZWxhcHNlZE1zOiBNYXRoLm1heCgwLCBEYXRlLm5vdygpIC0gc3RhcnRlZEF0TXMhKSxcbiAgICAgICAgICAgIHN0ZXBzOiBhY2NlcHRlZE1vZHVsZXMuc2l6ZSxcbiAgICAgICAgICAgIHR4bkNvdW50OiBhY2NlcHRlZE1vZHVsZXMuc2l6ZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJhY2tsb2csXG4gICAgICAgICAgcmVzdWx0LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAodGVsZW1ldHJ5Py5vblRpY2tEZWdyYWRlZCAmJiAoc2NoZWR1bGUuZm9yY2VkTWFjcm90YXNrIHx8ICFjYXB0dXJlZC5zdGFibGUpICYmIHNob3VsZFNhbXBsZVRpY2soY3VycmVudFRpY2tTZXEsIHRlbGVtZXRyeVNhbXBsZVJhdGUpKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0ZWxlbWV0cnkub25UaWNrRGVncmFkZWQoe1xuICAgICAgICAgIHRpY2tTZXE6IGN1cnJlbnRUaWNrU2VxLFxuICAgICAgICAgIHN0YWJsZTogY2FwdHVyZWQuc3RhYmxlLFxuICAgICAgICAgIGRlZ3JhZGVSZWFzb246IGNhcHR1cmVkLnN0YWJsZSA/IHVuZGVmaW5lZCA6IChjYXB0dXJlZC5kZWdyYWRlUmVhc29uID8/ICd1bmtub3duJyksXG4gICAgICAgICAgZm9yY2VkTWFjcm90YXNrOiBzY2hlZHVsZS5mb3JjZWRNYWNyb3Rhc2ssXG4gICAgICAgICAgc2NoZWR1bGVSZWFzb246IHNjaGVkdWxlLnJlYXNvbixcbiAgICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoOiBzY2hlZHVsZS5taWNyb3Rhc2tDaGFpbkRlcHRoLFxuICAgICAgICAgIGRlZmVycmVkV29ya0NvdW50OiBkZWZlcnJlZERyYWluID8gZGVmZXJyZWREcmFpbi5tb2R1bGVzLnNpemUgKyBkZWZlcnJlZERyYWluLmRpcnR5VG9waWNzLnNpemUgOiAwLFxuICAgICAgICB9KVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIGJlc3QtZWZmb3J0OiBuZXZlciBsZXQgdXNlciB0ZWxlbWV0cnkgYnJlYWsgdGhlIHRpY2tcbiAgICAgIH1cbiAgICB9XG4gICAgY29hbGVzY2VkTW9kdWxlcyA9IDBcbiAgICBjb2FsZXNjZWRUb3BpY3MgPSAwXG5cbiAgICByZXR1cm4geyBzdGFibGU6IGNhcHR1cmVkLnN0YWJsZSwgZGVncmFkZVJlYXNvbjogY2FwdHVyZWQuZGVncmFkZVJlYXNvbiB9XG4gIH0pXG5cbiAgY29uc3QgZmx1c2hOb3c6IFRpY2tTY2hlZHVsZXJbJ2ZsdXNoTm93J10gPSBmbHVzaFRpY2soeyBzdGFydGVkQXM6ICd1bmtub3duJyB9KS5waXBlKEVmZmVjdC5hc1ZvaWQpXG5cbiAgY29uc3Qgc3RvcmVUb3BpY1RvTW9kdWxlSW5zdGFuY2VLZXkgPSAodG9waWNLZXk6IHN0cmluZyk6IE1vZHVsZUluc3RhbmNlS2V5IHwgdW5kZWZpbmVkID0+IHtcbiAgICBjb25zdCBpZHggPSB0b3BpY0tleS5pbmRleE9mKCc6OnJxOicpXG4gICAgaWYgKGlkeCA+IDApIHtcbiAgICAgIHJldHVybiB0b3BpY0tleS5zbGljZSgwLCBpZHgpIGFzIE1vZHVsZUluc3RhbmNlS2V5XG4gICAgfVxuICAgIGlmICh0b3BpY0tleS5pbmNsdWRlcygnOjonKSkge1xuICAgICAgcmV0dXJuIHRvcGljS2V5IGFzIE1vZHVsZUluc3RhbmNlS2V5XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIGNvbnN0IG9uU2VsZWN0b3JDaGFuZ2VkOiBUaWNrU2NoZWR1bGVyWydvblNlbGVjdG9yQ2hhbmdlZCddID0gKHsgbW9kdWxlSW5zdGFuY2VLZXksIHNlbGVjdG9ySWQsIHByaW9yaXR5IH0pID0+IHtcbiAgICBjb25zdCBjb2FsZXNjZWQgPSBxdWV1ZS5tYXJrVG9waWNEaXJ0eShtYWtlUmVhZFF1ZXJ5VG9waWNLZXkobW9kdWxlSW5zdGFuY2VLZXksIHNlbGVjdG9ySWQpLCBwcmlvcml0eSlcbiAgICBpZiAoY29hbGVzY2VkKSBjb2FsZXNjZWRUb3BpY3MgKz0gMVxuICB9XG5cbiAgY29uc3Qgb25Nb2R1bGVDb21taXQ6IFRpY2tTY2hlZHVsZXJbJ29uTW9kdWxlQ29tbWl0J10gPSAoY29tbWl0KSA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IGNvYWxlc2NlZENvbW1pdCA9IHF1ZXVlLmVucXVldWVNb2R1bGVDb21taXQoY29tbWl0KVxuICAgICAgaWYgKGNvYWxlc2NlZENvbW1pdCkgY29hbGVzY2VkTW9kdWxlcyArPSAxXG4gICAgICBjb25zdCBjb2FsZXNjZWRUb3BpYyA9IHF1ZXVlLm1hcmtUb3BpY0RpcnR5KGNvbW1pdC5tb2R1bGVJbnN0YW5jZUtleSwgY29tbWl0Lm1ldGEucHJpb3JpdHkpXG4gICAgICBpZiAoY29hbGVzY2VkVG9waWMpIGNvYWxlc2NlZFRvcGljcyArPSAxXG4gICAgICB5aWVsZCogc2NoZWR1bGVUaWNrKClcbiAgICB9KVxuXG4gIHJldHVybiB7XG4gICAgZ2V0VGlja1NlcTogKCkgPT4gdGlja1NlcSxcbiAgICBvbk1vZHVsZUNvbW1pdCxcbiAgICBvblNlbGVjdG9yQ2hhbmdlZCxcbiAgICBmbHVzaE5vdyxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgU3RhdGVDb21taXRQcmlvcml0eSB9IGZyb20gJy4vbW9kdWxlLmpzJ1xuaW1wb3J0IHR5cGUgeyBNb2R1bGVJbnN0YW5jZUtleSwgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0LCBSdW50aW1lU3RvcmVQZW5kaW5nRHJhaW4sIFRvcGljS2V5IH0gZnJvbSAnLi9SdW50aW1lU3RvcmUuanMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgSm9iUXVldWUge1xuICByZWFkb25seSBoYXNQZW5kaW5nOiAoKSA9PiBib29sZWFuXG4gIC8qKiBSZXR1cm5zIHRydWUgd2hlbiB0aGUgb3BlcmF0aW9uIGNvYWxlc2NlZCB3aXRoIGFuIGV4aXN0aW5nIHBlbmRpbmcgZW50cnkuICovXG4gIHJlYWRvbmx5IGVucXVldWVNb2R1bGVDb21taXQ6IChjb21taXQ6IFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdCkgPT4gYm9vbGVhblxuICAvKiogUmV0dXJucyB0cnVlIHdoZW4gdGhlIG9wZXJhdGlvbiBjb2FsZXNjZWQgd2l0aCBhbiBleGlzdGluZyBwZW5kaW5nIGVudHJ5LiAqL1xuICByZWFkb25seSBtYXJrVG9waWNEaXJ0eTogKHRvcGljS2V5OiBUb3BpY0tleSwgcHJpb3JpdHk6IFN0YXRlQ29tbWl0UHJpb3JpdHkpID0+IGJvb2xlYW5cbiAgcmVhZG9ubHkgZHJhaW46ICgpID0+IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbiB8IHVuZGVmaW5lZFxuICByZWFkb25seSByZXF1ZXVlOiAoZHJhaW46IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbikgPT4gdm9pZFxufVxuXG5jb25zdCBtYXhQcmlvcml0eSA9IChhOiBTdGF0ZUNvbW1pdFByaW9yaXR5LCBiOiBTdGF0ZUNvbW1pdFByaW9yaXR5KTogU3RhdGVDb21taXRQcmlvcml0eSA9PlxuICBhID09PSAnbm9ybWFsJyB8fCBiID09PSAnbm9ybWFsJyA/ICdub3JtYWwnIDogJ2xvdydcblxuZXhwb3J0IGNvbnN0IG1ha2VKb2JRdWV1ZSA9ICgpOiBKb2JRdWV1ZSA9PiB7XG4gIGxldCBwZW5kaW5nTW9kdWxlcyA9IG5ldyBNYXA8TW9kdWxlSW5zdGFuY2VLZXksIFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdD4oKVxuICBsZXQgcGVuZGluZ0RpcnR5VG9waWNzID0gbmV3IE1hcDxUb3BpY0tleSwgU3RhdGVDb21taXRQcmlvcml0eT4oKVxuXG4gIGNvbnN0IGhhc1BlbmRpbmcgPSAoKTogYm9vbGVhbiA9PiBwZW5kaW5nTW9kdWxlcy5zaXplID4gMCB8fCBwZW5kaW5nRGlydHlUb3BpY3Muc2l6ZSA+IDBcblxuICBjb25zdCBlbnF1ZXVlTW9kdWxlQ29tbWl0ID0gKGNvbW1pdDogUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0KTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgcHJldiA9IHBlbmRpbmdNb2R1bGVzLmdldChjb21taXQubW9kdWxlSW5zdGFuY2VLZXkpXG4gICAgaWYgKCFwcmV2KSB7XG4gICAgICBwZW5kaW5nTW9kdWxlcy5zZXQoY29tbWl0Lm1vZHVsZUluc3RhbmNlS2V5LCBjb21taXQpXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBwZW5kaW5nTW9kdWxlcy5zZXQoY29tbWl0Lm1vZHVsZUluc3RhbmNlS2V5LCB7XG4gICAgICAuLi5jb21taXQsXG4gICAgICBtZXRhOiB7XG4gICAgICAgIC4uLmNvbW1pdC5tZXRhLFxuICAgICAgICBwcmlvcml0eTogbWF4UHJpb3JpdHkocHJldi5tZXRhLnByaW9yaXR5LCBjb21taXQubWV0YS5wcmlvcml0eSksXG4gICAgICB9LFxuICAgIH0pXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGNvbnN0IG1hcmtUb3BpY0RpcnR5ID0gKHRvcGljS2V5OiBUb3BpY0tleSwgcHJpb3JpdHk6IFN0YXRlQ29tbWl0UHJpb3JpdHkpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBwcmV2ID0gcGVuZGluZ0RpcnR5VG9waWNzLmdldCh0b3BpY0tleSlcbiAgICBwZW5kaW5nRGlydHlUb3BpY3Muc2V0KHRvcGljS2V5LCBwcmV2ID8gbWF4UHJpb3JpdHkocHJldiwgcHJpb3JpdHkpIDogcHJpb3JpdHkpXG4gICAgcmV0dXJuIHByZXYgIT0gbnVsbFxuICB9XG5cbiAgY29uc3QgZHJhaW4gPSAoKTogUnVudGltZVN0b3JlUGVuZGluZ0RyYWluIHwgdW5kZWZpbmVkID0+IHtcbiAgICBpZiAoIWhhc1BlbmRpbmcoKSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGNvbnN0IGRyYWluZWQ6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbiA9IHtcbiAgICAgIG1vZHVsZXM6IHBlbmRpbmdNb2R1bGVzLFxuICAgICAgZGlydHlUb3BpY3M6IHBlbmRpbmdEaXJ0eVRvcGljcyxcbiAgICB9XG4gICAgcGVuZGluZ01vZHVsZXMgPSBuZXcgTWFwKClcbiAgICBwZW5kaW5nRGlydHlUb3BpY3MgPSBuZXcgTWFwKClcbiAgICByZXR1cm4gZHJhaW5lZFxuICB9XG5cbiAgY29uc3QgcmVxdWV1ZSA9IChkcmFpbjogUnVudGltZVN0b3JlUGVuZGluZ0RyYWluKTogdm9pZCA9PiB7XG4gICAgZm9yIChjb25zdCBbLCBjb21taXRdIG9mIGRyYWluLm1vZHVsZXMpIHtcbiAgICAgIGVucXVldWVNb2R1bGVDb21taXQoY29tbWl0KVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtrLCBwXSBvZiBkcmFpbi5kaXJ0eVRvcGljcykge1xuICAgICAgbWFya1RvcGljRGlydHkoaywgcClcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGhhc1BlbmRpbmcsXG4gICAgZW5xdWV1ZU1vZHVsZUNvbW1pdCxcbiAgICBtYXJrVG9waWNEaXJ0eSxcbiAgICBkcmFpbixcbiAgICByZXF1ZXVlLFxuICB9XG59XG5cbiIsICJpbXBvcnQgeyBDYXVzZSwgRWZmZWN0LCBGaWJlciwgRmliZXJSZWYsIFJlZiwgU3RyZWFtIH0gZnJvbSAnZWZmZWN0J1xuaW1wb3J0ICogYXMgRGVidWcgZnJvbSAnLi9EZWJ1Z1NpbmsuanMnXG5pbXBvcnQgeyBpc0RldkVudiB9IGZyb20gJy4vZW52LmpzJ1xuaW1wb3J0IHR5cGUgKiBhcyBMb2dpYyBmcm9tICcuL0xvZ2ljTWlkZGxld2FyZS5qcydcbmltcG9ydCB0eXBlIHsgQW55TW9kdWxlU2hhcGUsIExvZ2ljRWZmZWN0IH0gZnJvbSAnLi9tb2R1bGUuanMnXG5pbXBvcnQgdHlwZSB7IFJ1bnRpbWVJbnRlcm5hbHNSZXNvbHZlZENvbmN1cnJlbmN5UG9saWN5IH0gZnJvbSAnLi9SdW50aW1lSW50ZXJuYWxzLmpzJ1xuaW1wb3J0IHR5cGUgeyBTdGF0ZVR4bk9yaWdpbiB9IGZyb20gJy4vU3RhdGVUcmFuc2FjdGlvbi5qcydcblxuLyoqXG4gKiBQcmV2ZW50cyBjYWxsaW5nIHJ1bipUYXNrIGluc2lkZSBhIFwic3luY2hyb25vdXMgdHJhbnNhY3Rpb24gZXhlY3V0aW9uIGZpYmVyXCIgKGl0IHdvdWxkIGRlYWRsb2NrIHRoZSB0eG5RdWV1ZSkuXG4gKlxuICogLSBNb2R1bGVSdW50aW1lIGxvY2FsbHkgbWFya3MgaXQgYXMgdHJ1ZSB3aGlsZSBleGVjdXRpbmcgZWFjaCB0cmFuc2FjdGlvbiAoZGlzcGF0Y2gvc291cmNlLXJlZnJlc2gvZGV2dG9vbHMvLi4uKS5cbiAqIC0gcnVuKlRhc2sgY2hlY2tzIHRoZSBmbGFnIG9uIHN0YXJ0OiB3aGVuIHRydWUsIGl0IGVtaXRzIGRpYWdub3N0aWNzIG9ubHkgaW4gZGV2L3Rlc3QgYW5kIHRoZW4gbm8tb3BzLlxuICovXG5leHBvcnQgY29uc3QgaW5TeW5jVHJhbnNhY3Rpb25GaWJlciA9IEZpYmVyUmVmLnVuc2FmZU1ha2UoZmFsc2UpXG5cbi8qKlxuICogRm9yY2Ugc291cmNlLnJlZnJlc2g6XG4gKiAtIERlZmF1bHQ6IHdoZW4gc25hcHNob3Qga2V5SGFzaCBpcyB1bmNoYW5nZWQgYW5kIGEgbm9uLWlkbGUgc25hcHNob3QgYWxyZWFkeSBleGlzdHMsIHJlZnJlc2ggU0hPVUxEIGJlIGEgbm8tb3BcbiAqICAgKGF2b2lkIHJlZHVuZGFudCBJTy93cml0ZWJhY2spLlxuICogLSBFeGNlcHRpb246IGV4cGxpY2l0IHJlZnJlc2ggKG1hbnVhbCByZWZyZXNoKSAvIGludmFsaWRhdGlvbi1kcml2ZW4gcmVmcmVzaCBuZWVkcyB0byBcInJlLWZldGNoIGV2ZW4gd2l0aCB0aGUgc2FtZSBrZXlIYXNoXCIuXG4gKlxuICogTm90ZTogdXNlIGEgRmliZXJSZWYgdG8gbG9jYWxseSBwYXNzIFwid2hldGhlciB0aGlzIHJlZnJlc2ggaXMgZm9yY2VkXCIsIGF2b2lkaW5nIGV4cGFuZGluZyB0aGUgc291cmNlIHJlZnJlc2ggaGFuZGxlciBzaWduYXR1cmUuXG4gKi9cbmV4cG9ydCBjb25zdCBmb3JjZVNvdXJjZVJlZnJlc2ggPSBGaWJlclJlZi51bnNhZmVNYWtlKGZhbHNlKVxuXG4vKipcbiAqIFN5bmNocm9ub3VzIHRyYW5zYWN0aW9uIHdpbmRvdyAocHJvY2Vzcy1sZXZlbCkgbWFya2VyOlxuICogLSBVc2VkIGFzIGEgaGFyZCBndWFyZCBpbiBcIm5vbi1FZmZlY3QgQVBJXCIgZW50cnkgcG9pbnRzIChlLmcuIFByb21pc2UvYXN5bmMgZnVuY3Rpb25zKS5cbiAqIC0gRmliZXJSZWYgY2Fubm90IHJlbGlhYmx5IHJlYWQgdGhlIFwiY3VycmVudCBmaWJlclwiIGluIHN1Y2ggZW50cnkgcG9pbnRzLCBzbyB3ZSBuZWVkIGEgc3luY2hyb25vdXMgY2FsbHN0YWNrLWxldmVsIG1hcmtlci5cbiAqXG4gKiBOb3RlOiBpZiBhIHRyYW5zYWN0aW9uIGJvZHkgaW5jb3JyZWN0bHkgY3Jvc3NlcyBhc3luYyBib3VuZGFyaWVzLCB0aGlzIG1hcmtlciB3aWxsIGJlIGhlbGQgbG9uZ2VyOyB0aGF0IGlzIGEgc2V2ZXJlIHZpb2xhdGlvbi5cbiAqL1xubGV0IGluU3luY1RyYW5zYWN0aW9uR2xvYmFsRGVwdGggPSAwXG5cbmV4cG9ydCBjb25zdCBlbnRlclN5bmNUcmFuc2FjdGlvbiA9ICgpOiB2b2lkID0+IHtcbiAgaW5TeW5jVHJhbnNhY3Rpb25HbG9iYWxEZXB0aCArPSAxXG59XG5cbmV4cG9ydCBjb25zdCBleGl0U3luY1RyYW5zYWN0aW9uID0gKCk6IHZvaWQgPT4ge1xuICBpblN5bmNUcmFuc2FjdGlvbkdsb2JhbERlcHRoID0gTWF0aC5tYXgoMCwgaW5TeW5jVHJhbnNhY3Rpb25HbG9iYWxEZXB0aCAtIDEpXG59XG5cbmV4cG9ydCBjb25zdCBpc0luU3luY1RyYW5zYWN0aW9uID0gKCk6IGJvb2xlYW4gPT4gaW5TeW5jVHJhbnNhY3Rpb25HbG9iYWxEZXB0aCA+IDBcblxuZXhwb3J0IHR5cGUgVGFza1J1bm5lck1vZGUgPVxuICB8ICd0YXNrJyAvLyBzZXF1ZW50aWFsXG4gIHwgJ3BhcmFsbGVsJ1xuICB8ICdsYXRlc3QnXG4gIHwgJ2V4aGF1c3QnXG5cbmV4cG9ydCB0eXBlIFRhc2tTdGF0dXMgPSAnaWRsZScgfCAncGVuZGluZycgfCAncnVubmluZycgfCAnc3VjY2VzcycgfCAnZmFpbHVyZScgfCAnaW50ZXJydXB0ZWQnXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGFza0V4ZWN1dGlvbiB7XG4gIHJlYWRvbmx5IHRhc2tJZDogbnVtYmVyXG4gIHJlYWRvbmx5IHN0YXR1czogVGFza1N0YXR1c1xuICByZWFkb25seSBhY2NlcHRlZEF0OiBudW1iZXJcbiAgcmVhZG9ubHkgc3RhcnRlZEF0PzogbnVtYmVyXG4gIHJlYWRvbmx5IGVuZGVkQXQ/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYXNrUnVubmVyT3JpZ2lucyB7XG4gIHJlYWRvbmx5IHBlbmRpbmc/OiBTdGF0ZVR4bk9yaWdpblxuICByZWFkb25seSBzdWNjZXNzPzogU3RhdGVUeG5PcmlnaW5cbiAgcmVhZG9ubHkgZmFpbHVyZT86IFN0YXRlVHhuT3JpZ2luXG59XG5cbnR5cGUgVGFza0hhbmRsZXI8UGF5bG9hZCwgU2ggZXh0ZW5kcyBBbnlNb2R1bGVTaGFwZSwgUj4gPVxuICB8IExvZ2ljRWZmZWN0PFNoLCBSLCB2b2lkLCBuZXZlcj5cbiAgfCAoKHBheWxvYWQ6IFBheWxvYWQpID0+IExvZ2ljRWZmZWN0PFNoLCBSLCB2b2lkLCBuZXZlcj4pXG5cbnR5cGUgVGFza0VmZmVjdDxQYXlsb2FkLCBTaCBleHRlbmRzIEFueU1vZHVsZVNoYXBlLCBSLCBBLCBFPiA9XG4gIHwgTG9naWNFZmZlY3Q8U2gsIFIsIEEsIEU+XG4gIHwgKChwYXlsb2FkOiBQYXlsb2FkKSA9PiBMb2dpY0VmZmVjdDxTaCwgUiwgQSwgRT4pXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGFza1J1bm5lckNvbmZpZzxQYXlsb2FkLCBTaCBleHRlbmRzIEFueU1vZHVsZVNoYXBlLCBSLCBBID0gdm9pZCwgRSA9IG5ldmVyPiB7XG4gIC8qKlxuICAgKiBPcHRpb25hbDogdHJpZ2dlciBzb3VyY2UgbmFtZSAoZS5nLiBhY3Rpb25UYWcgLyBmaWVsZFBhdGgpLCB1c2VkIGFzIHRoZSBkZWZhdWx0IHBlbmRpbmcgb3JpZ2luLm5hbWUuXG4gICAqIC0gQm91bmRBcGlSdW50aW1lIG1heSBmaWxsIHRoaXMgaW4gZm9yIG9uQWN0aW9uKFwieHh4XCIpIC8gdHJhaXRzLnNvdXJjZS5yZWZyZXNoKFwiZmllbGRcIiksIGV0Yy5cbiAgICogLSBPdGhlciBjYWxsZXJzIGFyZSBub3QgcmVxdWlyZWQgdG8gcHJvdmlkZSBpdC5cbiAgICovXG4gIHJlYWRvbmx5IHRyaWdnZXJOYW1lPzogc3RyaW5nXG5cbiAgLyoqXG4gICAqIHBlbmRpbmc6IHN5bmNocm9ub3VzIHN0YXRlIHdyaXRlcyAobG9hZGluZz10cnVlIC8gY2xlYXJpbmcgZXJyb3JzLCBldGMuKSwgYWx3YXlzIGEgc2VwYXJhdGUgdHJhbnNhY3Rpb24gZW50cnkuXG4gICAqIC0gT25seSBleGVjdXRlZCBmb3IgdGFza3MgdGhhdCBhcmUgYWNjZXB0ZWQgYW5kIGFjdHVhbGx5IHN0YXJ0ZWQgKGlnbm9yZWQgdHJpZ2dlcnMgaW4gcnVuRXhoYXVzdFRhc2sgZG8gbm90IHJ1biBwZW5kaW5nKS5cbiAgICovXG4gIHJlYWRvbmx5IHBlbmRpbmc/OiBUYXNrSGFuZGxlcjxQYXlsb2FkLCBTaCwgUj5cblxuICAvKipcbiAgICogZWZmZWN0OiByZWFsIElPIC8gYXN5bmMgd29yayAobXVzdCBydW4gb3V0c2lkZSB0aGUgdHJhbnNhY3Rpb24gd2luZG93KS5cbiAgICovXG4gIHJlYWRvbmx5IGVmZmVjdDogVGFza0VmZmVjdDxQYXlsb2FkLCBTaCwgUiwgQSwgRT5cblxuICAvKipcbiAgICogc3VjY2Vzczogc3VjY2VzcyB3cml0ZWJhY2sgKHNlcGFyYXRlIHRyYW5zYWN0aW9uIGVudHJ5KS5cbiAgICovXG4gIHJlYWRvbmx5IHN1Y2Nlc3M/OiAocmVzdWx0OiBBLCBwYXlsb2FkOiBQYXlsb2FkKSA9PiBMb2dpY0VmZmVjdDxTaCwgUiwgdm9pZCwgbmV2ZXI+XG5cbiAgLyoqXG4gICAqIGZhaWx1cmU6IGZhaWx1cmUgd3JpdGViYWNrIChzZXBhcmF0ZSB0cmFuc2FjdGlvbiBlbnRyeSkuXG4gICAqXG4gICAqIE5vdGU6IHRha2VzIGEgQ2F1c2UgdG8gcHJlc2VydmUgZGVmZWN0L2ludGVycnVwdCBzZW1hbnRpY3M7IGludGVycnVwdHMgZG8gbm90IHRyaWdnZXIgZmFpbHVyZSB3cml0ZWJhY2sgYnkgZGVmYXVsdC5cbiAgICovXG4gIHJlYWRvbmx5IGZhaWx1cmU/OiAoY2F1c2U6IENhdXNlLkNhdXNlPEU+LCBwYXlsb2FkOiBQYXlsb2FkKSA9PiBMb2dpY0VmZmVjdDxTaCwgUiwgdm9pZCwgbmV2ZXI+XG5cbiAgLyoqXG4gICAqIG9yaWdpbjogb3B0aW9uYWwgb3ZlcnJpZGUgZm9yIHRoZSB0aHJlZSB0cmFuc2FjdGlvbiBvcmlnaW5zLlxuICAgKiAtIERlZmF1bHQ6IHBlbmRpbmcua2luZD1cInRhc2s6cGVuZGluZ1wiOyBzdWNjZXNzL2ZhaWx1cmUua2luZD1cInNlcnZpY2UtY2FsbGJhY2tcIi5cbiAgICovXG4gIHJlYWRvbmx5IG9yaWdpbj86IFRhc2tSdW5uZXJPcmlnaW5zXG5cbiAgLyoqXG4gICAqIHByaW9yaXR5OiByZXNlcnZlZCBmb3IgZnV0dXJlIGRlYnVnZ2luZy9zb3J0aW5nOyBkb2VzIG5vdCBjaGFuZ2UgdHJhbnNhY3Rpb24gYm91bmRhcmllcyBvciBjb25jdXJyZW5jeSBzZW1hbnRpY3MuXG4gICAqL1xuICByZWFkb25seSBwcmlvcml0eT86IG51bWJlclxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRhc2tSdW5uZXJSdW50aW1lIHtcbiAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZ1xuICByZWFkb25seSBydW5XaXRoU3RhdGVUcmFuc2FjdGlvbjogKFxuICAgIG9yaWdpbjogU3RhdGVUeG5PcmlnaW4sXG4gICAgYm9keTogKCkgPT4gRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgYW55PixcbiAgKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBhbnk+XG4gIHJlYWRvbmx5IHJlc29sdmVDb25jdXJyZW5jeVBvbGljeT86ICgpID0+IEVmZmVjdC5FZmZlY3Q8UnVudGltZUludGVybmFsc1Jlc29sdmVkQ29uY3VycmVuY3lQb2xpY3ksIG5ldmVyLCBhbnk+XG59XG5cbmNvbnN0IHJlc29sdmUgPSA8UGF5bG9hZCwgU2ggZXh0ZW5kcyBBbnlNb2R1bGVTaGFwZSwgUiwgQSwgRT4oXG4gIGVmZjogVGFza0VmZmVjdDxQYXlsb2FkLCBTaCwgUiwgQSwgRT4gfCBUYXNrSGFuZGxlcjxQYXlsb2FkLCBTaCwgUj4sXG4gIHBheWxvYWQ6IFBheWxvYWQsXG4pOiBhbnkgPT4gKHR5cGVvZiBlZmYgPT09ICdmdW5jdGlvbicgPyAoZWZmIGFzIGFueSkocGF5bG9hZCkgOiBlZmYpXG5cbmNvbnN0IGRlZmF1bHRPcmlnaW5zID0gKHRyaWdnZXJOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBSZXF1aXJlZDxUYXNrUnVubmVyT3JpZ2lucz4gPT4gKHtcbiAgcGVuZGluZzoge1xuICAgIGtpbmQ6ICd0YXNrOnBlbmRpbmcnLFxuICAgIG5hbWU6IHRyaWdnZXJOYW1lLFxuICB9LFxuICBzdWNjZXNzOiB7XG4gICAga2luZDogJ3NlcnZpY2UtY2FsbGJhY2snLFxuICAgIG5hbWU6ICd0YXNrOnN1Y2Nlc3MnLFxuICB9LFxuICBmYWlsdXJlOiB7XG4gICAga2luZDogJ3NlcnZpY2UtY2FsbGJhY2snLFxuICAgIG5hbWU6ICd0YXNrOmZhaWx1cmUnLFxuICB9LFxufSlcblxuZXhwb3J0IGNvbnN0IHNob3VsZE5vb3BJblN5bmNUcmFuc2FjdGlvbkZpYmVyID0gKG9wdGlvbnM6IHtcbiAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZ1xuICByZWFkb25seSBjb2RlOiBzdHJpbmdcbiAgcmVhZG9ubHkgc2V2ZXJpdHk6ICdlcnJvcicgfCAnd2FybmluZycgfCAnaW5mbydcbiAgcmVhZG9ubHkgbWVzc2FnZTogc3RyaW5nXG4gIHJlYWRvbmx5IGhpbnQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgYWN0aW9uVGFnPzogc3RyaW5nXG4gIHJlYWRvbmx5IGtpbmQ/OiBzdHJpbmdcbn0pOiBFZmZlY3QuRWZmZWN0PGJvb2xlYW4+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBpblR4biA9IHlpZWxkKiBGaWJlclJlZi5nZXQoaW5TeW5jVHJhbnNhY3Rpb25GaWJlcilcbiAgICBpZiAoIWluVHhuKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgLy8gQWx3YXlzIG5vLW9wIHJlZ2FyZGxlc3Mgb2YgZW52IChvdGhlcndpc2Ugd2UgbWF5IGRlYWRsb2NrKTsgZGlhZ25vc3RpY3MgYXJlIGVtaXR0ZWQgb25seSBpbiBkZXYvdGVzdC5cbiAgICBpZiAoaXNEZXZFbnYoKSkge1xuICAgICAgeWllbGQqIERlYnVnLnJlY29yZCh7XG4gICAgICAgIHR5cGU6ICdkaWFnbm9zdGljJyxcbiAgICAgICAgbW9kdWxlSWQ6IG9wdGlvbnMubW9kdWxlSWQsXG4gICAgICAgIGluc3RhbmNlSWQ6IG9wdGlvbnMuaW5zdGFuY2VJZCxcbiAgICAgICAgY29kZTogb3B0aW9ucy5jb2RlLFxuICAgICAgICBzZXZlcml0eTogb3B0aW9ucy5zZXZlcml0eSxcbiAgICAgICAgbWVzc2FnZTogb3B0aW9ucy5tZXNzYWdlLFxuICAgICAgICBoaW50OiBvcHRpb25zLmhpbnQsXG4gICAgICAgIGFjdGlvblRhZzogb3B0aW9ucy5hY3Rpb25UYWcsXG4gICAgICAgIGtpbmQ6IG9wdGlvbnMua2luZCxcbiAgICAgIH0pXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH0pXG5cbmNvbnN0IHJlc29sdmVDb25jdXJyZW5jeUxpbWl0ID0gKHJ1bnRpbWU6IFRhc2tSdW5uZXJSdW50aW1lKTogRWZmZWN0LkVmZmVjdDxudW1iZXIgfCAndW5ib3VuZGVkJywgbmV2ZXIsIGFueT4gPT5cbiAgcnVudGltZS5yZXNvbHZlQ29uY3VycmVuY3lQb2xpY3lcbiAgICA/IHJ1bnRpbWUucmVzb2x2ZUNvbmN1cnJlbmN5UG9saWN5KCkucGlwZShFZmZlY3QubWFwKChwKSA9PiBwLmNvbmN1cnJlbmN5TGltaXQpKVxuICAgIDogRWZmZWN0LnN1Y2NlZWQoMTYpXG5cbmNvbnN0IHJ1blRhc2tMaWZlY3ljbGUgPSA8UGF5bG9hZCwgU2ggZXh0ZW5kcyBBbnlNb2R1bGVTaGFwZSwgUiwgQSwgRT4oXG4gIHBheWxvYWQ6IFBheWxvYWQsXG4gIHJ1bnRpbWU6IFRhc2tSdW5uZXJSdW50aW1lLFxuICBjb25maWc6IFRhc2tSdW5uZXJDb25maWc8UGF5bG9hZCwgU2gsIFIsIEEsIEU+LFxuICBnZXRDYW5Xcml0ZUJhY2s/OiBFZmZlY3QuRWZmZWN0PGJvb2xlYW4+LFxuKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgTG9naWMuRW52PFNoLCBSPj4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IG5vb3AgPSB5aWVsZCogc2hvdWxkTm9vcEluU3luY1RyYW5zYWN0aW9uRmliZXIoe1xuICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICBjb2RlOiAnbG9naWM6OmludmFsaWRfdXNhZ2UnLFxuICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICBtZXNzYWdlOiAncnVuKlRhc2sgaXMgbm90IGFsbG93ZWQgaW5zaWRlIGEgc3luY2hyb25vdXMgU3RhdGVUcmFuc2FjdGlvbiBib2R5IChpdCBtYXkgZGVhZGxvY2sgdGhlIHR4blF1ZXVlKS4nLFxuICAgICAgaGludDpcbiAgICAgICAgJ0NhbGwgcnVuKlRhc2sgZnJvbSB0aGUgcnVuIHNlY3Rpb24gb2YgYSB3YXRjaGVyIChlLmcuICQub25BY3Rpb24vJC5vblN0YXRlLyQub24pOyAnICtcbiAgICAgICAgJ2RvIG5vdCBjYWxsIGl0IGRpcmVjdGx5IGluc2lkZSBhIHJlZHVjZXIgLyB0cmFpdC5ydW4gLyBzeW5jaHJvbm91cyB0cmFuc2FjdGlvbiBib2R5LiBGb3IgbG9uZy1saXZlZCBmbG93cywgdXNlIGEgbXVsdGktZW50cnkgcGF0dGVybiAocGVuZGluZyBcdTIxOTIgSU8gXHUyMTkyIHdyaXRlYmFjaykuJyxcbiAgICAgIGtpbmQ6ICdydW5fdGFza19pbl90cmFuc2FjdGlvbicsXG4gICAgfSlcbiAgICBpZiAobm9vcCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZGVmYXVsdHMgPSBkZWZhdWx0T3JpZ2lucyhjb25maWcudHJpZ2dlck5hbWUpXG4gICAgY29uc3Qgb3JpZ2luczogUmVxdWlyZWQ8VGFza1J1bm5lck9yaWdpbnM+ID0ge1xuICAgICAgcGVuZGluZzogY29uZmlnLm9yaWdpbj8ucGVuZGluZyA/PyBkZWZhdWx0cy5wZW5kaW5nLFxuICAgICAgc3VjY2VzczogY29uZmlnLm9yaWdpbj8uc3VjY2VzcyA/PyBkZWZhdWx0cy5zdWNjZXNzLFxuICAgICAgZmFpbHVyZTogY29uZmlnLm9yaWdpbj8uZmFpbHVyZSA/PyBkZWZhdWx0cy5mYWlsdXJlLFxuICAgIH1cblxuICAgIC8vIDEpIHBlbmRpbmc6IHNlcGFyYXRlIHRyYW5zYWN0aW9uIGVudHJ5OyBvbmNlIHN0YXJ0ZWQgaXQgc2hvdWxkIG5vdCBiZSBpbnRlcnJ1cHRlZCBieSBydW5MYXRlc3QuXG4gICAgY29uc3QgcGVuZGluZyA9IGNvbmZpZy5wZW5kaW5nXG4gICAgaWYgKHBlbmRpbmcpIHtcbiAgICAgIHlpZWxkKiBFZmZlY3QudW5pbnRlcnJ1cHRpYmxlKFxuICAgICAgICBydW50aW1lLnJ1bldpdGhTdGF0ZVRyYW5zYWN0aW9uKG9yaWdpbnMucGVuZGluZywgKCkgPT4gRWZmZWN0LmFzVm9pZChyZXNvbHZlKHBlbmRpbmcsIHBheWxvYWQpKSksXG4gICAgICApXG4gICAgfVxuXG4gICAgLy8gMikgSU86IHJ1bnMgb3V0c2lkZSB0aGUgdHJhbnNhY3Rpb24gd2luZG93LlxuICAgIGNvbnN0IGlvID0gcmVzb2x2ZShjb25maWcuZWZmZWN0LCBwYXlsb2FkKSBhcyBFZmZlY3QuRWZmZWN0PEEsIEUsIExvZ2ljLkVudjxTaCwgUj4+XG4gICAgY29uc3QgZXhpdCA9IHlpZWxkKiBFZmZlY3QuZXhpdChpbylcblxuICAgIC8vIDMpIHdyaXRlYmFjazogdXNlIHRoZSBndWFyZCB0byBjb25maXJtIGl0J3Mgc3RpbGwgdGhlIGN1cnJlbnQgdGFzayAocnVuTGF0ZXN0VGFzaykuXG4gICAgaWYgKGdldENhbldyaXRlQmFjaykge1xuICAgICAgY29uc3Qgb2sgPSB5aWVsZCogZ2V0Q2FuV3JpdGVCYWNrXG4gICAgICBpZiAoIW9rKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleGl0Ll90YWcgPT09ICdTdWNjZXNzJykge1xuICAgICAgY29uc3Qgc3VjY2VzcyA9IGNvbmZpZy5zdWNjZXNzXG4gICAgICBpZiAoc3VjY2Vzcykge1xuICAgICAgICB5aWVsZCogcnVudGltZS5ydW5XaXRoU3RhdGVUcmFuc2FjdGlvbihvcmlnaW5zLnN1Y2Nlc3MsICgpID0+IEVmZmVjdC5hc1ZvaWQoc3VjY2VzcyhleGl0LnZhbHVlLCBwYXlsb2FkKSkpXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBGYWlsdXJlOiBpbnRlcnJ1cHRpb25zIGRvIG5vdCB0cmlnZ2VyIGZhaWx1cmUgd3JpdGViYWNrIChlLmcuIHJ1bkxhdGVzdFRhc2sgY2FuY2VsbGF0aW9uLCBTY29wZSBlbmRpbmcpLlxuICAgIGNvbnN0IGNhdXNlID0gZXhpdC5jYXVzZSBhcyBDYXVzZS5DYXVzZTxFPlxuICAgIGlmIChDYXVzZS5pc0ludGVycnVwdGVkKGNhdXNlKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZmFpbHVyZSA9IGNvbmZpZy5mYWlsdXJlXG4gICAgaWYgKGZhaWx1cmUpIHtcbiAgICAgIHlpZWxkKiBydW50aW1lLnJ1bldpdGhTdGF0ZVRyYW5zYWN0aW9uKG9yaWdpbnMuZmFpbHVyZSwgKCkgPT4gRWZmZWN0LmFzVm9pZChmYWlsdXJlKGNhdXNlLCBwYXlsb2FkKSkpXG4gICAgfVxuICB9KS5waXBlKFxuICAgIC8vIFdhdGNoZXJzIG11c3Qgbm90IGNyYXNoIGFzIGEgd2hvbGUgZHVlIHRvIGEgc2luZ2xlIHRhc2sgZmFpbHVyZTogc3dhbGxvdyBlcnJvcnMsIGJ1dCBrZWVwIHRoZW0gZGlhZ25vc2FibGUuXG4gICAgRWZmZWN0LmNhdGNoQWxsQ2F1c2UoKGNhdXNlKSA9PlxuICAgICAgRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogJ2RpYWdub3N0aWMnLFxuICAgICAgICBtb2R1bGVJZDogcnVudGltZS5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICBjb2RlOiAndGFza19ydW5uZXI6OnVuaGFuZGxlZF9mYWlsdXJlJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICAgIG1lc3NhZ2U6ICdUYXNrUnVubmVyIGVuY291bnRlcmVkIGFuIHVuaGFuZGxlZCBmYWlsdXJlIChwZW5kaW5nL0lPL3dyaXRlYmFjaykuJyxcbiAgICAgICAgaGludDogJ0FkZCBhIGZhaWx1cmUgd3JpdGViYWNrIGZvciB0aGlzIHRhc2sgb3IgaGFuZGxlIGVycm9ycyBleHBsaWNpdGx5IHVwc3RyZWFtOyBhdm9pZCBmaXJlLWFuZC1mb3JnZXQgc3dhbGxvd2luZyBlcnJvcnMuJyxcbiAgICAgICAgYWN0aW9uVGFnOiBjb25maWcudHJpZ2dlck5hbWUsXG4gICAgICAgIGtpbmQ6ICd0YXNrX3J1bm5lcl91bmhhbmRsZWRfZmFpbHVyZScsXG4gICAgICAgIHRyaWdnZXI6IHtcbiAgICAgICAgICBraW5kOiAndGFzaycsXG4gICAgICAgICAgbmFtZTogY29uZmlnLnRyaWdnZXJOYW1lLFxuICAgICAgICB9LFxuICAgICAgfSkucGlwZShFZmZlY3QuemlwUmlnaHQoRWZmZWN0LmxvZ0Vycm9yKCdUYXNrUnVubmVyIGVycm9yJywgY2F1c2UpKSksXG4gICAgKSxcbiAgKSBhcyBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBMb2dpYy5FbnY8U2gsIFI+PlxuXG4vKipcbiAqIG1ha2VUYXNrUnVubmVyXHVGRjFBXG4gKiAtIFJldXNlcyBGbG93UnVudGltZSBjb25jdXJyZW5jeSBzZW1hbnRpY3MgKHNlcXVlbnRpYWwvcGFyYWxsZWwvbGF0ZXN0L2V4aGF1c3QpLlxuICogLSBTcGxpdHMgYSBzaW5nbGUgdHJpZ2dlciBpbnRvOiBwZW5kaW5nIChzZXBhcmF0ZSB0eG4pIFx1MjE5MiBJTyBcdTIxOTIgc3VjY2Vzcy9mYWlsdXJlIChzZXBhcmF0ZSB0eG4pLlxuICovXG5leHBvcnQgY29uc3QgbWFrZVRhc2tSdW5uZXIgPSA8UGF5bG9hZCwgU2ggZXh0ZW5kcyBBbnlNb2R1bGVTaGFwZSwgUiwgQSA9IHZvaWQsIEUgPSBuZXZlcj4oXG4gIHN0cmVhbTogU3RyZWFtLlN0cmVhbTxQYXlsb2FkPixcbiAgbW9kZTogVGFza1J1bm5lck1vZGUsXG4gIHJ1bnRpbWU6IFRhc2tSdW5uZXJSdW50aW1lLFxuICBjb25maWc6IFRhc2tSdW5uZXJDb25maWc8UGF5bG9hZCwgU2gsIFIsIEEsIEU+LFxuKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgTG9naWMuRW52PFNoLCBSPj4gPT4ge1xuICBpZiAobW9kZSA9PT0gJ2xhdGVzdCcpIHtcbiAgICByZXR1cm4gRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgY29uc3QgdGFza0lkUmVmID0geWllbGQqIFJlZi5tYWtlKDApXG4gICAgICBjb25zdCBjdXJyZW50RmliZXJSZWYgPSB5aWVsZCogUmVmLm1ha2U8RmliZXIuUnVudGltZUZpYmVyPHZvaWQsIG5ldmVyPiB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKVxuXG4gICAgICBjb25zdCBzdGFydCA9IChwYXlsb2FkOiBQYXlsb2FkKSA9PlxuICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgY29uc3QgdGFza0lkID0geWllbGQqIFJlZi51cGRhdGVBbmRHZXQodGFza0lkUmVmLCAobikgPT4gbiArIDEpXG5cbiAgICAgICAgICBjb25zdCBwcmV2ID0geWllbGQqIFJlZi5nZXQoY3VycmVudEZpYmVyUmVmKVxuICAgICAgICAgIGlmIChwcmV2KSB7XG4gICAgICAgICAgICAvLyBEbyBub3Qgd2FpdCBmb3IgdGhlIG9sZCBmaWJlciB0byBmdWxseSBlbmQgKGF2b2lkIGJsb2NraW5nIG5ldyB0cmlnZ2Vycyk7IHdyaXRlYmFjayBpcyBndWFyZGVkIGJ5IHRhc2tJZC5cbiAgICAgICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHRGb3JrKHByZXYpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY2FuV3JpdGVCYWNrID0gUmVmLmdldCh0YXNrSWRSZWYpLnBpcGUoRWZmZWN0Lm1hcCgoY3VycmVudCkgPT4gY3VycmVudCA9PT0gdGFza0lkKSlcblxuICAgICAgICAgIGNvbnN0IGZpYmVyID0geWllbGQqIEVmZmVjdC5mb3JrKFxuICAgICAgICAgICAgcnVuVGFza0xpZmVjeWNsZTxQYXlsb2FkLCBTaCwgUiwgQSwgRT4ocGF5bG9hZCwgcnVudGltZSwgY29uZmlnLCBjYW5Xcml0ZUJhY2spLFxuICAgICAgICAgIClcblxuICAgICAgICAgIHlpZWxkKiBSZWYuc2V0KGN1cnJlbnRGaWJlclJlZiwgZmliZXIpXG4gICAgICAgIH0pXG5cbiAgICAgIHJldHVybiB5aWVsZCogU3RyZWFtLnJ1bkZvckVhY2goc3RyZWFtLCBzdGFydClcbiAgICB9KVxuICB9XG5cbiAgaWYgKG1vZGUgPT09ICdleGhhdXN0Jykge1xuICAgIHJldHVybiBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICBjb25zdCBjb25jdXJyZW5jeSA9IHlpZWxkKiByZXNvbHZlQ29uY3VycmVuY3lMaW1pdChydW50aW1lKVxuICAgICAgY29uc3QgYnVzeVJlZiA9IHlpZWxkKiBSZWYubWFrZShmYWxzZSlcblxuICAgICAgY29uc3QgbWFwcGVyID0gKHBheWxvYWQ6IFBheWxvYWQpID0+XG4gICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICBjb25zdCBhY3F1aXJlZCA9IHlpZWxkKiBSZWYubW9kaWZ5KGJ1c3lSZWYsIChidXN5KSA9PlxuICAgICAgICAgICAgYnVzeSA/IChbZmFsc2UsIGJ1c3ldIGFzIGNvbnN0KSA6IChbdHJ1ZSwgdHJ1ZV0gYXMgY29uc3QpLFxuICAgICAgICAgIClcbiAgICAgICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgdHJpZ2dlcjogbm8gcGVuZGluZyB0cmFuc2FjdGlvbiBpcyBwcm9kdWNlZC5cbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgeWllbGQqIHJ1blRhc2tMaWZlY3ljbGU8UGF5bG9hZCwgU2gsIFIsIEEsIEU+KHBheWxvYWQsIHJ1bnRpbWUsIGNvbmZpZylcbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgeWllbGQqIFJlZi5zZXQoYnVzeVJlZiwgZmFsc2UpXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICByZXR1cm4geWllbGQqIFN0cmVhbS5ydW5EcmFpbihzdHJlYW0ucGlwZShTdHJlYW0ubWFwRWZmZWN0KG1hcHBlciwgeyBjb25jdXJyZW5jeSB9KSkpXG4gICAgfSkgYXMgRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgTG9naWMuRW52PFNoLCBSPj5cbiAgfVxuXG4gIGlmIChtb2RlID09PSAncGFyYWxsZWwnKSB7XG4gICAgcmV0dXJuIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IGNvbmN1cnJlbmN5ID0geWllbGQqIHJlc29sdmVDb25jdXJyZW5jeUxpbWl0KHJ1bnRpbWUpXG5cbiAgICAgIHJldHVybiB5aWVsZCogU3RyZWFtLnJ1bkRyYWluKFxuICAgICAgICBzdHJlYW0ucGlwZShcbiAgICAgICAgICBTdHJlYW0ubWFwRWZmZWN0KChwYXlsb2FkKSA9PiBydW5UYXNrTGlmZWN5Y2xlPFBheWxvYWQsIFNoLCBSLCBBLCBFPihwYXlsb2FkLCBydW50aW1lLCBjb25maWcpLCB7XG4gICAgICAgICAgICBjb25jdXJyZW5jeSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgIClcbiAgICB9KSBhcyBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBMb2dpYy5FbnY8U2gsIFI+PlxuICB9XG5cbiAgLy8gbW9kZSA9PT0gXCJ0YXNrXCJcdUZGMDhzZXF1ZW50aWFsXHVGRjA5XG4gIHJldHVybiBTdHJlYW0ucnVuRm9yRWFjaChzdHJlYW0sIChwYXlsb2FkKSA9PlxuICAgIHJ1blRhc2tMaWZlY3ljbGU8UGF5bG9hZCwgU2gsIFIsIEEsIEU+KHBheWxvYWQsIHJ1bnRpbWUsIGNvbmZpZyksXG4gICkgYXMgRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgTG9naWMuRW52PFNoLCBSPj5cbn1cbiIsICJpbXBvcnQgeyBDb250ZXh0LCBFZmZlY3QsIExheWVyIH0gZnJvbSAnZWZmZWN0J1xuaW1wb3J0IHR5cGUgeyBUcmFpdENvbnZlcmdlUmVxdWVzdGVkTW9kZSB9IGZyb20gJy4uLy4uL3N0YXRlLXRyYWl0L21vZGVsLmpzJ1xuaW1wb3J0IHR5cGUgeyBSZWFkUXVlcnlTdHJpY3RHYXRlQ29uZmlnIH0gZnJvbSAnLi9SZWFkUXVlcnkuanMnXG5pbXBvcnQgeyBnZXRHbG9iYWxIb3N0U2NoZWR1bGVyLCB0eXBlIEhvc3RTY2hlZHVsZXIgfSBmcm9tICcuL0hvc3RTY2hlZHVsZXIuanMnXG5pbXBvcnQgeyBtYWtlUnVudGltZVN0b3JlLCB0eXBlIFJ1bnRpbWVTdG9yZSB9IGZyb20gJy4vUnVudGltZVN0b3JlLmpzJ1xuaW1wb3J0IHsgbWFrZVRpY2tTY2hlZHVsZXIsIHR5cGUgVGlja1NjaGVkdWxlciwgdHlwZSBUaWNrU2NoZWR1bGVyQ29uZmlnIH0gZnJvbSAnLi9UaWNrU2NoZWR1bGVyLmpzJ1xuaW1wb3J0IHsgbWFrZURlY2xhcmF0aXZlTGlua1J1bnRpbWUsIHR5cGUgRGVjbGFyYXRpdmVMaW5rUnVudGltZSB9IGZyb20gJy4vRGVjbGFyYXRpdmVMaW5rUnVudGltZS5qcydcblxuLy8gVW5pZmllZCBydW50aW1lIGVudiBkZXRlY3Rpb24sIGF2b2lkaW5nIGJ1bmRsZXJzIGlubGluaW5nIE5PREVfRU5WIGF0IGJ1aWxkIHRpbWUuXG5leHBvcnQgY29uc3QgZ2V0Tm9kZUVudiA9ICgpOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICB0cnkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgZW52ID0gKGdsb2JhbFRoaXMgYXMgYW55KT8ucHJvY2Vzcz8uZW52XG4gICAgcmV0dXJuIHR5cGVvZiBlbnY/Lk5PREVfRU5WID09PSAnc3RyaW5nJyA/IGVudi5OT0RFX0VOViA6IHVuZGVmaW5lZFxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGlzRGV2RW52ID0gKCk6IGJvb2xlYW4gPT4gZ2V0Tm9kZUVudigpICE9PSAncHJvZHVjdGlvbidcblxuZXhwb3J0IHR5cGUgU3RhdGVUcmFuc2FjdGlvbkluc3RydW1lbnRhdGlvbiA9ICdmdWxsJyB8ICdsaWdodCdcblxuLyoqXG4gKiBnZXREZWZhdWx0U3RhdGVUeG5JbnN0cnVtZW50YXRpb25cdUZGMUFcbiAqIC0gQ3VycmVudGx5IGNob29zZXMgZGVmYXVsdCBpbnN0cnVtZW50YXRpb24gYnkgTk9ERV9FTlY6XG4gKiAgIC0gZGV2IC8gdGVzdDogZnVsbCAoa2VlcCBwYXRjaGVzIGFuZCBzbmFwc2hvdHMgZm9yIGRlYnVnZ2luZykuXG4gKiAgIC0gcHJvZHVjdGlvbjogbGlnaHQgKGtlZXAgbWluaW1hbCBzZW1hbnRpY3MgdG8gcmVkdWNlIG92ZXJoZWFkKS5cbiAqIC0gTWF5IGV2b2x2ZSB3aXRoIGZpbmVyLWdyYWluZWQgb3ZlcnJpZGVzIGluIFJ1bnRpbWUubWFrZSAvIE1vZHVsZS5tYWtlLlxuICovXG5leHBvcnQgY29uc3QgZ2V0RGVmYXVsdFN0YXRlVHhuSW5zdHJ1bWVudGF0aW9uID0gKCk6IFN0YXRlVHJhbnNhY3Rpb25JbnN0cnVtZW50YXRpb24gPT4gKGlzRGV2RW52KCkgPyAnZnVsbCcgOiAnbGlnaHQnKVxuXG4vKipcbiAqIFJ1bnRpbWUtbGV2ZWwgU3RhdGVUcmFuc2FjdGlvbiBjb25maWcgU2VydmljZTpcbiAqIC0gUHJvdmlkZWQgYXQgdGhlIGFwcCBsYXllciBieSBMb2dpeC5SdW50aW1lLm1ha2UgLyBBcHBSdW50aW1lLm1ha2VBcHAuXG4gKiAtIE1vZHVsZVJ1bnRpbWUubWFrZSBjYW4gcmVhZCBydW50aW1lLWxldmVsIGRlZmF1bHRzIGZyb20gRW52LlxuICpcbiAqIE5vdGVzOlxuICogLSBpbnN0cnVtZW50YXRpb24gaXMgb25seSBhIHJ1bnRpbWUtbGV2ZWwgZGVmYXVsdC5cbiAqIC0gRXhwbGljaXQgaW5zdHJ1bWVudGF0aW9uIGluIE1vZHVsZUltcGwgLyBNb2R1bGVSdW50aW1lT3B0aW9ucyBoYXMgaGlnaGVyIHByaW9yaXR5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhbnNhY3Rpb25SdW50aW1lQ29uZmlnIHtcbiAgcmVhZG9ubHkgaW5zdHJ1bWVudGF0aW9uPzogU3RhdGVUcmFuc2FjdGlvbkluc3RydW1lbnRhdGlvblxuICAvKipcbiAgICogU3RhdGVUcmFpdCBkZXJpdmVkIGNvbnZlcmdlIGJ1ZGdldCAobXMpOlxuICAgKiAtIEV4Y2VlZGluZyB0aGUgYnVkZ2V0IHRyaWdnZXJzIGEgc29mdCBkZWdyYWRlIChmcmVlemUgZGVyaXZlZCBmaWVsZHMsIHByZXNlcnZlIGJhc2Ugd3JpdGVzIGFuZCAwLzEgY29tbWl0IHNlbWFudGljcykuXG4gICAqIC0gRGVmYXVsdCBpcyAyMDBtcyAoYWxpZ25lZCB3aXRoIHRoZSAwMDcgc3BlYyB0aHJlc2hvbGQpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZUJ1ZGdldE1zPzogbnVtYmVyXG4gIC8qKlxuICAgKiBBdXRvLW1vZGUgZGVjaXNpb24gYnVkZ2V0IChtcyk6XG4gICAqIC0gT25seSB1c2VkIGR1cmluZyB0aGUgZGVjaXNpb24gcGhhc2Ugd2hlbiByZXF1ZXN0ZWRNb2RlPVwiYXV0b1wiLlxuICAgKiAtIEV4Y2VlZGluZyB0aGUgYnVkZ2V0IG11c3QgaW1tZWRpYXRlbHkgZmFsbCBiYWNrIHRvIGZ1bGwgKGFuZCByZWNvcmQgZXZpZGVuY2UpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZURlY2lzaW9uQnVkZ2V0TXM/OiBudW1iZXJcbiAgLyoqXG4gICAqIFN0YXRlVHJhaXQgY29udmVyZ2Ugc2NoZWR1bGluZyBzdHJhdGVneTpcbiAgICogLSBmdWxsOiBmdWxsIHRvcG8gZXhlY3V0aW9uIChjdXJyZW50IGRlZmF1bHQ7IHNhZmVzdCkuXG4gICAqIC0gZGlydHk6IG1pbmltYWwgdHJpZ2dlcmluZyBiYXNlZCBvbiBkaXJ0eVBhdGhzICsgZGVwcyBpbiB0aGUgdHhuIHdpbmRvdyAocmVxdWlyZXMgYWNjdXJhdGUgZGVwcykuXG4gICAqL1xuICByZWFkb25seSB0cmFpdENvbnZlcmdlTW9kZT86IFRyYWl0Q29udmVyZ2VSZXF1ZXN0ZWRNb2RlXG4gIC8qKlxuICAgKiAwNDM6IFRyYWl0IGNvbnZlcmdlIHRpbWUtc2xpY2luZyAoZXhwbGljaXQgb3B0LWluKS4gRGlzYWJsZWQgYnkgZGVmYXVsdC5cbiAgICovXG4gIHJlYWRvbmx5IHRyYWl0Q29udmVyZ2VUaW1lU2xpY2luZz86IFRyYWl0Q29udmVyZ2VUaW1lU2xpY2luZ1BhdGNoXG4gIC8qKlxuICAgKiAwNjA6IFR4biBMYW5lcyAocHJpb3JpdHkgc2NoZWR1bGluZyBmb3IgdHJhbnNhY3Rpb24gZm9sbG93LXVwIHdvcmspLiBFbmFibGVkIGJ5IGRlZmF1bHQgc2luY2UgMDYyLlxuICAgKi9cbiAgcmVhZG9ubHkgdHhuTGFuZXM/OiBUeG5MYW5lc1BhdGNoXG4gIC8qKlxuICAgKiBSdW50aW1lLWxldmVsIHBlci1tb2R1bGUgb3ZlcnJpZGVzIChob3RmaXggcGF0aCk6XG4gICAqIC0gT25seSBhZmZlY3RzIGNvbnZlcmdlIGJlaGF2aW9yIGZvciB0aGUgc3BlY2lmaWVkIG1vZHVsZUlkLlxuICAgKiAtIExvd2VyIHByaW9yaXR5IHRoYW4gUHJvdmlkZXIgb3ZlcnJpZGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZU92ZXJyaWRlc0J5TW9kdWxlSWQ/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYW5zYWN0aW9uVHJhaXRDb252ZXJnZU92ZXJyaWRlcz4+XG4gIC8qKlxuICAgKiAwNjA6IFR4biBMYW5lcyBydW50aW1lX21vZHVsZSBvdmVycmlkZXMgKGhvdGZpeCAvIGdyYWR1YWwgdHVuaW5nKS5cbiAgICogLSBPbmx5IGFmZmVjdHMgdGhlIHNwZWNpZmllZCBtb2R1bGVJZC5cbiAgICogLSBMb3dlciBwcmlvcml0eSB0aGFuIFByb3ZpZGVyIG92ZXJyaWRlcy5cbiAgICovXG4gIHJlYWRvbmx5IHR4bkxhbmVzT3ZlcnJpZGVzQnlNb2R1bGVJZD86IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFR4bkxhbmVzUGF0Y2g+PlxufVxuXG5jbGFzcyBTdGF0ZVRyYW5zYWN0aW9uQ29uZmlnVGFnSW1wbCBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL1N0YXRlVHJhbnNhY3Rpb25SdW50aW1lQ29uZmlnJyk8XG4gIFN0YXRlVHJhbnNhY3Rpb25Db25maWdUYWdJbXBsLFxuICBTdGF0ZVRyYW5zYWN0aW9uUnVudGltZUNvbmZpZ1xuPigpIHt9XG5cbmV4cG9ydCBjb25zdCBTdGF0ZVRyYW5zYWN0aW9uQ29uZmlnVGFnID0gU3RhdGVUcmFuc2FjdGlvbkNvbmZpZ1RhZ0ltcGxcblxuZXhwb3J0IHR5cGUgUmVhZFF1ZXJ5U3RyaWN0R2F0ZVJ1bnRpbWVDb25maWcgPSBSZWFkUXVlcnlTdHJpY3RHYXRlQ29uZmlnXG5cbmNsYXNzIFJlYWRRdWVyeVN0cmljdEdhdGVDb25maWdUYWdJbXBsIGV4dGVuZHMgQ29udGV4dC5UYWcoJ0Bsb2dpeGpzL2NvcmUvUmVhZFF1ZXJ5U3RyaWN0R2F0ZVJ1bnRpbWVDb25maWcnKTxcbiAgUmVhZFF1ZXJ5U3RyaWN0R2F0ZUNvbmZpZ1RhZ0ltcGwsXG4gIFJlYWRRdWVyeVN0cmljdEdhdGVSdW50aW1lQ29uZmlnXG4+KCkge31cblxuZXhwb3J0IGNvbnN0IFJlYWRRdWVyeVN0cmljdEdhdGVDb25maWdUYWcgPSBSZWFkUXVlcnlTdHJpY3RHYXRlQ29uZmlnVGFnSW1wbFxuXG5leHBvcnQgdHlwZSBSZXBsYXlNb2RlID0gJ2xpdmUnIHwgJ3JlcGxheSdcblxuZXhwb3J0IGludGVyZmFjZSBSZXBsYXlNb2RlQ29uZmlnIHtcbiAgcmVhZG9ubHkgbW9kZTogUmVwbGF5TW9kZVxufVxuXG5jbGFzcyBSZXBsYXlNb2RlQ29uZmlnVGFnSW1wbCBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL1JlcGxheU1vZGVDb25maWcnKTxcbiAgUmVwbGF5TW9kZUNvbmZpZ1RhZ0ltcGwsXG4gIFJlcGxheU1vZGVDb25maWdcbj4oKSB7fVxuXG5leHBvcnQgY29uc3QgUmVwbGF5TW9kZUNvbmZpZ1RhZyA9IFJlcGxheU1vZGVDb25maWdUYWdJbXBsXG5cbmV4cG9ydCBjb25zdCByZXBsYXlNb2RlTGF5ZXIgPSAobW9kZTogUmVwbGF5TW9kZSk6IExheWVyLkxheWVyPFJlcGxheU1vZGVDb25maWdUYWdJbXBsLCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLnN1Y2NlZWQoUmVwbGF5TW9kZUNvbmZpZ1RhZywgeyBtb2RlIH0pXG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFuc2FjdGlvblRyYWl0Q29udmVyZ2VPdmVycmlkZXMge1xuICByZWFkb25seSB0cmFpdENvbnZlcmdlTW9kZT86IFRyYWl0Q29udmVyZ2VSZXF1ZXN0ZWRNb2RlXG4gIHJlYWRvbmx5IHRyYWl0Q29udmVyZ2VCdWRnZXRNcz86IG51bWJlclxuICByZWFkb25seSB0cmFpdENvbnZlcmdlRGVjaXNpb25CdWRnZXRNcz86IG51bWJlclxuICByZWFkb25seSB0cmFpdENvbnZlcmdlVGltZVNsaWNpbmc/OiBUcmFpdENvbnZlcmdlVGltZVNsaWNpbmdQYXRjaFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFR4bkxhbmVzUGF0Y2gge1xuICAvKipcbiAgICogZW5hYmxlZDogd2hldGhlciBUeG4gTGFuZXMgaXMgZW5hYmxlZCAoZGVmYXVsdCBvbiBzaW5jZSAwNjIpLlxuICAgKiAtIHVuZGVmaW5lZDogZGVmYXVsdCBlbmFibGVkICh3aGVuIG5vdCBleHBsaWNpdGx5IGNvbmZpZ3VyZWQpXG4gICAqIC0gZmFsc2U6IGRpc2FibGVkIChyZXR1cm5zIHRvIGJhc2VsaW5lIGJlaGF2aW9yKVxuICAgKiAtIHRydWU6IGVuYWJsZWQgKG9ubHkgYWZmZWN0cyBzY2hlZHVsaW5nIG9mIGZvbGxvdy11cCB3b3JrIG91dHNpZGUgdGhlIHRyYW5zYWN0aW9uOyB0cmFuc2FjdGlvbnMgcmVtYWluIHN5bmNocm9ub3VzKVxuICAgKi9cbiAgcmVhZG9ubHkgZW5hYmxlZD86IGJvb2xlYW5cbiAgLyoqXG4gICAqIG92ZXJyaWRlTW9kZTogcnVudGltZSB0ZW1wb3Jhcnkgb3ZlcnJpZGUgKGZvciBkZWJ1Z2dpbmcvcm9sbGJhY2svY29tcGFyaXNvbikuXG4gICAqIC0gZm9yY2VkX29mZjogZm9yY2libHkgZGlzYWJsZXMgVHhuIExhbmVzIChyZXR1cm5zIHRvIGJhc2VsaW5lIGJlaGF2aW9yKS5cbiAgICogLSBmb3JjZWRfc3luYzogZm9yY2VzIGZ1bGx5IHN5bmNocm9ub3VzIGV4ZWN1dGlvbiAoaWdub3JlcyBub24tdXJnZW50IGRlZmVycmFsIGFuZCB0aW1lLXNsaWNpbmc7IHVzZWQgZm9yIGNvbXBhcmlzb25zKS5cbiAgICpcbiAgICogTm90ZXM6XG4gICAqIC0gT3ZlcnJpZGUgcHJlY2VkZW5jZSBmb2xsb3dzIFN0YXRlVHJhbnNhY3Rpb25PdmVycmlkZXM6IHByb3ZpZGVyID4gcnVudGltZV9tb2R1bGUgPiBydW50aW1lX2RlZmF1bHQgPiBidWlsdGluLlxuICAgKiAtIE92ZXJyaWRlcyBtdXN0IGJlIGV4cGxhaW5hYmxlIGJ5IGV2aWRlbmNlIChzZWUgMDYwIExhbmVFdmlkZW5jZSByZWFzb25zKS5cbiAgICovXG4gIHJlYWRvbmx5IG92ZXJyaWRlTW9kZT86ICdmb3JjZWRfb2ZmJyB8ICdmb3JjZWRfc3luYydcbiAgLyoqIG5vbi11cmdlbnQgd29yayBsb29wIHNsaWNlIGJ1ZGdldCAobXMpLiAqL1xuICByZWFkb25seSBidWRnZXRNcz86IG51bWJlclxuICAvKiogTm9uLXVyZ2VudCBiYWNrbG9nIGNvYWxlc2Npbmcgd2luZG93IChtcykuICovXG4gIHJlYWRvbmx5IGRlYm91bmNlTXM/OiBudW1iZXJcbiAgLyoqIE1heCBsYWcgdXBwZXIgYm91bmQgKG1zKTogZXhjZWVkaW5nIGl0IHRyaWdnZXJzIGFuIGV4cGxhaW5hYmxlIHN0YXJ2YXRpb24gcHJvdGVjdGlvbiAoZm9yY2VkIGNhdGNoLXVwKS4gKi9cbiAgcmVhZG9ubHkgbWF4TGFnTXM/OiBudW1iZXJcbiAgLyoqIFdoZXRoZXIgdG8gYWxsb3cgY29hbGVzY2luZy9jYW5jZWxpbmcgaW50ZXJtZWRpYXRlIG5vbi11cmdlbnQgd29yayAobXVzdCBwcmVzZXJ2ZSBldmVudHVhbCBjb25zaXN0ZW5jeSkuICovXG4gIHJlYWRvbmx5IGFsbG93Q29hbGVzY2U/OiBib29sZWFuXG4gIC8qKlxuICAgKiBZaWVsZCBzdHJhdGVneSBmb3IgdGhlIG5vbi11cmdlbnQgd29yayBsb29wIChwcm9ncmVzc2l2ZSBlbmhhbmNlbWVudCkuXG4gICAqIC0gYmFzZWxpbmU6IHVzZXMgb25seSB0aW1lIGJ1ZGdldCArIGhhcmQgdXBwZXIgYm91bmRcbiAgICogLSBpbnB1dFBlbmRpbmc6IHdoZW4gc3VwcG9ydGVkIGJ5IGJyb3dzZXJzLCBhbHNvIGNvbnN1bHRzIGBuYXZpZ2F0b3Iuc2NoZWR1bGluZy5pc0lucHV0UGVuZGluZ2BcbiAgICovXG4gIHJlYWRvbmx5IHlpZWxkU3RyYXRlZ3k/OiAnYmFzZWxpbmUnIHwgJ2lucHV0UGVuZGluZydcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlVGltZVNsaWNpbmdQYXRjaCB7XG4gIC8qKlxuICAgKiBlbmFibGVkXHVGRjFBXG4gICAqIC0gZmFsc2UvdW5kZWZpbmVkOiBkaXNhYmxlZCAoZGVmYXVsdClcbiAgICogLSB0cnVlOiBlbmFibGVzIHRpbWUtc2xpY2luZyAob25seSBhZmZlY3RzIGNvbXB1dGVkL2xpbmsgZXhwbGljaXRseSBtYXJrZWQgYXMgZGVmZXJyZWQpXG4gICAqL1xuICByZWFkb25seSBlbmFibGVkPzogYm9vbGVhblxuICAvKipcbiAgICogZGVib3VuY2VNczogY29hbGVzY2luZyBpbnRlcnZhbCAobXMpIGZvciB0aGUgZGVmZXJyYWwgd2luZG93OyBtZXJnZXMgaGlnaC1mcmVxdWVuY3kgaW5wdXRzIGludG8gb25lIGRlZmVycmVkIGZsdXNoLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVib3VuY2VNcz86IG51bWJlclxuICAvKipcbiAgICogbWF4TGFnTXM6IG1heCBsYWcgdXBwZXIgYm91bmQgKG1zKTsgZXhjZWVkaW5nIGl0IHRyaWdnZXJzIGFuIGV4cGxhaW5hYmxlIGZvcmNlZCBmbHVzaCAoc3RhcnZhdGlvbiBwcm90ZWN0aW9uKS5cbiAgICovXG4gIHJlYWRvbmx5IG1heExhZ01zPzogbnVtYmVyXG59XG5cbi8qKlxuICogUHJvdmlkZXItc2NvcGVkIFN0YXRlVHJhbnNhY3Rpb25PdmVycmlkZXMgKGRlbHRhIG92ZXJyaWRlcyk6XG4gKiAtIFVzZWQgdG8gaW5qZWN0IG1vcmUgbG9jYWwgb3ZlcnJpZGVzIGludG8gYSBQcm92aWRlciBzdWJ0cmVlIG9uIHRvcCBvZiBpbmhlcml0ZWQgZ2xvYmFsIHJ1bnRpbWUgY29uZmlnLlxuICogLSBPdmVycmlkZSBwcmVjZWRlbmNlOiBwcm92aWRlciA+IHJ1bnRpbWVfbW9kdWxlID4gcnVudGltZV9kZWZhdWx0ID4gYnVpbHRpbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYW5zYWN0aW9uT3ZlcnJpZGVzIHtcbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZU1vZGU/OiBUcmFpdENvbnZlcmdlUmVxdWVzdGVkTW9kZVxuICByZWFkb25seSB0cmFpdENvbnZlcmdlQnVkZ2V0TXM/OiBudW1iZXJcbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZURlY2lzaW9uQnVkZ2V0TXM/OiBudW1iZXJcbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZVRpbWVTbGljaW5nPzogVHJhaXRDb252ZXJnZVRpbWVTbGljaW5nUGF0Y2hcbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZU92ZXJyaWRlc0J5TW9kdWxlSWQ/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYW5zYWN0aW9uVHJhaXRDb252ZXJnZU92ZXJyaWRlcz4+XG4gIC8qKiAwNjA6IFR4biBMYW5lcyBwcm92aWRlci1sZXZlbCBvdmVycmlkZXMgKGRlbHRhIG92ZXJyaWRlcykuICovXG4gIHJlYWRvbmx5IHR4bkxhbmVzPzogVHhuTGFuZXNQYXRjaFxuICAvKiogMDYwOiBUeG4gTGFuZXMgcHJvdmlkZXJfbW9kdWxlIG92ZXJyaWRlcyAoYnkgbW9kdWxlSWQpLiAqL1xuICByZWFkb25seSB0eG5MYW5lc092ZXJyaWRlc0J5TW9kdWxlSWQ/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBUeG5MYW5lc1BhdGNoPj5cbn1cblxuY2xhc3MgU3RhdGVUcmFuc2FjdGlvbk92ZXJyaWRlc1RhZ0ltcGwgZXh0ZW5kcyBDb250ZXh0LlRhZygnQGxvZ2l4anMvY29yZS9TdGF0ZVRyYW5zYWN0aW9uT3ZlcnJpZGVzJyk8XG4gIFN0YXRlVHJhbnNhY3Rpb25PdmVycmlkZXNUYWdJbXBsLFxuICBTdGF0ZVRyYW5zYWN0aW9uT3ZlcnJpZGVzXG4+KCkge31cblxuZXhwb3J0IGNvbnN0IFN0YXRlVHJhbnNhY3Rpb25PdmVycmlkZXNUYWcgPSBTdGF0ZVRyYW5zYWN0aW9uT3ZlcnJpZGVzVGFnSW1wbFxuXG5leHBvcnQgdHlwZSBDb25jdXJyZW5jeUxpbWl0ID0gbnVtYmVyIHwgJ3VuYm91bmRlZCdcblxuZXhwb3J0IGludGVyZmFjZSBDb25jdXJyZW5jeVBvbGljeVBhdGNoIHtcbiAgcmVhZG9ubHkgY29uY3VycmVuY3lMaW1pdD86IENvbmN1cnJlbmN5TGltaXRcbiAgcmVhZG9ubHkgbG9zc2xlc3NCYWNrcHJlc3N1cmVDYXBhY2l0eT86IG51bWJlclxuICByZWFkb25seSBhbGxvd1VuYm91bmRlZD86IGJvb2xlYW5cbiAgcmVhZG9ubHkgcHJlc3N1cmVXYXJuaW5nVGhyZXNob2xkPzoge1xuICAgIHJlYWRvbmx5IGJhY2tsb2dDb3VudD86IG51bWJlclxuICAgIHJlYWRvbmx5IGJhY2tsb2dEdXJhdGlvbk1zPzogbnVtYmVyXG4gIH1cbiAgcmVhZG9ubHkgd2FybmluZ0Nvb2xkb3duTXM/OiBudW1iZXJcbn1cblxuLyoqXG4gKiBSdW50aW1lLWxldmVsIENvbmN1cnJlbmN5UG9saWN5OlxuICogLSBQcm92aWRlZCBhdCB0aGUgYXBwIGxheWVyIGJ5IExvZ2l4LlJ1bnRpbWUubWFrZSAvIEFwcFJ1bnRpbWUubWFrZUFwcC5cbiAqIC0gTW9kdWxlUnVudGltZSBtZXJnZXMgc291cmNlcyB2aWEgYSByZXNvbHZlciAoYnVpbHRpbi9ydW50aW1lX21vZHVsZS9wcm92aWRlciwgZXRjLikuXG4gKlxuICogTm90ZXM6XG4gKiAtIG92ZXJyaWRlc0J5TW9kdWxlSWQgaXMgdXNlZCBmb3IgcnVudGltZV9tb2R1bGUgaG90LXN3aXRjaGluZyAoaG90Zml4IC8gZ3JhZHVhbCB0dW5pbmcpIGFuZCBpcyBsb3dlciBwcmlvcml0eSB0aGFuIHByb3ZpZGVyIG92ZXJyaWRlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb25jdXJyZW5jeVBvbGljeSBleHRlbmRzIENvbmN1cnJlbmN5UG9saWN5UGF0Y2gge1xuICByZWFkb25seSBvdmVycmlkZXNCeU1vZHVsZUlkPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgQ29uY3VycmVuY3lQb2xpY3lQYXRjaD4+XG59XG5cbmNsYXNzIENvbmN1cnJlbmN5UG9saWN5VGFnSW1wbCBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL0NvbmN1cnJlbmN5UG9saWN5Jyk8XG4gIENvbmN1cnJlbmN5UG9saWN5VGFnSW1wbCxcbiAgQ29uY3VycmVuY3lQb2xpY3lcbj4oKSB7fVxuXG5leHBvcnQgY29uc3QgQ29uY3VycmVuY3lQb2xpY3lUYWcgPSBDb25jdXJyZW5jeVBvbGljeVRhZ0ltcGxcblxuLyoqXG4gKiBQcm92aWRlci1zY29wZWQgQ29uY3VycmVuY3lQb2xpY3lPdmVycmlkZXMgKGRlbHRhIG92ZXJyaWRlcyk6XG4gKiAtIFVzZWQgdG8gaW5qZWN0IG1vcmUgbG9jYWwgb3ZlcnJpZGVzIGludG8gYSBQcm92aWRlciBzdWJ0cmVlIG9uIHRvcCBvZiBpbmhlcml0ZWQgZ2xvYmFsIHJ1bnRpbWUgY29uZmlnLlxuICogLSBPdmVycmlkZSBwcmVjZWRlbmNlOiBwcm92aWRlciA+IHJ1bnRpbWVfbW9kdWxlID4gcnVudGltZV9kZWZhdWx0ID4gYnVpbHRpbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb25jdXJyZW5jeVBvbGljeU92ZXJyaWRlcyBleHRlbmRzIENvbmN1cnJlbmN5UG9saWN5UGF0Y2gge1xuICByZWFkb25seSBvdmVycmlkZXNCeU1vZHVsZUlkPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgQ29uY3VycmVuY3lQb2xpY3lQYXRjaD4+XG59XG5cbmNsYXNzIENvbmN1cnJlbmN5UG9saWN5T3ZlcnJpZGVzVGFnSW1wbCBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL0NvbmN1cnJlbmN5UG9saWN5T3ZlcnJpZGVzJyk8XG4gIENvbmN1cnJlbmN5UG9saWN5T3ZlcnJpZGVzVGFnSW1wbCxcbiAgQ29uY3VycmVuY3lQb2xpY3lPdmVycmlkZXNcbj4oKSB7fVxuXG5leHBvcnQgY29uc3QgQ29uY3VycmVuY3lQb2xpY3lPdmVycmlkZXNUYWcgPSBDb25jdXJyZW5jeVBvbGljeU92ZXJyaWRlc1RhZ0ltcGxcblxuLy8gLS0tLSAwNzM6IFRpY2tTY2hlZHVsZXIgKyBSdW50aW1lU3RvcmUgKGluamVjdGFibGUgcnVudGltZSBzZXJ2aWNlcykgLS0tLVxuXG5leHBvcnQgaW50ZXJmYWNlIFJ1bnRpbWVTdG9yZVNlcnZpY2UgZXh0ZW5kcyBSdW50aW1lU3RvcmUge31cblxuZXhwb3J0IGNsYXNzIFJ1bnRpbWVTdG9yZVRhZyBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL1J1bnRpbWVTdG9yZScpPFJ1bnRpbWVTdG9yZVRhZywgUnVudGltZVN0b3JlU2VydmljZT4oKSB7fVxuXG5leHBvcnQgY29uc3QgcnVudGltZVN0b3JlTGF5ZXI6IExheWVyLkxheWVyPGFueSwgbmV2ZXIsIG5ldmVyPiA9IExheWVyLnNjb3BlZChcbiAgUnVudGltZVN0b3JlVGFnLFxuICBFZmZlY3QuYWNxdWlyZVJlbGVhc2UoXG4gICAgRWZmZWN0LnN5bmMoKCkgPT4gbWFrZVJ1bnRpbWVTdG9yZSgpIGFzIFJ1bnRpbWVTdG9yZVNlcnZpY2UpLFxuICAgIChzdG9yZSkgPT4gRWZmZWN0LnN5bmMoKCkgPT4gc3RvcmUuZGlzcG9zZSgpKSxcbiAgKSxcbikgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG5cbmV4cG9ydCBjb25zdCBydW50aW1lU3RvcmVUZXN0U3R1YkxheWVyID0gKHN0b3JlOiBSdW50aW1lU3RvcmVTZXJ2aWNlKTogTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLnN1Y2NlZWQoUnVudGltZVN0b3JlVGFnLCBzdG9yZSkgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG5cbmV4cG9ydCBpbnRlcmZhY2UgSG9zdFNjaGVkdWxlclNlcnZpY2UgZXh0ZW5kcyBIb3N0U2NoZWR1bGVyIHt9XG5cbmV4cG9ydCBjbGFzcyBIb3N0U2NoZWR1bGVyVGFnIGV4dGVuZHMgQ29udGV4dC5UYWcoJ0Bsb2dpeGpzL2NvcmUvSG9zdFNjaGVkdWxlcicpPFxuICBIb3N0U2NoZWR1bGVyVGFnLFxuICBIb3N0U2NoZWR1bGVyU2VydmljZVxuPigpIHt9XG5cbmV4cG9ydCBjb25zdCBob3N0U2NoZWR1bGVyTGF5ZXI6IExheWVyLkxheWVyPGFueSwgbmV2ZXIsIG5ldmVyPiA9IExheWVyLnN1Y2NlZWQoXG4gIEhvc3RTY2hlZHVsZXJUYWcsXG4gIGdldEdsb2JhbEhvc3RTY2hlZHVsZXIoKSBhcyBIb3N0U2NoZWR1bGVyU2VydmljZSxcbikgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG5cbmV4cG9ydCBjb25zdCBob3N0U2NoZWR1bGVyVGVzdFN0dWJMYXllciA9IChzY2hlZHVsZXI6IEhvc3RTY2hlZHVsZXJTZXJ2aWNlKTogTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLnN1Y2NlZWQoSG9zdFNjaGVkdWxlclRhZywgc2NoZWR1bGVyKSBhcyBMYXllci5MYXllcjxhbnksIG5ldmVyLCBuZXZlcj5cblxuZXhwb3J0IGludGVyZmFjZSBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lU2VydmljZSBleHRlbmRzIERlY2xhcmF0aXZlTGlua1J1bnRpbWUge31cblxuZXhwb3J0IGNsYXNzIERlY2xhcmF0aXZlTGlua1J1bnRpbWVUYWcgZXh0ZW5kcyBDb250ZXh0LlRhZygnQGxvZ2l4anMvY29yZS9EZWNsYXJhdGl2ZUxpbmtSdW50aW1lJyk8XG4gIERlY2xhcmF0aXZlTGlua1J1bnRpbWVUYWcsXG4gIERlY2xhcmF0aXZlTGlua1J1bnRpbWVTZXJ2aWNlXG4+KCkge31cblxuZXhwb3J0IGNvbnN0IGRlY2xhcmF0aXZlTGlua1J1bnRpbWVMYXllcjogTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+ID0gTGF5ZXIuc3VjY2VlZChcbiAgRGVjbGFyYXRpdmVMaW5rUnVudGltZVRhZyxcbiAgbWFrZURlY2xhcmF0aXZlTGlua1J1bnRpbWUoKSBhcyBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lU2VydmljZSxcbikgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG5cbmV4cG9ydCBjb25zdCBkZWNsYXJhdGl2ZUxpbmtSdW50aW1lVGVzdFN0dWJMYXllciA9IChcbiAgcnVudGltZTogRGVjbGFyYXRpdmVMaW5rUnVudGltZVNlcnZpY2UsXG4pOiBMYXllci5MYXllcjxhbnksIG5ldmVyLCBuZXZlcj4gPT4gTGF5ZXIuc3VjY2VlZChEZWNsYXJhdGl2ZUxpbmtSdW50aW1lVGFnLCBydW50aW1lKSBhcyBMYXllci5MYXllcjxhbnksIG5ldmVyLCBuZXZlcj5cblxuZXhwb3J0IGludGVyZmFjZSBUaWNrU2NoZWR1bGVyU2VydmljZSBleHRlbmRzIFRpY2tTY2hlZHVsZXIge31cblxuZXhwb3J0IGNsYXNzIFRpY2tTY2hlZHVsZXJUYWcgZXh0ZW5kcyBDb250ZXh0LlRhZygnQGxvZ2l4anMvY29yZS9UaWNrU2NoZWR1bGVyJyk8VGlja1NjaGVkdWxlclRhZywgVGlja1NjaGVkdWxlclNlcnZpY2U+KCkge31cblxuZXhwb3J0IGNvbnN0IHRpY2tTY2hlZHVsZXJMYXllciA9IChjb25maWc/OiBUaWNrU2NoZWR1bGVyQ29uZmlnKTogTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLmVmZmVjdChcbiAgICBUaWNrU2NoZWR1bGVyVGFnLFxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IHN0b3JlID0geWllbGQqIFJ1bnRpbWVTdG9yZVRhZ1xuICAgICAgY29uc3QgZGVjbGFyYXRpdmVMaW5rUnVudGltZSA9IHlpZWxkKiBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lVGFnXG4gICAgICBjb25zdCBob3N0U2NoZWR1bGVyID0geWllbGQqIEhvc3RTY2hlZHVsZXJUYWdcbiAgICAgIHJldHVybiBtYWtlVGlja1NjaGVkdWxlcih7IHJ1bnRpbWVTdG9yZTogc3RvcmUsIGRlY2xhcmF0aXZlTGlua1J1bnRpbWUsIGhvc3RTY2hlZHVsZXIsIGNvbmZpZyB9KSBhcyBUaWNrU2NoZWR1bGVyU2VydmljZVxuICAgIH0pLFxuICApIGFzIExheWVyLkxheWVyPGFueSwgbmV2ZXIsIG5ldmVyPlxuXG5leHBvcnQgY29uc3QgdGlja1NjaGVkdWxlclRlc3RTdHViTGF5ZXIgPSAoc2NoZWR1bGVyOiBUaWNrU2NoZWR1bGVyU2VydmljZSk6IExheWVyLkxheWVyPGFueSwgbmV2ZXIsIG5ldmVyPiA9PlxuICBMYXllci5zdWNjZWVkKFRpY2tTY2hlZHVsZXJUYWcsIHNjaGVkdWxlcikgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG4iLCAiaW1wb3J0IHR5cGUgeyBTdGF0ZUNvbW1pdE1ldGEsIFN0YXRlQ29tbWl0UHJpb3JpdHkgfSBmcm9tICcuL21vZHVsZS5qcydcblxuZXhwb3J0IHR5cGUgTW9kdWxlSW5zdGFuY2VLZXkgPSBgJHtzdHJpbmd9Ojoke3N0cmluZ31gXG5leHBvcnQgdHlwZSBUb3BpY0tleSA9IHN0cmluZ1xuXG5leHBvcnQgdHlwZSBUb3BpY0tpbmQgPSAnbW9kdWxlJyB8ICdyZWFkUXVlcnknXG5cbmV4cG9ydCB0eXBlIFRvcGljSW5mbyA9XG4gIHwgeyByZWFkb25seSBraW5kOiAnbW9kdWxlJzsgcmVhZG9ubHkgbW9kdWxlSW5zdGFuY2VLZXk6IE1vZHVsZUluc3RhbmNlS2V5IH1cbiAgfCB7IHJlYWRvbmx5IGtpbmQ6ICdyZWFkUXVlcnknOyByZWFkb25seSBtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXk7IHJlYWRvbmx5IHNlbGVjdG9ySWQ6IHN0cmluZyB9XG5cbmV4cG9ydCBjb25zdCBtYWtlTW9kdWxlSW5zdGFuY2VLZXkgPSAobW9kdWxlSWQ6IHN0cmluZywgaW5zdGFuY2VJZDogc3RyaW5nKTogTW9kdWxlSW5zdGFuY2VLZXkgPT5cbiAgYCR7bW9kdWxlSWR9Ojoke2luc3RhbmNlSWR9YFxuXG5leHBvcnQgY29uc3QgbWFrZVJlYWRRdWVyeVRvcGljS2V5ID0gKG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleSwgc2VsZWN0b3JJZDogc3RyaW5nKTogVG9waWNLZXkgPT5cbiAgYCR7bW9kdWxlSW5zdGFuY2VLZXl9OjpycToke3NlbGVjdG9ySWR9YFxuXG5leHBvcnQgY29uc3QgcGFyc2VUb3BpY0tleSA9ICh0b3BpY0tleTogc3RyaW5nKTogVG9waWNJbmZvIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgaWR4ID0gdG9waWNLZXkuaW5kZXhPZignOjonKVxuICBpZiAoaWR4IDw9IDApIHJldHVybiB1bmRlZmluZWRcblxuICBjb25zdCBtb2R1bGVJZCA9IHRvcGljS2V5LnNsaWNlKDAsIGlkeClcbiAgY29uc3QgcmVzdCA9IHRvcGljS2V5LnNsaWNlKGlkeCArIDIpXG4gIGlmIChyZXN0Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIGNvbnN0IGlkeDIgPSByZXN0LmluZGV4T2YoJzo6JylcbiAgaWYgKGlkeDIgPCAwKSB7XG4gICAgcmV0dXJuIHsga2luZDogJ21vZHVsZScsIG1vZHVsZUluc3RhbmNlS2V5OiBgJHttb2R1bGVJZH06OiR7cmVzdH1gIH1cbiAgfVxuXG4gIGNvbnN0IGluc3RhbmNlSWQgPSByZXN0LnNsaWNlKDAsIGlkeDIpXG4gIGNvbnN0IHN1ZmZpeCA9IHJlc3Quc2xpY2UoaWR4MiArIDIpXG4gIGlmIChzdWZmaXguc3RhcnRzV2l0aCgncnE6JykpIHtcbiAgICBjb25zdCBzZWxlY3RvcklkID0gc3VmZml4LnNsaWNlKCdycTonLmxlbmd0aClcbiAgICBpZiAoc2VsZWN0b3JJZC5sZW5ndGggPT09IDApIHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4ge1xuICAgICAga2luZDogJ3JlYWRRdWVyeScsXG4gICAgICBtb2R1bGVJbnN0YW5jZUtleTogYCR7bW9kdWxlSWR9Ojoke2luc3RhbmNlSWR9YCxcbiAgICAgIHNlbGVjdG9ySWQsXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsga2luZDogJ21vZHVsZScsIG1vZHVsZUluc3RhbmNlS2V5OiBgJHttb2R1bGVJZH06OiR7aW5zdGFuY2VJZH1gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdW50aW1lU3RvcmVNb2R1bGVDb21taXQge1xuICByZWFkb25seSBtb2R1bGVJZDogc3RyaW5nXG4gIHJlYWRvbmx5IGluc3RhbmNlSWQ6IHN0cmluZ1xuICByZWFkb25seSBtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXlcbiAgcmVhZG9ubHkgc3RhdGU6IHVua25vd25cbiAgcmVhZG9ubHkgbWV0YTogU3RhdGVDb21taXRNZXRhXG4gIHJlYWRvbmx5IG9wU2VxPzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVudGltZVN0b3JlUGVuZGluZ0RyYWluIHtcbiAgcmVhZG9ubHkgbW9kdWxlczogUmVhZG9ubHlNYXA8TW9kdWxlSW5zdGFuY2VLZXksIFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdD5cbiAgcmVhZG9ubHkgZGlydHlUb3BpY3M6IFJlYWRvbmx5TWFwPFRvcGljS2V5LCBTdGF0ZUNvbW1pdFByaW9yaXR5PlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJ1bnRpbWVTdG9yZUNvbW1pdFJlc3VsdCB7XG4gIHJlYWRvbmx5IGNoYW5nZWRUb3BpY3M6IFJlYWRvbmx5TWFwPFRvcGljS2V5LCB7IHJlYWRvbmx5IHByaW9yaXR5OiBTdGF0ZUNvbW1pdFByaW9yaXR5OyByZWFkb25seSBsaXN0ZW5lcnM6IFJlYWRvbmx5QXJyYXk8KCkgPT4gdm9pZD4gfT5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdW50aW1lU3RvcmUge1xuICAvLyAtLS0tIFJlYWN0LWZhY2luZyBzeW5jIHNuYXBzaG90IEFQSXMgLS0tLVxuICByZWFkb25seSBnZXRUaWNrU2VxOiAoKSA9PiBudW1iZXJcbiAgcmVhZG9ubHkgZ2V0TW9kdWxlU3RhdGU6IChtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXkpID0+IHVua25vd25cbiAgcmVhZG9ubHkgZ2V0VG9waWNWZXJzaW9uOiAodG9waWNLZXk6IFRvcGljS2V5KSA9PiBudW1iZXJcbiAgcmVhZG9ubHkgZ2V0VG9waWNQcmlvcml0eTogKHRvcGljS2V5OiBUb3BpY0tleSkgPT4gU3RhdGVDb21taXRQcmlvcml0eVxuICByZWFkb25seSBzdWJzY3JpYmVUb3BpYzogKHRvcGljS2V5OiBUb3BpY0tleSwgbGlzdGVuZXI6ICgpID0+IHZvaWQpID0+ICgpID0+IHZvaWRcbiAgcmVhZG9ubHkgZ2V0VG9waWNTdWJzY3JpYmVyQ291bnQ6ICh0b3BpY0tleTogVG9waWNLZXkpID0+IG51bWJlclxuICByZWFkb25seSBnZXRNb2R1bGVTdWJzY3JpYmVyQ291bnQ6IChtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXkpID0+IG51bWJlclxuXG4gIC8vIC0tLS0gUnVudGltZSBpbnRlZ3JhdGlvbiAtLS0tXG4gIHJlYWRvbmx5IHJlZ2lzdGVyTW9kdWxlSW5zdGFuY2U6IChhcmdzOiB7XG4gICAgcmVhZG9ubHkgbW9kdWxlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IGluc3RhbmNlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleVxuICAgIHJlYWRvbmx5IGluaXRpYWxTdGF0ZTogdW5rbm93blxuICB9KSA9PiB2b2lkXG4gIHJlYWRvbmx5IHVucmVnaXN0ZXJNb2R1bGVJbnN0YW5jZTogKG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleSkgPT4gdm9pZFxuXG4gIC8vIC0tLS0gVGlja1NjaGVkdWxlciBpbnRlZ3JhdGlvbiAoaW50ZXJuYWwpIC0tLS1cbiAgcmVhZG9ubHkgY29tbWl0VGljazogKGFyZ3M6IHtcbiAgICByZWFkb25seSB0aWNrU2VxOiBudW1iZXJcbiAgICByZWFkb25seSBhY2NlcHRlZDogUnVudGltZVN0b3JlUGVuZGluZ0RyYWluXG4gIH0pID0+IFJ1bnRpbWVTdG9yZUNvbW1pdFJlc3VsdFxuXG4gIHJlYWRvbmx5IGRpc3Bvc2U6ICgpID0+IHZvaWRcbn1cblxuZXhwb3J0IGNvbnN0IG1ha2VSdW50aW1lU3RvcmUgPSAoKTogUnVudGltZVN0b3JlID0+IHtcbiAgbGV0IHRpY2tTZXEgPSAwXG5cbiAgLy8gLS0tLSBDb21taXR0ZWQgc25hcHNob3QgKHJlYWQgYnkgUmVhY3QpIC0tLS1cbiAgY29uc3QgbW9kdWxlU3RhdGVzID0gbmV3IE1hcDxNb2R1bGVJbnN0YW5jZUtleSwgdW5rbm93bj4oKVxuICBjb25zdCB0b3BpY1ZlcnNpb25zID0gbmV3IE1hcDxUb3BpY0tleSwgbnVtYmVyPigpXG4gIGNvbnN0IHRvcGljUHJpb3JpdGllcyA9IG5ldyBNYXA8VG9waWNLZXksIFN0YXRlQ29tbWl0UHJpb3JpdHk+KClcblxuICAvLyAtLS0tIFN1YnNjcmlwdGlvbnMgLS0tLVxuICBjb25zdCBsaXN0ZW5lcnNCeVRvcGljID0gbmV3IE1hcDxUb3BpY0tleSwgU2V0PCgpID0+IHZvaWQ+PigpXG4gIGNvbnN0IHN1YnNjcmliZXJDb3VudEJ5TW9kdWxlID0gbmV3IE1hcDxNb2R1bGVJbnN0YW5jZUtleSwgbnVtYmVyPigpXG5cbiAgY29uc3QgZ2V0VG9waWNWZXJzaW9uID0gKHRvcGljS2V5OiBUb3BpY0tleSk6IG51bWJlciA9PiB0b3BpY1ZlcnNpb25zLmdldCh0b3BpY0tleSkgPz8gMFxuICBjb25zdCBnZXRUb3BpY1ByaW9yaXR5ID0gKHRvcGljS2V5OiBUb3BpY0tleSk6IFN0YXRlQ29tbWl0UHJpb3JpdHkgPT4gdG9waWNQcmlvcml0aWVzLmdldCh0b3BpY0tleSkgPz8gJ25vcm1hbCdcblxuICBjb25zdCBjb21taXRUb3BpY0J1bXAgPSAodG9waWNLZXk6IFRvcGljS2V5LCBwcmlvcml0eTogU3RhdGVDb21taXRQcmlvcml0eSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHByZXYgPSB0b3BpY1ZlcnNpb25zLmdldCh0b3BpY0tleSkgPz8gMFxuICAgIHRvcGljVmVyc2lvbnMuc2V0KHRvcGljS2V5LCBwcmV2ICsgMSlcbiAgICB0b3BpY1ByaW9yaXRpZXMuc2V0KHRvcGljS2V5LCBwcmlvcml0eSlcbiAgfVxuXG4gIGNvbnN0IHN1YnNjcmliZVRvcGljID0gKHRvcGljS2V5OiBUb3BpY0tleSwgbGlzdGVuZXI6ICgpID0+IHZvaWQpOiAoKCkgPT4gdm9pZCkgPT4ge1xuICAgIGNvbnN0IGluZm8gPSBwYXJzZVRvcGljS2V5KHRvcGljS2V5KVxuICAgIGNvbnN0IGV4aXN0aW5nID0gbGlzdGVuZXJzQnlUb3BpYy5nZXQodG9waWNLZXkpXG4gICAgY29uc3Qgc2V0ID0gZXhpc3RpbmcgPz8gbmV3IFNldDwoKSA9PiB2b2lkPigpXG4gICAgY29uc3QgYWxyZWFkeUhhcyA9IHNldC5oYXMobGlzdGVuZXIpXG4gICAgaWYgKCFhbHJlYWR5SGFzKSB7XG4gICAgICBzZXQuYWRkKGxpc3RlbmVyKVxuICAgIH1cbiAgICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgICBsaXN0ZW5lcnNCeVRvcGljLnNldCh0b3BpY0tleSwgc2V0KVxuICAgIH1cblxuICAgIGlmICghYWxyZWFkeUhhcyAmJiBpbmZvKSB7XG4gICAgICBjb25zdCBwcmV2ID0gc3Vic2NyaWJlckNvdW50QnlNb2R1bGUuZ2V0KGluZm8ubW9kdWxlSW5zdGFuY2VLZXkpID8/IDBcbiAgICAgIHN1YnNjcmliZXJDb3VudEJ5TW9kdWxlLnNldChpbmZvLm1vZHVsZUluc3RhbmNlS2V5LCBwcmV2ICsgMSlcbiAgICB9XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudCA9IGxpc3RlbmVyc0J5VG9waWMuZ2V0KHRvcGljS2V5KVxuICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm5cbiAgICAgIGNvbnN0IGRlbGV0ZWQgPSBjdXJyZW50LmRlbGV0ZShsaXN0ZW5lcilcbiAgICAgIGlmIChkZWxldGVkICYmIGluZm8pIHtcbiAgICAgICAgY29uc3QgcHJldiA9IHN1YnNjcmliZXJDb3VudEJ5TW9kdWxlLmdldChpbmZvLm1vZHVsZUluc3RhbmNlS2V5KSA/PyAwXG4gICAgICAgIGNvbnN0IG5leHQgPSBwcmV2IC0gMVxuICAgICAgICBpZiAobmV4dCA8PSAwKSB7XG4gICAgICAgICAgc3Vic2NyaWJlckNvdW50QnlNb2R1bGUuZGVsZXRlKGluZm8ubW9kdWxlSW5zdGFuY2VLZXkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3Vic2NyaWJlckNvdW50QnlNb2R1bGUuc2V0KGluZm8ubW9kdWxlSW5zdGFuY2VLZXksIG5leHQpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjdXJyZW50LnNpemUgPT09IDApIHtcbiAgICAgICAgbGlzdGVuZXJzQnlUb3BpYy5kZWxldGUodG9waWNLZXkpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZ2V0VG9waWNTdWJzY3JpYmVyQ291bnQgPSAodG9waWNLZXk6IFRvcGljS2V5KTogbnVtYmVyID0+IGxpc3RlbmVyc0J5VG9waWMuZ2V0KHRvcGljS2V5KT8uc2l6ZSA/PyAwXG4gIGNvbnN0IGdldE1vZHVsZVN1YnNjcmliZXJDb3VudCA9IChtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXkpOiBudW1iZXIgPT4gc3Vic2NyaWJlckNvdW50QnlNb2R1bGUuZ2V0KG1vZHVsZUluc3RhbmNlS2V5KSA/PyAwXG5cbiAgY29uc3QgcmVnaXN0ZXJNb2R1bGVJbnN0YW5jZSA9IChhcmdzOiB7XG4gICAgcmVhZG9ubHkgbW9kdWxlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IGluc3RhbmNlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleVxuICAgIHJlYWRvbmx5IGluaXRpYWxTdGF0ZTogdW5rbm93blxuICB9KTogdm9pZCA9PiB7XG4gICAgbW9kdWxlU3RhdGVzLnNldChhcmdzLm1vZHVsZUluc3RhbmNlS2V5LCBhcmdzLmluaXRpYWxTdGF0ZSlcbiAgICAvLyBFbnN1cmUgdGhlIG1vZHVsZSB0b3BpYyBleGlzdHMgd2l0aCBhIHN0YWJsZSBiYXNlbGluZSB2ZXJzaW9uL3ByaW9yaXR5LlxuICAgIGlmICghdG9waWNWZXJzaW9ucy5oYXMoYXJncy5tb2R1bGVJbnN0YW5jZUtleSkpIHtcbiAgICAgIHRvcGljVmVyc2lvbnMuc2V0KGFyZ3MubW9kdWxlSW5zdGFuY2VLZXksIDApXG4gICAgICB0b3BpY1ByaW9yaXRpZXMuc2V0KGFyZ3MubW9kdWxlSW5zdGFuY2VLZXksICdub3JtYWwnKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHVucmVnaXN0ZXJNb2R1bGVJbnN0YW5jZSA9IChtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXkpOiB2b2lkID0+IHtcbiAgICBtb2R1bGVTdGF0ZXMuZGVsZXRlKG1vZHVsZUluc3RhbmNlS2V5KVxuICAgIC8vIEtlZXAgdG9waWMgdmVyc2lvbnMgYnkgZGVmYXVsdCAoaGVscHMgZGVidWdnaW5nKS4gU3Vic2NyaWJlcnMgYXJlIGV4cGVjdGVkIHRvIGRldGFjaCBvbiBtb2R1bGUgZGVzdHJveS5cbiAgfVxuXG4gIGNvbnN0IGNvbW1pdFRpY2sgPSAoYXJnczogeyByZWFkb25seSB0aWNrU2VxOiBudW1iZXI7IHJlYWRvbmx5IGFjY2VwdGVkOiBSdW50aW1lU3RvcmVQZW5kaW5nRHJhaW4gfSk6IFJ1bnRpbWVTdG9yZUNvbW1pdFJlc3VsdCA9PiB7XG4gICAgdGlja1NlcSA9IGFyZ3MudGlja1NlcVxuXG4gICAgZm9yIChjb25zdCBba2V5LCBjb21taXRdIG9mIGFyZ3MuYWNjZXB0ZWQubW9kdWxlcykge1xuICAgICAgbW9kdWxlU3RhdGVzLnNldChrZXksIGNvbW1pdC5zdGF0ZSlcbiAgICB9XG5cbiAgICBjb25zdCBjaGFuZ2VkVG9waWNzID0gbmV3IE1hcDxUb3BpY0tleSwgeyByZWFkb25seSBwcmlvcml0eTogU3RhdGVDb21taXRQcmlvcml0eTsgcmVhZG9ubHkgbGlzdGVuZXJzOiBSZWFkb25seUFycmF5PCgpID0+IHZvaWQ+IH0+KClcblxuICAgIGZvciAoY29uc3QgW3RvcGljS2V5LCBwcmlvcml0eV0gb2YgYXJncy5hY2NlcHRlZC5kaXJ0eVRvcGljcykge1xuICAgICAgY29tbWl0VG9waWNCdW1wKHRvcGljS2V5LCBwcmlvcml0eSlcbiAgICAgIGNvbnN0IGxpc3RlbmVycyA9IEFycmF5LmZyb20obGlzdGVuZXJzQnlUb3BpYy5nZXQodG9waWNLZXkpID8/IFtdKVxuICAgICAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNoYW5nZWRUb3BpY3Muc2V0KHRvcGljS2V5LCB7IHByaW9yaXR5LCBsaXN0ZW5lcnMgfSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBjaGFuZ2VkVG9waWNzIH1cbiAgfVxuXG4gIGNvbnN0IGdldE1vZHVsZVN0YXRlID0gKG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleSk6IHVua25vd24gPT4gbW9kdWxlU3RhdGVzLmdldChtb2R1bGVJbnN0YW5jZUtleSlcblxuICBjb25zdCBkaXNwb3NlID0gKCk6IHZvaWQgPT4ge1xuICAgIG1vZHVsZVN0YXRlcy5jbGVhcigpXG4gICAgdG9waWNWZXJzaW9ucy5jbGVhcigpXG4gICAgdG9waWNQcmlvcml0aWVzLmNsZWFyKClcbiAgICBsaXN0ZW5lcnNCeVRvcGljLmNsZWFyKClcbiAgICBzdWJzY3JpYmVyQ291bnRCeU1vZHVsZS5jbGVhcigpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGdldFRpY2tTZXE6ICgpID0+IHRpY2tTZXEsXG4gICAgZ2V0TW9kdWxlU3RhdGUsXG4gICAgZ2V0VG9waWNWZXJzaW9uLFxuICAgIGdldFRvcGljUHJpb3JpdHksXG4gICAgc3Vic2NyaWJlVG9waWMsXG4gICAgZ2V0VG9waWNTdWJzY3JpYmVyQ291bnQsXG4gICAgZ2V0TW9kdWxlU3Vic2NyaWJlckNvdW50LFxuICAgIHJlZ2lzdGVyTW9kdWxlSW5zdGFuY2UsXG4gICAgdW5yZWdpc3Rlck1vZHVsZUluc3RhbmNlLFxuICAgIGNvbW1pdFRpY2ssXG4gICAgZGlzcG9zZSxcbiAgfVxufVxuIiwgImltcG9ydCB7IEVmZmVjdCB9IGZyb20gJ2VmZmVjdCdcbmltcG9ydCB0eXBlIHsgUmVhZFF1ZXJ5Q29tcGlsZWQgfSBmcm9tICcuL1JlYWRRdWVyeS5qcydcbmltcG9ydCB0eXBlIHsgRGVjbGFyYXRpdmVMaW5rSVIsIERlY2xhcmF0aXZlTGlua05vZGVJZCB9IGZyb20gJy4vRGVjbGFyYXRpdmVMaW5rSVIuanMnXG5pbXBvcnQgdHlwZSB7IE1vZHVsZUluc3RhbmNlS2V5LCBSdW50aW1lU3RvcmVNb2R1bGVDb21taXQgfSBmcm9tICcuL1J1bnRpbWVTdG9yZS5qcydcblxuZXhwb3J0IGludGVyZmFjZSBNb2R1bGVBc1NvdXJjZUxpbmsge1xuICByZWFkb25seSBpZDogc3RyaW5nXG4gIHJlYWRvbmx5IHNvdXJjZU1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleVxuICByZWFkb25seSByZWFkUXVlcnk6IFJlYWRRdWVyeUNvbXBpbGVkPGFueSwgYW55PlxuICByZWFkb25seSBjb21wdXRlVmFsdWU6IChzbmFwc2hvdDogdW5rbm93bikgPT4gdW5rbm93blxuICByZWFkb25seSBlcXVhbHNWYWx1ZTogKGE6IHVua25vd24sIGI6IHVua25vd24pID0+IGJvb2xlYW5cbiAgcmVhZG9ubHkgYXBwbHlWYWx1ZTogKG5leHQ6IHVua25vd24pID0+IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIG5ldmVyPlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlY2xhcmF0aXZlTGlua1JlZ2lzdHJhdGlvbiB7XG4gIHJlYWRvbmx5IGxpbmtJZDogc3RyaW5nXG4gIHJlYWRvbmx5IGlyOiBEZWNsYXJhdGl2ZUxpbmtJUlxuICByZWFkb25seSByZWFkTm9kZXM6IFJlYWRvbmx5QXJyYXk8e1xuICAgIHJlYWRvbmx5IG5vZGVJZDogRGVjbGFyYXRpdmVMaW5rTm9kZUlkXG4gICAgcmVhZG9ubHkgbW9kdWxlSW5zdGFuY2VLZXk6IE1vZHVsZUluc3RhbmNlS2V5XG4gICAgcmVhZG9ubHkgcmVhZFF1ZXJ5OiBSZWFkUXVlcnlDb21waWxlZDxhbnksIGFueT5cbiAgfT5cbiAgcmVhZG9ubHkgZGlzcGF0Y2hOb2RlczogUmVhZG9ubHlBcnJheTx7XG4gICAgcmVhZG9ubHkgbm9kZUlkOiBEZWNsYXJhdGl2ZUxpbmtOb2RlSWRcbiAgICByZWFkb25seSBkaXNwYXRjaDogKHBheWxvYWQ6IHVua25vd24pID0+IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIG5ldmVyPlxuICB9PlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlY2xhcmF0aXZlTGlua1J1bnRpbWUge1xuICByZWFkb25seSByZWdpc3Rlck1vZHVsZUFzU291cmNlTGluazogKGxpbms6IE1vZHVsZUFzU291cmNlTGluaykgPT4gKCkgPT4gdm9pZFxuICByZWFkb25seSByZWdpc3RlckRlY2xhcmF0aXZlTGluazogKGxpbms6IERlY2xhcmF0aXZlTGlua1JlZ2lzdHJhdGlvbikgPT4gKCkgPT4gdm9pZFxuICByZWFkb25seSBhcHBseUZvclNvdXJjZXM6IChhcmdzOiB7XG4gICAgcmVhZG9ubHkgdGlja1NlcTogbnVtYmVyXG4gICAgcmVhZG9ubHkgYWNjZXB0ZWRNb2R1bGVzOiBSZWFkb25seU1hcDxNb2R1bGVJbnN0YW5jZUtleSwgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0PlxuICAgIHJlYWRvbmx5IGNoYW5nZWRNb2R1bGVJbnN0YW5jZUtleXM6IFJlYWRvbmx5QXJyYXk8TW9kdWxlSW5zdGFuY2VLZXk+XG4gIH0pID0+IEVmZmVjdC5FZmZlY3Q8eyByZWFkb25seSBzY2hlZHVsZWQ6IGJvb2xlYW4gfSwgbmV2ZXIsIG5ldmVyPlxufVxuXG50eXBlIFN0b3JlZE1vZHVsZUFzU291cmNlTGluayA9IE1vZHVsZUFzU291cmNlTGluayAmIHtcbiAgaGFzVmFsdWU6IGJvb2xlYW5cbiAgbGFzdFZhbHVlOiB1bmtub3duXG59XG5cbnR5cGUgU3RvcmVkRGVjbGFyYXRpdmVMaW5rID0gRGVjbGFyYXRpdmVMaW5rUmVnaXN0cmF0aW9uICYge1xuICByZWFkb25seSByZWFkTm9kZUJ5SWQ6IFJlYWRvbmx5TWFwPHN0cmluZywgeyByZWFkb25seSBub2RlSWQ6IERlY2xhcmF0aXZlTGlua05vZGVJZDsgcmVhZG9ubHkgbW9kdWxlSW5zdGFuY2VLZXk6IE1vZHVsZUluc3RhbmNlS2V5OyByZWFkb25seSByZWFkUXVlcnk6IFJlYWRRdWVyeUNvbXBpbGVkPGFueSwgYW55PiB9PlxuICByZWFkb25seSBkaXNwYXRjaE5vZGVCeUlkOiBSZWFkb25seU1hcDxzdHJpbmcsIHsgcmVhZG9ubHkgbm9kZUlkOiBEZWNsYXJhdGl2ZUxpbmtOb2RlSWQ7IHJlYWRvbmx5IGRpc3BhdGNoOiAocGF5bG9hZDogdW5rbm93bikgPT4gRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgbmV2ZXI+IH0+XG4gIHJlYWRvbmx5IGRpc3BhdGNoVGFyZ2V0c0J5UmVhZE5vZGU6IFJlYWRvbmx5TWFwPHN0cmluZywgUmVhZG9ubHlBcnJheTxEZWNsYXJhdGl2ZUxpbmtOb2RlSWQ+PlxuICByZWFkb25seSByZWFkTm9kZVN0YXRlOiBNYXA8c3RyaW5nLCB7IGhhc1ZhbHVlOiBib29sZWFuOyBsYXN0VmFsdWU6IHVua25vd24gfT5cbn1cblxuZXhwb3J0IGNvbnN0IG1ha2VEZWNsYXJhdGl2ZUxpbmtSdW50aW1lID0gKCk6IERlY2xhcmF0aXZlTGlua1J1bnRpbWUgPT4ge1xuICBjb25zdCBtb2R1bGVBc1NvdXJjZUJ5SWQgPSBuZXcgTWFwPHN0cmluZywgU3RvcmVkTW9kdWxlQXNTb3VyY2VMaW5rPigpXG4gIGNvbnN0IG1vZHVsZUFzU291cmNlSWRzQnlTb3VyY2UgPSBuZXcgTWFwPE1vZHVsZUluc3RhbmNlS2V5LCBTZXQ8c3RyaW5nPj4oKVxuXG4gIGNvbnN0IGRlY2xhcmF0aXZlQnlJZCA9IG5ldyBNYXA8c3RyaW5nLCBTdG9yZWREZWNsYXJhdGl2ZUxpbms+KClcbiAgY29uc3QgZGVjbGFyYXRpdmVSZWFkTm9kZXNCeVNvdXJjZSA9IG5ldyBNYXA8TW9kdWxlSW5zdGFuY2VLZXksIEFycmF5PHsgcmVhZG9ubHkgbGlua0lkOiBzdHJpbmc7IHJlYWRvbmx5IG5vZGVJZDogRGVjbGFyYXRpdmVMaW5rTm9kZUlkIH0+PigpXG5cbiAgY29uc3QgcmVnaXN0ZXJNb2R1bGVBc1NvdXJjZUxpbms6IERlY2xhcmF0aXZlTGlua1J1bnRpbWVbJ3JlZ2lzdGVyTW9kdWxlQXNTb3VyY2VMaW5rJ10gPSAobGluaykgPT4ge1xuICAgIGNvbnN0IHN0b3JlZDogU3RvcmVkTW9kdWxlQXNTb3VyY2VMaW5rID0ge1xuICAgICAgLi4ubGluayxcbiAgICAgIGhhc1ZhbHVlOiBmYWxzZSxcbiAgICAgIGxhc3RWYWx1ZTogdW5kZWZpbmVkLFxuICAgIH1cblxuICAgIG1vZHVsZUFzU291cmNlQnlJZC5zZXQobGluay5pZCwgc3RvcmVkKVxuICAgIGNvbnN0IHNldCA9IG1vZHVsZUFzU291cmNlSWRzQnlTb3VyY2UuZ2V0KGxpbmsuc291cmNlTW9kdWxlSW5zdGFuY2VLZXkpID8/IG5ldyBTZXQ8c3RyaW5nPigpXG4gICAgc2V0LmFkZChsaW5rLmlkKVxuICAgIG1vZHVsZUFzU291cmNlSWRzQnlTb3VyY2Uuc2V0KGxpbmsuc291cmNlTW9kdWxlSW5zdGFuY2VLZXksIHNldClcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBtb2R1bGVBc1NvdXJjZUJ5SWQuZGVsZXRlKGxpbmsuaWQpXG4gICAgICBjb25zdCBjdXJyZW50ID0gbW9kdWxlQXNTb3VyY2VJZHNCeVNvdXJjZS5nZXQobGluay5zb3VyY2VNb2R1bGVJbnN0YW5jZUtleSlcbiAgICAgIGlmICghY3VycmVudCkgcmV0dXJuXG4gICAgICBjdXJyZW50LmRlbGV0ZShsaW5rLmlkKVxuICAgICAgaWYgKGN1cnJlbnQuc2l6ZSA9PT0gMCkge1xuICAgICAgICBtb2R1bGVBc1NvdXJjZUlkc0J5U291cmNlLmRlbGV0ZShsaW5rLnNvdXJjZU1vZHVsZUluc3RhbmNlS2V5KVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJlZ2lzdGVyRGVjbGFyYXRpdmVMaW5rOiBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lWydyZWdpc3RlckRlY2xhcmF0aXZlTGluayddID0gKGxpbmspID0+IHtcbiAgICBjb25zdCByZWFkTm9kZUJ5SWQgPSBuZXcgTWFwPHN0cmluZywgeyByZWFkb25seSBub2RlSWQ6IERlY2xhcmF0aXZlTGlua05vZGVJZDsgcmVhZG9ubHkgbW9kdWxlSW5zdGFuY2VLZXk6IE1vZHVsZUluc3RhbmNlS2V5OyByZWFkb25seSByZWFkUXVlcnk6IFJlYWRRdWVyeUNvbXBpbGVkPGFueSwgYW55PiB9PigpXG4gICAgZm9yIChjb25zdCBuIG9mIGxpbmsucmVhZE5vZGVzKSB7XG4gICAgICByZWFkTm9kZUJ5SWQuc2V0KG4ubm9kZUlkLCBuKVxuICAgIH1cblxuICAgIGNvbnN0IGRpc3BhdGNoTm9kZUJ5SWQgPSBuZXcgTWFwPFxuICAgICAgc3RyaW5nLFxuICAgICAgeyByZWFkb25seSBub2RlSWQ6IERlY2xhcmF0aXZlTGlua05vZGVJZDsgcmVhZG9ubHkgZGlzcGF0Y2g6IChwYXlsb2FkOiB1bmtub3duKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBuZXZlcj4gfVxuICAgID4oKVxuICAgIGZvciAoY29uc3QgbiBvZiBsaW5rLmRpc3BhdGNoTm9kZXMpIHtcbiAgICAgIGRpc3BhdGNoTm9kZUJ5SWQuc2V0KG4ubm9kZUlkLCBuKVxuICAgIH1cblxuICAgIC8vIFYxIGNvbnN0cmFpbnQ6IGRpc3BhdGNoIG11c3QgaGF2ZSBhdCBtb3N0IG9uZSBpbmNvbWluZyBlZGdlLCBpbnRlcnByZXRlZCBhcyBcInBheWxvYWQgZmxvd1wiLlxuICAgIGNvbnN0IGluY29taW5nQnlEaXNwYXRjaCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KClcbiAgICBmb3IgKGNvbnN0IGUgb2YgbGluay5pci5lZGdlcykge1xuICAgICAgY29uc3QgdG8gPSBlLnRvXG4gICAgICBjb25zdCBpc0Rpc3BhdGNoID0gZGlzcGF0Y2hOb2RlQnlJZC5oYXModG8pXG4gICAgICBpZiAoIWlzRGlzcGF0Y2gpIGNvbnRpbnVlXG4gICAgICBpbmNvbWluZ0J5RGlzcGF0Y2guc2V0KHRvLCAoaW5jb21pbmdCeURpc3BhdGNoLmdldCh0bykgPz8gMCkgKyAxKVxuICAgICAgY29uc3QgY291bnQgPSBpbmNvbWluZ0J5RGlzcGF0Y2guZ2V0KHRvKSA/PyAwXG4gICAgICBpZiAoY291bnQgPiAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgW0RlY2xhcmF0aXZlTGlua1J1bnRpbWVdIEludmFsaWQgRGVjbGFyYXRpdmVMaW5rSVI6IGRpc3BhdGNoIG5vZGUgaGFzIG11bHRpcGxlIGluY29taW5nIGVkZ2VzIChsaW5rSWQ9JHtsaW5rLmxpbmtJZH0sIG5vZGVJZD0ke3RvfSkuYCxcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGRpc3BhdGNoVGFyZ2V0c0J5UmVhZE5vZGUgPSBuZXcgTWFwPHN0cmluZywgQXJyYXk8RGVjbGFyYXRpdmVMaW5rTm9kZUlkPj4oKVxuICAgIGZvciAoY29uc3QgZSBvZiBsaW5rLmlyLmVkZ2VzKSB7XG4gICAgICBjb25zdCBmcm9tID0gZS5mcm9tXG4gICAgICBjb25zdCB0byA9IGUudG9cbiAgICAgIGlmICghcmVhZE5vZGVCeUlkLmhhcyhmcm9tKSkgY29udGludWVcbiAgICAgIGlmICghZGlzcGF0Y2hOb2RlQnlJZC5oYXModG8pKSBjb250aW51ZVxuICAgICAgY29uc3QgbGlzdCA9IGRpc3BhdGNoVGFyZ2V0c0J5UmVhZE5vZGUuZ2V0KGZyb20pID8/IFtdXG4gICAgICBsaXN0LnB1c2godG8pXG4gICAgICBkaXNwYXRjaFRhcmdldHNCeVJlYWROb2RlLnNldChmcm9tLCBsaXN0KVxuICAgIH1cblxuICAgIGNvbnN0IHN0b3JlZDogU3RvcmVkRGVjbGFyYXRpdmVMaW5rID0ge1xuICAgICAgLi4ubGluayxcbiAgICAgIHJlYWROb2RlQnlJZCxcbiAgICAgIGRpc3BhdGNoTm9kZUJ5SWQsXG4gICAgICBkaXNwYXRjaFRhcmdldHNCeVJlYWROb2RlLFxuICAgICAgcmVhZE5vZGVTdGF0ZTogbmV3IE1hcCgpLFxuICAgIH1cblxuICAgIGRlY2xhcmF0aXZlQnlJZC5zZXQobGluay5saW5rSWQsIHN0b3JlZClcblxuICAgIGZvciAoY29uc3QgbiBvZiBsaW5rLnJlYWROb2Rlcykge1xuICAgICAgY29uc3QgbGlzdCA9IGRlY2xhcmF0aXZlUmVhZE5vZGVzQnlTb3VyY2UuZ2V0KG4ubW9kdWxlSW5zdGFuY2VLZXkpID8/IFtdXG4gICAgICBsaXN0LnB1c2goeyBsaW5rSWQ6IGxpbmsubGlua0lkLCBub2RlSWQ6IG4ubm9kZUlkIH0pXG4gICAgICBkZWNsYXJhdGl2ZVJlYWROb2Rlc0J5U291cmNlLnNldChuLm1vZHVsZUluc3RhbmNlS2V5LCBsaXN0KVxuICAgIH1cblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkZWNsYXJhdGl2ZUJ5SWQuZGVsZXRlKGxpbmsubGlua0lkKVxuICAgICAgZm9yIChjb25zdCBuIG9mIGxpbmsucmVhZE5vZGVzKSB7XG4gICAgICAgIGNvbnN0IGxpc3QgPSBkZWNsYXJhdGl2ZVJlYWROb2Rlc0J5U291cmNlLmdldChuLm1vZHVsZUluc3RhbmNlS2V5KVxuICAgICAgICBpZiAoIWxpc3QpIGNvbnRpbnVlXG4gICAgICAgIGNvbnN0IG5leHQgPSBsaXN0LmZpbHRlcigoeCkgPT4gISh4LmxpbmtJZCA9PT0gbGluay5saW5rSWQgJiYgeC5ub2RlSWQgPT09IG4ubm9kZUlkKSlcbiAgICAgICAgaWYgKG5leHQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgZGVjbGFyYXRpdmVSZWFkTm9kZXNCeVNvdXJjZS5kZWxldGUobi5tb2R1bGVJbnN0YW5jZUtleSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZWNsYXJhdGl2ZVJlYWROb2Rlc0J5U291cmNlLnNldChuLm1vZHVsZUluc3RhbmNlS2V5LCBuZXh0KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgYXBwbHlGb3JTb3VyY2VzOiBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lWydhcHBseUZvclNvdXJjZXMnXSA9IChhcmdzKSA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGxldCBzY2hlZHVsZWQgPSBmYWxzZVxuXG4gICAgICAvLyAtLS0tIE1vZHVsZS1hcy1Tb3VyY2UgZWRnZXMgKG1vZHVsZSByZWFkUXVlcnkgLT4gZXh0ZXJuYWxTdG9yZSB0cmFpdCB3cml0ZWJhY2spIC0tLS1cbiAgICAgIGZvciAoY29uc3Qgc291cmNlS2V5IG9mIGFyZ3MuY2hhbmdlZE1vZHVsZUluc3RhbmNlS2V5cykge1xuICAgICAgICBjb25zdCBpZHMgPSBtb2R1bGVBc1NvdXJjZUlkc0J5U291cmNlLmdldChzb3VyY2VLZXkpXG4gICAgICAgIGlmICghaWRzIHx8IGlkcy5zaXplID09PSAwKSBjb250aW51ZVxuICAgICAgICBjb25zdCBjb21taXQgPSBhcmdzLmFjY2VwdGVkTW9kdWxlcy5nZXQoc291cmNlS2V5KVxuICAgICAgICBpZiAoIWNvbW1pdCkgY29udGludWVcblxuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIGlkcykge1xuICAgICAgICAgIGNvbnN0IGxpbmsgPSBtb2R1bGVBc1NvdXJjZUJ5SWQuZ2V0KGlkKVxuICAgICAgICAgIGlmICghbGluaykgY29udGludWVcblxuICAgICAgICAgIGxldCBzZWxlY3RlZDogdW5rbm93blxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzZWxlY3RlZCA9IGxpbmsucmVhZFF1ZXJ5LnNlbGVjdChjb21taXQuc3RhdGUgYXMgYW55KVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBuZXh0VmFsdWUgPSBsaW5rLmNvbXB1dGVWYWx1ZShzZWxlY3RlZClcbiAgICAgICAgICBpZiAobGluay5oYXNWYWx1ZSAmJiBsaW5rLmVxdWFsc1ZhbHVlKGxpbmsubGFzdFZhbHVlLCBuZXh0VmFsdWUpKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGxpbmsuaGFzVmFsdWUgPSB0cnVlXG4gICAgICAgICAgbGluay5sYXN0VmFsdWUgPSBuZXh0VmFsdWVcbiAgICAgICAgICBzY2hlZHVsZWQgPSB0cnVlXG4gICAgICAgICAgeWllbGQqIGxpbmsuYXBwbHlWYWx1ZShuZXh0VmFsdWUpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gLS0tLSBEZWNsYXJhdGl2ZUxpbmtJUiBlZGdlcyAobW9kdWxlIHJlYWRRdWVyeSAtPiBkaXNwYXRjaCkgLS0tLVxuICAgICAgZm9yIChjb25zdCBzb3VyY2VLZXkgb2YgYXJncy5jaGFuZ2VkTW9kdWxlSW5zdGFuY2VLZXlzKSB7XG4gICAgICAgIGNvbnN0IHJlZnMgPSBkZWNsYXJhdGl2ZVJlYWROb2Rlc0J5U291cmNlLmdldChzb3VyY2VLZXkpXG4gICAgICAgIGlmICghcmVmcyB8fCByZWZzLmxlbmd0aCA9PT0gMCkgY29udGludWVcbiAgICAgICAgY29uc3QgY29tbWl0ID0gYXJncy5hY2NlcHRlZE1vZHVsZXMuZ2V0KHNvdXJjZUtleSlcbiAgICAgICAgaWYgKCFjb21taXQpIGNvbnRpbnVlXG5cbiAgICAgICAgZm9yIChjb25zdCByZWYgb2YgcmVmcykge1xuICAgICAgICAgIGNvbnN0IGxpbmsgPSBkZWNsYXJhdGl2ZUJ5SWQuZ2V0KHJlZi5saW5rSWQpXG4gICAgICAgICAgaWYgKCFsaW5rKSBjb250aW51ZVxuICAgICAgICAgIGNvbnN0IHJlYWROb2RlID0gbGluay5yZWFkTm9kZUJ5SWQuZ2V0KHJlZi5ub2RlSWQpXG4gICAgICAgICAgaWYgKCFyZWFkTm9kZSkgY29udGludWVcblxuICAgICAgICAgIGxldCB2YWx1ZTogdW5rbm93blxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHJlYWROb2RlLnJlYWRRdWVyeS5zZWxlY3QoY29tbWl0LnN0YXRlIGFzIGFueSlcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgc3RhdGUgPSBsaW5rLnJlYWROb2RlU3RhdGUuZ2V0KHJlZi5ub2RlSWQpID8/IHsgaGFzVmFsdWU6IGZhbHNlLCBsYXN0VmFsdWU6IHVuZGVmaW5lZCB9XG4gICAgICAgICAgY29uc3QgY2hhbmdlZCA9ICFzdGF0ZS5oYXNWYWx1ZSB8fCAhT2JqZWN0LmlzKHN0YXRlLmxhc3RWYWx1ZSwgdmFsdWUpXG4gICAgICAgICAgaWYgKCFjaGFuZ2VkKSBjb250aW51ZVxuXG4gICAgICAgICAgc3RhdGUuaGFzVmFsdWUgPSB0cnVlXG4gICAgICAgICAgc3RhdGUubGFzdFZhbHVlID0gdmFsdWVcbiAgICAgICAgICBsaW5rLnJlYWROb2RlU3RhdGUuc2V0KHJlZi5ub2RlSWQsIHN0YXRlKVxuXG4gICAgICAgICAgY29uc3QgdGFyZ2V0cyA9IGxpbmsuZGlzcGF0Y2hUYXJnZXRzQnlSZWFkTm9kZS5nZXQocmVmLm5vZGVJZCkgPz8gW11cbiAgICAgICAgICBmb3IgKGNvbnN0IGRpc3BhdGNoTm9kZUlkIG9mIHRhcmdldHMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBsaW5rLmRpc3BhdGNoTm9kZUJ5SWQuZ2V0KGRpc3BhdGNoTm9kZUlkKVxuICAgICAgICAgICAgaWYgKCFub2RlKSBjb250aW51ZVxuICAgICAgICAgICAgc2NoZWR1bGVkID0gdHJ1ZVxuICAgICAgICAgICAgeWllbGQqIG5vZGUuZGlzcGF0Y2godmFsdWUpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHNjaGVkdWxlZCB9IGFzIGNvbnN0XG4gICAgfSlcblxuICByZXR1cm4ge1xuICAgIHJlZ2lzdGVyTW9kdWxlQXNTb3VyY2VMaW5rLFxuICAgIHJlZ2lzdGVyRGVjbGFyYXRpdmVMaW5rLFxuICAgIGFwcGx5Rm9yU291cmNlcyxcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjog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O0FBQUEsTUFFUjtBQUFBLElBQ0Y7QUFDQSx1QkFBbUI7QUFDbkIsc0JBQWtCO0FBRWxCLFdBQU8sRUFBRSxRQUFRLFNBQVMsUUFBUSxlQUFlLFNBQVMsY0FBYztBQUFBLEVBQzFFLENBQUM7QUFFRCxRQUFNLFdBQXNDLFVBQVUsRUFBRSxXQUFXLFVBQVUsQ0FBQyxFQUFFLEtBQUtILFFBQU8sTUFBTTtBQUVsRyxRQUFNLGdDQUFnQyxDQUFDLGFBQW9EO0FBQ3pGLFVBQU0sTUFBTSxTQUFTLFFBQVEsT0FBTztBQUNwQyxRQUFJLE1BQU0sR0FBRztBQUNYLGFBQU8sU0FBUyxNQUFNLEdBQUcsR0FBRztBQUFBLElBQzlCO0FBQ0EsUUFBSSxTQUFTLFNBQVMsSUFBSSxHQUFHO0FBQzNCLGFBQU87QUFBQSxJQUNUO0FBQ0EsV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLG9CQUF3RCxDQUFDLEVBQUUsbUJBQW1CLFlBQVksU0FBUyxNQUFNO0FBQzdHLFVBQU0sWUFBWSxNQUFNLGVBQWUsc0JBQXNCLG1CQUFtQixVQUFVLEdBQUcsUUFBUTtBQUNyRyxRQUFJLFVBQVcsb0JBQW1CO0FBQUEsRUFDcEM7QUFFQSxRQUFNLGlCQUFrRCxDQUFDLFdBQ3ZEQSxRQUFPLElBQUksYUFBYTtBQUN0QixVQUFNLGtCQUFrQixNQUFNLG9CQUFvQixNQUFNO0FBQ3hELFFBQUksZ0JBQWlCLHFCQUFvQjtBQUN6QyxVQUFNLGlCQUFpQixNQUFNLGVBQWUsT0FBTyxtQkFBbUIsT0FBTyxLQUFLLFFBQVE7QUFDMUYsUUFBSSxlQUFnQixvQkFBbUI7QUFDdkMsV0FBTyxhQUFhO0FBQUEsRUFDdEIsQ0FBQztBQUVILFNBQU87QUFBQSxJQUNMLFlBQVksTUFBTTtBQUFBLElBQ2xCO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7IiwKICAibmFtZXMiOiBbIkVmZmVjdCIsICJGaWJlclJlZiIsICJkcmFpbiIsICJFZmZlY3QiLCAiRmliZXJSZWYiLCAiRWZmZWN0IiwgImxpc3RlbmVycyIsICJFZmZlY3QiLCAiRWZmZWN0IiwgIkVmZmVjdCIsICJGaWJlclJlZiIsICJFZmZlY3QiLCAiRWZmZWN0IiwgIm1heFByaW9yaXR5IiwgIkZpYmVyUmVmIiwgImxpc3RlbmVycyJdCn0K
|