@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,819 @@
|
|
|
1
|
+
// @logixjs/core subpath bundles for @logixjs/sandbox
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
compileWorkflowRuntimeStepsV1,
|
|
5
|
+
evalInputExpr,
|
|
6
|
+
makeWorkflowError
|
|
7
|
+
} from "./chunk-UZZBHWIO.js";
|
|
8
|
+
import {
|
|
9
|
+
attachLogicUnitMeta,
|
|
10
|
+
currentTxnOriginOverride
|
|
11
|
+
} from "./chunk-BJOWSSEL.js";
|
|
12
|
+
import {
|
|
13
|
+
RootContextTag
|
|
14
|
+
} from "./chunk-UBMUY7WO.js";
|
|
15
|
+
import {
|
|
16
|
+
getRuntimeInternals
|
|
17
|
+
} from "./chunk-7GPAF2UK.js";
|
|
18
|
+
import {
|
|
19
|
+
HostSchedulerTag,
|
|
20
|
+
TickSchedulerTag,
|
|
21
|
+
forceSourceRefresh,
|
|
22
|
+
inSyncTransactionFiber
|
|
23
|
+
} from "./chunk-YMVMZA3U.js";
|
|
24
|
+
import {
|
|
25
|
+
makeInRunSession,
|
|
26
|
+
run
|
|
27
|
+
} from "./chunk-W365QUZ5.js";
|
|
28
|
+
import {
|
|
29
|
+
currentDiagnosticsLevel,
|
|
30
|
+
record,
|
|
31
|
+
toSerializableErrorSummary
|
|
32
|
+
} from "./chunk-SH7TP5CJ.js";
|
|
33
|
+
import {
|
|
34
|
+
EffectOpMiddlewareTag
|
|
35
|
+
} from "./chunk-SI5OKFFY.js";
|
|
36
|
+
|
|
37
|
+
// ../logix-core/src/internal/runtime/core/WorkflowRuntime.ts
|
|
38
|
+
import { Cause, Context, Deferred, Effect, Exit, Fiber, FiberRef, Option, Stream } from "../effect.js";
|
|
39
|
+
var WORKFLOW_REGISTRY = /* @__PURE__ */ Symbol.for("@logixjs/core/workflowRegistry");
|
|
40
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41
|
+
var isObjectLike = (value) => typeof value === "object" && value !== null || typeof value === "function";
|
|
42
|
+
var getRegistry = (runtime) => runtime[WORKFLOW_REGISTRY];
|
|
43
|
+
var resolveActionTag = (action) => {
|
|
44
|
+
const tag = isObjectLike(action) ? action._tag : void 0;
|
|
45
|
+
if (typeof tag === "string" && tag.length > 0) return tag;
|
|
46
|
+
const type = isObjectLike(action) ? action.type : void 0;
|
|
47
|
+
if (typeof type === "string" && type.length > 0) return type;
|
|
48
|
+
if (tag != null) return String(tag);
|
|
49
|
+
if (type != null) return String(type);
|
|
50
|
+
return void 0;
|
|
51
|
+
};
|
|
52
|
+
var asNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
53
|
+
var KERNEL_PORT_SOURCE_REFRESH = "logix/kernel/sourceRefresh";
|
|
54
|
+
var resolveServicePort = (runtime, env, serviceId, programId, stepKey) => {
|
|
55
|
+
if (serviceId === KERNEL_PORT_SOURCE_REFRESH) {
|
|
56
|
+
return (input) => Effect.gen(function* () {
|
|
57
|
+
const fieldPath = asNonEmptyString(isRecord(input) ? input.fieldPath : void 0);
|
|
58
|
+
if (!fieldPath) {
|
|
59
|
+
throw makeWorkflowError({
|
|
60
|
+
code: "WORKFLOW_INVALID_STEP",
|
|
61
|
+
message: "KernelPort sourceRefresh requires input.fieldPath (non-empty string).",
|
|
62
|
+
programId,
|
|
63
|
+
source: { stepKey },
|
|
64
|
+
detail: { serviceId, input }
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const internals = getRuntimeInternals(runtime);
|
|
68
|
+
const handler = internals.traits.getSourceRefreshHandler(fieldPath);
|
|
69
|
+
if (!handler) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const force = isRecord(input) && input.force === true;
|
|
73
|
+
const runHandler = (state) => force ? Effect.locally(forceSourceRefresh, true)(handler(state)) : handler(state);
|
|
74
|
+
const inTxn = yield* FiberRef.get(inSyncTransactionFiber);
|
|
75
|
+
if (inTxn) {
|
|
76
|
+
const state = yield* runtime.getState;
|
|
77
|
+
yield* runHandler(state);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
yield* internals.txn.runWithStateTransaction(
|
|
81
|
+
{
|
|
82
|
+
kind: "source-refresh",
|
|
83
|
+
name: fieldPath
|
|
84
|
+
},
|
|
85
|
+
() => Effect.gen(function* () {
|
|
86
|
+
const state = yield* runtime.getState;
|
|
87
|
+
yield* runHandler(state);
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const tag = Context.GenericTag(serviceId);
|
|
93
|
+
const opt = Context.getOption(env, tag);
|
|
94
|
+
if (Option.isNone(opt)) {
|
|
95
|
+
throw makeWorkflowError({
|
|
96
|
+
code: "WORKFLOW_MISSING_SERVICE",
|
|
97
|
+
message: `Missing service for serviceId="${serviceId}".`,
|
|
98
|
+
programId,
|
|
99
|
+
source: { stepKey },
|
|
100
|
+
detail: { serviceId }
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const value = opt.value;
|
|
104
|
+
if (typeof value === "function") {
|
|
105
|
+
const fn = value;
|
|
106
|
+
return (input) => fn(input);
|
|
107
|
+
}
|
|
108
|
+
const callFn = isObjectLike(value) ? value.call : void 0;
|
|
109
|
+
if (typeof callFn === "function") {
|
|
110
|
+
const call = callFn;
|
|
111
|
+
return (input) => call.call(value, input);
|
|
112
|
+
}
|
|
113
|
+
throw makeWorkflowError({
|
|
114
|
+
code: "WORKFLOW_INVALID_SERVICE_PORT",
|
|
115
|
+
message: `Invalid service port for serviceId="${serviceId}" (expected a function or { call(input): Effect }).`,
|
|
116
|
+
programId,
|
|
117
|
+
source: { stepKey },
|
|
118
|
+
detail: { serviceId, portType: typeof value }
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
var compileSteps = (steps, resolvePort) => {
|
|
122
|
+
const visit = (step) => {
|
|
123
|
+
switch (step.kind) {
|
|
124
|
+
case "dispatch":
|
|
125
|
+
return {
|
|
126
|
+
kind: "dispatch",
|
|
127
|
+
key: step.key,
|
|
128
|
+
actionTag: step.actionTag,
|
|
129
|
+
...step.payload ? { payload: step.payload } : null
|
|
130
|
+
};
|
|
131
|
+
case "delay":
|
|
132
|
+
return { kind: "delay", key: step.key, ms: step.ms };
|
|
133
|
+
case "call":
|
|
134
|
+
return {
|
|
135
|
+
kind: "call",
|
|
136
|
+
key: step.key,
|
|
137
|
+
serviceId: step.serviceId,
|
|
138
|
+
port: resolvePort(step.serviceId, step.key),
|
|
139
|
+
...step.input ? { input: step.input } : null,
|
|
140
|
+
...step.timeoutMs !== void 0 ? { timeoutMs: step.timeoutMs } : null,
|
|
141
|
+
...step.retryTimes !== void 0 ? { retryTimes: step.retryTimes } : null,
|
|
142
|
+
onSuccess: step.onSuccess.map(visit),
|
|
143
|
+
onFailure: step.onFailure.map(visit)
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
return steps.map(visit);
|
|
148
|
+
};
|
|
149
|
+
var resolveConcurrency = (def) => def.policy?.concurrency ?? "parallel";
|
|
150
|
+
var resolvePriority = (def) => def.policy?.priority ?? "urgent";
|
|
151
|
+
var makeRunId = (instanceId, programId, runSeq) => `${instanceId}::wf:${programId}::r${runSeq}`;
|
|
152
|
+
var runBoundary = (args) => Effect.gen(function* () {
|
|
153
|
+
const op = yield* makeInRunSession({
|
|
154
|
+
kind: args.kind,
|
|
155
|
+
name: args.name,
|
|
156
|
+
effect: args.effect,
|
|
157
|
+
payload: args.payload,
|
|
158
|
+
meta: args.meta
|
|
159
|
+
});
|
|
160
|
+
const stack = args.middleware?.stack ?? [];
|
|
161
|
+
return yield* run(op, stack);
|
|
162
|
+
});
|
|
163
|
+
var makeTimer = (args) => Effect.async((resume) => {
|
|
164
|
+
let fired = false;
|
|
165
|
+
const cancel = args.host.scheduleTimeout(args.ms, () => {
|
|
166
|
+
fired = true;
|
|
167
|
+
args.host.scheduleMicrotask(() => resume(Effect.void));
|
|
168
|
+
});
|
|
169
|
+
return Effect.sync(() => {
|
|
170
|
+
cancel();
|
|
171
|
+
}).pipe(Effect.zipRight(fired ? Effect.void : args.onCancel));
|
|
172
|
+
});
|
|
173
|
+
var ensureLimiterReady = (registry, runtime) => Effect.gen(function* () {
|
|
174
|
+
if (registry.parallelLimiter !== void 0) return;
|
|
175
|
+
const internals = getRuntimeInternals(runtime);
|
|
176
|
+
const policy = yield* internals.concurrency.resolveConcurrencyPolicy();
|
|
177
|
+
const limit = policy.concurrencyLimit;
|
|
178
|
+
if (limit === "unbounded") {
|
|
179
|
+
registry.parallelLimiter = null;
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const n = typeof limit === "number" && Number.isFinite(limit) && limit >= 1 ? Math.floor(limit) : 16;
|
|
183
|
+
registry.parallelLimiter = yield* Effect.makeSemaphore(n);
|
|
184
|
+
});
|
|
185
|
+
var withRootEnvIfAvailable = (eff) => Effect.gen(function* () {
|
|
186
|
+
const rootOpt = yield* Effect.serviceOption(RootContextTag);
|
|
187
|
+
if (Option.isNone(rootOpt)) {
|
|
188
|
+
return yield* eff;
|
|
189
|
+
}
|
|
190
|
+
const root = rootOpt.value;
|
|
191
|
+
const rootEnv = root.context ?? (yield* Deferred.await(root.ready));
|
|
192
|
+
const currentEnv = yield* Effect.context();
|
|
193
|
+
const mergedEnv = Context.merge(rootEnv, currentEnv);
|
|
194
|
+
return yield* Effect.provide(eff, mergedEnv);
|
|
195
|
+
});
|
|
196
|
+
var ensurePortsResolved = (registry, runtime) => Effect.gen(function* () {
|
|
197
|
+
const done = yield* Deferred.isDone(registry.portsReady);
|
|
198
|
+
if (done) {
|
|
199
|
+
yield* Deferred.await(registry.portsReady);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (registry.portsResolving) {
|
|
203
|
+
yield* Deferred.await(registry.portsReady);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
registry.portsResolving = true;
|
|
207
|
+
const env = yield* Effect.context();
|
|
208
|
+
yield* Effect.sync(() => {
|
|
209
|
+
const portCache = /* @__PURE__ */ new Map();
|
|
210
|
+
for (const entry of registry.entries) {
|
|
211
|
+
const program = entry.program;
|
|
212
|
+
if (program.steps) continue;
|
|
213
|
+
const resolvePort = (serviceId, stepKey) => {
|
|
214
|
+
const cached = portCache.get(serviceId);
|
|
215
|
+
if (cached) return cached;
|
|
216
|
+
const resolved = resolveServicePort(runtime, env, serviceId, program.programId, stepKey);
|
|
217
|
+
portCache.set(serviceId, resolved);
|
|
218
|
+
return resolved;
|
|
219
|
+
};
|
|
220
|
+
program.steps = compileSteps(program.compiledSteps, resolvePort);
|
|
221
|
+
}
|
|
222
|
+
}).pipe(
|
|
223
|
+
Effect.tap(() => Deferred.succeed(registry.portsReady, void 0)),
|
|
224
|
+
Effect.catchAllCause((cause) => Deferred.failCause(registry.portsReady, cause).pipe(Effect.zipRight(Effect.failCause(cause)))),
|
|
225
|
+
Effect.ensuring(
|
|
226
|
+
Effect.sync(() => {
|
|
227
|
+
registry.portsResolving = false;
|
|
228
|
+
})
|
|
229
|
+
)
|
|
230
|
+
);
|
|
231
|
+
});
|
|
232
|
+
var shouldObserveForRun = (diagnostics, runSeq) => {
|
|
233
|
+
if (diagnostics === "off") return false;
|
|
234
|
+
if (diagnostics === "sampled") {
|
|
235
|
+
return (runSeq & 15) === 0;
|
|
236
|
+
}
|
|
237
|
+
return true;
|
|
238
|
+
};
|
|
239
|
+
var startProgramRun = (args) => Effect.gen(function* () {
|
|
240
|
+
const { entry, runtime, registry } = args;
|
|
241
|
+
const { program, state } = entry;
|
|
242
|
+
const diagnostics = yield* FiberRef.get(currentDiagnosticsLevel);
|
|
243
|
+
const beginRun = () => {
|
|
244
|
+
if (state.mode === "latest") {
|
|
245
|
+
state.runSeq += 1;
|
|
246
|
+
const runSeq3 = state.runSeq;
|
|
247
|
+
const runId3 = makeRunId(runtime.instanceId, program.programId, runSeq3);
|
|
248
|
+
return {
|
|
249
|
+
runSeq: runSeq3,
|
|
250
|
+
runId: runId3,
|
|
251
|
+
canWriteBack: () => state.runSeq === runSeq3
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
state.runSeq += 1;
|
|
255
|
+
const runSeq2 = state.runSeq;
|
|
256
|
+
const runId2 = makeRunId(runtime.instanceId, program.programId, runSeq2);
|
|
257
|
+
return {
|
|
258
|
+
runSeq: runSeq2,
|
|
259
|
+
runId: runId2,
|
|
260
|
+
canWriteBack: () => true
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
if (state.mode === "exhaust") {
|
|
264
|
+
if (state.busy) {
|
|
265
|
+
if (diagnostics !== "off") {
|
|
266
|
+
const observe2 = shouldObserveForRun(diagnostics, state.runSeq);
|
|
267
|
+
const tickSeq = observe2 ? (yield* TickSchedulerTag).getTickSeq() : void 0;
|
|
268
|
+
yield* runBoundary({
|
|
269
|
+
kind: "flow",
|
|
270
|
+
name: "workflow.drop",
|
|
271
|
+
payload: { programId: program.programId, trigger: args.trigger },
|
|
272
|
+
meta: {
|
|
273
|
+
moduleId: runtime.moduleId,
|
|
274
|
+
instanceId: runtime.instanceId,
|
|
275
|
+
programId: program.programId,
|
|
276
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
277
|
+
policy: { disableObservers: !observe2 },
|
|
278
|
+
reason: "exhaust"
|
|
279
|
+
},
|
|
280
|
+
effect: Effect.void,
|
|
281
|
+
middleware: args.middleware
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
state.busy = true;
|
|
287
|
+
}
|
|
288
|
+
const { runSeq, runId, canWriteBack } = beginRun();
|
|
289
|
+
if (state.mode === "latest") {
|
|
290
|
+
const prev = state.current;
|
|
291
|
+
const prevRunId = state.currentRunId;
|
|
292
|
+
if (prev) {
|
|
293
|
+
yield* Fiber.interruptFork(prev);
|
|
294
|
+
if (diagnostics !== "off") {
|
|
295
|
+
const observe2 = shouldObserveForRun(diagnostics, runSeq);
|
|
296
|
+
const tickSeq = observe2 ? (yield* TickSchedulerTag).getTickSeq() : void 0;
|
|
297
|
+
yield* runBoundary({
|
|
298
|
+
kind: "flow",
|
|
299
|
+
name: "workflow.cancel",
|
|
300
|
+
payload: { programId: program.programId, cancelled: prevRunId, by: runId },
|
|
301
|
+
meta: {
|
|
302
|
+
moduleId: runtime.moduleId,
|
|
303
|
+
instanceId: runtime.instanceId,
|
|
304
|
+
programId: program.programId,
|
|
305
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
306
|
+
policy: { disableObservers: !observe2 },
|
|
307
|
+
reason: "latest",
|
|
308
|
+
cancelledByRunId: runId,
|
|
309
|
+
cancelledRunId: prevRunId
|
|
310
|
+
},
|
|
311
|
+
effect: Effect.void,
|
|
312
|
+
middleware: args.middleware
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
state.currentRunId = runId;
|
|
317
|
+
}
|
|
318
|
+
const observe = shouldObserveForRun(diagnostics, runSeq);
|
|
319
|
+
const policy = { disableObservers: !observe };
|
|
320
|
+
const programEffect = Effect.gen(function* () {
|
|
321
|
+
const host = yield* HostSchedulerTag;
|
|
322
|
+
const tick = yield* TickSchedulerTag;
|
|
323
|
+
if (!program.steps) {
|
|
324
|
+
const env = yield* Effect.context();
|
|
325
|
+
const portCache = /* @__PURE__ */ new Map();
|
|
326
|
+
const resolvePort = (serviceId, stepKey) => {
|
|
327
|
+
const cached = portCache.get(serviceId);
|
|
328
|
+
if (cached) return cached;
|
|
329
|
+
const resolved = resolveServicePort(runtime, env, serviceId, program.programId, stepKey);
|
|
330
|
+
portCache.set(serviceId, resolved);
|
|
331
|
+
return resolved;
|
|
332
|
+
};
|
|
333
|
+
program.steps = compileSteps(program.compiledSteps, resolvePort);
|
|
334
|
+
}
|
|
335
|
+
const getTickSeq = () => observe ? tick.getTickSeq() : void 0;
|
|
336
|
+
const emitTimerEvents = observe && diagnostics === "full";
|
|
337
|
+
const evalPayload = (expr) => expr ? evalInputExpr(expr, args.payload) : void 0;
|
|
338
|
+
const defaultInputForCall = () => args.trigger.kind === "action" ? args.payload : void 0;
|
|
339
|
+
let timerTriggered = false;
|
|
340
|
+
const runSteps = (steps) => Effect.gen(function* () {
|
|
341
|
+
for (const step of steps) {
|
|
342
|
+
if (!canWriteBack()) return;
|
|
343
|
+
if (step.kind === "dispatch") {
|
|
344
|
+
const payload = evalPayload(step.payload);
|
|
345
|
+
const action = { _tag: step.actionTag, payload };
|
|
346
|
+
const tickSeq = getTickSeq();
|
|
347
|
+
const dispatchEffectBase = program.priority === "nonUrgent" ? runtime.dispatchLowPriority(action) : runtime.dispatch(action);
|
|
348
|
+
const dispatchEffect = timerTriggered ? Effect.locally(
|
|
349
|
+
currentTxnOriginOverride,
|
|
350
|
+
{
|
|
351
|
+
kind: "workflow.timer",
|
|
352
|
+
name: `timer:${program.programId}:${step.key}`
|
|
353
|
+
}
|
|
354
|
+
)(dispatchEffectBase) : dispatchEffectBase;
|
|
355
|
+
yield* runBoundary({
|
|
356
|
+
kind: "flow",
|
|
357
|
+
name: "workflow.dispatch",
|
|
358
|
+
payload: { actionTag: step.actionTag },
|
|
359
|
+
meta: {
|
|
360
|
+
moduleId: runtime.moduleId,
|
|
361
|
+
instanceId: runtime.instanceId,
|
|
362
|
+
programId: program.programId,
|
|
363
|
+
runId,
|
|
364
|
+
stepKey: step.key,
|
|
365
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
366
|
+
policy
|
|
367
|
+
},
|
|
368
|
+
effect: dispatchEffect,
|
|
369
|
+
middleware: args.middleware
|
|
370
|
+
}).pipe(Effect.asVoid);
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
if (step.kind === "delay") {
|
|
374
|
+
const timerId = emitTimerEvents ? `${runId}::timer:${step.key}` : void 0;
|
|
375
|
+
const recordTimerEvent = (name, patchMeta) => Effect.gen(function* () {
|
|
376
|
+
const tickSeq2 = getTickSeq();
|
|
377
|
+
yield* runBoundary({
|
|
378
|
+
kind: "flow",
|
|
379
|
+
name,
|
|
380
|
+
payload: { ms: step.ms },
|
|
381
|
+
meta: {
|
|
382
|
+
moduleId: runtime.moduleId,
|
|
383
|
+
instanceId: runtime.instanceId,
|
|
384
|
+
programId: program.programId,
|
|
385
|
+
runId,
|
|
386
|
+
stepKey: step.key,
|
|
387
|
+
...timerId ? { timerId } : null,
|
|
388
|
+
...tickSeq2 !== void 0 ? { tickSeq: tickSeq2 } : null,
|
|
389
|
+
policy,
|
|
390
|
+
...patchMeta ?? null
|
|
391
|
+
},
|
|
392
|
+
effect: Effect.void,
|
|
393
|
+
middleware: args.middleware
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
const schedule = emitTimerEvents ? recordTimerEvent("workflow.timer.schedule") : Effect.void;
|
|
397
|
+
const onCancel = emitTimerEvents ? recordTimerEvent("workflow.timer.cancel", { reason: "interrupt" }) : Effect.void;
|
|
398
|
+
const fired = emitTimerEvents ? recordTimerEvent("workflow.timer.fired") : Effect.void;
|
|
399
|
+
const delayEffect = schedule.pipe(
|
|
400
|
+
Effect.zipRight(makeTimer({ host, ms: step.ms, onCancel })),
|
|
401
|
+
Effect.zipRight(fired)
|
|
402
|
+
);
|
|
403
|
+
const tickSeq = getTickSeq();
|
|
404
|
+
yield* runBoundary({
|
|
405
|
+
kind: "flow",
|
|
406
|
+
name: "workflow.delay",
|
|
407
|
+
payload: { ms: step.ms },
|
|
408
|
+
meta: {
|
|
409
|
+
moduleId: runtime.moduleId,
|
|
410
|
+
instanceId: runtime.instanceId,
|
|
411
|
+
programId: program.programId,
|
|
412
|
+
runId,
|
|
413
|
+
stepKey: step.key,
|
|
414
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
415
|
+
...timerId ? { timerId } : null,
|
|
416
|
+
policy
|
|
417
|
+
},
|
|
418
|
+
effect: delayEffect,
|
|
419
|
+
middleware: args.middleware
|
|
420
|
+
}).pipe(Effect.asVoid);
|
|
421
|
+
timerTriggered = true;
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
const input = step.input ? evalInputExpr(step.input, args.payload) : defaultInputForCall();
|
|
425
|
+
const maxRetries = step.retryTimes ?? 0;
|
|
426
|
+
let exit;
|
|
427
|
+
for (let attempt = 1; attempt <= maxRetries + 1; attempt += 1) {
|
|
428
|
+
const tickSeq = getTickSeq();
|
|
429
|
+
const base = runBoundary({
|
|
430
|
+
kind: "service",
|
|
431
|
+
name: `workflow.call:${step.serviceId}`,
|
|
432
|
+
payload: { serviceId: step.serviceId },
|
|
433
|
+
meta: {
|
|
434
|
+
moduleId: runtime.moduleId,
|
|
435
|
+
instanceId: runtime.instanceId,
|
|
436
|
+
programId: program.programId,
|
|
437
|
+
runId,
|
|
438
|
+
stepKey: step.key,
|
|
439
|
+
serviceId: step.serviceId,
|
|
440
|
+
attempt,
|
|
441
|
+
...tickSeq !== void 0 ? { tickSeq } : null,
|
|
442
|
+
policy
|
|
443
|
+
},
|
|
444
|
+
effect: step.port(input),
|
|
445
|
+
middleware: args.middleware
|
|
446
|
+
});
|
|
447
|
+
const withTimeout = step.timeoutMs === void 0 ? base : Effect.gen(function* () {
|
|
448
|
+
const timeoutMs = step.timeoutMs;
|
|
449
|
+
if (timeoutMs === void 0) {
|
|
450
|
+
return yield* base;
|
|
451
|
+
}
|
|
452
|
+
const timerId = emitTimerEvents ? `${runId}::timeout:${step.key}:a${attempt}` : void 0;
|
|
453
|
+
const recordTimeoutEvent = (name, patchMeta) => Effect.gen(function* () {
|
|
454
|
+
const tickSeq2 = getTickSeq();
|
|
455
|
+
yield* runBoundary({
|
|
456
|
+
kind: "flow",
|
|
457
|
+
name,
|
|
458
|
+
payload: { ms: timeoutMs },
|
|
459
|
+
meta: {
|
|
460
|
+
moduleId: runtime.moduleId,
|
|
461
|
+
instanceId: runtime.instanceId,
|
|
462
|
+
programId: program.programId,
|
|
463
|
+
runId,
|
|
464
|
+
stepKey: step.key,
|
|
465
|
+
attempt,
|
|
466
|
+
...timerId ? { timerId } : null,
|
|
467
|
+
...tickSeq2 !== void 0 ? { tickSeq: tickSeq2 } : null,
|
|
468
|
+
policy,
|
|
469
|
+
...patchMeta ?? null
|
|
470
|
+
},
|
|
471
|
+
effect: Effect.void,
|
|
472
|
+
middleware: args.middleware
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
const schedule = emitTimerEvents ? recordTimeoutEvent("workflow.timeout.schedule") : Effect.void;
|
|
476
|
+
const onCancel = emitTimerEvents ? recordTimeoutEvent("workflow.timeout.cancel", { reason: "interrupt" }) : Effect.void;
|
|
477
|
+
const fired = emitTimerEvents ? recordTimeoutEvent("workflow.timeout.fired") : Effect.void;
|
|
478
|
+
const timeoutError = makeWorkflowError({
|
|
479
|
+
code: "WORKFLOW_CALL_TIMEOUT",
|
|
480
|
+
message: `Workflow call timed out (serviceId="${step.serviceId}", timeoutMs=${timeoutMs}).`,
|
|
481
|
+
programId: program.programId,
|
|
482
|
+
source: { stepKey: step.key },
|
|
483
|
+
detail: { serviceId: step.serviceId, timeoutMs, attempt }
|
|
484
|
+
});
|
|
485
|
+
const timeoutFail = schedule.pipe(
|
|
486
|
+
Effect.zipRight(makeTimer({ host, ms: timeoutMs, onCancel })),
|
|
487
|
+
Effect.zipRight(fired),
|
|
488
|
+
Effect.zipRight(Effect.fail(timeoutError))
|
|
489
|
+
);
|
|
490
|
+
return yield* Effect.raceFirst(base, timeoutFail);
|
|
491
|
+
});
|
|
492
|
+
const attemptExit = yield* Effect.exit(withTimeout);
|
|
493
|
+
exit = attemptExit;
|
|
494
|
+
if (!canWriteBack() || Exit.isSuccess(attemptExit)) {
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
if (Cause.isInterrupted(attemptExit.cause) || Option.isNone(Cause.failureOption(attemptExit.cause))) {
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
if (attempt < maxRetries + 1) {
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
if (!exit) {
|
|
506
|
+
exit = Exit.succeed(void 0);
|
|
507
|
+
}
|
|
508
|
+
if (!canWriteBack()) return;
|
|
509
|
+
if (Exit.isSuccess(exit)) {
|
|
510
|
+
yield* runSteps(step.onSuccess);
|
|
511
|
+
} else {
|
|
512
|
+
const failure = Option.getOrUndefined(Cause.failureOption(exit.cause));
|
|
513
|
+
const isTimeout = isObjectLike(failure) && failure._tag === "WorkflowError" && failure.code === "WORKFLOW_CALL_TIMEOUT";
|
|
514
|
+
if (isTimeout) timerTriggered = true;
|
|
515
|
+
yield* runSteps(step.onFailure);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
const runTickSeq = getTickSeq();
|
|
520
|
+
yield* runBoundary({
|
|
521
|
+
kind: "flow",
|
|
522
|
+
name: "workflow.run",
|
|
523
|
+
payload: { trigger: args.trigger },
|
|
524
|
+
meta: {
|
|
525
|
+
moduleId: runtime.moduleId,
|
|
526
|
+
instanceId: runtime.instanceId,
|
|
527
|
+
programId: program.programId,
|
|
528
|
+
runId,
|
|
529
|
+
...runTickSeq !== void 0 ? { tickSeq: runTickSeq } : null,
|
|
530
|
+
policy
|
|
531
|
+
},
|
|
532
|
+
effect: runSteps(program.steps),
|
|
533
|
+
middleware: args.middleware
|
|
534
|
+
}).pipe(Effect.asVoid);
|
|
535
|
+
});
|
|
536
|
+
const limited = registry.parallelLimiter ? registry.parallelLimiter.withPermits(1)(programEffect) : programEffect;
|
|
537
|
+
const fiber = yield* Effect.forkScoped(
|
|
538
|
+
limited.pipe(
|
|
539
|
+
Effect.catchAllCause((cause) => {
|
|
540
|
+
const { errorSummary, downgrade } = toSerializableErrorSummary(cause);
|
|
541
|
+
const downgradeHint = downgrade ? ` (downgrade=${downgrade})` : "";
|
|
542
|
+
return record({
|
|
543
|
+
type: "diagnostic",
|
|
544
|
+
moduleId: runtime.moduleId,
|
|
545
|
+
instanceId: runtime.instanceId,
|
|
546
|
+
code: "workflow::run_crashed",
|
|
547
|
+
severity: "error",
|
|
548
|
+
message: `Workflow run crashed for programId="${program.programId}" runId="${runId}".${downgradeHint}`,
|
|
549
|
+
hint: `${errorSummary.name ? `${errorSummary.name}: ` : ""}${errorSummary.message}`,
|
|
550
|
+
actionTag: args.trigger.kind === "action" ? args.trigger.actionTag : void 0,
|
|
551
|
+
kind: "workflow_run_crashed",
|
|
552
|
+
trigger: {
|
|
553
|
+
kind: "workflow",
|
|
554
|
+
name: "run",
|
|
555
|
+
details: {
|
|
556
|
+
programId: program.programId,
|
|
557
|
+
runId,
|
|
558
|
+
trigger: args.trigger
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}).pipe(Effect.catchAllCause(() => Effect.void));
|
|
562
|
+
}),
|
|
563
|
+
Effect.ensuring(
|
|
564
|
+
Effect.sync(() => {
|
|
565
|
+
if (state.mode === "exhaust") {
|
|
566
|
+
state.busy = false;
|
|
567
|
+
}
|
|
568
|
+
})
|
|
569
|
+
)
|
|
570
|
+
)
|
|
571
|
+
);
|
|
572
|
+
if (state.mode === "latest") {
|
|
573
|
+
state.current = fiber;
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
var ensureRegistry = (runtime) => Effect.gen(function* () {
|
|
577
|
+
const existing = getRegistry(runtime);
|
|
578
|
+
if (existing) {
|
|
579
|
+
return {
|
|
580
|
+
moduleId: runtime.moduleId,
|
|
581
|
+
instanceId: runtime.instanceId,
|
|
582
|
+
registry: existing
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
const portsReady = yield* Deferred.make();
|
|
586
|
+
const next = {
|
|
587
|
+
byActionTag: /* @__PURE__ */ new Map(),
|
|
588
|
+
entries: [],
|
|
589
|
+
watcherStarted: false,
|
|
590
|
+
watcherStartCount: 0,
|
|
591
|
+
portsResolving: false,
|
|
592
|
+
portsReady,
|
|
593
|
+
parallelLimiter: void 0
|
|
594
|
+
};
|
|
595
|
+
Object.defineProperty(runtime, WORKFLOW_REGISTRY, {
|
|
596
|
+
value: next,
|
|
597
|
+
enumerable: false,
|
|
598
|
+
configurable: true,
|
|
599
|
+
writable: false
|
|
600
|
+
});
|
|
601
|
+
return { moduleId: runtime.moduleId, instanceId: runtime.instanceId, registry: next };
|
|
602
|
+
});
|
|
603
|
+
var registerPrograms = (args) => Effect.gen(function* () {
|
|
604
|
+
const runtime = yield* args.moduleTag;
|
|
605
|
+
const { moduleId, instanceId, registry } = yield* ensureRegistry(runtime);
|
|
606
|
+
if (registry.parallelLimiter === void 0) {
|
|
607
|
+
yield* ensureLimiterReady(registry, runtime);
|
|
608
|
+
}
|
|
609
|
+
const validateNoIoStepsForOnInit = (steps, programId) => {
|
|
610
|
+
const visit = (step) => {
|
|
611
|
+
if (step.kind === "call" || step.kind === "delay") {
|
|
612
|
+
throw makeWorkflowError({
|
|
613
|
+
code: "WORKFLOW_INVALID_TRIGGER",
|
|
614
|
+
message: "Lifecycle onInit programs must not include call/delay (initRequired must stay sync-only; use onStart for IO/time).",
|
|
615
|
+
programId,
|
|
616
|
+
source: { stepKey: step.key },
|
|
617
|
+
detail: { kind: step.kind }
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
for (const s of steps) visit(s);
|
|
622
|
+
};
|
|
623
|
+
const programHasCall = (steps) => steps.some((s) => s.kind === "call");
|
|
624
|
+
const insertEntry = (actionTag, entry) => {
|
|
625
|
+
const prev = registry.byActionTag.get(actionTag);
|
|
626
|
+
registry.byActionTag.set(actionTag, prev ? [...prev, entry] : [entry]);
|
|
627
|
+
};
|
|
628
|
+
const internals = getRuntimeInternals(runtime);
|
|
629
|
+
for (const program of args.programs) {
|
|
630
|
+
const def = program.def;
|
|
631
|
+
const localId = asNonEmptyString(def.localId);
|
|
632
|
+
if (!localId) {
|
|
633
|
+
throw makeWorkflowError({
|
|
634
|
+
code: "WORKFLOW_INVALID_DEF",
|
|
635
|
+
message: "Workflow.install: def.localId must be a non-empty string.",
|
|
636
|
+
detail: { localId: def.localId }
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
const programId = `${moduleId}.${localId}`;
|
|
640
|
+
const compiled = compileWorkflowRuntimeStepsV1({ def });
|
|
641
|
+
if (def.trigger.kind === "lifecycle" && def.trigger.phase === "onInit") {
|
|
642
|
+
validateNoIoStepsForOnInit(compiled, programId);
|
|
643
|
+
}
|
|
644
|
+
const compiledProgram = {
|
|
645
|
+
programId,
|
|
646
|
+
localId,
|
|
647
|
+
trigger: def.trigger,
|
|
648
|
+
concurrency: resolveConcurrency(def),
|
|
649
|
+
priority: resolvePriority(def),
|
|
650
|
+
compiledSteps: compiled
|
|
651
|
+
};
|
|
652
|
+
if (!programHasCall(compiled)) {
|
|
653
|
+
compiledProgram.steps = compileSteps(compiled, () => {
|
|
654
|
+
throw makeWorkflowError({
|
|
655
|
+
code: "WORKFLOW_MISSING_SERVICE",
|
|
656
|
+
message: "Internal error: unexpected call step while resolving call-less program.",
|
|
657
|
+
programId,
|
|
658
|
+
detail: { programId }
|
|
659
|
+
});
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
const state = compiledProgram.concurrency === "latest" ? { mode: "latest", runSeq: 0, current: void 0, currentRunId: void 0 } : compiledProgram.concurrency === "exhaust" ? { mode: "exhaust", runSeq: 0, busy: false } : { mode: "parallel", runSeq: 0 };
|
|
663
|
+
const entry = { program: compiledProgram, state };
|
|
664
|
+
registry.entries.push(entry);
|
|
665
|
+
if (def.trigger.kind === "action") {
|
|
666
|
+
insertEntry(def.trigger.actionTag, entry);
|
|
667
|
+
} else {
|
|
668
|
+
if (def.trigger.phase === "onStart") {
|
|
669
|
+
internals.lifecycle.registerStart(
|
|
670
|
+
withRootEnvIfAvailable(
|
|
671
|
+
Effect.gen(function* () {
|
|
672
|
+
const middlewareOpt = yield* Effect.serviceOption(EffectOpMiddlewareTag);
|
|
673
|
+
const middleware = Option.isSome(middlewareOpt) ? middlewareOpt.value : void 0;
|
|
674
|
+
yield* ensurePortsResolved(registry, runtime).pipe(Effect.orDie);
|
|
675
|
+
yield* startProgramRun({
|
|
676
|
+
entry,
|
|
677
|
+
runtime,
|
|
678
|
+
registry,
|
|
679
|
+
trigger: { kind: "lifecycle", phase: "onStart" },
|
|
680
|
+
payload: void 0,
|
|
681
|
+
middleware
|
|
682
|
+
});
|
|
683
|
+
})
|
|
684
|
+
),
|
|
685
|
+
{ name: `workflow:${localId}` }
|
|
686
|
+
);
|
|
687
|
+
} else {
|
|
688
|
+
internals.lifecycle.registerInitRequired(
|
|
689
|
+
Effect.gen(function* () {
|
|
690
|
+
const middlewareOpt = yield* Effect.serviceOption(EffectOpMiddlewareTag);
|
|
691
|
+
const middleware = Option.isSome(middlewareOpt) ? middlewareOpt.value : void 0;
|
|
692
|
+
yield* startProgramRun({
|
|
693
|
+
entry,
|
|
694
|
+
runtime,
|
|
695
|
+
registry,
|
|
696
|
+
trigger: { kind: "lifecycle", phase: "onInit" },
|
|
697
|
+
payload: void 0,
|
|
698
|
+
middleware
|
|
699
|
+
});
|
|
700
|
+
}),
|
|
701
|
+
{ name: `workflow:${localId}` }
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
void instanceId;
|
|
707
|
+
});
|
|
708
|
+
var startWatcherIfNeeded = (args) => Effect.gen(function* () {
|
|
709
|
+
const runtime = yield* args.moduleTag;
|
|
710
|
+
const init = yield* ensureRegistry(runtime);
|
|
711
|
+
const registry = init.registry;
|
|
712
|
+
if (registry.watcherStarted) {
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
registry.watcherStarted = true;
|
|
716
|
+
registry.watcherStartCount += 1;
|
|
717
|
+
const middlewareOpt = yield* Effect.serviceOption(EffectOpMiddlewareTag);
|
|
718
|
+
const middleware = Option.isSome(middlewareOpt) ? middlewareOpt.value : void 0;
|
|
719
|
+
const actions$ = runtime.actions$;
|
|
720
|
+
const portsExit = yield* Effect.exit(ensurePortsResolved(registry, runtime));
|
|
721
|
+
if (Exit.isFailure(portsExit)) {
|
|
722
|
+
const { errorSummary, downgrade } = toSerializableErrorSummary(portsExit.cause);
|
|
723
|
+
const downgradeHint = downgrade ? ` (downgrade=${downgrade})` : "";
|
|
724
|
+
yield* record({
|
|
725
|
+
type: "diagnostic",
|
|
726
|
+
moduleId: runtime.moduleId,
|
|
727
|
+
instanceId: runtime.instanceId,
|
|
728
|
+
code: "workflow::ports_resolution_failed",
|
|
729
|
+
severity: "error",
|
|
730
|
+
message: `Workflow ports resolution failed before starting watcher.${downgradeHint}`,
|
|
731
|
+
hint: `${errorSummary.name ? `${errorSummary.name}: ` : ""}${errorSummary.message}`,
|
|
732
|
+
kind: "workflow_ports_resolution_failed",
|
|
733
|
+
trigger: {
|
|
734
|
+
kind: "workflow",
|
|
735
|
+
name: "portsResolution",
|
|
736
|
+
details: {
|
|
737
|
+
entryLabel: args.entryLabel
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
yield* Stream.runForEach(
|
|
744
|
+
actions$,
|
|
745
|
+
(action) => Effect.gen(function* () {
|
|
746
|
+
const actionTag = resolveActionTag(action);
|
|
747
|
+
if (!actionTag) return;
|
|
748
|
+
const entries = registry.byActionTag.get(actionTag);
|
|
749
|
+
if (!entries || entries.length === 0) return;
|
|
750
|
+
const payload = isRecord(action) ? action.payload : void 0;
|
|
751
|
+
yield* Effect.forEach(
|
|
752
|
+
entries,
|
|
753
|
+
(entry) => startProgramRun({
|
|
754
|
+
entry,
|
|
755
|
+
runtime,
|
|
756
|
+
registry,
|
|
757
|
+
trigger: { kind: "action", actionTag },
|
|
758
|
+
payload,
|
|
759
|
+
middleware
|
|
760
|
+
}),
|
|
761
|
+
{ discard: true }
|
|
762
|
+
);
|
|
763
|
+
})
|
|
764
|
+
).pipe(
|
|
765
|
+
Effect.catchAllCause((cause) => {
|
|
766
|
+
const { errorSummary, downgrade } = toSerializableErrorSummary(cause);
|
|
767
|
+
const downgradeHint = downgrade ? ` (downgrade=${downgrade})` : "";
|
|
768
|
+
return record({
|
|
769
|
+
type: "diagnostic",
|
|
770
|
+
moduleId: runtime.moduleId,
|
|
771
|
+
instanceId: runtime.instanceId,
|
|
772
|
+
code: "workflow::watcher_crashed",
|
|
773
|
+
severity: "error",
|
|
774
|
+
message: `Workflow watcher crashed.${downgradeHint}`,
|
|
775
|
+
hint: `${errorSummary.name ? `${errorSummary.name}: ` : ""}${errorSummary.message}`,
|
|
776
|
+
kind: "workflow_watcher_crashed",
|
|
777
|
+
trigger: {
|
|
778
|
+
kind: "workflow",
|
|
779
|
+
name: "watcher",
|
|
780
|
+
details: {
|
|
781
|
+
entryLabel: args.entryLabel
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
})
|
|
786
|
+
);
|
|
787
|
+
void args.entryLabel;
|
|
788
|
+
});
|
|
789
|
+
var mountAll = (args) => {
|
|
790
|
+
const plan = {
|
|
791
|
+
setup: registerPrograms({ moduleTag: args.moduleTag, programs: args.programs, entryLabel: "mountAll" }),
|
|
792
|
+
run: startWatcherIfNeeded({ moduleTag: args.moduleTag, entryLabel: "mountAll" })
|
|
793
|
+
};
|
|
794
|
+
attachLogicUnitMeta(plan, {
|
|
795
|
+
id: "__logix_internal:workflows",
|
|
796
|
+
kind: "internal",
|
|
797
|
+
name: "workflows"
|
|
798
|
+
});
|
|
799
|
+
return plan;
|
|
800
|
+
};
|
|
801
|
+
var installOne = (args) => {
|
|
802
|
+
const localId = asNonEmptyString(args.program.def.localId) ?? "unknown";
|
|
803
|
+
const plan = {
|
|
804
|
+
setup: registerPrograms({ moduleTag: args.moduleTag, programs: [args.program], entryLabel: `install:${localId}` }),
|
|
805
|
+
run: startWatcherIfNeeded({ moduleTag: args.moduleTag, entryLabel: `install:${localId}` })
|
|
806
|
+
};
|
|
807
|
+
attachLogicUnitMeta(plan, {
|
|
808
|
+
id: `workflow:${localId}`,
|
|
809
|
+
kind: "workflow",
|
|
810
|
+
name: localId
|
|
811
|
+
});
|
|
812
|
+
return plan;
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
export {
|
|
816
|
+
mountAll,
|
|
817
|
+
installOne
|
|
818
|
+
};
|
|
819
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL1dvcmtmbG93UnVudGltZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgQ2F1c2UsIENvbnRleHQsIERlZmVycmVkLCBFZmZlY3QsIEV4aXQsIEZpYmVyLCBGaWJlclJlZiwgT3B0aW9uLCBTdHJlYW0gfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgKiBhcyBFZmZlY3RPcENvcmUgZnJvbSAnLi9FZmZlY3RPcENvcmUuanMnXG5pbXBvcnQgKiBhcyBEZWJ1ZyBmcm9tICcuL0RlYnVnU2luay5qcydcbmltcG9ydCAqIGFzIExvZ2ljVW5pdE1ldGEgZnJvbSAnLi9Mb2dpY1VuaXRNZXRhLmpzJ1xuaW1wb3J0IHsgdG9TZXJpYWxpemFibGVFcnJvclN1bW1hcnkgfSBmcm9tICcuL2Vycm9yU3VtbWFyeS5qcydcbmltcG9ydCB0eXBlIHsgQW55TW9kdWxlU2hhcGUsIExvZ2ljUGxhbiwgTW9kdWxlUnVudGltZSBhcyBQdWJsaWNNb2R1bGVSdW50aW1lIH0gZnJvbSAnLi9tb2R1bGUuanMnXG5pbXBvcnQgeyBIb3N0U2NoZWR1bGVyVGFnLCBUaWNrU2NoZWR1bGVyVGFnIH0gZnJvbSAnLi9lbnYuanMnXG5pbXBvcnQgeyBjdXJyZW50VHhuT3JpZ2luT3ZlcnJpZGUgfSBmcm9tICcuL1R4bk9yaWdpbk92ZXJyaWRlLmpzJ1xuaW1wb3J0IHsgZ2V0UnVudGltZUludGVybmFscyB9IGZyb20gJy4vcnVudGltZUludGVybmFsc0FjY2Vzc29yLmpzJ1xuaW1wb3J0IHsgUm9vdENvbnRleHRUYWcsIHR5cGUgUm9vdENvbnRleHQgfSBmcm9tICcuL1Jvb3RDb250ZXh0LmpzJ1xuaW1wb3J0ICogYXMgVGFza1J1bm5lciBmcm9tICcuL1Rhc2tSdW5uZXIuanMnXG5pbXBvcnQgKiBhcyBFZmZlY3RPcCBmcm9tICcuLi8uLi9lZmZlY3Qtb3AuanMnXG5pbXBvcnQgeyBtYWtlV29ya2Zsb3dFcnJvciB9IGZyb20gJy4uLy4uL3dvcmtmbG93L2Vycm9ycy5qcydcbmltcG9ydCB7IGNvbXBpbGVXb3JrZmxvd1J1bnRpbWVTdGVwc1YxLCB0eXBlIENvbXBpbGVkV29ya2Zsb3dTdGVwIH0gZnJvbSAnLi4vLi4vd29ya2Zsb3cvY29tcGlsZXIuanMnXG5pbXBvcnQgeyBldmFsSW5wdXRFeHByLCB0eXBlIENvbXBpbGVkSW5wdXRFeHByIH0gZnJvbSAnLi4vLi4vd29ya2Zsb3cvaW5wdXRFeHByLmpzJ1xuaW1wb3J0IHR5cGUgeyBXb3JrZmxvd0RlZlYxLCBXb3JrZmxvd1RyaWdnZXJWMSB9IGZyb20gJy4uLy4uL3dvcmtmbG93L21vZGVsLmpzJ1xuXG50eXBlIE1vZHVsZVRhZyA9IENvbnRleHQuVGFnPHVua25vd24sIFB1YmxpY01vZHVsZVJ1bnRpbWU8dW5rbm93biwgdW5rbm93bj4+XG5cbmV4cG9ydCB0eXBlIFdvcmtmbG93TGlrZSA9IHtcbiAgcmVhZG9ubHkgX3RhZz86ICdXb3JrZmxvdydcbiAgcmVhZG9ubHkgZGVmOiBXb3JrZmxvd0RlZlYxXG4gIHJlYWRvbmx5IHZhbGlkYXRlPzogKCkgPT4gdm9pZFxufVxuXG50eXBlIENvbmN1cnJlbmN5TW9kZSA9ICdsYXRlc3QnIHwgJ2V4aGF1c3QnIHwgJ3BhcmFsbGVsJ1xudHlwZSBQcmlvcml0eSA9ICd1cmdlbnQnIHwgJ25vblVyZ2VudCdcblxudHlwZSBTZXJ2aWNlUG9ydCA9IChpbnB1dDogdW5rbm93bikgPT4gRWZmZWN0LkVmZmVjdDx1bmtub3duLCB1bmtub3duLCB1bmtub3duPlxuXG50eXBlIENvbXBpbGVkUnVudGltZVN0ZXAgPVxuICB8IHsgcmVhZG9ubHkga2luZDogJ2Rpc3BhdGNoJzsgcmVhZG9ubHkga2V5OiBzdHJpbmc7IHJlYWRvbmx5IGFjdGlvblRhZzogc3RyaW5nOyByZWFkb25seSBwYXlsb2FkPzogQ29tcGlsZWRJbnB1dEV4cHIgfVxuICB8IHsgcmVhZG9ubHkga2luZDogJ2RlbGF5JzsgcmVhZG9ubHkga2V5OiBzdHJpbmc7IHJlYWRvbmx5IG1zOiBudW1iZXIgfVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdjYWxsJ1xuICAgICAgcmVhZG9ubHkga2V5OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IHNlcnZpY2VJZDogc3RyaW5nXG4gICAgICByZWFkb25seSBpbnB1dD86IENvbXBpbGVkSW5wdXRFeHByXG4gICAgICByZWFkb25seSB0aW1lb3V0TXM/OiBudW1iZXJcbiAgICAgIHJlYWRvbmx5IHJldHJ5VGltZXM/OiBudW1iZXJcbiAgICAgIHJlYWRvbmx5IHBvcnQ6IFNlcnZpY2VQb3J0XG4gICAgICByZWFkb25seSBvblN1Y2Nlc3M6IFJlYWRvbmx5QXJyYXk8Q29tcGlsZWRSdW50aW1lU3RlcD5cbiAgICAgIHJlYWRvbmx5IG9uRmFpbHVyZTogUmVhZG9ubHlBcnJheTxDb21waWxlZFJ1bnRpbWVTdGVwPlxuICAgIH1cblxudHlwZSBDb21waWxlZFByb2dyYW0gPSB7XG4gIHJlYWRvbmx5IHByb2dyYW1JZDogc3RyaW5nXG4gIHJlYWRvbmx5IGxvY2FsSWQ6IHN0cmluZ1xuICByZWFkb25seSB0cmlnZ2VyOiBXb3JrZmxvd1RyaWdnZXJWMVxuICByZWFkb25seSBjb25jdXJyZW5jeTogQ29uY3VycmVuY3lNb2RlXG4gIHJlYWRvbmx5IHByaW9yaXR5OiBQcmlvcml0eVxuICByZWFkb25seSBjb21waWxlZFN0ZXBzOiBSZWFkb25seUFycmF5PENvbXBpbGVkV29ya2Zsb3dTdGVwPlxuICBzdGVwcz86IFJlYWRvbmx5QXJyYXk8Q29tcGlsZWRSdW50aW1lU3RlcD5cbn1cblxudHlwZSBQcm9ncmFtU3RhdGUgPVxuICB8IHsgcmVhZG9ubHkgbW9kZTogJ2xhdGVzdCc7IHJ1blNlcTogbnVtYmVyOyBjdXJyZW50PzogRmliZXIuUnVudGltZUZpYmVyPHZvaWQsIG5ldmVyPjsgY3VycmVudFJ1bklkPzogc3RyaW5nIH1cbiAgfCB7IHJlYWRvbmx5IG1vZGU6ICdleGhhdXN0JzsgcnVuU2VxOiBudW1iZXI7IGJ1c3k6IGJvb2xlYW4gfVxuICB8IHsgcmVhZG9ubHkgbW9kZTogJ3BhcmFsbGVsJzsgcnVuU2VxOiBudW1iZXIgfVxuXG50eXBlIFByb2dyYW1FbnRyeSA9IHtcbiAgcmVhZG9ubHkgcHJvZ3JhbTogQ29tcGlsZWRQcm9ncmFtXG4gIHJlYWRvbmx5IHN0YXRlOiBQcm9ncmFtU3RhdGVcbn1cblxudHlwZSBXb3JrZmxvd1JlZ2lzdHJ5VjEgPSB7XG4gIHJlYWRvbmx5IGJ5QWN0aW9uVGFnOiBNYXA8c3RyaW5nLCBSZWFkb25seUFycmF5PFByb2dyYW1FbnRyeT4+XG4gIHJlYWRvbmx5IGVudHJpZXM6IEFycmF5PFByb2dyYW1FbnRyeT5cbiAgd2F0Y2hlclN0YXJ0ZWQ6IGJvb2xlYW5cbiAgd2F0Y2hlclN0YXJ0Q291bnQ6IG51bWJlclxuICBwb3J0c1Jlc29sdmluZzogYm9vbGVhblxuICBwb3J0c1JlYWR5OiBEZWZlcnJlZC5EZWZlcnJlZDx2b2lkLCB1bmtub3duPlxuICBwYXJhbGxlbExpbWl0ZXI6IEVmZmVjdC5TZW1hcGhvcmUgfCBudWxsIHwgdW5kZWZpbmVkXG59XG5cbmNvbnN0IFdPUktGTE9XX1JFR0lTVFJZID0gU3ltYm9sLmZvcignQGxvZ2l4anMvY29yZS93b3JrZmxvd1JlZ2lzdHJ5JylcblxuY29uc3QgaXNSZWNvcmQgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PlxuICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKVxuXG5jb25zdCBpc09iamVjdExpa2UgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8ICgoLi4uYXJnczogbmV2ZXJbXSkgPT4gdW5rbm93bikgPT5cbiAgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwpIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJ1xuXG5jb25zdCBnZXRSZWdpc3RyeSA9IChydW50aW1lOiBvYmplY3QpOiBXb3JrZmxvd1JlZ2lzdHJ5VjEgfCB1bmRlZmluZWQgPT5cbiAgKHJ1bnRpbWUgYXMgUmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPilbV09SS0ZMT1dfUkVHSVNUUlldIGFzIFdvcmtmbG93UmVnaXN0cnlWMSB8IHVuZGVmaW5lZFxuXG5jb25zdCByZXNvbHZlQWN0aW9uVGFnID0gKGFjdGlvbjogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IHRhZyA9IGlzT2JqZWN0TGlrZShhY3Rpb24pID8gKGFjdGlvbiBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikuX3RhZyA6IHVuZGVmaW5lZFxuICBpZiAodHlwZW9mIHRhZyA9PT0gJ3N0cmluZycgJiYgdGFnLmxlbmd0aCA+IDApIHJldHVybiB0YWdcbiAgY29uc3QgdHlwZSA9IGlzT2JqZWN0TGlrZShhY3Rpb24pID8gKGFjdGlvbiBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikudHlwZSA6IHVuZGVmaW5lZFxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnICYmIHR5cGUubGVuZ3RoID4gMCkgcmV0dXJuIHR5cGVcbiAgaWYgKHRhZyAhPSBudWxsKSByZXR1cm4gU3RyaW5nKHRhZylcbiAgaWYgKHR5cGUgIT0gbnVsbCkgcmV0dXJuIFN0cmluZyh0eXBlKVxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmNvbnN0IGFzTm9uRW1wdHlTdHJpbmcgPSAodmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQgPT5cbiAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS50cmltKCkubGVuZ3RoID4gMCA/IHZhbHVlLnRyaW0oKSA6IHVuZGVmaW5lZFxuXG5jb25zdCBLRVJORUxfUE9SVF9TT1VSQ0VfUkVGUkVTSCA9ICdsb2dpeC9rZXJuZWwvc291cmNlUmVmcmVzaCdcblxuY29uc3QgcmVzb2x2ZVNlcnZpY2VQb3J0ID0gKFxuICBydW50aW1lOiBQdWJsaWNNb2R1bGVSdW50aW1lPHVua25vd24sIHVua25vd24+LFxuICBlbnY6IENvbnRleHQuQ29udGV4dDx1bmtub3duPixcbiAgc2VydmljZUlkOiBzdHJpbmcsXG4gIHByb2dyYW1JZDogc3RyaW5nLFxuICBzdGVwS2V5OiBzdHJpbmcsXG4pOiBTZXJ2aWNlUG9ydCA9PiB7XG4gIGlmIChzZXJ2aWNlSWQgPT09IEtFUk5FTF9QT1JUX1NPVVJDRV9SRUZSRVNIKSB7XG4gICAgcmV0dXJuIChpbnB1dCkgPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgZmllbGRQYXRoID0gYXNOb25FbXB0eVN0cmluZyhpc1JlY29yZChpbnB1dCkgPyBpbnB1dC5maWVsZFBhdGggOiB1bmRlZmluZWQpXG4gICAgICAgIGlmICghZmllbGRQYXRoKSB7XG4gICAgICAgICAgdGhyb3cgbWFrZVdvcmtmbG93RXJyb3Ioe1xuICAgICAgICAgICAgY29kZTogJ1dPUktGTE9XX0lOVkFMSURfU1RFUCcsXG4gICAgICAgICAgICBtZXNzYWdlOiAnS2VybmVsUG9ydCBzb3VyY2VSZWZyZXNoIHJlcXVpcmVzIGlucHV0LmZpZWxkUGF0aCAobm9uLWVtcHR5IHN0cmluZykuJyxcbiAgICAgICAgICAgIHByb2dyYW1JZCxcbiAgICAgICAgICAgIHNvdXJjZTogeyBzdGVwS2V5IH0sXG4gICAgICAgICAgICBkZXRhaWw6IHsgc2VydmljZUlkLCBpbnB1dCB9LFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbnRlcm5hbHMgPSBnZXRSdW50aW1lSW50ZXJuYWxzKHJ1bnRpbWUpXG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBpbnRlcm5hbHMudHJhaXRzLmdldFNvdXJjZVJlZnJlc2hIYW5kbGVyKGZpZWxkUGF0aClcblxuICAgICAgICAvLyBJZiBubyByZWZyZXNoIGhhbmRsZXIgaXMgcmVnaXN0ZXJlZCwgdHJlYXQgaXQgYXMgYSBuby1vcCAoYWxpZ25zIHdpdGggQm91bmRBcGlSdW50aW1lIGJlaGF2aW9yKS5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmb3JjZSA9IGlzUmVjb3JkKGlucHV0KSAmJiBpbnB1dC5mb3JjZSA9PT0gdHJ1ZVxuICAgICAgICBjb25zdCBydW5IYW5kbGVyID0gKHN0YXRlOiB1bmtub3duKSA9PlxuICAgICAgICAgIGZvcmNlID8gRWZmZWN0LmxvY2FsbHkoVGFza1J1bm5lci5mb3JjZVNvdXJjZVJlZnJlc2gsIHRydWUpKGhhbmRsZXIoc3RhdGUpKSA6IGhhbmRsZXIoc3RhdGUpXG5cbiAgICAgICAgY29uc3QgaW5UeG4gPSB5aWVsZCogRmliZXJSZWYuZ2V0KFRhc2tSdW5uZXIuaW5TeW5jVHJhbnNhY3Rpb25GaWJlcilcbiAgICAgICAgaWYgKGluVHhuKSB7XG4gICAgICAgICAgY29uc3Qgc3RhdGUgPSB5aWVsZCogcnVudGltZS5nZXRTdGF0ZVxuICAgICAgICAgIHlpZWxkKiBydW5IYW5kbGVyKHN0YXRlKVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgeWllbGQqIGludGVybmFscy50eG4ucnVuV2l0aFN0YXRlVHJhbnNhY3Rpb24oXG4gICAgICAgICAge1xuICAgICAgICAgICAga2luZDogJ3NvdXJjZS1yZWZyZXNoJyxcbiAgICAgICAgICAgIG5hbWU6IGZpZWxkUGF0aCxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHN0YXRlID0geWllbGQqIHJ1bnRpbWUuZ2V0U3RhdGVcbiAgICAgICAgICAgICAgeWllbGQqIHJ1bkhhbmRsZXIoc3RhdGUpXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgfSlcbiAgfVxuXG4gIGNvbnN0IHRhZyA9IENvbnRleHQuR2VuZXJpY1RhZzx1bmtub3duPihzZXJ2aWNlSWQpXG4gIGNvbnN0IG9wdCA9IENvbnRleHQuZ2V0T3B0aW9uKGVudiwgdGFnKVxuICBpZiAoT3B0aW9uLmlzTm9uZShvcHQpKSB7XG4gICAgdGhyb3cgbWFrZVdvcmtmbG93RXJyb3Ioe1xuICAgICAgY29kZTogJ1dPUktGTE9XX01JU1NJTkdfU0VSVklDRScsXG4gICAgICBtZXNzYWdlOiBgTWlzc2luZyBzZXJ2aWNlIGZvciBzZXJ2aWNlSWQ9XCIke3NlcnZpY2VJZH1cIi5gLFxuICAgICAgcHJvZ3JhbUlkLFxuICAgICAgc291cmNlOiB7IHN0ZXBLZXkgfSxcbiAgICAgIGRldGFpbDogeyBzZXJ2aWNlSWQgfSxcbiAgICB9KVxuICB9XG5cbiAgY29uc3QgdmFsdWU6IHVua25vd24gPSBvcHQudmFsdWVcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IGZuID0gdmFsdWUgYXMgKGlucHV0OiB1bmtub3duKSA9PiBFZmZlY3QuRWZmZWN0PHVua25vd24sIHVua25vd24sIHVua25vd24+XG4gICAgcmV0dXJuIChpbnB1dCkgPT4gZm4oaW5wdXQpXG4gIH1cblxuICBjb25zdCBjYWxsRm4gPSBpc09iamVjdExpa2UodmFsdWUpID8gKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5jYWxsIDogdW5kZWZpbmVkXG4gIGlmICh0eXBlb2YgY2FsbEZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3QgY2FsbCA9IGNhbGxGbiBhcyAodGhpczogdW5rbm93biwgaW5wdXQ6IHVua25vd24pID0+IEVmZmVjdC5FZmZlY3Q8dW5rbm93biwgdW5rbm93biwgdW5rbm93bj5cbiAgICByZXR1cm4gKGlucHV0KSA9PiBjYWxsLmNhbGwodmFsdWUsIGlucHV0KVxuICB9XG5cbiAgdGhyb3cgbWFrZVdvcmtmbG93RXJyb3Ioe1xuICAgIGNvZGU6ICdXT1JLRkxPV19JTlZBTElEX1NFUlZJQ0VfUE9SVCcsXG4gICAgbWVzc2FnZTogYEludmFsaWQgc2VydmljZSBwb3J0IGZvciBzZXJ2aWNlSWQ9XCIke3NlcnZpY2VJZH1cIiAoZXhwZWN0ZWQgYSBmdW5jdGlvbiBvciB7IGNhbGwoaW5wdXQpOiBFZmZlY3QgfSkuYCxcbiAgICBwcm9ncmFtSWQsXG4gICAgc291cmNlOiB7IHN0ZXBLZXkgfSxcbiAgICBkZXRhaWw6IHsgc2VydmljZUlkLCBwb3J0VHlwZTogdHlwZW9mIHZhbHVlIH0sXG4gIH0pXG59XG5cbmNvbnN0IGNvbXBpbGVTdGVwcyA9IChzdGVwczogUmVhZG9ubHlBcnJheTxDb21waWxlZFdvcmtmbG93U3RlcD4sIHJlc29sdmVQb3J0OiAoc2VydmljZUlkOiBzdHJpbmcsIHN0ZXBLZXk6IHN0cmluZykgPT4gU2VydmljZVBvcnQpID0+IHtcbiAgY29uc3QgdmlzaXQgPSAoc3RlcDogQ29tcGlsZWRXb3JrZmxvd1N0ZXApOiBDb21waWxlZFJ1bnRpbWVTdGVwID0+IHtcbiAgICBzd2l0Y2ggKHN0ZXAua2luZCkge1xuICAgICAgY2FzZSAnZGlzcGF0Y2gnOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtpbmQ6ICdkaXNwYXRjaCcsXG4gICAgICAgICAga2V5OiBzdGVwLmtleSxcbiAgICAgICAgICBhY3Rpb25UYWc6IHN0ZXAuYWN0aW9uVGFnLFxuICAgICAgICAgIC4uLihzdGVwLnBheWxvYWQgPyB7IHBheWxvYWQ6IHN0ZXAucGF5bG9hZCB9IDogbnVsbCksXG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2RlbGF5JzpcbiAgICAgICAgcmV0dXJuIHsga2luZDogJ2RlbGF5Jywga2V5OiBzdGVwLmtleSwgbXM6IHN0ZXAubXMgfVxuICAgICAgY2FzZSAnY2FsbCc6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2luZDogJ2NhbGwnLFxuICAgICAgICAgIGtleTogc3RlcC5rZXksXG4gICAgICAgICAgc2VydmljZUlkOiBzdGVwLnNlcnZpY2VJZCxcbiAgICAgICAgICBwb3J0OiByZXNvbHZlUG9ydChzdGVwLnNlcnZpY2VJZCwgc3RlcC5rZXkpLFxuICAgICAgICAgIC4uLihzdGVwLmlucHV0ID8geyBpbnB1dDogc3RlcC5pbnB1dCB9IDogbnVsbCksXG4gICAgICAgICAgLi4uKHN0ZXAudGltZW91dE1zICE9PSB1bmRlZmluZWQgPyB7IHRpbWVvdXRNczogc3RlcC50aW1lb3V0TXMgfSA6IG51bGwpLFxuICAgICAgICAgIC4uLihzdGVwLnJldHJ5VGltZXMgIT09IHVuZGVmaW5lZCA/IHsgcmV0cnlUaW1lczogc3RlcC5yZXRyeVRpbWVzIH0gOiBudWxsKSxcbiAgICAgICAgICBvblN1Y2Nlc3M6IHN0ZXAub25TdWNjZXNzLm1hcCh2aXNpdCksXG4gICAgICAgICAgb25GYWlsdXJlOiBzdGVwLm9uRmFpbHVyZS5tYXAodmlzaXQpLFxuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHN0ZXBzLm1hcCh2aXNpdClcbn1cblxuY29uc3QgcmVzb2x2ZUNvbmN1cnJlbmN5ID0gKGRlZjogV29ya2Zsb3dEZWZWMSk6IENvbmN1cnJlbmN5TW9kZSA9PiAoZGVmLnBvbGljeT8uY29uY3VycmVuY3kgPz8gJ3BhcmFsbGVsJykgYXMgQ29uY3VycmVuY3lNb2RlXG5jb25zdCByZXNvbHZlUHJpb3JpdHkgPSAoZGVmOiBXb3JrZmxvd0RlZlYxKTogUHJpb3JpdHkgPT4gKGRlZi5wb2xpY3k/LnByaW9yaXR5ID8/ICd1cmdlbnQnKSBhcyBQcmlvcml0eVxuXG5jb25zdCBtYWtlUnVuSWQgPSAoaW5zdGFuY2VJZDogc3RyaW5nLCBwcm9ncmFtSWQ6IHN0cmluZywgcnVuU2VxOiBudW1iZXIpOiBzdHJpbmcgPT5cbiAgYCR7aW5zdGFuY2VJZH06OndmOiR7cHJvZ3JhbUlkfTo6ciR7cnVuU2VxfWBcblxuY29uc3QgcnVuQm91bmRhcnkgPSA8QSwgRSwgUj4oYXJnczoge1xuICByZWFkb25seSBraW5kOiBFZmZlY3RPcC5FZmZlY3RPcFsna2luZCddXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZ1xuICByZWFkb25seSBlZmZlY3Q6IEVmZmVjdC5FZmZlY3Q8QSwgRSwgUj5cbiAgcmVhZG9ubHkgcGF5bG9hZD86IHVua25vd25cbiAgcmVhZG9ubHkgbWV0YT86IEVmZmVjdE9wLkVmZmVjdE9wWydtZXRhJ11cbiAgcmVhZG9ubHkgbWlkZGxld2FyZTogRWZmZWN0T3BDb3JlLkVmZmVjdE9wTWlkZGxld2FyZUVudiB8IHVuZGVmaW5lZFxufSk6IEVmZmVjdC5FZmZlY3Q8QSwgRSwgUj4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IG9wID0geWllbGQqIEVmZmVjdE9wLm1ha2VJblJ1blNlc3Npb24oe1xuICAgICAga2luZDogYXJncy5raW5kLFxuICAgICAgbmFtZTogYXJncy5uYW1lLFxuICAgICAgZWZmZWN0OiBhcmdzLmVmZmVjdCxcbiAgICAgIHBheWxvYWQ6IGFyZ3MucGF5bG9hZCxcbiAgICAgIG1ldGE6IGFyZ3MubWV0YSxcbiAgICB9KVxuICAgIGNvbnN0IHN0YWNrID0gYXJncy5taWRkbGV3YXJlPy5zdGFjayA/PyBbXVxuICAgIHJldHVybiB5aWVsZCogRWZmZWN0T3AucnVuKG9wLCBzdGFjaylcbiAgfSkgYXMgdW5rbm93biBhcyBFZmZlY3QuRWZmZWN0PEEsIEUsIFI+XG5cbmNvbnN0IG1ha2VUaW1lciA9IChhcmdzOiB7XG4gIHJlYWRvbmx5IGhvc3Q6IHtcbiAgICByZWFkb25seSBzY2hlZHVsZU1pY3JvdGFzazogKGNiOiAoKSA9PiB2b2lkKSA9PiB2b2lkXG4gICAgcmVhZG9ubHkgc2NoZWR1bGVUaW1lb3V0OiAobXM6IG51bWJlciwgY2I6ICgpID0+IHZvaWQpID0+ICgpID0+IHZvaWRcbiAgfVxuICByZWFkb25seSBtczogbnVtYmVyXG4gIHJlYWRvbmx5IG9uQ2FuY2VsOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCB1bmtub3duPlxufSk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIHVua25vd24+ID0+XG4gIEVmZmVjdC5hc3luYzx2b2lkLCBuZXZlciwgdW5rbm93bj4oKHJlc3VtZSkgPT4ge1xuICAgIGxldCBmaXJlZCA9IGZhbHNlXG4gICAgY29uc3QgY2FuY2VsID0gYXJncy5ob3N0LnNjaGVkdWxlVGltZW91dChhcmdzLm1zLCAoKSA9PiB7XG4gICAgICBmaXJlZCA9IHRydWVcbiAgICAgIC8vIFJvdXRlIHJlc3VtcHRpb24gdGhyb3VnaCBhIG1pY3JvdGFzayBib3VuZGFyeTpcbiAgICAgIC8vIC0gSW1wcm92ZXMgZGV0ZXJtaW5pc20gaW4gdGVzdHMgKGRldGVybWluaXN0aWMgSG9zdFNjaGVkdWxlcikuXG4gICAgICAvLyAtIEF2b2lkcyBkZWVwIEpTLW1pY3JvdGFzayBjaGFpbnMgdGhhdCBhcmUgaW52aXNpYmxlIHRvIEhvc3RTY2hlZHVsZXIgZmx1c2hpbmcuXG4gICAgICBhcmdzLmhvc3Quc2NoZWR1bGVNaWNyb3Rhc2soKCkgPT4gcmVzdW1lKEVmZmVjdC52b2lkKSlcbiAgICB9KVxuICAgIHJldHVybiBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgICBjYW5jZWwoKVxuICAgIH0pLnBpcGUoRWZmZWN0LnppcFJpZ2h0KGZpcmVkID8gRWZmZWN0LnZvaWQgOiBhcmdzLm9uQ2FuY2VsKSlcbiAgfSlcblxuY29uc3QgZW5zdXJlTGltaXRlclJlYWR5ID0gKHJlZ2lzdHJ5OiBXb3JrZmxvd1JlZ2lzdHJ5VjEsIHJ1bnRpbWU6IFB1YmxpY01vZHVsZVJ1bnRpbWU8dW5rbm93biwgdW5rbm93bj4pID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBpZiAocmVnaXN0cnkucGFyYWxsZWxMaW1pdGVyICE9PSB1bmRlZmluZWQpIHJldHVyblxuXG4gICAgY29uc3QgaW50ZXJuYWxzID0gZ2V0UnVudGltZUludGVybmFscyhydW50aW1lKVxuICAgIGNvbnN0IHBvbGljeSA9IHlpZWxkKiBpbnRlcm5hbHMuY29uY3VycmVuY3kucmVzb2x2ZUNvbmN1cnJlbmN5UG9saWN5KClcbiAgICBjb25zdCBsaW1pdCA9IHBvbGljeS5jb25jdXJyZW5jeUxpbWl0XG4gICAgaWYgKGxpbWl0ID09PSAndW5ib3VuZGVkJykge1xuICAgICAgcmVnaXN0cnkucGFyYWxsZWxMaW1pdGVyID0gbnVsbFxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgbiA9IHR5cGVvZiBsaW1pdCA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKGxpbWl0KSAmJiBsaW1pdCA+PSAxID8gTWF0aC5mbG9vcihsaW1pdCkgOiAxNlxuICAgIHJlZ2lzdHJ5LnBhcmFsbGVsTGltaXRlciA9IHlpZWxkKiBFZmZlY3QubWFrZVNlbWFwaG9yZShuKVxuICB9KVxuXG5jb25zdCB3aXRoUm9vdEVudklmQXZhaWxhYmxlID0gPEEsIEUsIFI+KGVmZjogRWZmZWN0LkVmZmVjdDxBLCBFLCBSPik6IEVmZmVjdC5FZmZlY3Q8QSwgRSwgUj4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IHJvb3RPcHQgPSB5aWVsZCogRWZmZWN0LnNlcnZpY2VPcHRpb24oUm9vdENvbnRleHRUYWcpXG4gICAgaWYgKE9wdGlvbi5pc05vbmUocm9vdE9wdCkpIHtcbiAgICAgIHJldHVybiB5aWVsZCogZWZmXG4gICAgfVxuICAgIGNvbnN0IHJvb3Q6IFJvb3RDb250ZXh0ID0gcm9vdE9wdC52YWx1ZVxuICAgIGNvbnN0IHJvb3RFbnYgPSByb290LmNvbnRleHQgPz8gKHlpZWxkKiBEZWZlcnJlZC5hd2FpdChyb290LnJlYWR5KSlcblxuICAgIGNvbnN0IGN1cnJlbnRFbnYgPSB5aWVsZCogRWZmZWN0LmNvbnRleHQ8dW5rbm93bj4oKVxuICAgIGNvbnN0IG1lcmdlZEVudiA9IENvbnRleHQubWVyZ2Uocm9vdEVudiBhcyB1bmtub3duIGFzIENvbnRleHQuQ29udGV4dDx1bmtub3duPiwgY3VycmVudEVudilcbiAgICByZXR1cm4geWllbGQqIChFZmZlY3QucHJvdmlkZShlZmYgYXMgdW5rbm93biBhcyBFZmZlY3QuRWZmZWN0PEEsIEUsIHVua25vd24+LCBtZXJnZWRFbnYpIGFzIHVua25vd24gYXMgRWZmZWN0LkVmZmVjdDxBLCBFLCBSPilcbiAgfSkgYXMgdW5rbm93biBhcyBFZmZlY3QuRWZmZWN0PEEsIEUsIFI+XG5cbmNvbnN0IGVuc3VyZVBvcnRzUmVzb2x2ZWQgPSAoXG4gIHJlZ2lzdHJ5OiBXb3JrZmxvd1JlZ2lzdHJ5VjEsXG4gIHJ1bnRpbWU6IFB1YmxpY01vZHVsZVJ1bnRpbWU8dW5rbm93biwgdW5rbm93bj4sXG4pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIHVua25vd24sIHVua25vd24+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBkb25lID0geWllbGQqIERlZmVycmVkLmlzRG9uZShyZWdpc3RyeS5wb3J0c1JlYWR5KVxuICAgIGlmIChkb25lKSB7XG4gICAgICB5aWVsZCogRGVmZXJyZWQuYXdhaXQocmVnaXN0cnkucG9ydHNSZWFkeSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChyZWdpc3RyeS5wb3J0c1Jlc29sdmluZykge1xuICAgICAgeWllbGQqIERlZmVycmVkLmF3YWl0KHJlZ2lzdHJ5LnBvcnRzUmVhZHkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICByZWdpc3RyeS5wb3J0c1Jlc29sdmluZyA9IHRydWVcbiAgICBjb25zdCBlbnYgPSB5aWVsZCogRWZmZWN0LmNvbnRleHQ8dW5rbm93bj4oKVxuXG4gICAgeWllbGQqIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgIGNvbnN0IHBvcnRDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBTZXJ2aWNlUG9ydD4oKVxuICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiByZWdpc3RyeS5lbnRyaWVzKSB7XG4gICAgICAgIGNvbnN0IHByb2dyYW0gPSBlbnRyeS5wcm9ncmFtXG4gICAgICAgIGlmIChwcm9ncmFtLnN0ZXBzKSBjb250aW51ZVxuXG4gICAgICAgIGNvbnN0IHJlc29sdmVQb3J0ID0gKHNlcnZpY2VJZDogc3RyaW5nLCBzdGVwS2V5OiBzdHJpbmcpOiBTZXJ2aWNlUG9ydCA9PiB7XG4gICAgICAgICAgY29uc3QgY2FjaGVkID0gcG9ydENhY2hlLmdldChzZXJ2aWNlSWQpXG4gICAgICAgICAgaWYgKGNhY2hlZCkgcmV0dXJuIGNhY2hlZFxuICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZVNlcnZpY2VQb3J0KHJ1bnRpbWUsIGVudiwgc2VydmljZUlkLCBwcm9ncmFtLnByb2dyYW1JZCwgc3RlcEtleSlcbiAgICAgICAgICBwb3J0Q2FjaGUuc2V0KHNlcnZpY2VJZCwgcmVzb2x2ZWQpXG4gICAgICAgICAgcmV0dXJuIHJlc29sdmVkXG4gICAgICAgIH1cblxuICAgICAgICBwcm9ncmFtLnN0ZXBzID0gY29tcGlsZVN0ZXBzKHByb2dyYW0uY29tcGlsZWRTdGVwcywgcmVzb2x2ZVBvcnQpXG4gICAgICB9XG4gICAgfSkucGlwZShcbiAgICAgIEVmZmVjdC50YXAoKCkgPT4gRGVmZXJyZWQuc3VjY2VlZChyZWdpc3RyeS5wb3J0c1JlYWR5LCB1bmRlZmluZWQpKSxcbiAgICAgIEVmZmVjdC5jYXRjaEFsbENhdXNlKChjYXVzZSkgPT4gRGVmZXJyZWQuZmFpbENhdXNlKHJlZ2lzdHJ5LnBvcnRzUmVhZHksIGNhdXNlKS5waXBlKEVmZmVjdC56aXBSaWdodChFZmZlY3QuZmFpbENhdXNlKGNhdXNlKSkpKSxcbiAgICAgIEVmZmVjdC5lbnN1cmluZyhcbiAgICAgICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgICAgIHJlZ2lzdHJ5LnBvcnRzUmVzb2x2aW5nID0gZmFsc2VcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIClcbiAgfSlcblxuY29uc3Qgc2hvdWxkT2JzZXJ2ZUZvclJ1biA9IChkaWFnbm9zdGljczogRGVidWcuRGlhZ25vc3RpY3NMZXZlbCwgcnVuU2VxOiBudW1iZXIpOiBib29sZWFuID0+IHtcbiAgaWYgKGRpYWdub3N0aWNzID09PSAnb2ZmJykgcmV0dXJuIGZhbHNlXG4gIGlmIChkaWFnbm9zdGljcyA9PT0gJ3NhbXBsZWQnKSB7XG4gICAgLy8gRGV0ZXJtaW5pc3RpYyBzYW1wbGluZyAobm8gTWF0aC5yYW5kb20pOiAxLzE2IGJ5IHJ1blNlcS5cbiAgICByZXR1cm4gKHJ1blNlcSAmIDB4MGYpID09PSAwXG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuY29uc3Qgc3RhcnRQcm9ncmFtUnVuID0gKGFyZ3M6IHtcbiAgcmVhZG9ubHkgZW50cnk6IFByb2dyYW1FbnRyeVxuICByZWFkb25seSBydW50aW1lOiBQdWJsaWNNb2R1bGVSdW50aW1lPHVua25vd24sIHVua25vd24+XG4gIHJlYWRvbmx5IHJlZ2lzdHJ5OiBXb3JrZmxvd1JlZ2lzdHJ5VjFcbiAgcmVhZG9ubHkgdHJpZ2dlcjogeyByZWFkb25seSBraW5kOiAnYWN0aW9uJzsgcmVhZG9ubHkgYWN0aW9uVGFnOiBzdHJpbmcgfSB8IHsgcmVhZG9ubHkga2luZDogJ2xpZmVjeWNsZSc7IHJlYWRvbmx5IHBoYXNlOiBzdHJpbmcgfVxuICByZWFkb25seSBwYXlsb2FkOiB1bmtub3duXG4gIHJlYWRvbmx5IG1pZGRsZXdhcmU6IEVmZmVjdE9wQ29yZS5FZmZlY3RPcE1pZGRsZXdhcmVFbnYgfCB1bmRlZmluZWRcbn0pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCB1bmtub3duPiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3QgeyBlbnRyeSwgcnVudGltZSwgcmVnaXN0cnkgfSA9IGFyZ3NcbiAgICBjb25zdCB7IHByb2dyYW0sIHN0YXRlIH0gPSBlbnRyeVxuXG4gICAgY29uc3QgZGlhZ25vc3RpY3MgPSB5aWVsZCogRmliZXJSZWYuZ2V0KERlYnVnLmN1cnJlbnREaWFnbm9zdGljc0xldmVsKVxuXG4gICAgY29uc3QgYmVnaW5SdW4gPSAoKTogeyByZWFkb25seSBydW5TZXE6IG51bWJlcjsgcmVhZG9ubHkgcnVuSWQ6IHN0cmluZzsgcmVhZG9ubHkgY2FuV3JpdGVCYWNrOiAoKSA9PiBib29sZWFuIH0gPT4ge1xuICAgICAgaWYgKHN0YXRlLm1vZGUgPT09ICdsYXRlc3QnKSB7XG4gICAgICAgIHN0YXRlLnJ1blNlcSArPSAxXG4gICAgICAgIGNvbnN0IHJ1blNlcSA9IHN0YXRlLnJ1blNlcVxuICAgICAgICBjb25zdCBydW5JZCA9IG1ha2VSdW5JZChydW50aW1lLmluc3RhbmNlSWQsIHByb2dyYW0ucHJvZ3JhbUlkLCBydW5TZXEpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcnVuU2VxLFxuICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgIGNhbldyaXRlQmFjazogKCkgPT4gc3RhdGUucnVuU2VxID09PSBydW5TZXEsXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RhdGUucnVuU2VxICs9IDFcbiAgICAgIGNvbnN0IHJ1blNlcSA9IHN0YXRlLnJ1blNlcVxuICAgICAgY29uc3QgcnVuSWQgPSBtYWtlUnVuSWQocnVudGltZS5pbnN0YW5jZUlkLCBwcm9ncmFtLnByb2dyYW1JZCwgcnVuU2VxKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcnVuU2VxLFxuICAgICAgICBydW5JZCxcbiAgICAgICAgY2FuV3JpdGVCYWNrOiAoKSA9PiB0cnVlLFxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdGF0ZS5tb2RlID09PSAnZXhoYXVzdCcpIHtcbiAgICAgIGlmIChzdGF0ZS5idXN5KSB7XG4gICAgICAgIGlmIChkaWFnbm9zdGljcyAhPT0gJ29mZicpIHtcbiAgICAgICAgICBjb25zdCBvYnNlcnZlID0gc2hvdWxkT2JzZXJ2ZUZvclJ1bihkaWFnbm9zdGljcywgc3RhdGUucnVuU2VxKVxuICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBvYnNlcnZlID8gKHlpZWxkKiBUaWNrU2NoZWR1bGVyVGFnKS5nZXRUaWNrU2VxKCkgOiB1bmRlZmluZWRcbiAgICAgICAgICB5aWVsZCogcnVuQm91bmRhcnkoe1xuICAgICAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICAgICAgbmFtZTogJ3dvcmtmbG93LmRyb3AnLFxuICAgICAgICAgICAgcGF5bG9hZDogeyBwcm9ncmFtSWQ6IHByb2dyYW0ucHJvZ3JhbUlkLCB0cmlnZ2VyOiBhcmdzLnRyaWdnZXIgfSxcbiAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgLi4uKHRpY2tTZXEgIT09IHVuZGVmaW5lZCA/IHsgdGlja1NlcSB9IDogbnVsbCksXG4gICAgICAgICAgICAgIHBvbGljeTogeyBkaXNhYmxlT2JzZXJ2ZXJzOiAhb2JzZXJ2ZSB9LFxuICAgICAgICAgICAgICByZWFzb246ICdleGhhdXN0JyBhcyBjb25zdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBzdGF0ZS5idXN5ID0gdHJ1ZVxuICAgIH1cblxuICAgIGNvbnN0IHsgcnVuU2VxLCBydW5JZCwgY2FuV3JpdGVCYWNrIH0gPSBiZWdpblJ1bigpXG5cbiAgICBpZiAoc3RhdGUubW9kZSA9PT0gJ2xhdGVzdCcpIHtcbiAgICAgIGNvbnN0IHByZXYgPSBzdGF0ZS5jdXJyZW50XG4gICAgICBjb25zdCBwcmV2UnVuSWQgPSBzdGF0ZS5jdXJyZW50UnVuSWRcbiAgICAgIGlmIChwcmV2KSB7XG4gICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHRGb3JrKHByZXYpXG4gICAgICAgIGlmIChkaWFnbm9zdGljcyAhPT0gJ29mZicpIHtcbiAgICAgICAgICBjb25zdCBvYnNlcnZlID0gc2hvdWxkT2JzZXJ2ZUZvclJ1bihkaWFnbm9zdGljcywgcnVuU2VxKVxuICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBvYnNlcnZlID8gKHlpZWxkKiBUaWNrU2NoZWR1bGVyVGFnKS5nZXRUaWNrU2VxKCkgOiB1bmRlZmluZWRcbiAgICAgICAgICB5aWVsZCogcnVuQm91bmRhcnkoe1xuICAgICAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICAgICAgbmFtZTogJ3dvcmtmbG93LmNhbmNlbCcsXG4gICAgICAgICAgICBwYXlsb2FkOiB7IHByb2dyYW1JZDogcHJvZ3JhbS5wcm9ncmFtSWQsIGNhbmNlbGxlZDogcHJldlJ1bklkLCBieTogcnVuSWQgfSxcbiAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgLi4uKHRpY2tTZXEgIT09IHVuZGVmaW5lZCA/IHsgdGlja1NlcSB9IDogbnVsbCksXG4gICAgICAgICAgICAgIHBvbGljeTogeyBkaXNhYmxlT2JzZXJ2ZXJzOiAhb2JzZXJ2ZSB9LFxuICAgICAgICAgICAgICByZWFzb246ICdsYXRlc3QnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICBjYW5jZWxsZWRCeVJ1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgY2FuY2VsbGVkUnVuSWQ6IHByZXZSdW5JZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN0YXRlLmN1cnJlbnRSdW5JZCA9IHJ1bklkXG4gICAgfVxuXG4gICAgY29uc3Qgb2JzZXJ2ZSA9IHNob3VsZE9ic2VydmVGb3JSdW4oZGlhZ25vc3RpY3MsIHJ1blNlcSlcbiAgICBjb25zdCBwb2xpY3kgPSB7IGRpc2FibGVPYnNlcnZlcnM6ICFvYnNlcnZlIH0gc2F0aXNmaWVzIE5vbk51bGxhYmxlPEVmZmVjdE9wLkVmZmVjdE9wWydtZXRhJ10+Wydwb2xpY3knXVxuXG4gICAgY29uc3QgcHJvZ3JhbUVmZmVjdCA9IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IGhvc3QgPSB5aWVsZCogSG9zdFNjaGVkdWxlclRhZ1xuICAgICAgY29uc3QgdGljayA9IHlpZWxkKiBUaWNrU2NoZWR1bGVyVGFnXG5cbiAgICAgIGlmICghcHJvZ3JhbS5zdGVwcykge1xuICAgICAgICBjb25zdCBlbnYgPSB5aWVsZCogRWZmZWN0LmNvbnRleHQ8dW5rbm93bj4oKVxuICAgICAgICBjb25zdCBwb3J0Q2FjaGUgPSBuZXcgTWFwPHN0cmluZywgU2VydmljZVBvcnQ+KClcbiAgICAgICAgY29uc3QgcmVzb2x2ZVBvcnQgPSAoc2VydmljZUlkOiBzdHJpbmcsIHN0ZXBLZXk6IHN0cmluZyk6IFNlcnZpY2VQb3J0ID0+IHtcbiAgICAgICAgICBjb25zdCBjYWNoZWQgPSBwb3J0Q2FjaGUuZ2V0KHNlcnZpY2VJZClcbiAgICAgICAgICBpZiAoY2FjaGVkKSByZXR1cm4gY2FjaGVkXG4gICAgICAgICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlU2VydmljZVBvcnQocnVudGltZSwgZW52LCBzZXJ2aWNlSWQsIHByb2dyYW0ucHJvZ3JhbUlkLCBzdGVwS2V5KVxuICAgICAgICAgIHBvcnRDYWNoZS5zZXQoc2VydmljZUlkLCByZXNvbHZlZClcbiAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRcbiAgICAgICAgfVxuICAgICAgICBwcm9ncmFtLnN0ZXBzID0gY29tcGlsZVN0ZXBzKHByb2dyYW0uY29tcGlsZWRTdGVwcywgcmVzb2x2ZVBvcnQpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGdldFRpY2tTZXEgPSAoKTogbnVtYmVyIHwgdW5kZWZpbmVkID0+IChvYnNlcnZlID8gdGljay5nZXRUaWNrU2VxKCkgOiB1bmRlZmluZWQpXG4gICAgICBjb25zdCBlbWl0VGltZXJFdmVudHMgPSBvYnNlcnZlICYmIGRpYWdub3N0aWNzID09PSAnZnVsbCdcblxuICAgICAgY29uc3QgZXZhbFBheWxvYWQgPSAoZXhwcjogQ29tcGlsZWRJbnB1dEV4cHIgfCB1bmRlZmluZWQpOiB1bmtub3duID0+IChleHByID8gZXZhbElucHV0RXhwcihleHByLCBhcmdzLnBheWxvYWQpIDogdW5kZWZpbmVkKVxuXG4gICAgICBjb25zdCBkZWZhdWx0SW5wdXRGb3JDYWxsID0gKCk6IHVua25vd24gPT5cbiAgICAgICAgYXJncy50cmlnZ2VyLmtpbmQgPT09ICdhY3Rpb24nID8gYXJncy5wYXlsb2FkIDogdW5kZWZpbmVkXG5cbiAgICAgIGxldCB0aW1lclRyaWdnZXJlZCA9IGZhbHNlXG5cbiAgICAgIGNvbnN0IHJ1blN0ZXBzID0gKHN0ZXBzOiBSZWFkb25seUFycmF5PENvbXBpbGVkUnVudGltZVN0ZXA+KTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgdW5rbm93bj4gPT5cbiAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgIGZvciAoY29uc3Qgc3RlcCBvZiBzdGVwcykge1xuICAgICAgICAgICAgaWYgKCFjYW5Xcml0ZUJhY2soKSkgcmV0dXJuXG5cbiAgICAgICAgICAgIGlmIChzdGVwLmtpbmQgPT09ICdkaXNwYXRjaCcpIHtcbiAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGV2YWxQYXlsb2FkKHN0ZXAucGF5bG9hZClcbiAgICAgICAgICAgICAgY29uc3QgYWN0aW9uID0geyBfdGFnOiBzdGVwLmFjdGlvblRhZywgcGF5bG9hZCB9XG4gICAgICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBnZXRUaWNrU2VxKClcblxuICAgICAgICAgICAgICBjb25zdCBkaXNwYXRjaEVmZmVjdEJhc2UgPVxuICAgICAgICAgICAgICAgIHByb2dyYW0ucHJpb3JpdHkgPT09ICdub25VcmdlbnQnID8gcnVudGltZS5kaXNwYXRjaExvd1ByaW9yaXR5KGFjdGlvbikgOiBydW50aW1lLmRpc3BhdGNoKGFjdGlvbilcblxuICAgICAgICAgICAgICBjb25zdCBkaXNwYXRjaEVmZmVjdCA9IHRpbWVyVHJpZ2dlcmVkXG4gICAgICAgICAgICAgICAgPyBFZmZlY3QubG9jYWxseShcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFR4bk9yaWdpbk92ZXJyaWRlLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAga2luZDogJ3dvcmtmbG93LnRpbWVyJyxcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBgdGltZXI6JHtwcm9ncmFtLnByb2dyYW1JZH06JHtzdGVwLmtleX1gLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgKShkaXNwYXRjaEVmZmVjdEJhc2UpXG4gICAgICAgICAgICAgICAgOiBkaXNwYXRjaEVmZmVjdEJhc2VcblxuICAgICAgICAgICAgICB5aWVsZCogcnVuQm91bmRhcnkoe1xuICAgICAgICAgICAgICAgIGtpbmQ6ICdmbG93JyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnd29ya2Zsb3cuZGlzcGF0Y2gnLFxuICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsgYWN0aW9uVGFnOiBzdGVwLmFjdGlvblRhZyB9LFxuICAgICAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICAgICAgc3RlcEtleTogc3RlcC5rZXksXG4gICAgICAgICAgICAgICAgICAuLi4odGlja1NlcSAhPT0gdW5kZWZpbmVkID8geyB0aWNrU2VxIH0gOiBudWxsKSxcbiAgICAgICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVmZmVjdDogZGlzcGF0Y2hFZmZlY3QsXG4gICAgICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgICAgICB9KS5waXBlKEVmZmVjdC5hc1ZvaWQpXG4gICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdGVwLmtpbmQgPT09ICdkZWxheScpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGltZXJJZCA9IGVtaXRUaW1lckV2ZW50cyA/IGAke3J1bklkfTo6dGltZXI6JHtzdGVwLmtleX1gIDogdW5kZWZpbmVkXG5cbiAgICAgICAgICAgICAgY29uc3QgcmVjb3JkVGltZXJFdmVudCA9IChuYW1lOiBzdHJpbmcsIHBhdGNoTWV0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgICAgICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBnZXRUaWNrU2VxKClcbiAgICAgICAgICAgICAgICAgIHlpZWxkKiBydW5Cb3VuZGFyeSh7XG4gICAgICAgICAgICAgICAgICAgIGtpbmQ6ICdmbG93JyxcbiAgICAgICAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZDogeyBtczogc3RlcC5tcyB9LFxuICAgICAgICAgICAgICAgICAgICBtZXRhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgICAgIHByb2dyYW1JZDogcHJvZ3JhbS5wcm9ncmFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgICAgICAgICAgc3RlcEtleTogc3RlcC5rZXksXG4gICAgICAgICAgICAgICAgICAgICAgLi4uKHRpbWVySWQgPyB7IHRpbWVySWQgfSA6IG51bGwpLFxuICAgICAgICAgICAgICAgICAgICAgIC4uLih0aWNrU2VxICE9PSB1bmRlZmluZWQgPyB7IHRpY2tTZXEgfSA6IG51bGwpLFxuICAgICAgICAgICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgICAgICAgICAuLi4ocGF0Y2hNZXRhID8/IG51bGwpLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgICAgICAgICBtaWRkbGV3YXJlOiBhcmdzLm1pZGRsZXdhcmUsXG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgY29uc3Qgc2NoZWR1bGUgPSBlbWl0VGltZXJFdmVudHMgPyByZWNvcmRUaW1lckV2ZW50KCd3b3JrZmxvdy50aW1lci5zY2hlZHVsZScpIDogRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgY29uc3Qgb25DYW5jZWwgPSBlbWl0VGltZXJFdmVudHMgPyByZWNvcmRUaW1lckV2ZW50KCd3b3JrZmxvdy50aW1lci5jYW5jZWwnLCB7IHJlYXNvbjogJ2ludGVycnVwdCcgfSkgOiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICBjb25zdCBmaXJlZCA9IGVtaXRUaW1lckV2ZW50cyA/IHJlY29yZFRpbWVyRXZlbnQoJ3dvcmtmbG93LnRpbWVyLmZpcmVkJykgOiBFZmZlY3Qudm9pZFxuXG4gICAgICAgICAgICAgIGNvbnN0IGRlbGF5RWZmZWN0ID0gc2NoZWR1bGUucGlwZShcbiAgICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQobWFrZVRpbWVyKHsgaG9zdCwgbXM6IHN0ZXAubXMsIG9uQ2FuY2VsIH0pKSxcbiAgICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQoZmlyZWQpLFxuICAgICAgICAgICAgICApXG5cbiAgICAgICAgICAgICAgY29uc3QgdGlja1NlcSA9IGdldFRpY2tTZXEoKVxuXG4gICAgICAgICAgICAgIHlpZWxkKiBydW5Cb3VuZGFyeSh7XG4gICAgICAgICAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICd3b3JrZmxvdy5kZWxheScsXG4gICAgICAgICAgICAgICAgcGF5bG9hZDogeyBtczogc3RlcC5tcyB9LFxuICAgICAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICAgICAgc3RlcEtleTogc3RlcC5rZXksXG4gICAgICAgICAgICAgICAgICAuLi4odGlja1NlcSAhPT0gdW5kZWZpbmVkID8geyB0aWNrU2VxIH0gOiBudWxsKSxcbiAgICAgICAgICAgICAgICAgIC4uLih0aW1lcklkID8geyB0aW1lcklkIH0gOiBudWxsKSxcbiAgICAgICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVmZmVjdDogZGVsYXlFZmZlY3QsXG4gICAgICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgICAgICB9KS5waXBlKEVmZmVjdC5hc1ZvaWQpXG5cbiAgICAgICAgICAgICAgdGltZXJUcmlnZ2VyZWQgPSB0cnVlXG4gICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGNhbGxcbiAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gc3RlcC5pbnB1dCA/IGV2YWxJbnB1dEV4cHIoc3RlcC5pbnB1dCwgYXJncy5wYXlsb2FkKSA6IGRlZmF1bHRJbnB1dEZvckNhbGwoKVxuICAgICAgICAgICAgY29uc3QgbWF4UmV0cmllcyA9IHN0ZXAucmV0cnlUaW1lcyA/PyAwXG4gICAgICAgICAgICAvLyBBdHRlbXB0IGlkIGlzIDEtYmFzZWQgYW5kIHN0YWJsZSB3aXRoaW4gYSBydW4uXG4gICAgICAgICAgICBsZXQgZXhpdDogRXhpdC5FeGl0PHVua25vd24sIHVua25vd24+IHwgdW5kZWZpbmVkXG4gICAgICAgICAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgYXR0ZW1wdCA8PSBtYXhSZXRyaWVzICsgMTsgYXR0ZW1wdCArPSAxKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBnZXRUaWNrU2VxKClcblxuICAgICAgICAgICAgICBjb25zdCBiYXNlID0gcnVuQm91bmRhcnkoe1xuICAgICAgICAgICAgICAgIGtpbmQ6ICdzZXJ2aWNlJyxcbiAgICAgICAgICAgICAgICBuYW1lOiBgd29ya2Zsb3cuY2FsbDoke3N0ZXAuc2VydmljZUlkfWAsXG4gICAgICAgICAgICAgICAgcGF5bG9hZDogeyBzZXJ2aWNlSWQ6IHN0ZXAuc2VydmljZUlkIH0sXG4gICAgICAgICAgICAgICAgbWV0YToge1xuICAgICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6IHByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgICAgICBzdGVwS2V5OiBzdGVwLmtleSxcbiAgICAgICAgICAgICAgICAgIHNlcnZpY2VJZDogc3RlcC5zZXJ2aWNlSWQsXG4gICAgICAgICAgICAgICAgICBhdHRlbXB0LFxuICAgICAgICAgICAgICAgICAgLi4uKHRpY2tTZXEgIT09IHVuZGVmaW5lZCA/IHsgdGlja1NlcSB9IDogbnVsbCksXG4gICAgICAgICAgICAgICAgICBwb2xpY3ksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlZmZlY3Q6IHN0ZXAucG9ydChpbnB1dCksXG4gICAgICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgIGNvbnN0IHdpdGhUaW1lb3V0ID1cbiAgICAgICAgICAgICAgICBzdGVwLnRpbWVvdXRNcyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICA/IGJhc2VcbiAgICAgICAgICAgICAgICAgIDogRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWVvdXRNcyA9IHN0ZXAudGltZW91dE1zXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVvdXRNcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWZlbnNpdmU6IFRTIGRvZXNuJ3Qga2VlcCBuYXJyb3dpbmcgYWNyb3NzIGdlbmVyYXRvciBib3VuZGFyaWVzLlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBiYXNlXG4gICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gVW5pcXVlIHBlciBhdHRlbXB0IChvdGhlcndpc2UgcmV0cmllcyB3b3VsZCByZXVzZSB0aGUgc2FtZSB0aW1lcklkIGFuZCBicmVhayBleHBsYWluYWJpbGl0eSkuXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGltZXJJZCA9IGVtaXRUaW1lckV2ZW50cyA/IGAke3J1bklkfTo6dGltZW91dDoke3N0ZXAua2V5fTphJHthdHRlbXB0fWAgOiB1bmRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlY29yZFRpbWVvdXRFdmVudCA9IChuYW1lOiBzdHJpbmcsIHBhdGNoTWV0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aWNrU2VxID0gZ2V0VGlja1NlcSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHlpZWxkKiBydW5Cb3VuZGFyeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZDogeyBtczogdGltZW91dE1zIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6IHByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwS2V5OiBzdGVwLmtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dGVtcHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4odGltZXJJZCA/IHsgdGltZXJJZCB9IDogbnVsbCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4odGlja1NlcSAhPT0gdW5kZWZpbmVkID8geyB0aWNrU2VxIH0gOiBudWxsKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLihwYXRjaE1ldGEgPz8gbnVsbCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pZGRsZXdhcmU6IGFyZ3MubWlkZGxld2FyZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzY2hlZHVsZSA9IGVtaXRUaW1lckV2ZW50cyA/IHJlY29yZFRpbWVvdXRFdmVudCgnd29ya2Zsb3cudGltZW91dC5zY2hlZHVsZScpIDogRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbkNhbmNlbCA9IGVtaXRUaW1lckV2ZW50c1xuICAgICAgICAgICAgICAgICAgICAgICAgPyByZWNvcmRUaW1lb3V0RXZlbnQoJ3dvcmtmbG93LnRpbWVvdXQuY2FuY2VsJywgeyByZWFzb246ICdpbnRlcnJ1cHQnIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICA6IEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWQgPSBlbWl0VGltZXJFdmVudHMgPyByZWNvcmRUaW1lb3V0RXZlbnQoJ3dvcmtmbG93LnRpbWVvdXQuZmlyZWQnKSA6IEVmZmVjdC52b2lkXG5cbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lb3V0RXJyb3IgPSBtYWtlV29ya2Zsb3dFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiAnV09SS0ZMT1dfQ0FMTF9USU1FT1VUJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBXb3JrZmxvdyBjYWxsIHRpbWVkIG91dCAoc2VydmljZUlkPVwiJHtzdGVwLnNlcnZpY2VJZH1cIiwgdGltZW91dE1zPSR7dGltZW91dE1zfSkuYCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyYW1JZDogcHJvZ3JhbS5wcm9ncmFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHsgc3RlcEtleTogc3RlcC5rZXkgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRldGFpbDogeyBzZXJ2aWNlSWQ6IHN0ZXAuc2VydmljZUlkLCB0aW1lb3V0TXMsIGF0dGVtcHQgfSxcbiAgICAgICAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGltZW91dEZhaWwgPSBzY2hlZHVsZS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgRWZmZWN0LnppcFJpZ2h0KG1ha2VUaW1lcih7IGhvc3QsIG1zOiB0aW1lb3V0TXMsIG9uQ2FuY2VsIH0pKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIEVmZmVjdC56aXBSaWdodChmaXJlZCksXG4gICAgICAgICAgICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQoRWZmZWN0LmZhaWwodGltZW91dEVycm9yKSksXG4gICAgICAgICAgICAgICAgICAgICAgKVxuXG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QucmFjZUZpcnN0KGJhc2UsIHRpbWVvdXRGYWlsKVxuICAgICAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgIGNvbnN0IGF0dGVtcHRFeGl0ID0geWllbGQqIEVmZmVjdC5leGl0KHdpdGhUaW1lb3V0KVxuICAgICAgICAgICAgICBleGl0ID0gYXR0ZW1wdEV4aXRcblxuICAgICAgICAgICAgICBpZiAoIWNhbldyaXRlQmFjaygpIHx8IEV4aXQuaXNTdWNjZXNzKGF0dGVtcHRFeGl0KSkge1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBEbyBub3QgcmV0cnkgZGVmZWN0cy9pbnRlcnJ1cHRzOyBvbmx5IHJldHJ5IGZhaWx1cmUtY2hhbm5lbCBlcnJvcnMuXG4gICAgICAgICAgICAgIGlmIChDYXVzZS5pc0ludGVycnVwdGVkKGF0dGVtcHRFeGl0LmNhdXNlKSB8fCBPcHRpb24uaXNOb25lKENhdXNlLmZhaWx1cmVPcHRpb24oYXR0ZW1wdEV4aXQuY2F1c2UpKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBSZXRyeSBpZiB3ZSBzdGlsbCBoYXZlIHJlbWFpbmluZyBhdHRlbXB0cy5cbiAgICAgICAgICAgICAgaWYgKGF0dGVtcHQgPCBtYXhSZXRyaWVzICsgMSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEZWZlbnNpdmU6IGF0dGVtcHQgbG9vcCBhbHdheXMgcnVucyBhdCBsZWFzdCBvbmNlLlxuICAgICAgICAgICAgaWYgKCFleGl0KSB7XG4gICAgICAgICAgICAgIGV4aXQgPSBFeGl0LnN1Y2NlZWQodW5kZWZpbmVkKSBhcyBFeGl0LkV4aXQ8dW5rbm93biwgdW5rbm93bj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFjYW5Xcml0ZUJhY2soKSkgcmV0dXJuXG5cbiAgICAgICAgICAgIGlmIChFeGl0LmlzU3VjY2VzcyhleGl0KSkge1xuICAgICAgICAgICAgICB5aWVsZCogcnVuU3RlcHMoc3RlcC5vblN1Y2Nlc3MpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBUaW1lb3V0IHVzZXMgYSB0aW1lcjsgbWFyayB0aGUgY29udGludWF0aW9uIGFzIHRpbWVyLXRyaWdnZXJlZCAoZm9yIHRyYWNlOnRpY2sudHJpZ2dlclN1bW1hcnkpLlxuICAgICAgICAgICAgICBjb25zdCBmYWlsdXJlID0gT3B0aW9uLmdldE9yVW5kZWZpbmVkKENhdXNlLmZhaWx1cmVPcHRpb24oZXhpdC5jYXVzZSkpXG4gICAgICAgICAgICAgIGNvbnN0IGlzVGltZW91dCA9XG4gICAgICAgICAgICAgICAgaXNPYmplY3RMaWtlKGZhaWx1cmUpICYmXG4gICAgICAgICAgICAgICAgKGZhaWx1cmUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLl90YWcgPT09ICdXb3JrZmxvd0Vycm9yJyAmJlxuICAgICAgICAgICAgICAgIChmYWlsdXJlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5jb2RlID09PSAnV09SS0ZMT1dfQ0FMTF9USU1FT1VUJ1xuICAgICAgICAgICAgICBpZiAoaXNUaW1lb3V0KSB0aW1lclRyaWdnZXJlZCA9IHRydWVcbiAgICAgICAgICAgICAgeWllbGQqIHJ1blN0ZXBzKHN0ZXAub25GYWlsdXJlKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgY29uc3QgcnVuVGlja1NlcSA9IGdldFRpY2tTZXEoKVxuICAgICAgeWllbGQqIHJ1bkJvdW5kYXJ5KHtcbiAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICBuYW1lOiAnd29ya2Zsb3cucnVuJyxcbiAgICAgICAgcGF5bG9hZDogeyB0cmlnZ2VyOiBhcmdzLnRyaWdnZXIgfSxcbiAgICAgICAgbWV0YToge1xuICAgICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICAgIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCxcbiAgICAgICAgICBwcm9ncmFtSWQ6IHByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgIC4uLihydW5UaWNrU2VxICE9PSB1bmRlZmluZWQgPyB7IHRpY2tTZXE6IHJ1blRpY2tTZXEgfSA6IG51bGwpLFxuICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgfSxcbiAgICAgICAgZWZmZWN0OiBydW5TdGVwcyhwcm9ncmFtLnN0ZXBzISksXG4gICAgICAgIG1pZGRsZXdhcmU6IGFyZ3MubWlkZGxld2FyZSxcbiAgICAgIH0pLnBpcGUoRWZmZWN0LmFzVm9pZClcbiAgICB9KVxuXG4gICAgY29uc3QgbGltaXRlZCA9IHJlZ2lzdHJ5LnBhcmFsbGVsTGltaXRlciA/IHJlZ2lzdHJ5LnBhcmFsbGVsTGltaXRlci53aXRoUGVybWl0cygxKShwcm9ncmFtRWZmZWN0KSA6IHByb2dyYW1FZmZlY3RcblxuICAgIGNvbnN0IGZpYmVyID0geWllbGQqIEVmZmVjdC5mb3JrU2NvcGVkKFxuICAgICAgbGltaXRlZC5waXBlKFxuICAgICAgICBFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoY2F1c2UpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVycm9yU3VtbWFyeSwgZG93bmdyYWRlIH0gPSB0b1NlcmlhbGl6YWJsZUVycm9yU3VtbWFyeShjYXVzZSlcbiAgICAgICAgICBjb25zdCBkb3duZ3JhZGVIaW50ID0gZG93bmdyYWRlID8gYCAoZG93bmdyYWRlPSR7ZG93bmdyYWRlfSlgIDogJydcbiAgICAgICAgICByZXR1cm4gRGVidWcucmVjb3JkKHtcbiAgICAgICAgICAgIHR5cGU6ICdkaWFnbm9zdGljJyxcbiAgICAgICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgY29kZTogJ3dvcmtmbG93OjpydW5fY3Jhc2hlZCcsXG4gICAgICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGBXb3JrZmxvdyBydW4gY3Jhc2hlZCBmb3IgcHJvZ3JhbUlkPVwiJHtwcm9ncmFtLnByb2dyYW1JZH1cIiBydW5JZD1cIiR7cnVuSWR9XCIuJHtkb3duZ3JhZGVIaW50fWAsXG4gICAgICAgICAgICBoaW50OiBgJHtlcnJvclN1bW1hcnkubmFtZSA/IGAke2Vycm9yU3VtbWFyeS5uYW1lfTogYCA6ICcnfSR7ZXJyb3JTdW1tYXJ5Lm1lc3NhZ2V9YCxcbiAgICAgICAgICAgIGFjdGlvblRhZzogYXJncy50cmlnZ2VyLmtpbmQgPT09ICdhY3Rpb24nID8gYXJncy50cmlnZ2VyLmFjdGlvblRhZyA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGtpbmQ6ICd3b3JrZmxvd19ydW5fY3Jhc2hlZCcsXG4gICAgICAgICAgICB0cmlnZ2VyOiB7XG4gICAgICAgICAgICAgIGtpbmQ6ICd3b3JrZmxvdycsXG4gICAgICAgICAgICAgIG5hbWU6ICdydW4nLFxuICAgICAgICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgICAgICB0cmlnZ2VyOiBhcmdzLnRyaWdnZXIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLnBpcGUoRWZmZWN0LmNhdGNoQWxsQ2F1c2UoKCkgPT4gRWZmZWN0LnZvaWQpKVxuICAgICAgICB9KSxcbiAgICAgICAgRWZmZWN0LmVuc3VyaW5nKFxuICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgIGlmIChzdGF0ZS5tb2RlID09PSAnZXhoYXVzdCcpIHtcbiAgICAgICAgICAgICAgc3RhdGUuYnVzeSA9IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICApLFxuICAgIClcblxuICAgIGlmIChzdGF0ZS5tb2RlID09PSAnbGF0ZXN0Jykge1xuICAgICAgc3RhdGUuY3VycmVudCA9IGZpYmVyIGFzIEZpYmVyLlJ1bnRpbWVGaWJlcjx2b2lkLCBuZXZlcj5cbiAgICB9XG4gIH0pXG5cbnR5cGUgUmVnaXN0cnlJbml0ID0ge1xuICByZWFkb25seSBtb2R1bGVJZDogc3RyaW5nXG4gIHJlYWRvbmx5IGluc3RhbmNlSWQ6IHN0cmluZ1xuICByZWFkb25seSByZWdpc3RyeTogV29ya2Zsb3dSZWdpc3RyeVYxXG59XG5cbmNvbnN0IGVuc3VyZVJlZ2lzdHJ5ID0gKHJ1bnRpbWU6IFB1YmxpY01vZHVsZVJ1bnRpbWU8dW5rbm93biwgdW5rbm93bj4pID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IGdldFJlZ2lzdHJ5KHJ1bnRpbWUpXG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBtb2R1bGVJZDogcnVudGltZS5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICByZWdpc3RyeTogZXhpc3RpbmcsXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcG9ydHNSZWFkeSA9IHlpZWxkKiBEZWZlcnJlZC5tYWtlPHZvaWQsIHVua25vd24+KClcblxuICAgIGNvbnN0IG5leHQ6IFdvcmtmbG93UmVnaXN0cnlWMSA9IHtcbiAgICAgIGJ5QWN0aW9uVGFnOiBuZXcgTWFwKCksXG4gICAgICBlbnRyaWVzOiBbXSxcbiAgICAgIHdhdGNoZXJTdGFydGVkOiBmYWxzZSxcbiAgICAgIHdhdGNoZXJTdGFydENvdW50OiAwLFxuICAgICAgcG9ydHNSZXNvbHZpbmc6IGZhbHNlLFxuICAgICAgcG9ydHNSZWFkeSxcbiAgICAgIHBhcmFsbGVsTGltaXRlcjogdW5kZWZpbmVkLFxuICAgIH1cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShydW50aW1lLCBXT1JLRkxPV19SRUdJU1RSWSwge1xuICAgICAgdmFsdWU6IG5leHQsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICB9KVxuXG4gICAgcmV0dXJuIHsgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCwgcmVnaXN0cnk6IG5leHQgfVxuICB9KVxuXG5jb25zdCByZWdpc3RlclByb2dyYW1zID0gKGFyZ3M6IHtcbiAgcmVhZG9ubHkgbW9kdWxlVGFnOiBNb2R1bGVUYWdcbiAgcmVhZG9ubHkgcHJvZ3JhbXM6IFJlYWRvbmx5QXJyYXk8V29ya2Zsb3dMaWtlPlxuICByZWFkb25seSBlbnRyeUxhYmVsOiBzdHJpbmdcbn0pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCB1bmtub3duPiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3QgcnVudGltZSA9IHlpZWxkKiBhcmdzLm1vZHVsZVRhZ1xuICAgIGNvbnN0IHsgbW9kdWxlSWQsIGluc3RhbmNlSWQsIHJlZ2lzdHJ5IH0gPSB5aWVsZCogZW5zdXJlUmVnaXN0cnkocnVudGltZSlcblxuICAgIC8vIExhemlseSByZXNvbHZlIHRoZSBnbG9iYWwgcGFyYWxsZWwgbGltaXRlciBvbmNlLlxuICAgIGlmIChyZWdpc3RyeS5wYXJhbGxlbExpbWl0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgeWllbGQqIGVuc3VyZUxpbWl0ZXJSZWFkeShyZWdpc3RyeSwgcnVudGltZSlcbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZGF0ZU5vSW9TdGVwc0Zvck9uSW5pdCA9IChzdGVwczogUmVhZG9ubHlBcnJheTxDb21waWxlZFdvcmtmbG93U3RlcD4sIHByb2dyYW1JZDogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgICBjb25zdCB2aXNpdCA9IChzdGVwOiBDb21waWxlZFdvcmtmbG93U3RlcCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoc3RlcC5raW5kID09PSAnY2FsbCcgfHwgc3RlcC5raW5kID09PSAnZGVsYXknKSB7XG4gICAgICAgICAgdGhyb3cgbWFrZVdvcmtmbG93RXJyb3Ioe1xuICAgICAgICAgICAgY29kZTogJ1dPUktGTE9XX0lOVkFMSURfVFJJR0dFUicsXG4gICAgICAgICAgICBtZXNzYWdlOiAnTGlmZWN5Y2xlIG9uSW5pdCBwcm9ncmFtcyBtdXN0IG5vdCBpbmNsdWRlIGNhbGwvZGVsYXkgKGluaXRSZXF1aXJlZCBtdXN0IHN0YXkgc3luYy1vbmx5OyB1c2Ugb25TdGFydCBmb3IgSU8vdGltZSkuJyxcbiAgICAgICAgICAgIHByb2dyYW1JZCxcbiAgICAgICAgICAgIHNvdXJjZTogeyBzdGVwS2V5OiBzdGVwLmtleSB9LFxuICAgICAgICAgICAgZGV0YWlsOiB7IGtpbmQ6IHN0ZXAua2luZCB9LFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgcyBvZiBzdGVwcykgdmlzaXQocylcbiAgICB9XG5cbiAgICBjb25zdCBwcm9ncmFtSGFzQ2FsbCA9IChzdGVwczogUmVhZG9ubHlBcnJheTxDb21waWxlZFdvcmtmbG93U3RlcD4pOiBib29sZWFuID0+XG4gICAgICBzdGVwcy5zb21lKChzKSA9PiBzLmtpbmQgPT09ICdjYWxsJylcblxuICAgIGNvbnN0IGluc2VydEVudHJ5ID0gKGFjdGlvblRhZzogc3RyaW5nLCBlbnRyeTogUHJvZ3JhbUVudHJ5KTogdm9pZCA9PiB7XG4gICAgICBjb25zdCBwcmV2ID0gcmVnaXN0cnkuYnlBY3Rpb25UYWcuZ2V0KGFjdGlvblRhZylcbiAgICAgIHJlZ2lzdHJ5LmJ5QWN0aW9uVGFnLnNldChhY3Rpb25UYWcsIHByZXYgPyBbLi4ucHJldiwgZW50cnldIDogW2VudHJ5XSlcbiAgICB9XG5cbiAgICBjb25zdCBpbnRlcm5hbHMgPSBnZXRSdW50aW1lSW50ZXJuYWxzKHJ1bnRpbWUpXG5cbiAgICBmb3IgKGNvbnN0IHByb2dyYW0gb2YgYXJncy5wcm9ncmFtcykge1xuICAgICAgY29uc3QgZGVmID0gcHJvZ3JhbS5kZWZcbiAgICAgIGNvbnN0IGxvY2FsSWQgPSBhc05vbkVtcHR5U3RyaW5nKGRlZi5sb2NhbElkKVxuICAgICAgaWYgKCFsb2NhbElkKSB7XG4gICAgICAgIHRocm93IG1ha2VXb3JrZmxvd0Vycm9yKHtcbiAgICAgICAgICBjb2RlOiAnV09SS0ZMT1dfSU5WQUxJRF9ERUYnLFxuICAgICAgICAgIG1lc3NhZ2U6ICdXb3JrZmxvdy5pbnN0YWxsOiBkZWYubG9jYWxJZCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZy4nLFxuICAgICAgICAgIGRldGFpbDogeyBsb2NhbElkOiBkZWYubG9jYWxJZCB9LFxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBjb25zdCBwcm9ncmFtSWQgPSBgJHttb2R1bGVJZH0uJHtsb2NhbElkfWBcbiAgICAgIGNvbnN0IGNvbXBpbGVkID0gY29tcGlsZVdvcmtmbG93UnVudGltZVN0ZXBzVjEoeyBkZWYgfSlcblxuICAgICAgaWYgKGRlZi50cmlnZ2VyLmtpbmQgPT09ICdsaWZlY3ljbGUnICYmIGRlZi50cmlnZ2VyLnBoYXNlID09PSAnb25Jbml0Jykge1xuICAgICAgICB2YWxpZGF0ZU5vSW9TdGVwc0Zvck9uSW5pdChjb21waWxlZCwgcHJvZ3JhbUlkKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBjb21waWxlZFByb2dyYW06IENvbXBpbGVkUHJvZ3JhbSA9IHtcbiAgICAgICAgcHJvZ3JhbUlkLFxuICAgICAgICBsb2NhbElkLFxuICAgICAgICB0cmlnZ2VyOiBkZWYudHJpZ2dlcixcbiAgICAgICAgY29uY3VycmVuY3k6IHJlc29sdmVDb25jdXJyZW5jeShkZWYpLFxuICAgICAgICBwcmlvcml0eTogcmVzb2x2ZVByaW9yaXR5KGRlZiksXG4gICAgICAgIGNvbXBpbGVkU3RlcHM6IGNvbXBpbGVkLFxuICAgICAgfVxuXG4gICAgICBpZiAoIXByb2dyYW1IYXNDYWxsKGNvbXBpbGVkKSkge1xuICAgICAgICBjb21waWxlZFByb2dyYW0uc3RlcHMgPSBjb21waWxlU3RlcHMoY29tcGlsZWQsICgpID0+IHtcbiAgICAgICAgICB0aHJvdyBtYWtlV29ya2Zsb3dFcnJvcih7XG4gICAgICAgICAgICBjb2RlOiAnV09SS0ZMT1dfTUlTU0lOR19TRVJWSUNFJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBlcnJvcjogdW5leHBlY3RlZCBjYWxsIHN0ZXAgd2hpbGUgcmVzb2x2aW5nIGNhbGwtbGVzcyBwcm9ncmFtLicsXG4gICAgICAgICAgICBwcm9ncmFtSWQsXG4gICAgICAgICAgICBkZXRhaWw6IHsgcHJvZ3JhbUlkIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhdGU6IFByb2dyYW1TdGF0ZSA9XG4gICAgICAgIGNvbXBpbGVkUHJvZ3JhbS5jb25jdXJyZW5jeSA9PT0gJ2xhdGVzdCdcbiAgICAgICAgICA/IHsgbW9kZTogJ2xhdGVzdCcsIHJ1blNlcTogMCwgY3VycmVudDogdW5kZWZpbmVkLCBjdXJyZW50UnVuSWQ6IHVuZGVmaW5lZCB9XG4gICAgICAgICAgOiBjb21waWxlZFByb2dyYW0uY29uY3VycmVuY3kgPT09ICdleGhhdXN0J1xuICAgICAgICAgICAgPyB7IG1vZGU6ICdleGhhdXN0JywgcnVuU2VxOiAwLCBidXN5OiBmYWxzZSB9XG4gICAgICAgICAgICA6IHsgbW9kZTogJ3BhcmFsbGVsJywgcnVuU2VxOiAwIH1cblxuICAgICAgY29uc3QgZW50cnk6IFByb2dyYW1FbnRyeSA9IHsgcHJvZ3JhbTogY29tcGlsZWRQcm9ncmFtLCBzdGF0ZSB9XG4gICAgICByZWdpc3RyeS5lbnRyaWVzLnB1c2goZW50cnkpXG5cbiAgICAgIGlmIChkZWYudHJpZ2dlci5raW5kID09PSAnYWN0aW9uJykge1xuICAgICAgICBpbnNlcnRFbnRyeShkZWYudHJpZ2dlci5hY3Rpb25UYWcsIGVudHJ5KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGRlZi50cmlnZ2VyLnBoYXNlID09PSAnb25TdGFydCcpIHtcbiAgICAgICAgICBpbnRlcm5hbHMubGlmZWN5Y2xlLnJlZ2lzdGVyU3RhcnQoXG4gICAgICAgICAgICB3aXRoUm9vdEVudklmQXZhaWxhYmxlKFxuICAgICAgICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWlkZGxld2FyZU9wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihFZmZlY3RPcENvcmUuRWZmZWN0T3BNaWRkbGV3YXJlVGFnKVxuICAgICAgICAgICAgICAgIGNvbnN0IG1pZGRsZXdhcmUgPSBPcHRpb24uaXNTb21lKG1pZGRsZXdhcmVPcHQpID8gbWlkZGxld2FyZU9wdC52YWx1ZSA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIHlpZWxkKiBlbnN1cmVQb3J0c1Jlc29sdmVkKHJlZ2lzdHJ5LCBydW50aW1lKS5waXBlKEVmZmVjdC5vckRpZSlcbiAgICAgICAgICAgICAgICB5aWVsZCogc3RhcnRQcm9ncmFtUnVuKHtcbiAgICAgICAgICAgICAgICAgIGVudHJ5LFxuICAgICAgICAgICAgICAgICAgcnVudGltZSxcbiAgICAgICAgICAgICAgICAgIHJlZ2lzdHJ5LFxuICAgICAgICAgICAgICAgICAgdHJpZ2dlcjogeyBraW5kOiAnbGlmZWN5Y2xlJywgcGhhc2U6ICdvblN0YXJ0JyB9LFxuICAgICAgICAgICAgICAgICAgcGF5bG9hZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgbWlkZGxld2FyZSxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB7IG5hbWU6IGB3b3JrZmxvdzoke2xvY2FsSWR9YCB9LFxuICAgICAgICAgIClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbnRlcm5hbHMubGlmZWN5Y2xlLnJlZ2lzdGVySW5pdFJlcXVpcmVkKFxuICAgICAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICBjb25zdCBtaWRkbGV3YXJlT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKEVmZmVjdE9wQ29yZS5FZmZlY3RPcE1pZGRsZXdhcmVUYWcpXG4gICAgICAgICAgICAgIGNvbnN0IG1pZGRsZXdhcmUgPSBPcHRpb24uaXNTb21lKG1pZGRsZXdhcmVPcHQpID8gbWlkZGxld2FyZU9wdC52YWx1ZSA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgICB5aWVsZCogc3RhcnRQcm9ncmFtUnVuKHtcbiAgICAgICAgICAgICAgICBlbnRyeSxcbiAgICAgICAgICAgICAgICBydW50aW1lLFxuICAgICAgICAgICAgICAgIHJlZ2lzdHJ5LFxuICAgICAgICAgICAgICAgIHRyaWdnZXI6IHsga2luZDogJ2xpZmVjeWNsZScsIHBoYXNlOiAnb25Jbml0JyB9LFxuICAgICAgICAgICAgICAgIHBheWxvYWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBtaWRkbGV3YXJlLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB7IG5hbWU6IGB3b3JrZmxvdzoke2xvY2FsSWR9YCB9LFxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZvaWQgaW5zdGFuY2VJZFxuICB9KVxuXG5jb25zdCBzdGFydFdhdGNoZXJJZk5lZWRlZCA9IChhcmdzOiB7XG4gIHJlYWRvbmx5IG1vZHVsZVRhZzogTW9kdWxlVGFnXG4gIHJlYWRvbmx5IGVudHJ5TGFiZWw6IHN0cmluZ1xufSk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIHVua25vd24+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBydW50aW1lID0geWllbGQqIGFyZ3MubW9kdWxlVGFnXG4gICAgY29uc3QgaW5pdCA9IHlpZWxkKiBlbnN1cmVSZWdpc3RyeShydW50aW1lKVxuICAgIGNvbnN0IHJlZ2lzdHJ5ID0gaW5pdC5yZWdpc3RyeVxuXG4gICAgaWYgKHJlZ2lzdHJ5LndhdGNoZXJTdGFydGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICByZWdpc3RyeS53YXRjaGVyU3RhcnRlZCA9IHRydWVcbiAgICByZWdpc3RyeS53YXRjaGVyU3RhcnRDb3VudCArPSAxXG5cbiAgICBjb25zdCBtaWRkbGV3YXJlT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKEVmZmVjdE9wQ29yZS5FZmZlY3RPcE1pZGRsZXdhcmVUYWcpXG4gICAgY29uc3QgbWlkZGxld2FyZSA9IE9wdGlvbi5pc1NvbWUobWlkZGxld2FyZU9wdCkgPyBtaWRkbGV3YXJlT3B0LnZhbHVlIDogdW5kZWZpbmVkXG5cbiAgICBjb25zdCBhY3Rpb25zJCA9IHJ1bnRpbWUuYWN0aW9ucyQgYXMgU3RyZWFtLlN0cmVhbTx1bmtub3duPlxuXG4gICAgY29uc3QgcG9ydHNFeGl0ID0geWllbGQqIEVmZmVjdC5leGl0KGVuc3VyZVBvcnRzUmVzb2x2ZWQocmVnaXN0cnksIHJ1bnRpbWUpKVxuICAgIGlmIChFeGl0LmlzRmFpbHVyZShwb3J0c0V4aXQpKSB7XG4gICAgICBjb25zdCB7IGVycm9yU3VtbWFyeSwgZG93bmdyYWRlIH0gPSB0b1NlcmlhbGl6YWJsZUVycm9yU3VtbWFyeShwb3J0c0V4aXQuY2F1c2UpXG4gICAgICBjb25zdCBkb3duZ3JhZGVIaW50ID0gZG93bmdyYWRlID8gYCAoZG93bmdyYWRlPSR7ZG93bmdyYWRlfSlgIDogJydcbiAgICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICB0eXBlOiAnZGlhZ25vc3RpYycsXG4gICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICAgIGNvZGU6ICd3b3JrZmxvdzo6cG9ydHNfcmVzb2x1dGlvbl9mYWlsZWQnLFxuICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgbWVzc2FnZTogYFdvcmtmbG93IHBvcnRzIHJlc29sdXRpb24gZmFpbGVkIGJlZm9yZSBzdGFydGluZyB3YXRjaGVyLiR7ZG93bmdyYWRlSGludH1gLFxuICAgICAgICBoaW50OiBgJHtlcnJvclN1bW1hcnkubmFtZSA/IGAke2Vycm9yU3VtbWFyeS5uYW1lfTogYCA6ICcnfSR7ZXJyb3JTdW1tYXJ5Lm1lc3NhZ2V9YCxcbiAgICAgICAga2luZDogJ3dvcmtmbG93X3BvcnRzX3Jlc29sdXRpb25fZmFpbGVkJyxcbiAgICAgICAgdHJpZ2dlcjoge1xuICAgICAgICAgIGtpbmQ6ICd3b3JrZmxvdycsXG4gICAgICAgICAgbmFtZTogJ3BvcnRzUmVzb2x1dGlvbicsXG4gICAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgICAgZW50cnlMYWJlbDogYXJncy5lbnRyeUxhYmVsLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgeWllbGQqIFN0cmVhbS5ydW5Gb3JFYWNoKGFjdGlvbnMkLCAoYWN0aW9uKSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBhY3Rpb25UYWcgPSByZXNvbHZlQWN0aW9uVGFnKGFjdGlvbilcbiAgICAgICAgaWYgKCFhY3Rpb25UYWcpIHJldHVyblxuXG4gICAgICAgIGNvbnN0IGVudHJpZXMgPSByZWdpc3RyeS5ieUFjdGlvblRhZy5nZXQoYWN0aW9uVGFnKVxuICAgICAgICBpZiAoIWVudHJpZXMgfHwgZW50cmllcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBpc1JlY29yZChhY3Rpb24pID8gYWN0aW9uLnBheWxvYWQgOiB1bmRlZmluZWRcblxuICAgICAgICB5aWVsZCogRWZmZWN0LmZvckVhY2goXG4gICAgICAgICAgZW50cmllcyxcbiAgICAgICAgICAoZW50cnkpID0+XG4gICAgICAgICAgICBzdGFydFByb2dyYW1SdW4oe1xuICAgICAgICAgICAgICBlbnRyeSxcbiAgICAgICAgICAgICAgcnVudGltZSxcbiAgICAgICAgICAgICAgcmVnaXN0cnksXG4gICAgICAgICAgICAgIHRyaWdnZXI6IHsga2luZDogJ2FjdGlvbicsIGFjdGlvblRhZyB9LFxuICAgICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICAgICAgICBtaWRkbGV3YXJlLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgeyBkaXNjYXJkOiB0cnVlIH0sXG4gICAgICAgIClcbiAgICAgIH0pLFxuICAgICkucGlwZShcbiAgICAgIEVmZmVjdC5jYXRjaEFsbENhdXNlKChjYXVzZSkgPT4ge1xuICAgICAgICBjb25zdCB7IGVycm9yU3VtbWFyeSwgZG93bmdyYWRlIH0gPSB0b1NlcmlhbGl6YWJsZUVycm9yU3VtbWFyeShjYXVzZSlcbiAgICAgICAgY29uc3QgZG93bmdyYWRlSGludCA9IGRvd25ncmFkZSA/IGAgKGRvd25ncmFkZT0ke2Rvd25ncmFkZX0pYCA6ICcnXG4gICAgICAgIHJldHVybiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICAgIHR5cGU6ICdkaWFnbm9zdGljJyxcbiAgICAgICAgICBtb2R1bGVJZDogcnVudGltZS5tb2R1bGVJZCxcbiAgICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICAgICAgY29kZTogJ3dvcmtmbG93Ojp3YXRjaGVyX2NyYXNoZWQnLFxuICAgICAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgICAgICAgIG1lc3NhZ2U6IGBXb3JrZmxvdyB3YXRjaGVyIGNyYXNoZWQuJHtkb3duZ3JhZGVIaW50fWAsXG4gICAgICAgICAgaGludDogYCR7ZXJyb3JTdW1tYXJ5Lm5hbWUgPyBgJHtlcnJvclN1bW1hcnkubmFtZX06IGAgOiAnJ30ke2Vycm9yU3VtbWFyeS5tZXNzYWdlfWAsXG4gICAgICAgICAga2luZDogJ3dvcmtmbG93X3dhdGNoZXJfY3Jhc2hlZCcsXG4gICAgICAgICAgdHJpZ2dlcjoge1xuICAgICAgICAgICAga2luZDogJ3dvcmtmbG93JyxcbiAgICAgICAgICAgIG5hbWU6ICd3YXRjaGVyJyxcbiAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgZW50cnlMYWJlbDogYXJncy5lbnRyeUxhYmVsLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgfSksXG4gICAgKVxuXG4gICAgdm9pZCBhcmdzLmVudHJ5TGFiZWxcbiAgfSlcblxuZXhwb3J0IGNvbnN0IG1vdW50QWxsID0gKGFyZ3M6IHtcbiAgcmVhZG9ubHkgbW9kdWxlVGFnOiBNb2R1bGVUYWdcbiAgcmVhZG9ubHkgcHJvZ3JhbXM6IFJlYWRvbmx5QXJyYXk8V29ya2Zsb3dMaWtlPlxufSk6IExvZ2ljUGxhbjxBbnlNb2R1bGVTaGFwZSwgdW5rbm93biwgbmV2ZXI+ID0+IHtcbiAgY29uc3QgcGxhbiA9IHtcbiAgICBzZXR1cDogcmVnaXN0ZXJQcm9ncmFtcyh7IG1vZHVsZVRhZzogYXJncy5tb2R1bGVUYWcsIHByb2dyYW1zOiBhcmdzLnByb2dyYW1zLCBlbnRyeUxhYmVsOiAnbW91bnRBbGwnIH0pLFxuICAgIHJ1bjogc3RhcnRXYXRjaGVySWZOZWVkZWQoeyBtb2R1bGVUYWc6IGFyZ3MubW9kdWxlVGFnLCBlbnRyeUxhYmVsOiAnbW91bnRBbGwnIH0pLFxuICB9IHNhdGlzZmllcyBMb2dpY1BsYW48QW55TW9kdWxlU2hhcGUsIHVua25vd24sIG5ldmVyPlxuXG4gIExvZ2ljVW5pdE1ldGEuYXR0YWNoTG9naWNVbml0TWV0YShwbGFuLCB7XG4gICAgaWQ6ICdfX2xvZ2l4X2ludGVybmFsOndvcmtmbG93cycsXG4gICAga2luZDogJ2ludGVybmFsJyxcbiAgICBuYW1lOiAnd29ya2Zsb3dzJyxcbiAgfSlcblxuICByZXR1cm4gcGxhblxufVxuXG5leHBvcnQgY29uc3QgaW5zdGFsbE9uZSA9IChhcmdzOiB7XG4gIHJlYWRvbmx5IG1vZHVsZVRhZzogTW9kdWxlVGFnXG4gIHJlYWRvbmx5IHByb2dyYW06IFdvcmtmbG93TGlrZVxufSk6IExvZ2ljUGxhbjxBbnlNb2R1bGVTaGFwZSwgdW5rbm93biwgbmV2ZXI+ID0+IHtcbiAgY29uc3QgbG9jYWxJZCA9IGFzTm9uRW1wdHlTdHJpbmcoYXJncy5wcm9ncmFtLmRlZi5sb2NhbElkKSA/PyAndW5rbm93bidcbiAgY29uc3QgcGxhbiA9IHtcbiAgICBzZXR1cDogcmVnaXN0ZXJQcm9ncmFtcyh7IG1vZHVsZVRhZzogYXJncy5tb2R1bGVUYWcsIHByb2dyYW1zOiBbYXJncy5wcm9ncmFtXSwgZW50cnlMYWJlbDogYGluc3RhbGw6JHtsb2NhbElkfWAgfSksXG4gICAgcnVuOiBzdGFydFdhdGNoZXJJZk5lZWRlZCh7IG1vZHVsZVRhZzogYXJncy5tb2R1bGVUYWcsIGVudHJ5TGFiZWw6IGBpbnN0YWxsOiR7bG9jYWxJZH1gIH0pLFxuICB9IHNhdGlzZmllcyBMb2dpY1BsYW48QW55TW9kdWxlU2hhcGUsIHVua25vd24sIG5ldmVyPlxuXG4gIExvZ2ljVW5pdE1ldGEuYXR0YWNoTG9naWNVbml0TWV0YShwbGFuLCB7XG4gICAgaWQ6IGB3b3JrZmxvdzoke2xvY2FsSWR9YCxcbiAgICBraW5kOiAnd29ya2Zsb3cnLFxuICAgIG5hbWU6IGxvY2FsSWQsXG4gIH0pXG5cbiAgcmV0dXJuIHBsYW5cbn1cblxuLy8gdGVzdC1vbmx5IHByb2JlOiB3aGV0aGVyIGEgd2F0Y2hlciBoYXMgc3RhcnRlZCAoZm9yIHNpbmdsZS1zdWJzY3JpcHRpb24gZ2F0ZXMpLlxuZXhwb3J0IGNvbnN0IF9fdW5zYWZlR2V0V2F0Y2hlclN0YXJ0Q291bnQgPSAocnVudGltZTogdW5rbm93bik6IG51bWJlciA9PiB7XG4gIGlmICghcnVudGltZSB8fCB0eXBlb2YgcnVudGltZSAhPT0gJ29iamVjdCcpIHJldHVybiAwXG4gIGNvbnN0IHJlZyA9IGdldFJlZ2lzdHJ5KHJ1bnRpbWUpXG4gIHJldHVybiByZWcgPyByZWcud2F0Y2hlclN0YXJ0Q291bnQgOiAwXG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsU0FBUyxPQUFP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
|