@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,900 @@
|
|
|
1
|
+
// @logix/core subpath bundles for @logix/sandbox
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
exportStaticIr
|
|
5
|
+
} from "./chunk-7KQFTS2Y.js";
|
|
6
|
+
import {
|
|
7
|
+
installSourceRefresh
|
|
8
|
+
} from "./chunk-3BHC6JAV.js";
|
|
9
|
+
import {
|
|
10
|
+
getAtPath
|
|
11
|
+
} from "./chunk-Z6LV34RO.js";
|
|
12
|
+
import {
|
|
13
|
+
compareFieldPath,
|
|
14
|
+
getFieldPathId,
|
|
15
|
+
makeFieldPathIdRegistry,
|
|
16
|
+
normalizeFieldPath
|
|
17
|
+
} from "./chunk-BCEO3MGD.js";
|
|
18
|
+
import {
|
|
19
|
+
getBoundInternals
|
|
20
|
+
} from "./chunk-F743SKYD.js";
|
|
21
|
+
|
|
22
|
+
// ../logix-core/src/internal/state-trait/meta.ts
|
|
23
|
+
var uniqSortedStrings = (input) => {
|
|
24
|
+
const set = /* @__PURE__ */ new Set();
|
|
25
|
+
for (const item of input) {
|
|
26
|
+
const v = item.trim();
|
|
27
|
+
if (!v) continue;
|
|
28
|
+
set.add(v);
|
|
29
|
+
}
|
|
30
|
+
return Array.from(set).sort((a, b) => a.localeCompare(b));
|
|
31
|
+
};
|
|
32
|
+
var isPlainRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
33
|
+
var sanitizeJsonValue = (input, depth) => {
|
|
34
|
+
if (input === null) return null;
|
|
35
|
+
if (typeof input === "string") return input;
|
|
36
|
+
if (typeof input === "boolean") return input;
|
|
37
|
+
if (typeof input === "number") {
|
|
38
|
+
return Number.isFinite(input) ? input : void 0;
|
|
39
|
+
}
|
|
40
|
+
if (depth >= 6) return void 0;
|
|
41
|
+
if (Array.isArray(input)) {
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const item of input) {
|
|
44
|
+
const v = sanitizeJsonValue(item, depth + 1);
|
|
45
|
+
if (v !== void 0) out.push(v);
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
if (isPlainRecord(input)) {
|
|
50
|
+
const keys = Object.keys(input).sort();
|
|
51
|
+
const out = {};
|
|
52
|
+
for (const key of keys) {
|
|
53
|
+
const v = sanitizeJsonValue(input[key], depth + 1);
|
|
54
|
+
if (v !== void 0) out[key] = v;
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
return void 0;
|
|
59
|
+
};
|
|
60
|
+
var sanitize = (input) => {
|
|
61
|
+
if (input === null || input === void 0) return void 0;
|
|
62
|
+
if (typeof input !== "object" || Array.isArray(input)) return void 0;
|
|
63
|
+
const record = input;
|
|
64
|
+
const out = {};
|
|
65
|
+
const pickString = (key) => {
|
|
66
|
+
const value = record[key];
|
|
67
|
+
if (typeof value !== "string") return;
|
|
68
|
+
const trimmed = value.trim();
|
|
69
|
+
if (!trimmed) return;
|
|
70
|
+
out[key] = trimmed;
|
|
71
|
+
};
|
|
72
|
+
pickString("label");
|
|
73
|
+
pickString("description");
|
|
74
|
+
pickString("group");
|
|
75
|
+
pickString("docsUrl");
|
|
76
|
+
pickString("cacheGroup");
|
|
77
|
+
const canonical = record.canonical;
|
|
78
|
+
if (typeof canonical === "boolean") {
|
|
79
|
+
out.canonical = canonical;
|
|
80
|
+
}
|
|
81
|
+
const tagsRaw = record.tags;
|
|
82
|
+
if (typeof tagsRaw === "string") {
|
|
83
|
+
const tags = uniqSortedStrings([tagsRaw]);
|
|
84
|
+
if (tags.length > 0) out.tags = tags;
|
|
85
|
+
} else if (Array.isArray(tagsRaw)) {
|
|
86
|
+
const tags = uniqSortedStrings(tagsRaw.filter((x) => typeof x === "string"));
|
|
87
|
+
if (tags.length > 0) out.tags = tags;
|
|
88
|
+
}
|
|
89
|
+
const annotations = {};
|
|
90
|
+
const annotationKeys = Object.keys(record).filter((k) => k.startsWith("x-")).sort((a, b) => a.localeCompare(b));
|
|
91
|
+
for (const key of annotationKeys) {
|
|
92
|
+
const v = sanitizeJsonValue(record[key], 0);
|
|
93
|
+
if (v !== void 0) annotations[key] = v;
|
|
94
|
+
}
|
|
95
|
+
const annotationsRaw = record.annotations;
|
|
96
|
+
if (isPlainRecord(annotationsRaw)) {
|
|
97
|
+
const keys = Object.keys(annotationsRaw).filter((k) => k.startsWith("x-")).sort((a, b) => a.localeCompare(b));
|
|
98
|
+
for (const key of keys) {
|
|
99
|
+
const v = sanitizeJsonValue(annotationsRaw[key], 0);
|
|
100
|
+
if (v !== void 0) annotations[key] = v;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (Object.keys(annotations).length > 0) out.annotations = annotations;
|
|
104
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
105
|
+
};
|
|
106
|
+
var stableStringify = (meta) => {
|
|
107
|
+
const out = {};
|
|
108
|
+
const keys = Object.keys(meta).sort();
|
|
109
|
+
for (const k of keys) {
|
|
110
|
+
out[k] = meta[k];
|
|
111
|
+
}
|
|
112
|
+
return JSON.stringify(out);
|
|
113
|
+
};
|
|
114
|
+
var equals = (a, b) => {
|
|
115
|
+
if (a === b) return true;
|
|
116
|
+
if (!a || !b) return false;
|
|
117
|
+
return stableStringify(a) === stableStringify(b);
|
|
118
|
+
};
|
|
119
|
+
var mergeCanonical = (current, incoming) => {
|
|
120
|
+
const existing = current.meta;
|
|
121
|
+
if (!existing) {
|
|
122
|
+
return {
|
|
123
|
+
meta: incoming.meta,
|
|
124
|
+
origin: incoming.origin,
|
|
125
|
+
conflicts: current.conflicts
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (equals(existing, incoming.meta)) {
|
|
129
|
+
return current;
|
|
130
|
+
}
|
|
131
|
+
const conflicts = [...current.conflicts ?? []];
|
|
132
|
+
const push = (conflict) => {
|
|
133
|
+
const exists = conflicts.some((c) => c.origin === conflict.origin && equals(c.meta, conflict.meta));
|
|
134
|
+
if (!exists) conflicts.push(conflict);
|
|
135
|
+
};
|
|
136
|
+
const existingCanonical = existing.canonical === true;
|
|
137
|
+
const incomingCanonical = incoming.meta.canonical === true;
|
|
138
|
+
if (!existingCanonical && incomingCanonical) {
|
|
139
|
+
push({
|
|
140
|
+
origin: current.origin ?? "unknown",
|
|
141
|
+
meta: existing
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
meta: incoming.meta,
|
|
145
|
+
origin: incoming.origin,
|
|
146
|
+
conflicts
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
push({
|
|
150
|
+
origin: incoming.origin,
|
|
151
|
+
meta: incoming.meta
|
|
152
|
+
});
|
|
153
|
+
return {
|
|
154
|
+
meta: existing,
|
|
155
|
+
origin: current.origin ?? incoming.origin,
|
|
156
|
+
conflicts
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// ../logix-core/src/internal/state-trait/model.ts
|
|
161
|
+
var normalizeSpec = (spec) => {
|
|
162
|
+
const entries = [];
|
|
163
|
+
const isNode = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitNode";
|
|
164
|
+
const isList = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitList";
|
|
165
|
+
const joinPath = (prefix, suffix) => {
|
|
166
|
+
if (!prefix) return suffix;
|
|
167
|
+
if (!suffix) return prefix;
|
|
168
|
+
return `${prefix}.${suffix}`;
|
|
169
|
+
};
|
|
170
|
+
const prefixDeps = (deps, prefix) => {
|
|
171
|
+
if (!deps || deps.length === 0) return [];
|
|
172
|
+
return deps.map((d) => prefix ? joinPath(prefix, d) : d);
|
|
173
|
+
};
|
|
174
|
+
const normalizeEntry = (entry, fieldPath, depPrefix) => {
|
|
175
|
+
if (entry.kind === "computed") {
|
|
176
|
+
const meta = entry.meta;
|
|
177
|
+
const rawDeps = meta.deps;
|
|
178
|
+
const deps = rawDeps !== void 0 ? prefixDeps(rawDeps, depPrefix) : void 0;
|
|
179
|
+
return {
|
|
180
|
+
...entry,
|
|
181
|
+
fieldPath,
|
|
182
|
+
meta: { ...meta, deps }
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (entry.kind === "source") {
|
|
186
|
+
const meta = entry.meta;
|
|
187
|
+
const rawDeps = meta.deps;
|
|
188
|
+
const deps = rawDeps !== void 0 ? prefixDeps(rawDeps, depPrefix) : void 0;
|
|
189
|
+
return {
|
|
190
|
+
...entry,
|
|
191
|
+
fieldPath,
|
|
192
|
+
meta: { ...meta, deps, _fieldPath: fieldPath }
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (entry.kind === "link") {
|
|
196
|
+
const meta = entry.meta;
|
|
197
|
+
const from2 = prefixDeps([meta.from], depPrefix)[0] ?? meta.from;
|
|
198
|
+
return {
|
|
199
|
+
...entry,
|
|
200
|
+
fieldPath,
|
|
201
|
+
meta: { ...meta, from: from2 }
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
...entry,
|
|
206
|
+
fieldPath
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
const expandNode = (scopeId, joinPrefix, node2, options) => {
|
|
210
|
+
const addEntry = (relativeTarget, raw) => {
|
|
211
|
+
const rel = raw.fieldPath ?? relativeTarget;
|
|
212
|
+
const fieldPath = joinPrefix ? joinPath(joinPrefix, String(rel)) : String(rel);
|
|
213
|
+
entries.push(normalizeEntry(raw, fieldPath, joinPrefix));
|
|
214
|
+
};
|
|
215
|
+
const expandMaybeRecord = (value) => {
|
|
216
|
+
if (!value) return;
|
|
217
|
+
if (typeof value.kind === "string") {
|
|
218
|
+
addEntry("", value);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const record = value;
|
|
222
|
+
for (const key in record) {
|
|
223
|
+
if (!Object.prototype.hasOwnProperty.call(record, key)) continue;
|
|
224
|
+
const entry = record[key];
|
|
225
|
+
if (!entry) continue;
|
|
226
|
+
addEntry(key, entry);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
expandMaybeRecord(node2.computed);
|
|
230
|
+
expandMaybeRecord(node2.source);
|
|
231
|
+
expandMaybeRecord(node2.link);
|
|
232
|
+
if (node2.check) {
|
|
233
|
+
const rules = {};
|
|
234
|
+
const checkDepsPrefix = options?.checkDepsPrefix ?? (joinPrefix.endsWith("[]") ? joinPrefix : "");
|
|
235
|
+
const prefixCheckDeps = (deps) => {
|
|
236
|
+
if (!deps || deps.length === 0) return [];
|
|
237
|
+
return deps.map((d) => d === "" ? scopeId : checkDepsPrefix ? joinPath(checkDepsPrefix, d) : d);
|
|
238
|
+
};
|
|
239
|
+
for (const name of Object.keys(node2.check)) {
|
|
240
|
+
const rule = node2.check[name];
|
|
241
|
+
if (typeof rule === "function") {
|
|
242
|
+
rules[name] = rule;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (rule && typeof rule === "object") {
|
|
246
|
+
const meta = sanitize(rule.meta);
|
|
247
|
+
rules[name] = {
|
|
248
|
+
...rule,
|
|
249
|
+
deps: prefixCheckDeps(rule.deps),
|
|
250
|
+
meta
|
|
251
|
+
};
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
entries.push({
|
|
256
|
+
fieldPath: scopeId,
|
|
257
|
+
kind: "check",
|
|
258
|
+
meta: {
|
|
259
|
+
rules,
|
|
260
|
+
writeback: { kind: "errors" }
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
for (const key in spec) {
|
|
266
|
+
if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
|
|
267
|
+
const raw = spec[key];
|
|
268
|
+
if (!raw) continue;
|
|
269
|
+
if (isList(raw)) {
|
|
270
|
+
const listPath = key;
|
|
271
|
+
if (raw.item) {
|
|
272
|
+
expandNode(`${listPath}[]`, `${listPath}[]`, raw.item);
|
|
273
|
+
}
|
|
274
|
+
if (raw.list) {
|
|
275
|
+
expandNode(listPath, listPath, raw.list, {
|
|
276
|
+
checkDepsPrefix: `${listPath}[]`
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (isNode(raw)) {
|
|
282
|
+
if (key === "$root") {
|
|
283
|
+
expandNode("$root", "", raw);
|
|
284
|
+
} else {
|
|
285
|
+
expandNode(key, key, raw);
|
|
286
|
+
}
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
const entry = raw;
|
|
290
|
+
const fieldPath = entry.fieldPath ?? key;
|
|
291
|
+
entries.push(normalizeEntry(entry, String(fieldPath), ""));
|
|
292
|
+
}
|
|
293
|
+
return entries;
|
|
294
|
+
};
|
|
295
|
+
var collectNodeMeta = (spec) => {
|
|
296
|
+
const out = /* @__PURE__ */ new Map();
|
|
297
|
+
const isNode = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitNode";
|
|
298
|
+
const isList = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitList";
|
|
299
|
+
const add = (scopeId, node2) => {
|
|
300
|
+
const meta = sanitize(node2.meta);
|
|
301
|
+
if (meta) out.set(scopeId, meta);
|
|
302
|
+
};
|
|
303
|
+
for (const key in spec) {
|
|
304
|
+
if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
|
|
305
|
+
const raw = spec[key];
|
|
306
|
+
if (!raw) continue;
|
|
307
|
+
if (isList(raw)) {
|
|
308
|
+
const listPath = key;
|
|
309
|
+
if (raw.item) add(`${listPath}[]`, raw.item);
|
|
310
|
+
if (raw.list) add(listPath, raw.list);
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
if (isNode(raw)) {
|
|
314
|
+
if (key === "$root") add("$root", raw);
|
|
315
|
+
else add(key, raw);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return out;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// ../logix-core/src/internal/state-trait/build.ts
|
|
323
|
+
var nowPerf = () => typeof globalThis.performance !== "undefined" && typeof globalThis.performance.now === "function" ? globalThis.performance.now() : Date.now();
|
|
324
|
+
var getConvergeWriterDeps = (entry) => {
|
|
325
|
+
if (entry.kind === "computed") {
|
|
326
|
+
return entry.meta?.deps ?? [];
|
|
327
|
+
}
|
|
328
|
+
return [entry.meta.from];
|
|
329
|
+
};
|
|
330
|
+
var computeConvergeTopoOrder = (writers) => {
|
|
331
|
+
const writerByPath = /* @__PURE__ */ new Map();
|
|
332
|
+
for (const entry of writers) {
|
|
333
|
+
const existing = writerByPath.get(entry.fieldPath);
|
|
334
|
+
if (existing) {
|
|
335
|
+
return {
|
|
336
|
+
order: [],
|
|
337
|
+
configError: {
|
|
338
|
+
code: "MULTIPLE_WRITERS",
|
|
339
|
+
message: `[StateTrait.converge] Multiple writers for field "${entry.fieldPath}" (${existing.kind} + ${entry.kind}).`,
|
|
340
|
+
fields: [entry.fieldPath]
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
writerByPath.set(entry.fieldPath, entry);
|
|
345
|
+
}
|
|
346
|
+
const nodes = /* @__PURE__ */ new Set();
|
|
347
|
+
for (const entry of writers) {
|
|
348
|
+
nodes.add(entry.fieldPath);
|
|
349
|
+
}
|
|
350
|
+
const indegree = /* @__PURE__ */ new Map();
|
|
351
|
+
const forward = /* @__PURE__ */ new Map();
|
|
352
|
+
for (const node2 of nodes) {
|
|
353
|
+
indegree.set(node2, 0);
|
|
354
|
+
forward.set(node2, []);
|
|
355
|
+
}
|
|
356
|
+
for (const entry of writers) {
|
|
357
|
+
const to = entry.fieldPath;
|
|
358
|
+
const deps = getConvergeWriterDeps(entry);
|
|
359
|
+
for (const dep of deps) {
|
|
360
|
+
if (!nodes.has(dep)) continue;
|
|
361
|
+
forward.get(dep).push(to);
|
|
362
|
+
indegree.set(to, (indegree.get(to) ?? 0) + 1);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
const queue = [];
|
|
366
|
+
for (const [node2, deg] of indegree.entries()) {
|
|
367
|
+
if (deg === 0) queue.push(node2);
|
|
368
|
+
}
|
|
369
|
+
const order = [];
|
|
370
|
+
while (queue.length) {
|
|
371
|
+
const n = queue.shift();
|
|
372
|
+
order.push(n);
|
|
373
|
+
const outs = forward.get(n);
|
|
374
|
+
for (const to of outs) {
|
|
375
|
+
const next = (indegree.get(to) ?? 0) - 1;
|
|
376
|
+
indegree.set(to, next);
|
|
377
|
+
if (next === 0) queue.push(to);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if (order.length !== nodes.size) {
|
|
381
|
+
const remaining = Array.from(nodes).filter((n) => !order.includes(n));
|
|
382
|
+
return {
|
|
383
|
+
order: [],
|
|
384
|
+
configError: {
|
|
385
|
+
code: "CYCLE_DETECTED",
|
|
386
|
+
message: `[StateTrait.converge] Cycle detected in computed/link graph: ${remaining.join(", ")}`,
|
|
387
|
+
fields: remaining
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
return { order };
|
|
392
|
+
};
|
|
393
|
+
var buildConvergeIr = (entries) => {
|
|
394
|
+
const startedAt = nowPerf();
|
|
395
|
+
const generation = 0;
|
|
396
|
+
const writers = entries.filter((e) => e.kind === "computed" || e.kind === "link");
|
|
397
|
+
const writersKey = writers.map((entry) => `${entry.kind}:${entry.fieldPath}`).sort().join("|");
|
|
398
|
+
const depsKey = writers.map((entry) => {
|
|
399
|
+
const deps = getConvergeWriterDeps(entry).slice().sort().join(",");
|
|
400
|
+
const scheduling = entry.meta?.scheduling === "deferred" ? "d" : "i";
|
|
401
|
+
return `${entry.kind}:${entry.fieldPath}@${scheduling}=>${deps}`;
|
|
402
|
+
}).sort().join("|");
|
|
403
|
+
const writerByPath = /* @__PURE__ */ new Map();
|
|
404
|
+
for (const entry of writers) {
|
|
405
|
+
writerByPath.set(entry.fieldPath, entry);
|
|
406
|
+
}
|
|
407
|
+
const topo = writers.length > 0 ? computeConvergeTopoOrder(writers) : { order: [] };
|
|
408
|
+
const stepsById = topo.configError ? [] : topo.order.map((path) => writerByPath.get(path));
|
|
409
|
+
const fieldPathTable = /* @__PURE__ */ new Map();
|
|
410
|
+
const addPath = (path) => {
|
|
411
|
+
for (let i = 1; i <= path.length; i++) {
|
|
412
|
+
const prefix = path.slice(0, i);
|
|
413
|
+
const key = JSON.stringify(prefix);
|
|
414
|
+
if (!fieldPathTable.has(key)) fieldPathTable.set(key, prefix);
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
for (const entry of writers) {
|
|
418
|
+
const out = normalizeFieldPath(entry.fieldPath);
|
|
419
|
+
if (out) addPath(out);
|
|
420
|
+
for (const dep of getConvergeWriterDeps(entry)) {
|
|
421
|
+
const depPath = normalizeFieldPath(dep);
|
|
422
|
+
if (depPath) addPath(depPath);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
const fieldPaths = Array.from(fieldPathTable.values()).sort(compareFieldPath);
|
|
426
|
+
const fieldPathIdRegistry = makeFieldPathIdRegistry(fieldPaths);
|
|
427
|
+
const stepOutFieldPathIdByStepId = [];
|
|
428
|
+
const stepDepsFieldPathIdsByStepId = [];
|
|
429
|
+
const stepSchedulingByStepId = [];
|
|
430
|
+
for (const entry of stepsById) {
|
|
431
|
+
const out = normalizeFieldPath(entry.fieldPath);
|
|
432
|
+
const outId = out != null ? getFieldPathId(fieldPathIdRegistry, out) : void 0;
|
|
433
|
+
if (outId == null) {
|
|
434
|
+
throw new Error(`[StateTrait.build] Failed to map converge output fieldPath "${entry.fieldPath}" to FieldPathId.`);
|
|
435
|
+
}
|
|
436
|
+
const depIds = [];
|
|
437
|
+
for (const dep of getConvergeWriterDeps(entry)) {
|
|
438
|
+
const depPath = normalizeFieldPath(dep);
|
|
439
|
+
if (!depPath) continue;
|
|
440
|
+
const depId = getFieldPathId(fieldPathIdRegistry, depPath);
|
|
441
|
+
if (depId != null) depIds.push(depId);
|
|
442
|
+
}
|
|
443
|
+
stepOutFieldPathIdByStepId.push(outId);
|
|
444
|
+
stepDepsFieldPathIdsByStepId.push(depIds);
|
|
445
|
+
stepSchedulingByStepId.push(entry.meta?.scheduling === "deferred" ? "deferred" : "immediate");
|
|
446
|
+
}
|
|
447
|
+
const topoOrder = stepsById.map((_, i) => i);
|
|
448
|
+
const buildDurationMs = Math.max(0, nowPerf() - startedAt);
|
|
449
|
+
return {
|
|
450
|
+
generation,
|
|
451
|
+
writersKey,
|
|
452
|
+
depsKey,
|
|
453
|
+
fieldPaths,
|
|
454
|
+
fieldPathIdRegistry,
|
|
455
|
+
...topo.configError ? { configError: topo.configError } : null,
|
|
456
|
+
stepsById,
|
|
457
|
+
stepOutFieldPathIdByStepId,
|
|
458
|
+
stepDepsFieldPathIdsByStepId,
|
|
459
|
+
stepSchedulingByStepId,
|
|
460
|
+
topoOrder,
|
|
461
|
+
buildDurationMs
|
|
462
|
+
};
|
|
463
|
+
};
|
|
464
|
+
var toFieldTrait = (entry) => {
|
|
465
|
+
const deps = [];
|
|
466
|
+
if (entry.kind === "computed") {
|
|
467
|
+
const meta = entry.meta;
|
|
468
|
+
const list2 = meta.deps;
|
|
469
|
+
if (list2) deps.push(...list2);
|
|
470
|
+
} else if (entry.kind === "source") {
|
|
471
|
+
const meta = entry.meta;
|
|
472
|
+
const list2 = meta.deps;
|
|
473
|
+
if (list2) deps.push(...list2);
|
|
474
|
+
} else if (entry.kind === "link") {
|
|
475
|
+
deps.push(entry.meta.from);
|
|
476
|
+
} else if (entry.kind === "check") {
|
|
477
|
+
const meta = entry.meta;
|
|
478
|
+
const rules = meta?.rules ?? {};
|
|
479
|
+
for (const name of Object.keys(rules)) {
|
|
480
|
+
const rule = rules[name];
|
|
481
|
+
if (rule && typeof rule === "object") {
|
|
482
|
+
const list2 = rule.deps;
|
|
483
|
+
if (list2) deps.push(...list2);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return {
|
|
488
|
+
fieldId: entry.fieldPath,
|
|
489
|
+
kind: entry.kind,
|
|
490
|
+
// meta 在运行时保持与 Entry.meta 一致,便于 install 直接复用。
|
|
491
|
+
meta: entry.meta,
|
|
492
|
+
deps
|
|
493
|
+
};
|
|
494
|
+
};
|
|
495
|
+
var buildGraph = (entries, nodeMetaByFieldPath) => {
|
|
496
|
+
const fieldMap = /* @__PURE__ */ new Map();
|
|
497
|
+
const nodes = [];
|
|
498
|
+
const edges = [];
|
|
499
|
+
const resourcesById = /* @__PURE__ */ new Map();
|
|
500
|
+
const planSteps = [];
|
|
501
|
+
const ensureField = (fieldPath) => {
|
|
502
|
+
let field = fieldMap.get(fieldPath);
|
|
503
|
+
if (!field) {
|
|
504
|
+
field = {
|
|
505
|
+
id: fieldPath,
|
|
506
|
+
path: fieldPath,
|
|
507
|
+
traits: []
|
|
508
|
+
};
|
|
509
|
+
fieldMap.set(fieldPath, field);
|
|
510
|
+
}
|
|
511
|
+
return field;
|
|
512
|
+
};
|
|
513
|
+
for (const entry of entries) {
|
|
514
|
+
const fieldPath = entry.fieldPath;
|
|
515
|
+
const field = ensureField(fieldPath);
|
|
516
|
+
const trait = toFieldTrait(entry);
|
|
517
|
+
field.traits.push(trait);
|
|
518
|
+
if (entry.kind === "computed") {
|
|
519
|
+
const stepId = `computed:${fieldPath}`;
|
|
520
|
+
planSteps.push({
|
|
521
|
+
id: stepId,
|
|
522
|
+
kind: "computed-update",
|
|
523
|
+
targetFieldPath: fieldPath
|
|
524
|
+
// 说明:当前版本不静态分析 computed 依赖字段,sourceFieldPaths 留空。
|
|
525
|
+
});
|
|
526
|
+
const deps = entry.meta.deps;
|
|
527
|
+
if (deps) {
|
|
528
|
+
for (const dep of deps) {
|
|
529
|
+
ensureField(dep);
|
|
530
|
+
edges.push({
|
|
531
|
+
id: `computed:${dep}->${fieldPath}`,
|
|
532
|
+
from: dep,
|
|
533
|
+
to: fieldPath,
|
|
534
|
+
kind: "computed"
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
} else if (entry.kind === "link") {
|
|
539
|
+
const from2 = entry.meta.from;
|
|
540
|
+
ensureField(from2);
|
|
541
|
+
const edgeId = `link:${from2}->${fieldPath}`;
|
|
542
|
+
edges.push({
|
|
543
|
+
id: edgeId,
|
|
544
|
+
from: from2,
|
|
545
|
+
to: fieldPath,
|
|
546
|
+
kind: "link"
|
|
547
|
+
});
|
|
548
|
+
planSteps.push({
|
|
549
|
+
id: `link:${fieldPath}`,
|
|
550
|
+
kind: "link-propagate",
|
|
551
|
+
targetFieldPath: fieldPath,
|
|
552
|
+
sourceFieldPaths: [from2],
|
|
553
|
+
debugInfo: {
|
|
554
|
+
graphEdgeId: edgeId
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
} else if (entry.kind === "source") {
|
|
558
|
+
const resourceId = entry.meta.resource;
|
|
559
|
+
const resourceMeta = sanitize(entry.meta.meta);
|
|
560
|
+
const existing = resourcesById.get(resourceId);
|
|
561
|
+
if (existing) {
|
|
562
|
+
const ownerFields = [...existing.ownerFields, fieldPath];
|
|
563
|
+
let meta = existing.meta;
|
|
564
|
+
let metaOrigin = existing.metaOrigin;
|
|
565
|
+
let metaConflicts = existing.metaConflicts;
|
|
566
|
+
if (resourceMeta) {
|
|
567
|
+
const merged = mergeCanonical(
|
|
568
|
+
{ meta, origin: metaOrigin, conflicts: metaConflicts },
|
|
569
|
+
{ origin: fieldPath, meta: resourceMeta }
|
|
570
|
+
);
|
|
571
|
+
meta = merged.meta;
|
|
572
|
+
metaOrigin = merged.origin;
|
|
573
|
+
metaConflicts = merged.conflicts;
|
|
574
|
+
}
|
|
575
|
+
resourcesById.set(resourceId, {
|
|
576
|
+
...existing,
|
|
577
|
+
ownerFields,
|
|
578
|
+
meta,
|
|
579
|
+
metaOrigin,
|
|
580
|
+
metaConflicts
|
|
581
|
+
});
|
|
582
|
+
} else {
|
|
583
|
+
resourcesById.set(resourceId, {
|
|
584
|
+
resourceId,
|
|
585
|
+
// 暂时使用简单的标识字符串,后续可根据 key 规则进一步结构化。
|
|
586
|
+
keySelector: `StateTrait.source@${fieldPath}`,
|
|
587
|
+
ownerFields: [fieldPath],
|
|
588
|
+
meta: resourceMeta,
|
|
589
|
+
metaOrigin: resourceMeta ? fieldPath : void 0
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
planSteps.push({
|
|
593
|
+
id: `source:${fieldPath}`,
|
|
594
|
+
kind: "source-refresh",
|
|
595
|
+
targetFieldPath: fieldPath,
|
|
596
|
+
resourceId,
|
|
597
|
+
keySelectorId: `StateTrait.source@${fieldPath}`
|
|
598
|
+
});
|
|
599
|
+
const deps = entry.meta.deps;
|
|
600
|
+
if (deps) {
|
|
601
|
+
for (const dep of deps) {
|
|
602
|
+
ensureField(dep);
|
|
603
|
+
edges.push({
|
|
604
|
+
id: `source-dep:${dep}->${fieldPath}`,
|
|
605
|
+
from: dep,
|
|
606
|
+
to: fieldPath,
|
|
607
|
+
kind: "source-dep"
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
} else if (entry.kind === "check") {
|
|
612
|
+
planSteps.push({
|
|
613
|
+
id: `check:${fieldPath}`,
|
|
614
|
+
kind: "check-validate",
|
|
615
|
+
targetFieldPath: fieldPath
|
|
616
|
+
});
|
|
617
|
+
if (trait.deps.length > 0) {
|
|
618
|
+
for (const dep of trait.deps) {
|
|
619
|
+
ensureField(dep);
|
|
620
|
+
edges.push({
|
|
621
|
+
id: `check-dep:${dep}->${fieldPath}`,
|
|
622
|
+
from: dep,
|
|
623
|
+
to: fieldPath,
|
|
624
|
+
kind: "check-dep"
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
for (const field of fieldMap.values()) {
|
|
631
|
+
nodes.push({
|
|
632
|
+
id: field.id,
|
|
633
|
+
field,
|
|
634
|
+
traits: field.traits,
|
|
635
|
+
meta: nodeMetaByFieldPath.get(field.id)
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
const graph = {
|
|
639
|
+
_tag: "StateTraitGraph",
|
|
640
|
+
nodes,
|
|
641
|
+
edges,
|
|
642
|
+
resources: Array.from(resourcesById.values())
|
|
643
|
+
};
|
|
644
|
+
const plan = {
|
|
645
|
+
_tag: "StateTraitPlan",
|
|
646
|
+
steps: planSteps
|
|
647
|
+
};
|
|
648
|
+
return { graph, plan };
|
|
649
|
+
};
|
|
650
|
+
var assertNoLinkCycles = (edges) => {
|
|
651
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
652
|
+
for (const edge of edges) {
|
|
653
|
+
if (edge.kind !== "link") continue;
|
|
654
|
+
const list2 = adjacency.get(edge.from) ?? [];
|
|
655
|
+
list2.push(edge.to);
|
|
656
|
+
adjacency.set(edge.from, list2);
|
|
657
|
+
}
|
|
658
|
+
const visited = /* @__PURE__ */ new Set();
|
|
659
|
+
const stack = /* @__PURE__ */ new Set();
|
|
660
|
+
const dfs = (node2) => {
|
|
661
|
+
if (stack.has(node2)) {
|
|
662
|
+
throw new Error(
|
|
663
|
+
`[StateTrait.build] link cycle detected at field "${node2}". Please check link traits for circular dependencies.`
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
if (visited.has(node2)) return;
|
|
667
|
+
visited.add(node2);
|
|
668
|
+
stack.add(node2);
|
|
669
|
+
const nexts = adjacency.get(node2);
|
|
670
|
+
if (nexts) {
|
|
671
|
+
for (const to of nexts) {
|
|
672
|
+
dfs(to);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
stack.delete(node2);
|
|
676
|
+
};
|
|
677
|
+
for (const node2 of adjacency.keys()) {
|
|
678
|
+
if (!visited.has(node2)) {
|
|
679
|
+
dfs(node2);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
var collectSchemaPaths = (entries) => {
|
|
684
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
685
|
+
const add = (ref) => {
|
|
686
|
+
if (!ref.path) return;
|
|
687
|
+
const k = `${ref.kind}|${ref.entryKind}|${ref.entryFieldPath}|${ref.ruleName ?? ""}|${ref.path}`;
|
|
688
|
+
byKey.set(k, ref);
|
|
689
|
+
};
|
|
690
|
+
const getCheckWritebackPath = (entry) => {
|
|
691
|
+
const wb = entry.meta?.writeback;
|
|
692
|
+
const p = wb && typeof wb === "object" ? wb.path : void 0;
|
|
693
|
+
const writebackPath = typeof p === "string" && p.startsWith("errors.") ? p : void 0;
|
|
694
|
+
if (writebackPath) return writebackPath;
|
|
695
|
+
const fieldPath = entry.fieldPath;
|
|
696
|
+
if (fieldPath.endsWith("[]")) {
|
|
697
|
+
return `errors.${fieldPath.slice(0, -2)}`;
|
|
698
|
+
}
|
|
699
|
+
return `errors.${fieldPath}`;
|
|
700
|
+
};
|
|
701
|
+
for (const entry of entries) {
|
|
702
|
+
add({
|
|
703
|
+
kind: "fieldPath",
|
|
704
|
+
entryKind: entry.kind,
|
|
705
|
+
entryFieldPath: entry.fieldPath,
|
|
706
|
+
path: entry.fieldPath
|
|
707
|
+
});
|
|
708
|
+
if (entry.kind === "computed" || entry.kind === "source") {
|
|
709
|
+
const deps = entry.meta?.deps ?? [];
|
|
710
|
+
for (const dep of deps) {
|
|
711
|
+
add({
|
|
712
|
+
kind: "dep",
|
|
713
|
+
entryKind: entry.kind,
|
|
714
|
+
entryFieldPath: entry.fieldPath,
|
|
715
|
+
path: dep
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
if (entry.kind === "link") {
|
|
720
|
+
add({
|
|
721
|
+
kind: "link_from",
|
|
722
|
+
entryKind: "link",
|
|
723
|
+
entryFieldPath: entry.fieldPath,
|
|
724
|
+
path: entry.meta.from
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
if (entry.kind === "check") {
|
|
728
|
+
add({
|
|
729
|
+
kind: "check_writeback",
|
|
730
|
+
entryKind: "check",
|
|
731
|
+
entryFieldPath: entry.fieldPath,
|
|
732
|
+
path: getCheckWritebackPath(entry)
|
|
733
|
+
});
|
|
734
|
+
const rules = entry.meta?.rules ?? {};
|
|
735
|
+
for (const name of Object.keys(rules)) {
|
|
736
|
+
const rule = rules[name];
|
|
737
|
+
if (!rule || typeof rule !== "object") continue;
|
|
738
|
+
const deps = rule.deps ?? [];
|
|
739
|
+
for (const dep of deps) {
|
|
740
|
+
add({
|
|
741
|
+
kind: "dep",
|
|
742
|
+
entryKind: "check",
|
|
743
|
+
entryFieldPath: entry.fieldPath,
|
|
744
|
+
ruleName: name,
|
|
745
|
+
path: dep
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
return Array.from(byKey.entries()).sort((a, b) => a[0].localeCompare(b[0])).map(([, v]) => v);
|
|
752
|
+
};
|
|
753
|
+
var build = (stateSchema, spec) => {
|
|
754
|
+
const entries = normalizeSpec(spec);
|
|
755
|
+
const nodeMetaByFieldPath = collectNodeMeta(spec);
|
|
756
|
+
for (const entry of entries) {
|
|
757
|
+
if (entry.kind === "computed") {
|
|
758
|
+
const deps = entry.meta.deps;
|
|
759
|
+
if (deps === void 0) {
|
|
760
|
+
throw new Error(
|
|
761
|
+
`[StateTrait.build] Missing explicit deps for computed "${entry.fieldPath}". Please use StateTrait.computed({ deps: [...], get: ... }).`
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (entry.kind === "source") {
|
|
766
|
+
const deps = entry.meta.deps;
|
|
767
|
+
if (deps === void 0) {
|
|
768
|
+
throw new Error(
|
|
769
|
+
`[StateTrait.build] Missing explicit deps for source "${entry.fieldPath}". Please provide meta.deps for StateTrait.source({ deps: [...], ... }).`
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
if (entry.kind === "check") {
|
|
774
|
+
const rules = entry.meta?.rules ?? {};
|
|
775
|
+
for (const name of Object.keys(rules)) {
|
|
776
|
+
const rule = rules[name];
|
|
777
|
+
if (typeof rule === "function" || !rule || typeof rule !== "object") {
|
|
778
|
+
throw new Error(
|
|
779
|
+
`[StateTrait.build] Missing explicit deps for check "${entry.fieldPath}" rule "${name}". Please use { deps: [...], validate: ... } form.`
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
if (rule.deps === void 0) {
|
|
783
|
+
throw new Error(
|
|
784
|
+
`[StateTrait.build] Missing explicit deps for check "${entry.fieldPath}" rule "${name}". Please provide deps: [...].`
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
const { graph, plan } = buildGraph(entries, nodeMetaByFieldPath);
|
|
791
|
+
assertNoLinkCycles(graph.edges);
|
|
792
|
+
return {
|
|
793
|
+
stateSchema,
|
|
794
|
+
spec,
|
|
795
|
+
entries,
|
|
796
|
+
graph,
|
|
797
|
+
plan,
|
|
798
|
+
convergeIr: buildConvergeIr(entries),
|
|
799
|
+
schemaPaths: collectSchemaPaths(entries)
|
|
800
|
+
};
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
// ../logix-core/src/internal/state-trait/install.ts
|
|
804
|
+
import { Effect } from "../effect.js";
|
|
805
|
+
var buildEntryIndex = (entries) => {
|
|
806
|
+
const index = /* @__PURE__ */ new Map();
|
|
807
|
+
for (const entry of entries) {
|
|
808
|
+
const list2 = index.get(entry.fieldPath) ?? [];
|
|
809
|
+
list2.push(entry);
|
|
810
|
+
index.set(entry.fieldPath, list2);
|
|
811
|
+
}
|
|
812
|
+
return index;
|
|
813
|
+
};
|
|
814
|
+
var install = (bound, program) => {
|
|
815
|
+
try {
|
|
816
|
+
const internals = getBoundInternals(bound);
|
|
817
|
+
internals.traits.registerStateTraitProgram(program, {
|
|
818
|
+
bumpReason: "logic_installed"
|
|
819
|
+
});
|
|
820
|
+
} catch {
|
|
821
|
+
}
|
|
822
|
+
const entryIndex = buildEntryIndex(program.entries);
|
|
823
|
+
const installStep = (step) => {
|
|
824
|
+
if (!step.targetFieldPath) {
|
|
825
|
+
return Effect.void;
|
|
826
|
+
}
|
|
827
|
+
if (step.kind !== "source-refresh") {
|
|
828
|
+
return Effect.void;
|
|
829
|
+
}
|
|
830
|
+
const candidates = entryIndex.get(step.targetFieldPath);
|
|
831
|
+
if (!candidates || candidates.length === 0) {
|
|
832
|
+
return Effect.void;
|
|
833
|
+
}
|
|
834
|
+
const entry = candidates.find((e) => e.kind === "source");
|
|
835
|
+
if (!entry) {
|
|
836
|
+
return Effect.void;
|
|
837
|
+
}
|
|
838
|
+
return installSourceRefresh(bound, step, entry);
|
|
839
|
+
};
|
|
840
|
+
return Effect.forEach(program.plan.steps, (step) => installStep(step)).pipe(Effect.asVoid);
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
// ../logix-core/src/StateTrait.ts
|
|
844
|
+
var $root = "$root";
|
|
845
|
+
var from = (_schema) => (spec) => spec;
|
|
846
|
+
var node = (spec) => ({
|
|
847
|
+
_tag: "StateTraitNode",
|
|
848
|
+
...spec
|
|
849
|
+
});
|
|
850
|
+
var list = (spec) => ({
|
|
851
|
+
_tag: "StateTraitList",
|
|
852
|
+
...spec
|
|
853
|
+
});
|
|
854
|
+
var computed = (input) => {
|
|
855
|
+
const derive = (state) => {
|
|
856
|
+
const args = input.deps.map((dep) => getAtPath(state, dep));
|
|
857
|
+
return input.get(...args);
|
|
858
|
+
};
|
|
859
|
+
return {
|
|
860
|
+
fieldPath: void 0,
|
|
861
|
+
kind: "computed",
|
|
862
|
+
meta: {
|
|
863
|
+
deps: input.deps,
|
|
864
|
+
derive,
|
|
865
|
+
equals: input.equals,
|
|
866
|
+
...input.scheduling ? { scheduling: input.scheduling } : {}
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
};
|
|
870
|
+
var source = (meta) => ({
|
|
871
|
+
fieldPath: void 0,
|
|
872
|
+
kind: "source",
|
|
873
|
+
meta
|
|
874
|
+
});
|
|
875
|
+
var link = (meta) => ({
|
|
876
|
+
fieldPath: void 0,
|
|
877
|
+
kind: "link",
|
|
878
|
+
meta: { ...meta, ...meta.scheduling ? { scheduling: meta.scheduling } : {} }
|
|
879
|
+
});
|
|
880
|
+
var build2 = (stateSchema, spec) => build(stateSchema, spec);
|
|
881
|
+
var install2 = (bound, program) => install(bound, program);
|
|
882
|
+
var exportStaticIr2 = (program, moduleId, options) => exportStaticIr({
|
|
883
|
+
program,
|
|
884
|
+
moduleId,
|
|
885
|
+
version: options?.version
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
export {
|
|
889
|
+
$root,
|
|
890
|
+
from,
|
|
891
|
+
node,
|
|
892
|
+
list,
|
|
893
|
+
computed,
|
|
894
|
+
source,
|
|
895
|
+
link,
|
|
896
|
+
build2 as build,
|
|
897
|
+
install2 as install,
|
|
898
|
+
exportStaticIr2 as exportStaticIr
|
|
899
|
+
};
|
|
900
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvbWV0YS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9zdGF0ZS10cmFpdC9tb2RlbC50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9zdGF0ZS10cmFpdC9idWlsZC50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9zdGF0ZS10cmFpdC9pbnN0YWxsLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL1N0YXRlVHJhaXQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImV4cG9ydCB0eXBlIFRyYWl0TWV0YSA9IFJlYWRvbmx5PHtcbiAgcmVhZG9ubHkgbGFiZWw/OiBzdHJpbmdcbiAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmdcbiAgcmVhZG9ubHkgdGFncz86IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICByZWFkb25seSBncm91cD86IHN0cmluZ1xuICByZWFkb25seSBkb2NzVXJsPzogc3RyaW5nXG4gIHJlYWRvbmx5IGNhY2hlR3JvdXA/OiBzdHJpbmdcbiAgLyoqXG4gICAqIFx1NjI2OVx1NUM1NVx1NkNFOFx1ODlFM1x1NEY0RFx1RkYxQVx1NEVDNVx1NjNBNVx1NTNENyBgeC0qYCBrZXlcdUZGMDhcdTc1MjhcdTRFOEUgUGhhbnRvbSBTb3VyY2UgLyBEcmlmdCBEZXRlY3Rpb24gXHU3QjQ5XHU4MEZEXHU1MjlCXHU3Njg0XHU5NTFBXHU3MEI5XHVGRjA5XHUzMDAyXG4gICAqXG4gICAqIFx1N0VBNlx1Njc1Rlx1RkYxQVxuICAgKiAtIFx1NUZDNVx1OTg3Qlx1NTNFRlx1NUU4Rlx1NTIxN1x1NTMxNlx1RkYwOEpTT04gXHU1MDNDXHVGRjA5XHVGRjFCXG4gICAqIC0gXHU1RkM1XHU5ODdCIFNsaW1cdUZGMDhcdTVFRkFcdThCQUVcdTUzRUFcdTY1M0VcdTVDMTFcdTkxQ0ZcdTUxNzNcdTk1MkVcdTYzRDBcdTc5M0FcdUZGMENcdTRFMERcdTg5ODFcdTU4NUVcdTU5MjdcdTVCRjlcdThDNjFcdUZGMDlcdTMwMDJcbiAgICovXG4gIHJlYWRvbmx5IGFubm90YXRpb25zPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgSnNvblZhbHVlPj5cbiAgLyoqXG4gICAqIFx1OEJFRFx1NEU0OVx1NjNEMFx1NzkzQVx1RkYxQVx1NUY1M1x1NTQwQ1x1NEUwMFx1NUI5RVx1NEY1M1x1RkYwOFx1NEY4Qlx1NTk4Mlx1NTQwQ1x1NEUwMCByZXNvdXJjZUlkXHVGRjA5XHU1MUZBXHU3M0IwXHU1OTFBXHU1OTA0IG1ldGEgXHU1OEYwXHU2NjBFXHU0RTE0XHU0RTBEXHU0RTAwXHU4MUY0XHU2NUY2XHVGRjBDXG4gICAqIGNhbm9uaWNhbD10cnVlIFx1NzY4NFx1NThGMFx1NjYwRVx1NEYxOFx1NTE0OFx1NjIxMFx1NEUzQVx1MjAxQ1x1NUM1NVx1NzkzQVx1NzUyOCBjYW5vbmljYWxcdTIwMURcdUZGMUJcdTUxNzZcdTRFRDZcdTU4RjBcdTY2MEVcdTRGMUFcdThCQjBcdTVGNTVcdTRFM0EgY29uZmxpY3RzXHUzMDAyXG4gICAqL1xuICByZWFkb25seSBjYW5vbmljYWw/OiBib29sZWFuXG59PlxuXG5leHBvcnQgdHlwZSBUcmFpdE1ldGFDb25mbGljdCA9IFJlYWRvbmx5PHtcbiAgcmVhZG9ubHkgb3JpZ2luOiBzdHJpbmdcbiAgcmVhZG9ubHkgbWV0YTogVHJhaXRNZXRhXG59PlxuXG5leHBvcnQgdHlwZSBKc29uUHJpbWl0aXZlID0gc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGxcbmV4cG9ydCB0eXBlIEpzb25WYWx1ZSA9IEpzb25QcmltaXRpdmUgfCBSZWFkb25seUFycmF5PEpzb25WYWx1ZT4gfCB7IHJlYWRvbmx5IFtrZXk6IHN0cmluZ106IEpzb25WYWx1ZSB9XG5cbmNvbnN0IHVuaXFTb3J0ZWRTdHJpbmdzID0gKGlucHV0OiBSZWFkb25seUFycmF5PHN0cmluZz4pOiBSZWFkb25seUFycmF5PHN0cmluZz4gPT4ge1xuICBjb25zdCBzZXQgPSBuZXcgU2V0PHN0cmluZz4oKVxuICBmb3IgKGNvbnN0IGl0ZW0gb2YgaW5wdXQpIHtcbiAgICBjb25zdCB2ID0gaXRlbS50cmltKClcbiAgICBpZiAoIXYpIGNvbnRpbnVlXG4gICAgc2V0LmFkZCh2KVxuICB9XG4gIHJldHVybiBBcnJheS5mcm9tKHNldCkuc29ydCgoYSwgYikgPT4gYS5sb2NhbGVDb21wYXJlKGIpKVxufVxuXG5jb25zdCBpc1BsYWluUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT5cbiAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSlcblxuY29uc3Qgc2FuaXRpemVKc29uVmFsdWUgPSAoaW5wdXQ6IHVua25vd24sIGRlcHRoOiBudW1iZXIpOiBKc29uVmFsdWUgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoaW5wdXQgPT09IG51bGwpIHJldHVybiBudWxsXG5cbiAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHJldHVybiBpbnB1dFxuICBpZiAodHlwZW9mIGlucHV0ID09PSAnYm9vbGVhbicpIHJldHVybiBpbnB1dFxuICBpZiAodHlwZW9mIGlucHV0ID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBOdW1iZXIuaXNGaW5pdGUoaW5wdXQpID8gaW5wdXQgOiB1bmRlZmluZWRcbiAgfVxuXG4gIGlmIChkZXB0aCA+PSA2KSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXQpKSB7XG4gICAgY29uc3Qgb3V0OiBBcnJheTxKc29uVmFsdWU+ID0gW11cbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaW5wdXQpIHtcbiAgICAgIGNvbnN0IHYgPSBzYW5pdGl6ZUpzb25WYWx1ZShpdGVtLCBkZXB0aCArIDEpXG4gICAgICBpZiAodiAhPT0gdW5kZWZpbmVkKSBvdXQucHVzaCh2KVxuICAgIH1cbiAgICByZXR1cm4gb3V0XG4gIH1cblxuICBpZiAoaXNQbGFpblJlY29yZChpbnB1dCkpIHtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoaW5wdXQpLnNvcnQoKVxuICAgIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgSnNvblZhbHVlPiA9IHt9XG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgY29uc3QgdiA9IHNhbml0aXplSnNvblZhbHVlKGlucHV0W2tleV0sIGRlcHRoICsgMSlcbiAgICAgIGlmICh2ICE9PSB1bmRlZmluZWQpIG91dFtrZXldID0gdlxuICAgIH1cbiAgICByZXR1cm4gb3V0XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmV4cG9ydCBjb25zdCBzYW5pdGl6ZSA9IChpbnB1dDogdW5rbm93bik6IFRyYWl0TWV0YSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChpbnB1dCA9PT0gbnVsbCB8fCBpbnB1dCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkXG4gIGlmICh0eXBlb2YgaW5wdXQgIT09ICdvYmplY3QnIHx8IEFycmF5LmlzQXJyYXkoaW5wdXQpKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3QgcmVjb3JkID0gaW5wdXQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgY29uc3Qgb3V0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9XG5cbiAgY29uc3QgcGlja1N0cmluZyA9IChrZXk6IGtleW9mIFRyYWl0TWV0YSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gcmVjb3JkW2tleSBhcyBzdHJpbmddXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHJldHVyblxuICAgIGNvbnN0IHRyaW1tZWQgPSB2YWx1ZS50cmltKClcbiAgICBpZiAoIXRyaW1tZWQpIHJldHVyblxuICAgIG91dFtrZXldID0gdHJpbW1lZFxuICB9XG5cbiAgcGlja1N0cmluZygnbGFiZWwnKVxuICBwaWNrU3RyaW5nKCdkZXNjcmlwdGlvbicpXG4gIHBpY2tTdHJpbmcoJ2dyb3VwJylcbiAgcGlja1N0cmluZygnZG9jc1VybCcpXG4gIHBpY2tTdHJpbmcoJ2NhY2hlR3JvdXAnKVxuXG4gIGNvbnN0IGNhbm9uaWNhbCA9IHJlY29yZC5jYW5vbmljYWxcbiAgaWYgKHR5cGVvZiBjYW5vbmljYWwgPT09ICdib29sZWFuJykge1xuICAgIG91dC5jYW5vbmljYWwgPSBjYW5vbmljYWxcbiAgfVxuXG4gIGNvbnN0IHRhZ3NSYXcgPSByZWNvcmQudGFnc1xuICBpZiAodHlwZW9mIHRhZ3NSYXcgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgdGFncyA9IHVuaXFTb3J0ZWRTdHJpbmdzKFt0YWdzUmF3XSlcbiAgICBpZiAodGFncy5sZW5ndGggPiAwKSBvdXQudGFncyA9IHRhZ3NcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHRhZ3NSYXcpKSB7XG4gICAgY29uc3QgdGFncyA9IHVuaXFTb3J0ZWRTdHJpbmdzKHRhZ3NSYXcuZmlsdGVyKCh4KTogeCBpcyBzdHJpbmcgPT4gdHlwZW9mIHggPT09ICdzdHJpbmcnKSlcbiAgICBpZiAodGFncy5sZW5ndGggPiAwKSBvdXQudGFncyA9IHRhZ3NcbiAgfVxuXG4gIGNvbnN0IGFubm90YXRpb25zOiBSZWNvcmQ8c3RyaW5nLCBKc29uVmFsdWU+ID0ge31cblxuICAvLyBsZWdhY3k6IGFsbG93IHBhc3NpbmcgYHgtKmAga2V5cyBhdCB0aGUgdG9wLWxldmVsICh1bnR5cGVkIGlucHV0KSwgdGhlbiBub3JtYWxpemUgaW50byBgYW5ub3RhdGlvbnNgLlxuICBjb25zdCBhbm5vdGF0aW9uS2V5cyA9IE9iamVjdC5rZXlzKHJlY29yZClcbiAgICAuZmlsdGVyKChrKSA9PiBrLnN0YXJ0c1dpdGgoJ3gtJykpXG4gICAgLnNvcnQoKGEsIGIpID0+IGEubG9jYWxlQ29tcGFyZShiKSlcbiAgZm9yIChjb25zdCBrZXkgb2YgYW5ub3RhdGlvbktleXMpIHtcbiAgICBjb25zdCB2ID0gc2FuaXRpemVKc29uVmFsdWUocmVjb3JkW2tleV0sIDApXG4gICAgaWYgKHYgIT09IHVuZGVmaW5lZCkgYW5ub3RhdGlvbnNba2V5XSA9IHZcbiAgfVxuXG4gIC8vIHByZWZlcnJlZDogdHlwZWQgYGFubm90YXRpb25zYCBmaWVsZCAob25seSBhY2NlcHRzIGB4LSpgIGtleXMpLlxuICBjb25zdCBhbm5vdGF0aW9uc1JhdyA9IHJlY29yZC5hbm5vdGF0aW9uc1xuICBpZiAoaXNQbGFpblJlY29yZChhbm5vdGF0aW9uc1JhdykpIHtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoYW5ub3RhdGlvbnNSYXcpXG4gICAgICAuZmlsdGVyKChrKSA9PiBrLnN0YXJ0c1dpdGgoJ3gtJykpXG4gICAgICAuc29ydCgoYSwgYikgPT4gYS5sb2NhbGVDb21wYXJlKGIpKVxuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgIGNvbnN0IHYgPSBzYW5pdGl6ZUpzb25WYWx1ZShhbm5vdGF0aW9uc1Jhd1trZXldLCAwKVxuICAgICAgaWYgKHYgIT09IHVuZGVmaW5lZCkgYW5ub3RhdGlvbnNba2V5XSA9IHZcbiAgICB9XG4gIH1cblxuICBpZiAoT2JqZWN0LmtleXMoYW5ub3RhdGlvbnMpLmxlbmd0aCA+IDApIG91dC5hbm5vdGF0aW9ucyA9IGFubm90YXRpb25zXG5cbiAgcmV0dXJuIE9iamVjdC5rZXlzKG91dCkubGVuZ3RoID4gMCA/IChvdXQgYXMgVHJhaXRNZXRhKSA6IHVuZGVmaW5lZFxufVxuXG5jb25zdCBzdGFibGVTdHJpbmdpZnkgPSAobWV0YTogVHJhaXRNZXRhKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgb3V0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhtZXRhKS5zb3J0KClcbiAgZm9yIChjb25zdCBrIG9mIGtleXMpIHtcbiAgICBvdXRba10gPSAobWV0YSBhcyBhbnkpW2tdXG4gIH1cbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG91dClcbn1cblxuZXhwb3J0IGNvbnN0IGVxdWFscyA9IChhOiBUcmFpdE1ldGEgfCB1bmRlZmluZWQsIGI6IFRyYWl0TWV0YSB8IHVuZGVmaW5lZCk6IGJvb2xlYW4gPT4ge1xuICBpZiAoYSA9PT0gYikgcmV0dXJuIHRydWVcbiAgaWYgKCFhIHx8ICFiKSByZXR1cm4gZmFsc2VcbiAgcmV0dXJuIHN0YWJsZVN0cmluZ2lmeShhKSA9PT0gc3RhYmxlU3RyaW5naWZ5KGIpXG59XG5cbmV4cG9ydCB0eXBlIENhbm9uaWNhbE1lcmdlSW5wdXQgPSBSZWFkb25seTx7XG4gIHJlYWRvbmx5IG1ldGE/OiBUcmFpdE1ldGFcbiAgcmVhZG9ubHkgb3JpZ2luPzogc3RyaW5nXG4gIHJlYWRvbmx5IGNvbmZsaWN0cz86IFJlYWRvbmx5QXJyYXk8VHJhaXRNZXRhQ29uZmxpY3Q+XG59PlxuXG5leHBvcnQgdHlwZSBDYW5vbmljYWxNZXJnZVJlc3VsdCA9IFJlYWRvbmx5PHtcbiAgcmVhZG9ubHkgbWV0YT86IFRyYWl0TWV0YVxuICByZWFkb25seSBvcmlnaW4/OiBzdHJpbmdcbiAgcmVhZG9ubHkgY29uZmxpY3RzPzogUmVhZG9ubHlBcnJheTxUcmFpdE1ldGFDb25mbGljdD5cbn0+XG5cbmV4cG9ydCBjb25zdCBtZXJnZUNhbm9uaWNhbCA9IChcbiAgY3VycmVudDogQ2Fub25pY2FsTWVyZ2VJbnB1dCxcbiAgaW5jb21pbmc6IFJlYWRvbmx5PHsgcmVhZG9ubHkgb3JpZ2luOiBzdHJpbmc7IHJlYWRvbmx5IG1ldGE6IFRyYWl0TWV0YSB9Pixcbik6IENhbm9uaWNhbE1lcmdlUmVzdWx0ID0+IHtcbiAgY29uc3QgZXhpc3RpbmcgPSBjdXJyZW50Lm1ldGFcbiAgaWYgKCFleGlzdGluZykge1xuICAgIHJldHVybiB7XG4gICAgICBtZXRhOiBpbmNvbWluZy5tZXRhLFxuICAgICAgb3JpZ2luOiBpbmNvbWluZy5vcmlnaW4sXG4gICAgICBjb25mbGljdHM6IGN1cnJlbnQuY29uZmxpY3RzLFxuICAgIH1cbiAgfVxuXG4gIGlmIChlcXVhbHMoZXhpc3RpbmcsIGluY29taW5nLm1ldGEpKSB7XG4gICAgcmV0dXJuIGN1cnJlbnRcbiAgfVxuXG4gIGNvbnN0IGNvbmZsaWN0czogQXJyYXk8VHJhaXRNZXRhQ29uZmxpY3Q+ID0gWy4uLigoY3VycmVudC5jb25mbGljdHMgPz8gW10pIGFzIFJlYWRvbmx5QXJyYXk8VHJhaXRNZXRhQ29uZmxpY3Q+KV1cblxuICBjb25zdCBwdXNoID0gKGNvbmZsaWN0OiBUcmFpdE1ldGFDb25mbGljdCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGV4aXN0cyA9IGNvbmZsaWN0cy5zb21lKChjKSA9PiBjLm9yaWdpbiA9PT0gY29uZmxpY3Qub3JpZ2luICYmIGVxdWFscyhjLm1ldGEsIGNvbmZsaWN0Lm1ldGEpKVxuICAgIGlmICghZXhpc3RzKSBjb25mbGljdHMucHVzaChjb25mbGljdClcbiAgfVxuXG4gIGNvbnN0IGV4aXN0aW5nQ2Fub25pY2FsID0gZXhpc3RpbmcuY2Fub25pY2FsID09PSB0cnVlXG4gIGNvbnN0IGluY29taW5nQ2Fub25pY2FsID0gaW5jb21pbmcubWV0YS5jYW5vbmljYWwgPT09IHRydWVcblxuICBpZiAoIWV4aXN0aW5nQ2Fub25pY2FsICYmIGluY29taW5nQ2Fub25pY2FsKSB7XG4gICAgcHVzaCh7XG4gICAgICBvcmlnaW46IGN1cnJlbnQub3JpZ2luID8/ICd1bmtub3duJyxcbiAgICAgIG1ldGE6IGV4aXN0aW5nLFxuICAgIH0pXG4gICAgcmV0dXJuIHtcbiAgICAgIG1ldGE6IGluY29taW5nLm1ldGEsXG4gICAgICBvcmlnaW46IGluY29taW5nLm9yaWdpbixcbiAgICAgIGNvbmZsaWN0cyxcbiAgICB9XG4gIH1cblxuICBwdXNoKHtcbiAgICBvcmlnaW46IGluY29taW5nLm9yaWdpbixcbiAgICBtZXRhOiBpbmNvbWluZy5tZXRhLFxuICB9KVxuXG4gIHJldHVybiB7XG4gICAgbWV0YTogZXhpc3RpbmcsXG4gICAgb3JpZ2luOiBjdXJyZW50Lm9yaWdpbiA/PyBpbmNvbWluZy5vcmlnaW4sXG4gICAgY29uZmxpY3RzLFxuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBTY2hlbWEgfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgdHlwZSB7IFN0YXRlQXRQYXRoLCBTdGF0ZUZpZWxkUGF0aCB9IGZyb20gJy4vZmllbGQtcGF0aC5qcydcbmltcG9ydCB0eXBlIHsgRGlydHlBbGxSZWFzb24gfSBmcm9tICcuLi9maWVsZC1wYXRoLmpzJ1xuaW1wb3J0ICogYXMgTWV0YSBmcm9tICcuL21ldGEuanMnXG5pbXBvcnQgdHlwZSB7IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeSB9IGZyb20gJy4vY29udmVyZ2UtaXIuanMnXG5pbXBvcnQgdHlwZSB7IENvbnZlcmdlRXhlY0lyIH0gZnJvbSAnLi9jb252ZXJnZS1leGVjLWlyLmpzJ1xuXG4vLyBTdGF0ZVRyYWl0IGNvcmUgbW9kZWxcdTMwMDJcbi8vIFx1NTE3N1x1NEY1M1x1NUI1N1x1NkJCNVx1OEJFRFx1NEU0OVx1NEUwRSBkYXRhLW1vZGVsLm1kIC8gcmVmZXJlbmNlcy9zdGF0ZS10cmFpdC1jb3JlLm1kIFx1NEZERFx1NjMwMVx1NUJGOVx1OUY1MFx1MzAwMlxuXG4vKipcbiAqIFN0YXRlVHJhaXRTcGVjPFM+XHVGRjFBXG4gKiAtIE1vZHVsZSBcdTU2RkVcdTdFQjhcdTRFMkQgdHJhaXRzIFx1NjlGRFx1NEY0RFx1NzY4NFx1NjgwN1x1NTFDNlx1NUY2Mlx1NjAwMVx1RkYxQlxuICogLSBrZXkgXHU1M0Q3IFN0YXRlRmllbGRQYXRoPFM+IFx1N0VBNlx1Njc1Rlx1RkYwQ3ZhbHVlIFx1NEUzQVx1NUJGOVx1NUU5NCBzY29wZSBcdTc2ODRcdTU4RjBcdTY2MEVcdUZGMDhFbnRyeSAvIE5vZGUgLyBMaXN0XHVGRjA5XHUzMDAyXG4gKi9cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRTcGVjPFM+ID0gUyBleHRlbmRzIG9iamVjdFxuICA/IHtcbiAgICAgIFtQYXRoIGluIFN0YXRlRmllbGRQYXRoPFM+IHwgJyRyb290J10/OiBTdGF0ZVRyYWl0U3BlY1ZhbHVlPFMsIFBhdGg+XG4gICAgfVxuICA6IG5ldmVyXG5cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRLaW5kID0gJ2NvbXB1dGVkJyB8ICdzb3VyY2UnIHwgJ2xpbmsnIHwgJ2NoZWNrJ1xuXG4vKipcbiAqIFRyYWl0Q29udmVyZ2VTY2hlZHVsaW5nXHVGRjFBXG4gKiAtIFx1NzUyOFx1NEU4RSBjb252ZXJnZS9kaXJ0eS1jaGVjayBcdTc2ODRcdThDMDNcdTVFQTZcdThCRURcdTRFNDlcdUZGMDgwNDNcdUZGMDlcdUZGMUFcdTUxQjNcdTVCOUFcdThCRTUgc3RlcCBcdTU3MjhcdTZCQ0ZcdTRFMkFcdTRFOEJcdTUyQTFcdTdBOTdcdTUzRTNcdTUxODVcdTY2MkZcdTU0MjZcdTVGQzVcdTk4N0JcdTY1MzZcdTY1NUJcdUZGMUJcbiAqIC0gXHU5RUQ4XHU4QkE0IGBpbW1lZGlhdGVgXHVGRjA4XHU0RkREXHU2MzAxXHU2NUUyXHU2NzA5XHU4ODRDXHU0RTNBXHVGRjA5XHVGRjFCYGRlZmVycmVkYCBcdTRFQzVcdTU3MjhcdTY2M0VcdTVGMEZcdTU4RjBcdTY2MEUgKyB0aW1lLXNsaWNpbmcgXHU1NDJGXHU3NTI4XHU2NUY2XHU3NTFGXHU2NTQ4XHUzMDAyXG4gKi9cbmV4cG9ydCB0eXBlIFRyYWl0Q29udmVyZ2VTY2hlZHVsaW5nID0gJ2ltbWVkaWF0ZScgfCAnZGVmZXJyZWQnXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcHV0ZWRNZXRhPFMsIFA+IHtcbiAgLyoqXG4gICAqIFx1NjYzRVx1NUYwRlx1NEY5RFx1OEQ1Nlx1NUI1N1x1NkJCNVx1OERFRlx1NUY4NFx1OTZDNlx1NTQwOFx1RkYwOFx1NUZDNVx1OTg3Qlx1RkYwOVx1RkYxQVxuICAgKlxuICAgKiAtIGRlcHMgXHU2NjJGXHU1NTJGXHU0RTAwXHU0RjlEXHU4RDU2XHU0RThCXHU1QjlFXHU2RTkwXHVGRjFBR3JhcGgvUmV2ZXJzZUNsb3N1cmUvXHU1ODlFXHU5MUNGXHU4QzAzXHU1RUE2L1x1NjAyN1x1ODBGRFx1NEYxOFx1NTMxNlx1OTBGRFx1NTNFQVx1OEJBNCBkZXBzXHVGRjFCXG4gICAqIC0gRFNMIFx1NEZBNyBgU3RhdGVUcmFpdC5jb21wdXRlZCh7IGRlcHMsIGdldCB9KWAgXHU3Njg0IGBnZXRgIFx1OTFDN1x1NzUyOCBkZXBzLWFzLWFyZ3NcdUZGMENcdTRFMERcdTY2QjRcdTk3MzIgYChzdGF0ZSkgPT4gLi4uYFx1RkYxQlxuICAgKiAtIGJ1aWxkIFx1OTYzNlx1NkJCNVx1NEYxQVx1NUMwNiBgZ2V0KC4uLmRlcHNWYWx1ZXMpYCBcdTk2NERcdTg5RTNcdTRFM0EgYGRlcml2ZShzdGF0ZSlgIFx1NEY5Qlx1OEZEMFx1ODg0Q1x1NjVGNlx1NjI2N1x1ODg0Q1x1RkYwQ1x1NEY0Nlx1NEY5RFx1OEQ1Nlx1OEJGQlx1OTZDNlx1NEVDRFx1NEVFNSBkZXBzIFx1NEUzQVx1NTFDNlx1RkYxQlxuICAgKiAtIGRldi1tb2RlIFx1NEUwQlx1ODJFNSBgZGVyaXZlKHN0YXRlKWAgXHU3Njg0XHU1QjlFXHU5NjQ1XHU4QkZCXHU1M0Q2XHU0RTBFIGRlcHMgXHU0RTBEXHU0RTAwXHU4MUY0XHVGRjBDXHU0RjFBXHU0RUE3XHU3NTFGIGBkZXBzX21pc21hdGNoYCBcdThCQ0FcdTY1QURcdTU0NEFcdThCNjZcdTMwMDJcbiAgICpcbiAgICogLSBcdTVCRjlcdTRFOEUgUm9vdCBcdTg5QzRcdTUyMTlcdUZGMUFkZXBzIFx1NEUzQSBTdGF0ZUZpZWxkUGF0aDxTdGF0ZT5cdUZGMUJcbiAgICogLSBcdTVCRjlcdTRFOEUgbGlzdC5pdGVtIHNjb3BlXHVGRjFBZGVwcyBcdTRFM0EgU3RhdGVGaWVsZFBhdGg8SXRlbT5cdUZGMDhcdTc2RjhcdTVCRjlcdThERUZcdTVGODRcdUZGMENidWlsZCBcdTk2MzZcdTZCQjVcdTRGMUFcdTUyNERcdTdGMDBcdTUzMTZcdUZGMDlcdTMwMDJcbiAgICovXG4gIHJlYWRvbmx5IGRlcHM6IFJlYWRvbmx5QXJyYXk8U3RhdGVGaWVsZFBhdGg8Uz4+XG4gIHJlYWRvbmx5IGRlcml2ZTogKHN0YXRlOiBSZWFkb25seTxTPikgPT4gU3RhdGVBdFBhdGg8UywgUD5cbiAgLyoqXG4gICAqIFx1NTNFRlx1OTAwOVx1RkYxQVx1N0I0OVx1NEVGN1x1NTIyNFx1NUI5QVx1RkYwOFx1NzUyOFx1NEU4RVx1OERGM1x1OEZDN1x1NjVFMFx1NTNEOFx1NTMxNlx1NTE5OVx1NTZERVx1RkYwOVx1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgZXF1YWxzPzogKHByZXY6IFN0YXRlQXRQYXRoPFMsIFA+LCBuZXh0OiBTdGF0ZUF0UGF0aDxTLCBQPikgPT4gYm9vbGVhblxuICAvKipcbiAgICogY29udmVyZ2UgXHU4QzAzXHU1RUE2XHU3QjU2XHU3NTY1XHVGRjA4MDQzXHVGRjA5XHVGRjFBXHU5RUQ4XHU4QkE0IGltbWVkaWF0ZVx1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgc2NoZWR1bGluZz86IFRyYWl0Q29udmVyZ2VTY2hlZHVsaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU291cmNlTWV0YTxTLCBQPiB7XG4gIHJlYWRvbmx5IGRlcHM6IFJlYWRvbmx5QXJyYXk8U3RhdGVGaWVsZFBhdGg8Uz4+XG4gIC8qKlxuICAgKiBcdTkwM0JcdThGOTFcdThENDRcdTZFOTBcdTY4MDdcdThCQzZcdUZGMDhcdTU5ODIgXCJ1c2VyL3Byb2ZpbGVcIlx1RkYwOVx1MzAwMlxuICAgKlxuICAgKiAtIFN0YXRlVHJhaXQuc291cmNlIERTTCBcdTRFMkRcdTc2ODQgYHJlc291cmNlYCBcdTVCNTdcdTZCQjVcdTU3MjggYnVpbGQgXHU5NjM2XHU2QkI1XHU0RjFBXHU4NDNEXHU1NzI4XHU2QjY0XHU1OTA0XHVGRjFCXG4gICAqIC0gZGF0YS1tb2RlbC5tZCBcdTRFMkRcdThCQjBcdTRFM0EgcmVzb3VyY2VJZFx1RkYwQ1x1OEZEOVx1OTFDQ1x1NkNCRlx1NzUyOCBEU0wgXHU1NDdEXHU1NDBEXHU5MDdGXHU1MTREXHU2REY3XHU2REM2XHUzMDAyXG4gICAqL1xuICByZWFkb25seSByZXNvdXJjZTogc3RyaW5nXG4gIC8qKlxuICAgKiBcdTRFQ0VcdTVCOENcdTY1NzQgU3RhdGUgXHU4QkExXHU3Qjk3XHU4QkJGXHU5NUVFXHU4QkU1XHU4RDQ0XHU2RTkwXHU2MjQwXHU5NzAwIGtleSBcdTc2ODRcdTg5QzRcdTUyMTlcdTMwMDJcbiAgICpcbiAgICogLSBcdTUxNDFcdThCQjhcdThGRDRcdTU2REUgdW5kZWZpbmVkXHVGRjFBXHU4ODY4XHU3OTNBXHU4QkU1XHU4RDQ0XHU2RTkwXHU1NzI4XHU1RjUzXHU1MjREIHN0YXRlIFx1NEUwQlx1NjcyQVx1NkZDMFx1NkQzQlx1RkYwOFx1NUU5NFx1NTZERVx1NjUzNlx1NEUzQSBpZGxlXHVGRjA5XHUzMDAyXG4gICAqL1xuICByZWFkb25seSBrZXk6IChzdGF0ZTogUmVhZG9ubHk8Uz4pID0+IHVua25vd25cbiAgcmVhZG9ubHkgdHJpZ2dlcnM/OiBSZWFkb25seUFycmF5PCdvbk1vdW50JyB8ICdvblZhbHVlQ2hhbmdlJyB8ICdtYW51YWwnPlxuICByZWFkb25seSBkZWJvdW5jZU1zPzogbnVtYmVyXG4gIHJlYWRvbmx5IGNvbmN1cnJlbmN5PzogJ3N3aXRjaCcgfCAnZXhoYXVzdC10cmFpbGluZydcbiAgLyoqXG4gICAqIFx1NzUyOFx1NEU4RSBEZXZ0b29scy9cdTY1ODdcdTY4NjNcdTc2ODRcdTUzRUZcdTVFOEZcdTUyMTdcdTUzMTZcdTUxNDNcdTRGRTFcdTYwNkZcdUZGMDhcdTc2N0RcdTU0MERcdTUzNTVcdTVCNTdcdTZCQjVcdUZGMDlcdTMwMDJcbiAgICovXG4gIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxuICAvKipcbiAgICogXHU5ODg0XHU3NTU5XHVGRjFBXHU1NzI4IGJ1aWxkIFx1OTYzNlx1NkJCNVx1NTNFRlx1NTg2Qlx1NTE0NVx1OEJFNSBUcmFpdCBcdTYyNDBcdTU3MjhcdTVCNTdcdTZCQjVcdThERUZcdTVGODRcdUZGMENcdTRGQkZcdTRFOEVcdThDMDNcdThCRDVcdTMwMDJcbiAgICovXG4gIHJlYWRvbmx5IF9maWVsZFBhdGg/OiBQXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlua01ldGE8Uz4ge1xuICAvKipcbiAgICogXHU2RTkwXHU1QjU3XHU2QkI1XHU4REVGXHU1Rjg0XHVGRjBDXHU1NDBDXHU2ODM3XHU1M0Q3IFN0YXRlRmllbGRQYXRoPFM+IFx1N0VBNlx1Njc1Rlx1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgZnJvbTogU3RhdGVGaWVsZFBhdGg8Uz5cbiAgLyoqXG4gICAqIGNvbnZlcmdlIFx1OEMwM1x1NUVBNlx1N0I1Nlx1NzU2NVx1RkYwODA0M1x1RkYwOVx1RkYxQVx1OUVEOFx1OEJBNCBpbW1lZGlhdGVcdTMwMDJcbiAgICovXG4gIHJlYWRvbmx5IHNjaGVkdWxpbmc/OiBUcmFpdENvbnZlcmdlU2NoZWR1bGluZ1xufVxuXG5leHBvcnQgdHlwZSBDaGVja1J1bGU8SW5wdXQgPSB1bmtub3duLCBDdHggPSB1bmtub3duPiA9IHtcbiAgcmVhZG9ubHkgZGVwczogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG4gIC8qKlxuICAgKiB2YWxpZGF0ZU9uXHVGRjFBXG4gICAqIC0gXHU0RUM1XHU1RjcxXHU1NENEXHU4MUVBXHU1MkE4XHU2ODIxXHU5QThDXHU5NjM2XHU2QkI1XHVGRjA4b25DaGFuZ2Uvb25CbHVyXHVGRjA5XHVGRjFCc3VibWl0L21hbnVhbCBcdTU5Q0JcdTdFQzhcdTYyNjdcdTg4NENcdUZGMUJcbiAgICogLSBcdTRFM0FcdTdBN0FcdTY1NzBcdTdFQzRcdTg4NjhcdTc5M0FcdTc5ODFcdTc1MjhcdTgxRUFcdTUyQThcdTY4MjFcdTlBOENcdUZGMDhcdTRFQzUgc3VibWl0L21hbnVhbCBcdTYyNjdcdTg4NENcdUZGMDlcdTMwMDJcbiAgICovXG4gIHJlYWRvbmx5IHZhbGlkYXRlT24/OiBSZWFkb25seUFycmF5PCdvbkNoYW5nZScgfCAnb25CbHVyJz5cbiAgcmVhZG9ubHkgdmFsaWRhdGU6IChpbnB1dDogSW5wdXQsIGN0eDogQ3R4KSA9PiB1bmtub3duXG4gIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENoZWNrTWV0YTxJbnB1dCA9IHVua25vd24sIEN0eCA9IHVua25vd24+IHtcbiAgLyoqXG4gICAqIFx1NTQ3RFx1NTQwRFx1ODlDNFx1NTIxOVx1OTZDNlx1NTQwOFx1RkYwOFx1OEJCMFx1NUY1NVx1NzUyOFx1NEU4RVx1Nzg2RVx1NUI5QVx1NjAyN1x1NTQwOFx1NUU3Nlx1NEUwRVx1OEJDQVx1NjVBRFx1NUM1NVx1NzkzQVx1RkYwOVx1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgcnVsZXM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIENoZWNrUnVsZTxJbnB1dCwgQ3R4Pj4+XG4gIC8qKlxuICAgKiBcdTk1MTlcdThCRUZcdTY4MTFcdTUxOTlcdTU2REVcdUZGMDhQaGFzZSAyXHVGRjFBXHU0RUM1XHU1NkZBXHU1MzE2XHU3RUQzXHU2Nzg0XHVGRjFCXHU1MTc3XHU0RjUzXHU1MTk5XHU1NkRFXHU4QkVEXHU0RTQ5XHU1NzI4XHU1NDBFXHU3RUVEIFBoYXNlIFx1NUI5RVx1NzNCMFx1RkYwOVx1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgd3JpdGViYWNrPzoge1xuICAgIHJlYWRvbmx5IGtpbmQ6ICdlcnJvcnMnXG4gICAgcmVhZG9ubHkgcGF0aD86IHN0cmluZ1xuICB9XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdEVudHJ5PFMsIFA+XHVGRjFBXG4gKiAtIFx1ODg2OFx1NzkzQVx1NjdEMFx1NEUyQVx1NUI1N1x1NkJCNVx1OERFRlx1NUY4NCBQIFx1NEUwQVx1NzY4NFx1NEUwMFx1OTg3OSBUcmFpdCBcdTkxNERcdTdGNkVcdUZGMUJcbiAqIC0ga2luZCBcdTRFMEUgbWV0YSBcdTYyMTBcdTVCRjlcdTUxRkFcdTczQjBcdUZGMENcdTc1MjhcdTRFOEVcdTU3MjggYnVpbGQvaW5zdGFsbCBcdTk2MzZcdTZCQjVcdTUyMDZcdTZEM0VcdTg4NENcdTRFM0FcdTMwMDJcbiAqL1xuZXhwb3J0IHR5cGUgU3RhdGVUcmFpdEVudHJ5PFMgPSB1bmtub3duLCBQIGV4dGVuZHMgc3RyaW5nID0gU3RhdGVGaWVsZFBhdGg8Uz4+ID1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdjb21wdXRlZCdcbiAgICAgIHJlYWRvbmx5IG1ldGE6IENvbXB1dGVkTWV0YTxTLCBQPlxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdzb3VyY2UnXG4gICAgICByZWFkb25seSBtZXRhOiBTb3VyY2VNZXRhPFMsIFA+XG4gICAgfVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IGZpZWxkUGF0aDogUFxuICAgICAgcmVhZG9ubHkga2luZDogJ2xpbmsnXG4gICAgICByZWFkb25seSBtZXRhOiBMaW5rTWV0YTxTPlxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdjaGVjaydcbiAgICAgIHJlYWRvbmx5IG1ldGE6IENoZWNrTWV0YTx1bmtub3duLCB1bmtub3duPlxuICAgIH1cblxuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0Tm9kZTxJbnB1dCA9IHVua25vd24sIEN0eCA9IHVua25vd24+IHtcbiAgcmVhZG9ubHkgX3RhZzogJ1N0YXRlVHJhaXROb2RlJ1xuICByZWFkb25seSBjb21wdXRlZD86IFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55PiB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55Pj4+XG4gIHJlYWRvbmx5IHNvdXJjZT86IFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55PiB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55Pj4+XG4gIHJlYWRvbmx5IGxpbms/OiBTdGF0ZVRyYWl0RW50cnk8SW5wdXQsIGFueT4gfCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYWl0RW50cnk8SW5wdXQsIGFueT4+PlxuICByZWFkb25seSBjaGVjaz86IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIENoZWNrUnVsZTxJbnB1dCwgQ3R4Pj4+XG4gIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRMaXN0PEl0ZW0gPSB1bmtub3duPiB7XG4gIHJlYWRvbmx5IF90YWc6ICdTdGF0ZVRyYWl0TGlzdCdcbiAgcmVhZG9ubHkgaXRlbT86IFN0YXRlVHJhaXROb2RlPEl0ZW0sIGFueT5cbiAgcmVhZG9ubHkgbGlzdD86IFN0YXRlVHJhaXROb2RlPFJlYWRvbmx5QXJyYXk8SXRlbT4sIGFueT5cbiAgcmVhZG9ubHkgaWRlbnRpdHlIaW50Pzoge1xuICAgIHJlYWRvbmx5IHRyYWNrQnk/OiBzdHJpbmdcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0U3BlY1ZhbHVlPFMsIFAgZXh0ZW5kcyBzdHJpbmc+ID1cbiAgfCBTdGF0ZVRyYWl0RW50cnk8UywgUD5cbiAgfCBTdGF0ZVRyYWl0Tm9kZTxhbnksIGFueT5cbiAgfCBTdGF0ZVRyYWl0TGlzdDxhbnk+XG5cbi8qKlxuICogU3RhdGVUcmFpdEZpZWxkXHVGRjFBXG4gKiAtIFx1ODg2OFx1NzkzQSBTdGF0ZSBcdTRFMkRcdTc2ODRcdTRFMDBcdTRFMkFcdTVCNTdcdTZCQjVcdTgyODJcdTcwQjlcdUZGMDhcdTRFMERcdThCQkFcdTY2MkZcdTU0MjZcdTYzMDIgVHJhaXRcdUZGMDlcdUZGMUJcbiAqIC0gXHU3NTMxIGJ1aWxkIFx1OTYzNlx1NkJCNVx1NEVDRSBTdGF0ZVRyYWl0U3BlYyBcdTVGNTJcdTRFMDBcdTUzMTZcdTgwMENcdTY3NjVcdTMwMDJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0RmllbGQge1xuICByZWFkb25seSBpZDogc3RyaW5nXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZ1xuICByZWFkb25seSBkaXNwbGF5TmFtZT86IHN0cmluZ1xuICByZWFkb25seSB2YWx1ZVR5cGU/OiBzdHJpbmdcbiAgcmVhZG9ubHkgdHJhaXRzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRGaWVsZFRyYWl0PlxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRGaWVsZFRyYWl0XHVGRjFBXG4gKiAtIFx1NjdEMFx1NEUyQVx1NUI1N1x1NkJCNVx1NEUwQVx1NzY4NFx1NEUwMFx1OTg3OSBUcmFpdFx1RkYwOGNvbXB1dGVkIC8gc291cmNlIC8gbGlua1x1RkYwOVx1NzY4NFx1N0VEM1x1Njc4NFx1NTMxNlx1NjNDRlx1OEZGMFx1RkYxQlxuICogLSBtZXRhIFx1NEUwRSBTdGF0ZVRyYWl0RW50cnkubWV0YSBcdTVCRjlcdTlGNTBcdUZGMENkZXBzIFx1ODg2OFx1NzkzQVx1OEJFNSBUcmFpdCBcdTYyNDBcdTRGOURcdThENTZcdTc2ODRcdTVCNTdcdTZCQjVcdThERUZcdTVGODRcdTk2QzZcdTU0MDhcdTMwMDJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0RmllbGRUcmFpdCB7XG4gIHJlYWRvbmx5IGZpZWxkSWQ6IHN0cmluZ1xuICByZWFkb25seSBraW5kOiBTdGF0ZVRyYWl0S2luZFxuICByZWFkb25seSBtZXRhOlxuICAgIHwgQ29tcHV0ZWRNZXRhPHVua25vd24sIHN0cmluZz5cbiAgICB8IFNvdXJjZU1ldGE8dW5rbm93biwgc3RyaW5nPlxuICAgIHwgTGlua01ldGE8dW5rbm93bj5cbiAgICB8IENoZWNrTWV0YTx1bmtub3duLCB1bmtub3duPlxuICByZWFkb25seSBkZXBzOiBSZWFkb25seUFycmF5PHN0cmluZz5cbn1cblxuLyoqXG4gKiBTdGF0ZVRyYWl0UmVzb3VyY2VcdUZGMUFcbiAqIC0gXHU2M0NGXHU4RkYwIHNvdXJjZSBcdTU3OEIgVHJhaXQgXHU2MjQwXHU0RjlEXHU4RDU2XHU3Njg0XHU5MDNCXHU4RjkxXHU4RDQ0XHU2RTkwXHU1MTQzXHU0RkUxXHU2MDZGXHVGRjFCXG4gKiAtIFJlc291cmNlU3BlYyBcdTc2ODRcdTUxNzdcdTRGNTNcdTVCOUVcdTczQjBcdTc1MzEgUmVzb3VyY2UgXHU1NDdEXHU1NDBEXHU3QTdBXHU5NUY0XHU4RDFGXHU4RDIzXHVGRjBDXHU4RkQ5XHU5MUNDXHU1M0VBXHU0RkREXHU3NTU5IFRyYWl0IFx1ODlDNlx1ODlEMlx1NzY4NFx1NEY5RFx1OEQ1Nlx1NEZFMVx1NjA2Rlx1MzAwMlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRSZXNvdXJjZSB7XG4gIHJlYWRvbmx5IHJlc291cmNlSWQ6IHN0cmluZ1xuICByZWFkb25seSBrZXlTZWxlY3Rvcjogc3RyaW5nXG4gIHJlYWRvbmx5IGtleUV4YW1wbGU/OiB1bmtub3duXG4gIHJlYWRvbmx5IG93bmVyRmllbGRzOiBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgcmVhZG9ubHkgbWV0YT86IE1ldGEuVHJhaXRNZXRhXG4gIHJlYWRvbmx5IG1ldGFPcmlnaW4/OiBzdHJpbmdcbiAgcmVhZG9ubHkgbWV0YUNvbmZsaWN0cz86IFJlYWRvbmx5QXJyYXk8TWV0YS5UcmFpdE1ldGFDb25mbGljdD5cbn1cblxuLyoqXG4gKiBHcmFwaCBOb2RlIC8gRWRnZVx1RkYxQVxuICogLSBcdTgyODJcdTcwQjlcdTkwMUFcdTVFMzhcdTVCRjlcdTVFOTRcdTRFMDBcdTRFMkFcdTVCNTdcdTZCQjVcdUZGMUJcbiAqIC0gXHU4RkI5XHU4ODY4XHU3OTNBXHU1QjU3XHU2QkI1XHU0RTRCXHU5NUY0XHU2MjE2XHU1QjU3XHU2QkI1XHU0RTBFXHU4RDQ0XHU2RTkwXHU0RTRCXHU5NUY0XHU3Njg0XHU0RjlEXHU4RDU2XHU1MTczXHU3Q0ZCXHUzMDAyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdEdyYXBoTm9kZSB7XG4gIHJlYWRvbmx5IGlkOiBzdHJpbmdcbiAgcmVhZG9ubHkgZmllbGQ6IFN0YXRlVHJhaXRGaWVsZFxuICByZWFkb25seSB0cmFpdHM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEZpZWxkVHJhaXQ+XG4gIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRHcmFwaEVkZ2Uge1xuICByZWFkb25seSBpZDogc3RyaW5nXG4gIHJlYWRvbmx5IGZyb206IHN0cmluZ1xuICByZWFkb25seSB0bzogc3RyaW5nXG4gIHJlYWRvbmx5IGtpbmQ6ICdjb21wdXRlZCcgfCAnbGluaycgfCAnc291cmNlLWRlcCcgfCAnY2hlY2stZGVwJ1xufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRHcmFwaFx1RkYxQVxuICogLSBTdGF0ZVRyYWl0IFx1NUYxNVx1NjRDRVx1NzY4NFx1N0VEM1x1Njc4NFx1ODlDNlx1NTZGRVx1RkYwQ1x1NEUwMFx1NUYyMFx1NTMwNVx1NTQyQlx1ODI4Mlx1NzBCOVx1NEUwRVx1NEY5RFx1OEQ1Nlx1OEZCOVx1NzY4NFx1NTZGRVx1RkYxQlxuICogLSBcdTRGOUIgRGV2dG9vbHMgLyBTdHVkaW8gXHU0RTBFIFJ1bnRpbWUgXHU1MDVBXHU3RUQzXHU2Nzg0XHU1MjA2XHU2NzkwXHU0RTBFXHU1M0VGXHU4OUM2XHU1MzE2XHU0RjdGXHU3NTI4XHUzMDAyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdEdyYXBoIHtcbiAgcmVhZG9ubHkgX3RhZzogJ1N0YXRlVHJhaXRHcmFwaCdcbiAgcmVhZG9ubHkgbm9kZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEdyYXBoTm9kZT5cbiAgcmVhZG9ubHkgZWRnZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEdyYXBoRWRnZT5cbiAgcmVhZG9ubHkgcmVzb3VyY2VzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRSZXNvdXJjZT5cbiAgcmVhZG9ubHkgbWV0YT86IHtcbiAgICByZWFkb25seSBtb2R1bGVJZD86IHN0cmluZ1xuICAgIHJlYWRvbmx5IHZlcnNpb24/OiBzdHJpbmdcbiAgfVxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRQbGFuU3RlcFx1RkYxQVxuICogLSBTdGF0ZVRyYWl0Lmluc3RhbGwgLyBSdW50aW1lIFx1NjI2N1x1ODg0Q1x1NjVGNlx1NzY4NFx1NjcwMFx1NUMwRlx1NjMwN1x1NEVFNFx1NTM1NVx1NTE0M1x1RkYxQlxuICogLSBcdTc1MzEgR3JhcGggXHU2M0E4XHU1QkZDXHU4MDBDXHU2NzY1XHVGRjBDXHU3NTI4XHU0RThFXHU1NzI4XHU4RkQwXHU4ODRDXHU2NUY2XHU1Qjg5XHU4OEM1IHdhdGNoZXIgXHU2MjE2XHU4OUU2XHU1M0QxXHU1OTE2XHU5MEU4XHU4QzAzXHU3NTI4XHUzMDAyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdFBsYW5TdGVwIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZ1xuICByZWFkb25seSBraW5kOiAnY29tcHV0ZWQtdXBkYXRlJyB8ICdsaW5rLXByb3BhZ2F0ZScgfCAnc291cmNlLXJlZnJlc2gnIHwgJ2NoZWNrLXZhbGlkYXRlJ1xuICByZWFkb25seSB0YXJnZXRGaWVsZFBhdGg/OiBzdHJpbmdcbiAgcmVhZG9ubHkgc291cmNlRmllbGRQYXRocz86IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICByZWFkb25seSByZXNvdXJjZUlkPzogc3RyaW5nXG4gIHJlYWRvbmx5IGtleVNlbGVjdG9ySWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgZGVidWdJbmZvPzoge1xuICAgIHJlYWRvbmx5IGdyYXBoTm9kZUlkPzogc3RyaW5nXG4gICAgcmVhZG9ubHkgZ3JhcGhFZGdlSWQ/OiBzdHJpbmdcbiAgfVxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRQbGFuXHVGRjFBXG4gKiAtIFx1NkM0N1x1NjAzQlx1NjdEMFx1NkEyMVx1NTc1N1x1NjI0MFx1NjcwOSBUcmFpdCBcdTg4NENcdTRFM0FcdTc2ODRcdTYyNjdcdTg4NENcdThCQTFcdTUyMTJcdUZGMUJcbiAqIC0gaW5zdGFsbCBcdTk2MzZcdTZCQjVcdTYzMDkgUGxhbiBcdTVDMDZcdTg4NENcdTRFM0FcdTYzMDJcdThGN0RcdTUyMzAgQm91bmQgQVBJIC8gRWZmZWN0T3AgXHU3QkExXHU5MDUzXHU0RTBBXHUzMDAyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdFBsYW4ge1xuICByZWFkb25seSBfdGFnOiAnU3RhdGVUcmFpdFBsYW4nXG4gIHJlYWRvbmx5IG1vZHVsZUlkPzogc3RyaW5nXG4gIHJlYWRvbmx5IHN0ZXBzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRQbGFuU3RlcD5cbiAgcmVhZG9ubHkgbWV0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG59XG5cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRTY2hlbWFQYXRoS2luZCA9ICdmaWVsZFBhdGgnIHwgJ2RlcCcgfCAnbGlua19mcm9tJyB8ICdjaGVja193cml0ZWJhY2snXG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdFNjaGVtYVBhdGhSZWYge1xuICByZWFkb25seSBraW5kOiBTdGF0ZVRyYWl0U2NoZW1hUGF0aEtpbmRcbiAgcmVhZG9ubHkgZW50cnlLaW5kOiBTdGF0ZVRyYWl0S2luZFxuICByZWFkb25seSBlbnRyeUZpZWxkUGF0aDogc3RyaW5nXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZ1xuICByZWFkb25seSBydWxlTmFtZT86IHN0cmluZ1xufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRQcm9ncmFtPFM+XHVGRjFBXG4gKiAtIFN0YXRlVHJhaXQgXHU1RjE1XHU2NENFXHU3Njg0IFByb2dyYW0gXHU4RjkzXHU1MUZBXHVGRjBDXHU2NjJGIFJ1bnRpbWUgLyBEZXZ0b29scyBcdTc2ODRcdTdFREZcdTRFMDBcdTUxNjVcdTUzRTNcdUZGMUJcbiAqIC0gc3RhdGVTY2hlbWEgXHU0RTBFIHNwZWMgXHU0RkREXHU3NTU5XHU1MzlGXHU1OUNCXHU4RjkzXHU1MTY1XHVGRjBDZ3JhcGgvcGxhbiBcdTRFM0FcdTUxODVcdTkwRTggSVJcdTMwMDJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0UHJvZ3JhbTxTPiB7XG4gIHJlYWRvbmx5IHN0YXRlU2NoZW1hOiBTY2hlbWEuU2NoZW1hPFMsIGFueT5cbiAgcmVhZG9ubHkgc3BlYzogU3RhdGVUcmFpdFNwZWM8Uz5cbiAgLyoqXG4gICAqIFByb2dyYW0uZW50cmllc1x1RkYxQVxuICAgKiAtIGJ1aWxkIFx1OTYzNlx1NkJCNVx1NEVDRSBzcGVjXHVGRjA4XHU1NDJCIG5vZGUvbGlzdC8kcm9vdFx1RkYwOVx1NUY1Mlx1NEUwMFx1NTMxNlx1NUY5N1x1NTIzMFx1NzY4NFx1NjcwMFx1NUMwRlx1ODlDNFx1NTIxOVx1OTZDNlx1NTQwOFx1RkYxQlxuICAgKiAtIFBoYXNlIDIgXHU1MTQ4XHU0RkREXHU4QkMxXHUyMDFDXHU1M0VGXHU4QkZCXHU1M0VGXHU4QkNBXHU2NUFEXHU3Njg0XHU3RUQzXHU2Nzg0XHUyMDFEXHVGRjBDXHU1NDBFXHU3RUVEIFBoYXNlIFx1NjI0RFx1NjNBNVx1NTE2NVx1NjI2N1x1ODg0Q1x1NEUwRVx1NjUzNlx1NjU1Qlx1OEJFRFx1NEU0OVx1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgZW50cmllczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PlxuICByZWFkb25seSBncmFwaDogU3RhdGVUcmFpdEdyYXBoXG4gIHJlYWRvbmx5IHBsYW46IFN0YXRlVHJhaXRQbGFuXG4gIHJlYWRvbmx5IGNvbnZlcmdlSXI/OiBDb252ZXJnZVN0YXRpY0lyUmVnaXN0cnlcbiAgcmVhZG9ubHkgY29udmVyZ2VFeGVjSXI/OiBDb252ZXJnZUV4ZWNJclxuICAvKipcbiAgICogc2NoZW1hUGF0aHNcdUZGMUFcbiAgICogLSBidWlsZCBcdTk2MzZcdTZCQjVcdTRFQ0UgZW50cmllcyBcdTZDNDdcdTYwM0JcdTUxRkFcdTc2ODRcdTIwMUNcdTk3MDBcdTg5ODFcdTVCNThcdTU3MjhcdTRFOEUgc3RhdGVTY2hlbWEgXHU3Njg0XHU4REVGXHU1Rjg0XHU1RjE1XHU3NTI4XHUyMDFEXHVGRjFCXHU0RUM1XHU3NTI4XHU0RThFIGRldiBcdThCQ0FcdTY1QURcdUZGMDhcdTRGOEJcdTU5ODIgc2NoZW1hX21pc21hdGNoXHVGRjA5XHUzMDAyXG4gICAqIC0gZGlhZ25vc3RpY3M9b2ZmIFx1NjVGNlx1NTNFRlx1NUI4Q1x1NTE2OFx1OERGM1x1OEZDN1x1NjgyMVx1OUE4Q1x1NEVFNVx1NEZERFx1NjMwMVx1OEZEMVx1OTZGNlx1NjIxMFx1NjcyQ1x1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgc2NoZW1hUGF0aHM/OiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRTY2hlbWFQYXRoUmVmPlxufVxuXG4vKipcbiAqIFx1NEVDRSBTdGF0ZVRyYWl0U3BlYyBcdTY3ODRcdTVFRkFcdTVGNTJcdTRFMDBcdTUzMTZcdTc2ODQgZW50cnkgXHU1MjE3XHU4ODY4XHUzMDAyXG4gKlxuICogLSBQaGFzZSAyXHVGRjFBXHU2NTJGXHU2MzAxIG5vZGUvbGlzdC8kcm9vdCBcdTc2ODRcdTdFRDNcdTY3ODRcdTVDNTVcdTVGMDBcdUZGMENcdTVFNzZcdTU3MjhcdTVGQzVcdTg5ODFcdTY1RjZcdTg4NjVcdTUxNjgvXHU1MjREXHU3RjAwXHU1MzE2IGZpZWxkUGF0aCBcdTRFMEUgZGVwc1x1RkYxQlxuICogLSBcdTU0MEVcdTdFRUQgUGhhc2UgXHU1M0VGXHU1NzI4XHU2QjY0XHU1OTA0XHU2MjY5XHU1QzU1XHU2ODIxXHU5QThDXHU5MDNCXHU4RjkxXHVGRjA4XHU0RjhCXHU1OTgyXHU2OEMwXHU2RDRCXHU5MUNEXHU1OTBEXHU1QjlBXHU0RTQ5XHUzMDAxXHU4OTg2XHU3NkQ2XHU2NzNBXHU1MjM2XHU3QjQ5XHVGRjA5XHUzMDAyXG4gKi9cbmV4cG9ydCBjb25zdCBub3JtYWxpemVTcGVjID0gPFM+KHNwZWM6IFN0YXRlVHJhaXRTcGVjPFM+KTogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PiA9PiB7XG4gIGNvbnN0IGVudHJpZXM6IEFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+ID0gW11cblxuICBjb25zdCBpc05vZGUgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTdGF0ZVRyYWl0Tm9kZTxhbnksIGFueT4gPT5cbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICh2YWx1ZSBhcyBhbnkpLl90YWcgPT09ICdTdGF0ZVRyYWl0Tm9kZSdcblxuICBjb25zdCBpc0xpc3QgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTdGF0ZVRyYWl0TGlzdDxhbnk+ID0+XG4gICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAodmFsdWUgYXMgYW55KS5fdGFnID09PSAnU3RhdGVUcmFpdExpc3QnXG5cbiAgY29uc3Qgam9pblBhdGggPSAocHJlZml4OiBzdHJpbmcsIHN1ZmZpeDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICBpZiAoIXByZWZpeCkgcmV0dXJuIHN1ZmZpeFxuICAgIGlmICghc3VmZml4KSByZXR1cm4gcHJlZml4XG4gICAgcmV0dXJuIGAke3ByZWZpeH0uJHtzdWZmaXh9YFxuICB9XG5cbiAgY29uc3QgcHJlZml4RGVwcyA9IChkZXBzOiBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWQsIHByZWZpeDogc3RyaW5nKTogUmVhZG9ubHlBcnJheTxzdHJpbmc+ID0+IHtcbiAgICBpZiAoIWRlcHMgfHwgZGVwcy5sZW5ndGggPT09IDApIHJldHVybiBbXVxuICAgIHJldHVybiBkZXBzLm1hcCgoZCkgPT4gKHByZWZpeCA/IGpvaW5QYXRoKHByZWZpeCwgZCkgOiBkKSlcbiAgfVxuXG4gIGNvbnN0IG5vcm1hbGl6ZUVudHJ5ID0gKFxuICAgIGVudHJ5OiBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+LFxuICAgIGZpZWxkUGF0aDogc3RyaW5nLFxuICAgIGRlcFByZWZpeDogc3RyaW5nLFxuICApOiBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+ID0+IHtcbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ2NvbXB1dGVkJykge1xuICAgICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgICBjb25zdCByYXdEZXBzID0gbWV0YS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgY29uc3QgZGVwcyA9IHJhd0RlcHMgIT09IHVuZGVmaW5lZCA/IHByZWZpeERlcHMocmF3RGVwcywgZGVwUHJlZml4KSA6IHVuZGVmaW5lZFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGVudHJ5IGFzIGFueSksXG4gICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgbWV0YTogeyAuLi5tZXRhLCBkZXBzIH0sXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbnRyeS5raW5kID09PSAnc291cmNlJykge1xuICAgICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgICBjb25zdCByYXdEZXBzID0gbWV0YS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgY29uc3QgZGVwcyA9IHJhd0RlcHMgIT09IHVuZGVmaW5lZCA/IHByZWZpeERlcHMocmF3RGVwcywgZGVwUHJlZml4KSA6IHVuZGVmaW5lZFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGVudHJ5IGFzIGFueSksXG4gICAgICAgIGZpZWxkUGF0aCxcbiAgICAgICAgbWV0YTogeyAuLi5tZXRhLCBkZXBzLCBfZmllbGRQYXRoOiBmaWVsZFBhdGggfSxcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVudHJ5LmtpbmQgPT09ICdsaW5rJykge1xuICAgICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgICBjb25zdCBmcm9tID0gcHJlZml4RGVwcyhbbWV0YS5mcm9tIGFzIHN0cmluZ10sIGRlcFByZWZpeClbMF0gPz8gbWV0YS5mcm9tXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi4oZW50cnkgYXMgYW55KSxcbiAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICBtZXRhOiB7IC4uLm1ldGEsIGZyb20gfSxcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY2hlY2tcdUZGMUFQaGFzZSAyIFx1NEVDNVx1OEMwM1x1NjU3NCBmaWVsZFBhdGhcdUZGMENkZXBzIFx1NEVDRFx1NzUzMSBtZXRhLnJ1bGVzIFx1NTcyOCBidWlsZCBcdTk2MzZcdTZCQjVcdTZDNDdcdTYwM0JcdTMwMDJcbiAgICByZXR1cm4ge1xuICAgICAgLi4uKGVudHJ5IGFzIGFueSksXG4gICAgICBmaWVsZFBhdGgsXG4gICAgfVxuICB9XG5cbiAgY29uc3QgZXhwYW5kTm9kZSA9IChcbiAgICBzY29wZUlkOiBzdHJpbmcsXG4gICAgam9pblByZWZpeDogc3RyaW5nLFxuICAgIG5vZGU6IFN0YXRlVHJhaXROb2RlPGFueSwgYW55PixcbiAgICBvcHRpb25zPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBjaGVjayBkZXBzIFx1NTI0RFx1N0YwMFx1RkYxQVx1NzUyOFx1NEU4RSBsaXN0LXNjb3BlIGNoZWNrIFx1NzY4NFx1OUVEOFx1OEJBNFx1OEJFRFx1NEU0OVx1RkYwOGRlcHMgXHU3NkY4XHU1QkY5XHUyMDFDXHU4ODRDXHU1MTQzXHU3RDIwXHUyMDFEXHU4MDBDXHU5NzVFIGxpc3QgXHU2ODM5XHVGRjA5XHUzMDAyXG4gICAgICAgKlxuICAgICAgICogLSBpdGVtIHNjb3BlXHVGRjFBZGVwc1ByZWZpeCA9IGAke2xpc3RQYXRofVtdYFx1RkYwOFx1NEUwRSBqb2luUHJlZml4IFx1NEUwMFx1ODFGNFx1RkYwOVx1RkYxQlxuICAgICAgICogLSBsaXN0IHNjb3BlXHVGRjFBZmllbGRQYXRoID0gYCR7bGlzdFBhdGh9YFx1RkYwQ1x1NEY0NiBkZXBzUHJlZml4IFx1NUU5NFx1NEUzQSBgJHtsaXN0UGF0aH1bXWBcdTMwMDJcbiAgICAgICAqL1xuICAgICAgcmVhZG9ubHkgY2hlY2tEZXBzUHJlZml4Pzogc3RyaW5nXG4gICAgfSxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgYWRkRW50cnkgPSAocmVsYXRpdmVUYXJnZXQ6IHN0cmluZywgcmF3OiBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+KTogdm9pZCA9PiB7XG4gICAgICBjb25zdCByZWwgPSAocmF3IGFzIGFueSkuZmllbGRQYXRoID8/IHJlbGF0aXZlVGFyZ2V0XG4gICAgICBjb25zdCBmaWVsZFBhdGggPSBqb2luUHJlZml4ID8gam9pblBhdGgoam9pblByZWZpeCwgU3RyaW5nKHJlbCkpIDogU3RyaW5nKHJlbClcbiAgICAgIGVudHJpZXMucHVzaChub3JtYWxpemVFbnRyeShyYXcsIGZpZWxkUGF0aCwgam9pblByZWZpeCkpXG4gICAgfVxuXG4gICAgY29uc3QgZXhwYW5kTWF5YmVSZWNvcmQgPSAoXG4gICAgICB2YWx1ZTogU3RhdGVUcmFpdEVudHJ5PGFueSwgYW55PiB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxhbnksIGFueT4+PiB8IHVuZGVmaW5lZCxcbiAgICApOiB2b2lkID0+IHtcbiAgICAgIGlmICghdmFsdWUpIHJldHVyblxuICAgICAgaWYgKHR5cGVvZiAodmFsdWUgYXMgYW55KS5raW5kID09PSAnc3RyaW5nJykge1xuICAgICAgICBhZGRFbnRyeSgnJywgdmFsdWUgYXMgYW55KVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY29yZCA9IHZhbHVlIGFzIFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxhbnksIGFueT4+PlxuICAgICAgZm9yIChjb25zdCBrZXkgaW4gcmVjb3JkKSB7XG4gICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY29yZCwga2V5KSkgY29udGludWVcbiAgICAgICAgY29uc3QgZW50cnkgPSByZWNvcmRba2V5XVxuICAgICAgICBpZiAoIWVudHJ5KSBjb250aW51ZVxuICAgICAgICBhZGRFbnRyeShrZXksIGVudHJ5IGFzIGFueSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBleHBhbmRNYXliZVJlY29yZChub2RlLmNvbXB1dGVkKVxuICAgIGV4cGFuZE1heWJlUmVjb3JkKG5vZGUuc291cmNlKVxuICAgIGV4cGFuZE1heWJlUmVjb3JkKG5vZGUubGluaylcblxuICAgIGlmIChub2RlLmNoZWNrKSB7XG4gICAgICBjb25zdCBydWxlczogUmVjb3JkPHN0cmluZywgQ2hlY2tSdWxlPGFueSwgYW55Pj4gPSB7fVxuICAgICAgY29uc3QgY2hlY2tEZXBzUHJlZml4ID0gb3B0aW9ucz8uY2hlY2tEZXBzUHJlZml4ID8/IChqb2luUHJlZml4LmVuZHNXaXRoKCdbXScpID8gam9pblByZWZpeCA6ICcnKVxuXG4gICAgICBjb25zdCBwcmVmaXhDaGVja0RlcHMgPSAoZGVwczogUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkKTogUmVhZG9ubHlBcnJheTxzdHJpbmc+ID0+IHtcbiAgICAgICAgaWYgKCFkZXBzIHx8IGRlcHMubGVuZ3RoID09PSAwKSByZXR1cm4gW11cbiAgICAgICAgcmV0dXJuIGRlcHMubWFwKChkKSA9PiAoZCA9PT0gJycgPyBzY29wZUlkIDogY2hlY2tEZXBzUHJlZml4ID8gam9pblBhdGgoY2hlY2tEZXBzUHJlZml4LCBkKSA6IGQpKVxuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKG5vZGUuY2hlY2spKSB7XG4gICAgICAgIGNvbnN0IHJ1bGUgPSAobm9kZS5jaGVjayBhcyBhbnkpW25hbWVdIGFzIENoZWNrUnVsZTxhbnksIGFueT5cbiAgICAgICAgaWYgKHR5cGVvZiBydWxlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcnVsZXNbbmFtZV0gPSBydWxlXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBpZiAocnVsZSAmJiB0eXBlb2YgcnVsZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBjb25zdCBtZXRhID0gTWV0YS5zYW5pdGl6ZSgocnVsZSBhcyBhbnkpLm1ldGEpXG4gICAgICAgICAgcnVsZXNbbmFtZV0gPSB7XG4gICAgICAgICAgICAuLi5ydWxlLFxuICAgICAgICAgICAgZGVwczogcHJlZml4Q2hlY2tEZXBzKHJ1bGUuZGVwcyksXG4gICAgICAgICAgICBtZXRhLFxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICAgIC8vIFx1OTc1RVx1NkNENVx1OEY5M1x1NTE2NVx1RkYxQVx1NUZGRFx1NzU2NVx1RkYwOFx1NTQwRVx1N0VFRCBQaGFzZSBcdTVDMDZcdTU3MjggYnVpbGQgXHU5NjM2XHU2QkI1XHU2M0QwXHU1MzQ3XHU0RTNBXHU5MTREXHU3RjZFXHU5NTE5XHU4QkVGXHVGRjA5XHUzMDAyXG4gICAgICB9XG5cbiAgICAgIGVudHJpZXMucHVzaCh7XG4gICAgICAgIGZpZWxkUGF0aDogc2NvcGVJZCxcbiAgICAgICAga2luZDogJ2NoZWNrJyxcbiAgICAgICAgbWV0YToge1xuICAgICAgICAgIHJ1bGVzLFxuICAgICAgICAgIHdyaXRlYmFjazogeyBraW5kOiAnZXJyb3JzJyB9LFxuICAgICAgICB9LFxuICAgICAgfSBhcyBTdGF0ZVRyYWl0RW50cnk8YW55LCBhbnk+KVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3Qga2V5IGluIHNwZWMpIHtcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzcGVjLCBrZXkpKSBjb250aW51ZVxuICAgIGNvbnN0IHJhdyA9IHNwZWNba2V5IGFzIGtleW9mIHR5cGVvZiBzcGVjXSBhcyBTdGF0ZVRyYWl0U3BlY1ZhbHVlPFMsIGFueT4gfCB1bmRlZmluZWRcbiAgICBpZiAoIXJhdykgY29udGludWVcblxuICAgIGlmIChpc0xpc3QocmF3KSkge1xuICAgICAgY29uc3QgbGlzdFBhdGggPSBrZXlcbiAgICAgIGlmIChyYXcuaXRlbSkge1xuICAgICAgICBleHBhbmROb2RlKGAke2xpc3RQYXRofVtdYCwgYCR7bGlzdFBhdGh9W11gLCByYXcuaXRlbSlcbiAgICAgIH1cbiAgICAgIGlmIChyYXcubGlzdCkge1xuICAgICAgICBleHBhbmROb2RlKGxpc3RQYXRoLCBsaXN0UGF0aCwgcmF3Lmxpc3QsIHtcbiAgICAgICAgICBjaGVja0RlcHNQcmVmaXg6IGAke2xpc3RQYXRofVtdYCxcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgaWYgKGlzTm9kZShyYXcpKSB7XG4gICAgICBpZiAoa2V5ID09PSAnJHJvb3QnKSB7XG4gICAgICAgIGV4cGFuZE5vZGUoJyRyb290JywgJycsIHJhdylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4cGFuZE5vZGUoa2V5LCBrZXksIHJhdylcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgY29uc3QgZW50cnkgPSByYXcgYXMgYW55IGFzIFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz5cbiAgICBjb25zdCBmaWVsZFBhdGggPSAoZW50cnkgYXMgYW55KS5maWVsZFBhdGggPz8ga2V5XG4gICAgZW50cmllcy5wdXNoKG5vcm1hbGl6ZUVudHJ5KGVudHJ5LCBTdHJpbmcoZmllbGRQYXRoKSwgJycpKVxuICB9XG5cbiAgcmV0dXJuIGVudHJpZXNcbn1cblxuLyoqXG4gKiBjb2xsZWN0Tm9kZU1ldGFcdUZGMUFcbiAqIC0gXHU0RUNFIFN0YXRlVHJhaXRTcGVjIFx1NEUyRFx1NjNEMFx1NTNENiBTdGF0ZVRyYWl0Tm9kZS5tZXRhXHVGRjA4XHU3NjdEXHU1NDBEXHU1MzU1XHU1QjU3XHU2QkI1XHVGRjA5XHVGRjBDXHU0RjlCIERldnRvb2xzIFx1OEZEQlx1ODg0Q1x1N0VEM1x1Njc4NFx1NUM1NVx1NzkzQVx1RkYxQlxuICogLSBtZXRhIFx1NEVDNVx1NzUyOFx1NEU4RVx1OEJDQVx1NjVBRFx1NEUwRVx1NUM1NVx1NzkzQVx1RkYwQ1x1NEUwRFx1NTNDMlx1NEUwRVx1OEZEMFx1ODg0Q1x1NjVGNlx1OEJFRFx1NEU0OVx1MzAwMlxuICovXG5leHBvcnQgY29uc3QgY29sbGVjdE5vZGVNZXRhID0gPFM+KHNwZWM6IFN0YXRlVHJhaXRTcGVjPFM+KTogUmVhZG9ubHlNYXA8c3RyaW5nLCBNZXRhLlRyYWl0TWV0YT4gPT4ge1xuICBjb25zdCBvdXQgPSBuZXcgTWFwPHN0cmluZywgTWV0YS5UcmFpdE1ldGE+KClcblxuICBjb25zdCBpc05vZGUgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTdGF0ZVRyYWl0Tm9kZTxhbnksIGFueT4gPT5cbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICh2YWx1ZSBhcyBhbnkpLl90YWcgPT09ICdTdGF0ZVRyYWl0Tm9kZSdcblxuICBjb25zdCBpc0xpc3QgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBTdGF0ZVRyYWl0TGlzdDxhbnk+ID0+XG4gICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAodmFsdWUgYXMgYW55KS5fdGFnID09PSAnU3RhdGVUcmFpdExpc3QnXG5cbiAgY29uc3QgYWRkID0gKHNjb3BlSWQ6IHN0cmluZywgbm9kZTogU3RhdGVUcmFpdE5vZGU8YW55LCBhbnk+KTogdm9pZCA9PiB7XG4gICAgY29uc3QgbWV0YSA9IE1ldGEuc2FuaXRpemUobm9kZS5tZXRhKVxuICAgIGlmIChtZXRhKSBvdXQuc2V0KHNjb3BlSWQsIG1ldGEpXG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjKSB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3BlYywga2V5KSkgY29udGludWVcbiAgICBjb25zdCByYXcgPSBzcGVjW2tleSBhcyBrZXlvZiB0eXBlb2Ygc3BlY10gYXMgU3RhdGVUcmFpdFNwZWNWYWx1ZTxTLCBhbnk+IHwgdW5kZWZpbmVkXG4gICAgaWYgKCFyYXcpIGNvbnRpbnVlXG5cbiAgICBpZiAoaXNMaXN0KHJhdykpIHtcbiAgICAgIGNvbnN0IGxpc3RQYXRoID0ga2V5XG4gICAgICBpZiAocmF3Lml0ZW0pIGFkZChgJHtsaXN0UGF0aH1bXWAsIHJhdy5pdGVtKVxuICAgICAgaWYgKHJhdy5saXN0KSBhZGQobGlzdFBhdGgsIHJhdy5saXN0KVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoaXNOb2RlKHJhdykpIHtcbiAgICAgIGlmIChrZXkgPT09ICckcm9vdCcpIGFkZCgnJHJvb3QnLCByYXcpXG4gICAgICBlbHNlIGFkZChrZXksIHJhdylcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG91dFxufVxuXG4vLyAtLS0tIENvbnZlcmdlICgwMTMpIGV2aWRlbmNlIG1vZGVsIC0tLS1cblxuZXhwb3J0IHR5cGUgVHJhaXRDb252ZXJnZVJlcXVlc3RlZE1vZGUgPSAnYXV0bycgfCAnZnVsbCcgfCAnZGlydHknXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlRXhlY3V0ZWRNb2RlID0gJ2Z1bGwnIHwgJ2RpcnR5J1xuZXhwb3J0IHR5cGUgVHJhaXRDb252ZXJnZU91dGNvbWUgPSAnQ29udmVyZ2VkJyB8ICdOb29wJyB8ICdEZWdyYWRlZCdcblxuZXhwb3J0IHR5cGUgVHJhaXRDb252ZXJnZUNvbmZpZ1Njb3BlID0gJ3Byb3ZpZGVyJyB8ICdydW50aW1lX21vZHVsZScgfCAncnVudGltZV9kZWZhdWx0JyB8ICdidWlsdGluJ1xuXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlUmVhc29uID1cbiAgfCAnY29sZF9zdGFydCdcbiAgfCAnY2FjaGVfaGl0J1xuICB8ICdjYWNoZV9taXNzJ1xuICB8ICdidWRnZXRfY3V0b2ZmJ1xuICB8ICduZWFyX2Z1bGwnXG4gIHwgJ3Vua25vd25fd3JpdGUnXG4gIHwgJ2RpcnR5X2FsbCdcbiAgfCAnZ2VuZXJhdGlvbl9idW1wZWQnXG4gIHwgJ2xvd19oaXRfcmF0ZV9wcm90ZWN0aW9uJ1xuICB8ICdtb2R1bGVfb3ZlcnJpZGUnXG4gIHwgJ3RpbWVfc2xpY2luZ19pbW1lZGlhdGUnXG4gIHwgJ3RpbWVfc2xpY2luZ19kZWZlcnJlZCdcblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlU3RlcFN0YXRzIHtcbiAgcmVhZG9ubHkgdG90YWxTdGVwczogbnVtYmVyXG4gIHJlYWRvbmx5IGV4ZWN1dGVkU3RlcHM6IG51bWJlclxuICByZWFkb25seSBza2lwcGVkU3RlcHM6IG51bWJlclxuICByZWFkb25seSBjaGFuZ2VkU3RlcHM6IG51bWJlclxuICByZWFkb25seSBhZmZlY3RlZFN0ZXBzPzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZURpcnR5U3VtbWFyeSB7XG4gIHJlYWRvbmx5IGRpcnR5QWxsOiBib29sZWFuXG4gIHJlYWRvbmx5IHJlYXNvbj86IERpcnR5QWxsUmVhc29uXG4gIHJlYWRvbmx5IHJvb3RDb3VudD86IG51bWJlclxuICByZWFkb25seSByb290SWRzPzogUmVhZG9ubHlBcnJheTxudW1iZXI+XG4gIHJlYWRvbmx5IHJvb3RJZHNUcnVuY2F0ZWQ/OiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZVBsYW5DYWNoZUV2aWRlbmNlIHtcbiAgcmVhZG9ubHkgY2FwYWNpdHk6IG51bWJlclxuICByZWFkb25seSBzaXplOiBudW1iZXJcbiAgcmVhZG9ubHkgaGl0czogbnVtYmVyXG4gIHJlYWRvbmx5IG1pc3NlczogbnVtYmVyXG4gIHJlYWRvbmx5IGV2aWN0czogbnVtYmVyXG4gIHJlYWRvbmx5IGhpdDogYm9vbGVhblxuICByZWFkb25seSBrZXlTaXplPzogbnVtYmVyXG4gIHJlYWRvbmx5IG1pc3NSZWFzb24/OiAnY29sZF9zdGFydCcgfCAnZ2VuZXJhdGlvbl9idW1wZWQnIHwgJ25vdF9jYWNoZWQnIHwgJ3Vua25vd24nXG4gIHJlYWRvbmx5IGRpc2FibGVkPzogYm9vbGVhblxuICByZWFkb25seSBkaXNhYmxlUmVhc29uPzogJ2xvd19oaXRfcmF0ZScgfCAnZ2VuZXJhdGlvbl90aHJhc2gnIHwgJ21hbnVhbF9vdmVycmlkZScgfCAndW5rbm93bidcbn1cblxuZXhwb3J0IHR5cGUgVHJhaXRDb252ZXJnZUdlbmVyYXRpb25CdW1wUmVhc29uID1cbiAgfCAnd3JpdGVyc19jaGFuZ2VkJ1xuICB8ICdkZXBzX2NoYW5nZWQnXG4gIHwgJ2xvZ2ljX2luc3RhbGxlZCdcbiAgfCAnbG9naWNfdW5pbnN0YWxsZWQnXG4gIHwgJ2ltcG9ydHNfY2hhbmdlZCdcbiAgfCAndW5rbm93bidcblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlR2VuZXJhdGlvbkV2aWRlbmNlIHtcbiAgcmVhZG9ubHkgZ2VuZXJhdGlvbjogbnVtYmVyXG4gIHJlYWRvbmx5IGdlbmVyYXRpb25CdW1wQ291bnQ/OiBudW1iZXJcbiAgcmVhZG9ubHkgbGFzdEJ1bXBSZWFzb24/OiBUcmFpdENvbnZlcmdlR2VuZXJhdGlvbkJ1bXBSZWFzb25cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlU3RhdGljSXJFdmlkZW5jZSB7XG4gIHJlYWRvbmx5IGZpZWxkUGF0aENvdW50OiBudW1iZXJcbiAgcmVhZG9ubHkgc3RlcENvdW50OiBudW1iZXJcbiAgcmVhZG9ubHkgYnVpbGREdXJhdGlvbk1zPzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZUhvdHNwb3Qge1xuICByZWFkb25seSBraW5kPzogc3RyaW5nXG4gIHJlYWRvbmx5IHN0ZXBJZDogbnVtYmVyXG4gIHJlYWRvbmx5IG91dEZpZWxkUGF0aElkPzogbnVtYmVyXG4gIHJlYWRvbmx5IGR1cmF0aW9uTXM6IG51bWJlclxuICByZWFkb25seSBjaGFuZ2VkOiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZVRpbWVTbGljaW5nU3VtbWFyeSB7XG4gIHJlYWRvbmx5IHNjb3BlOiAnYWxsJyB8ICdpbW1lZGlhdGUnIHwgJ2RlZmVycmVkJ1xuICByZWFkb25seSBpbW1lZGlhdGVTdGVwQ291bnQ6IG51bWJlclxuICByZWFkb25seSBkZWZlcnJlZFN0ZXBDb3VudDogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZURpYWdub3N0aWNzU2FtcGxpbmdTdW1tYXJ5IHtcbiAgLyoqXG4gICAqIFx1Nzg2RVx1NUI5QVx1NjAyN1x1OTFDN1x1NjgzN1x1N0I1Nlx1NzU2NVx1RkYxQVx1NEVFNVx1N0EzM1x1NUI5QSB0eG5TZXEgXHU0RTNBXHU5NTFBXHU3MEI5XHVGRjBDXHU2QkNGXHU5Njk0IE4gXHU0RTJBIHR4biBcdTkxQzdcdTY4MzdcdTRFMDBcdTZCMjFcdTMwMDJcbiAgICogLSBzYW1wbGVkPXRydWUgXHU4ODY4XHU3OTNBXHU2NzJDXHU2QjIxIGludm9jYXRpb24gXHU5MUM3XHU5NkM2XHU0RTg2IHBlci1zdGVwIFx1OEJBMVx1NjVGNlx1NUU3Nlx1NzUxRlx1NjIxMCBob3RzcG90c1x1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgc3RyYXRlZ3k6ICd0eG5TZXFfaW50ZXJ2YWwnXG4gIHJlYWRvbmx5IHNhbXBsZUV2ZXJ5TjogbnVtYmVyXG4gIHJlYWRvbmx5IHRvcEs6IG51bWJlclxuICByZWFkb25seSBzYW1wbGVkOiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZURlY2lzaW9uU3VtbWFyeSB7XG4gIHJlYWRvbmx5IHJlcXVlc3RlZE1vZGU6IFRyYWl0Q29udmVyZ2VSZXF1ZXN0ZWRNb2RlXG4gIHJlYWRvbmx5IGV4ZWN1dGVkTW9kZTogVHJhaXRDb252ZXJnZUV4ZWN1dGVkTW9kZVxuICByZWFkb25seSBvdXRjb21lOiBUcmFpdENvbnZlcmdlT3V0Y29tZVxuICByZWFkb25seSBjb25maWdTY29wZTogVHJhaXRDb252ZXJnZUNvbmZpZ1Njb3BlXG4gIHJlYWRvbmx5IHN0YXRpY0lyRGlnZXN0OiBzdHJpbmdcbiAgcmVhZG9ubHkgZXhlY3V0aW9uQnVkZ2V0TXM6IG51bWJlclxuICByZWFkb25seSBleGVjdXRpb25EdXJhdGlvbk1zOiBudW1iZXJcbiAgcmVhZG9ubHkgZGVjaXNpb25CdWRnZXRNcz86IG51bWJlclxuICByZWFkb25seSBkZWNpc2lvbkR1cmF0aW9uTXM/OiBudW1iZXJcbiAgcmVhZG9ubHkgcmVhc29uczogUmVhZG9ubHlBcnJheTxUcmFpdENvbnZlcmdlUmVhc29uPlxuICByZWFkb25seSBzdGVwU3RhdHM6IFRyYWl0Q29udmVyZ2VTdGVwU3RhdHNcbiAgcmVhZG9ubHkgZGlydHk/OiBUcmFpdENvbnZlcmdlRGlydHlTdW1tYXJ5XG4gIHJlYWRvbmx5IGNhY2hlPzogVHJhaXRDb252ZXJnZVBsYW5DYWNoZUV2aWRlbmNlXG4gIHJlYWRvbmx5IGdlbmVyYXRpb24/OiBUcmFpdENvbnZlcmdlR2VuZXJhdGlvbkV2aWRlbmNlXG4gIHJlYWRvbmx5IHN0YXRpY0lyPzogVHJhaXRDb252ZXJnZVN0YXRpY0lyRXZpZGVuY2VcbiAgcmVhZG9ubHkgdGltZVNsaWNpbmc/OiBUcmFpdENvbnZlcmdlVGltZVNsaWNpbmdTdW1tYXJ5XG4gIHJlYWRvbmx5IHRocmVzaG9sZHM/OiB7IHJlYWRvbmx5IGZsb29yUmF0aW8/OiBudW1iZXIgfVxuICByZWFkb25seSBkaWFnbm9zdGljc1NhbXBsaW5nPzogVHJhaXRDb252ZXJnZURpYWdub3N0aWNzU2FtcGxpbmdTdW1tYXJ5XG4gIHJlYWRvbmx5IHRvcDM/OiBSZWFkb25seUFycmF5PFRyYWl0Q29udmVyZ2VIb3RzcG90PlxufVxuIiwgImltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSAnZWZmZWN0J1xuaW1wb3J0IHtcbiAgdHlwZSBTdGF0ZVRyYWl0UHJvZ3JhbSxcbiAgdHlwZSBTdGF0ZVRyYWl0U3BlYyxcbiAgdHlwZSBTdGF0ZVRyYWl0RW50cnksXG4gIHR5cGUgU3RhdGVUcmFpdEdyYXBoLFxuICB0eXBlIFN0YXRlVHJhaXRHcmFwaEVkZ2UsXG4gIHR5cGUgU3RhdGVUcmFpdEdyYXBoTm9kZSxcbiAgdHlwZSBTdGF0ZVRyYWl0RmllbGQsXG4gIHR5cGUgU3RhdGVUcmFpdEZpZWxkVHJhaXQsXG4gIHR5cGUgU3RhdGVUcmFpdFBsYW4sXG4gIHR5cGUgU3RhdGVUcmFpdFBsYW5TdGVwLFxuICB0eXBlIFN0YXRlVHJhaXRSZXNvdXJjZSxcbiAgdHlwZSBTdGF0ZVRyYWl0U2NoZW1hUGF0aFJlZixcbiAgY29sbGVjdE5vZGVNZXRhLFxuICBub3JtYWxpemVTcGVjLFxufSBmcm9tICcuL21vZGVsLmpzJ1xuaW1wb3J0ICogYXMgTWV0YSBmcm9tICcuL21ldGEuanMnXG5pbXBvcnQge1xuICBjb21wYXJlRmllbGRQYXRoLFxuICBnZXRGaWVsZFBhdGhJZCxcbiAgbWFrZUZpZWxkUGF0aElkUmVnaXN0cnksXG4gIG5vcm1hbGl6ZUZpZWxkUGF0aCxcbiAgdHlwZSBGaWVsZFBhdGgsXG4gIHR5cGUgRmllbGRQYXRoSWQsXG59IGZyb20gJy4uL2ZpZWxkLXBhdGguanMnXG5pbXBvcnQgdHlwZSB7IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeSB9IGZyb20gJy4vY29udmVyZ2UtaXIuanMnXG5cbmNvbnN0IG5vd1BlcmYgPSAoKTogbnVtYmVyID0+XG4gIHR5cGVvZiBnbG9iYWxUaGlzLnBlcmZvcm1hbmNlICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgZ2xvYmFsVGhpcy5wZXJmb3JtYW5jZS5ub3cgPT09ICdmdW5jdGlvbidcbiAgICA/IGdsb2JhbFRoaXMucGVyZm9ybWFuY2Uubm93KClcbiAgICA6IERhdGUubm93KClcblxudHlwZSBDb252ZXJnZVdyaXRlciA9IEV4dHJhY3Q8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPiwgeyByZWFkb25seSBraW5kOiAnY29tcHV0ZWQnIHwgJ2xpbmsnIH0+XG5cbmNvbnN0IGdldENvbnZlcmdlV3JpdGVyRGVwcyA9IChlbnRyeTogQ29udmVyZ2VXcml0ZXIpOiBSZWFkb25seUFycmF5PHN0cmluZz4gPT4ge1xuICBpZiAoZW50cnkua2luZCA9PT0gJ2NvbXB1dGVkJykge1xuICAgIHJldHVybiAoKGVudHJ5Lm1ldGEgYXMgYW55KT8uZGVwcyA/PyBbXSkgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+XG4gIH1cbiAgcmV0dXJuIFtlbnRyeS5tZXRhLmZyb20gYXMgc3RyaW5nXVxufVxuXG5jb25zdCBjb21wdXRlQ29udmVyZ2VUb3BvT3JkZXIgPSAoXG4gIHdyaXRlcnM6IFJlYWRvbmx5QXJyYXk8Q29udmVyZ2VXcml0ZXI+LFxuKTogeyByZWFkb25seSBvcmRlcjogUmVhZG9ubHlBcnJheTxzdHJpbmc+OyByZWFkb25seSBjb25maWdFcnJvcj86IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeVsnY29uZmlnRXJyb3InXSB9ID0+IHtcbiAgY29uc3Qgd3JpdGVyQnlQYXRoID0gbmV3IE1hcDxzdHJpbmcsIENvbnZlcmdlV3JpdGVyPigpXG4gIGZvciAoY29uc3QgZW50cnkgb2Ygd3JpdGVycykge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gd3JpdGVyQnlQYXRoLmdldChlbnRyeS5maWVsZFBhdGgpXG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvcmRlcjogW10sXG4gICAgICAgIGNvbmZpZ0Vycm9yOiB7XG4gICAgICAgICAgY29kZTogJ01VTFRJUExFX1dSSVRFUlMnLFxuICAgICAgICAgIG1lc3NhZ2U6IGBbU3RhdGVUcmFpdC5jb252ZXJnZV0gTXVsdGlwbGUgd3JpdGVycyBmb3IgZmllbGQgXCIke2VudHJ5LmZpZWxkUGF0aH1cIiAoJHtleGlzdGluZy5raW5kfSArICR7ZW50cnkua2luZH0pLmAsXG4gICAgICAgICAgZmllbGRzOiBbZW50cnkuZmllbGRQYXRoXSxcbiAgICAgICAgfSxcbiAgICAgIH1cbiAgICB9XG4gICAgd3JpdGVyQnlQYXRoLnNldChlbnRyeS5maWVsZFBhdGgsIGVudHJ5KVxuICB9XG5cbiAgY29uc3Qgbm9kZXMgPSBuZXcgU2V0PHN0cmluZz4oKVxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHdyaXRlcnMpIHtcbiAgICBub2Rlcy5hZGQoZW50cnkuZmllbGRQYXRoKVxuICB9XG5cbiAgY29uc3QgaW5kZWdyZWUgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpXG4gIGNvbnN0IGZvcndhcmQgPSBuZXcgTWFwPHN0cmluZywgQXJyYXk8c3RyaW5nPj4oKVxuXG4gIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xuICAgIGluZGVncmVlLnNldChub2RlLCAwKVxuICAgIGZvcndhcmQuc2V0KG5vZGUsIFtdKVxuICB9XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiB3cml0ZXJzKSB7XG4gICAgY29uc3QgdG8gPSBlbnRyeS5maWVsZFBhdGhcbiAgICBjb25zdCBkZXBzID0gZ2V0Q29udmVyZ2VXcml0ZXJEZXBzKGVudHJ5KVxuICAgIGZvciAoY29uc3QgZGVwIG9mIGRlcHMpIHtcbiAgICAgIGlmICghbm9kZXMuaGFzKGRlcCkpIGNvbnRpbnVlXG4gICAgICBmb3J3YXJkLmdldChkZXApIS5wdXNoKHRvKVxuICAgICAgaW5kZWdyZWUuc2V0KHRvLCAoaW5kZWdyZWUuZ2V0KHRvKSA/PyAwKSArIDEpXG4gICAgfVxuICB9XG5cbiAgY29uc3QgcXVldWU6IEFycmF5PHN0cmluZz4gPSBbXVxuICBmb3IgKGNvbnN0IFtub2RlLCBkZWddIG9mIGluZGVncmVlLmVudHJpZXMoKSkge1xuICAgIGlmIChkZWcgPT09IDApIHF1ZXVlLnB1c2gobm9kZSlcbiAgfVxuXG4gIGNvbnN0IG9yZGVyOiBBcnJheTxzdHJpbmc+ID0gW11cbiAgd2hpbGUgKHF1ZXVlLmxlbmd0aCkge1xuICAgIGNvbnN0IG4gPSBxdWV1ZS5zaGlmdCgpIVxuICAgIG9yZGVyLnB1c2gobilcbiAgICBjb25zdCBvdXRzID0gZm9yd2FyZC5nZXQobikhXG4gICAgZm9yIChjb25zdCB0byBvZiBvdXRzKSB7XG4gICAgICBjb25zdCBuZXh0ID0gKGluZGVncmVlLmdldCh0bykgPz8gMCkgLSAxXG4gICAgICBpbmRlZ3JlZS5zZXQodG8sIG5leHQpXG4gICAgICBpZiAobmV4dCA9PT0gMCkgcXVldWUucHVzaCh0bylcbiAgICB9XG4gIH1cblxuICBpZiAob3JkZXIubGVuZ3RoICE9PSBub2Rlcy5zaXplKSB7XG4gICAgY29uc3QgcmVtYWluaW5nID0gQXJyYXkuZnJvbShub2RlcykuZmlsdGVyKChuKSA9PiAhb3JkZXIuaW5jbHVkZXMobikpXG4gICAgcmV0dXJuIHtcbiAgICAgIG9yZGVyOiBbXSxcbiAgICAgIGNvbmZpZ0Vycm9yOiB7XG4gICAgICAgIGNvZGU6ICdDWUNMRV9ERVRFQ1RFRCcsXG4gICAgICAgIG1lc3NhZ2U6IGBbU3RhdGVUcmFpdC5jb252ZXJnZV0gQ3ljbGUgZGV0ZWN0ZWQgaW4gY29tcHV0ZWQvbGluayBncmFwaDogJHtyZW1haW5pbmcuam9pbignLCAnKX1gLFxuICAgICAgICBmaWVsZHM6IHJlbWFpbmluZyxcbiAgICAgIH0sXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgb3JkZXIgfVxufVxuXG5jb25zdCBidWlsZENvbnZlcmdlSXIgPSAoZW50cmllczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+Pik6IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeSA9PiB7XG4gIGNvbnN0IHN0YXJ0ZWRBdCA9IG5vd1BlcmYoKVxuICBjb25zdCBnZW5lcmF0aW9uID0gMFxuXG4gIGNvbnN0IHdyaXRlcnMgPSBlbnRyaWVzLmZpbHRlcigoZSk6IGUgaXMgQ29udmVyZ2VXcml0ZXIgPT4gZS5raW5kID09PSAnY29tcHV0ZWQnIHx8IGUua2luZCA9PT0gJ2xpbmsnKVxuXG4gIGNvbnN0IHdyaXRlcnNLZXkgPSB3cml0ZXJzXG4gICAgLm1hcCgoZW50cnkpID0+IGAke2VudHJ5LmtpbmR9OiR7ZW50cnkuZmllbGRQYXRofWApXG4gICAgLnNvcnQoKVxuICAgIC5qb2luKCd8JylcblxuICBjb25zdCBkZXBzS2V5ID0gd3JpdGVyc1xuICAgIC5tYXAoKGVudHJ5KSA9PiB7XG4gICAgICBjb25zdCBkZXBzID0gZ2V0Q29udmVyZ2VXcml0ZXJEZXBzKGVudHJ5KS5zbGljZSgpLnNvcnQoKS5qb2luKCcsJylcbiAgICAgIGNvbnN0IHNjaGVkdWxpbmcgPSAoZW50cnkubWV0YSBhcyBhbnkpPy5zY2hlZHVsaW5nID09PSAnZGVmZXJyZWQnID8gJ2QnIDogJ2knXG4gICAgICByZXR1cm4gYCR7ZW50cnkua2luZH06JHtlbnRyeS5maWVsZFBhdGh9QCR7c2NoZWR1bGluZ309PiR7ZGVwc31gXG4gICAgfSlcbiAgICAuc29ydCgpXG4gICAgLmpvaW4oJ3wnKVxuXG4gIGNvbnN0IHdyaXRlckJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBDb252ZXJnZVdyaXRlcj4oKVxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHdyaXRlcnMpIHtcbiAgICB3cml0ZXJCeVBhdGguc2V0KGVudHJ5LmZpZWxkUGF0aCwgZW50cnkpXG4gIH1cblxuICBjb25zdCB0b3BvID0gd3JpdGVycy5sZW5ndGggPiAwID8gY29tcHV0ZUNvbnZlcmdlVG9wb09yZGVyKHdyaXRlcnMpIDogeyBvcmRlcjogW10gYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IH1cbiAgY29uc3Qgc3RlcHNCeUlkOiBBcnJheTxDb252ZXJnZVdyaXRlcj4gPSB0b3BvLmNvbmZpZ0Vycm9yID8gW10gOiB0b3BvLm9yZGVyLm1hcCgocGF0aCkgPT4gd3JpdGVyQnlQYXRoLmdldChwYXRoKSEpXG5cbiAgY29uc3QgZmllbGRQYXRoVGFibGUgPSBuZXcgTWFwPHN0cmluZywgRmllbGRQYXRoPigpXG4gIGNvbnN0IGFkZFBhdGggPSAocGF0aDogRmllbGRQYXRoKTogdm9pZCA9PiB7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcHJlZml4ID0gcGF0aC5zbGljZSgwLCBpKVxuICAgICAgY29uc3Qga2V5ID0gSlNPTi5zdHJpbmdpZnkocHJlZml4KVxuICAgICAgaWYgKCFmaWVsZFBhdGhUYWJsZS5oYXMoa2V5KSkgZmllbGRQYXRoVGFibGUuc2V0KGtleSwgcHJlZml4KVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2Ygd3JpdGVycykge1xuICAgIGNvbnN0IG91dCA9IG5vcm1hbGl6ZUZpZWxkUGF0aChlbnRyeS5maWVsZFBhdGgpXG4gICAgaWYgKG91dCkgYWRkUGF0aChvdXQpXG4gICAgZm9yIChjb25zdCBkZXAgb2YgZ2V0Q29udmVyZ2VXcml0ZXJEZXBzKGVudHJ5KSkge1xuICAgICAgY29uc3QgZGVwUGF0aCA9IG5vcm1hbGl6ZUZpZWxkUGF0aChkZXApXG4gICAgICBpZiAoZGVwUGF0aCkgYWRkUGF0aChkZXBQYXRoKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGZpZWxkUGF0aHMgPSBBcnJheS5mcm9tKGZpZWxkUGF0aFRhYmxlLnZhbHVlcygpKS5zb3J0KGNvbXBhcmVGaWVsZFBhdGgpXG4gIGNvbnN0IGZpZWxkUGF0aElkUmVnaXN0cnkgPSBtYWtlRmllbGRQYXRoSWRSZWdpc3RyeShmaWVsZFBhdGhzKVxuXG4gIGNvbnN0IHN0ZXBPdXRGaWVsZFBhdGhJZEJ5U3RlcElkOiBBcnJheTxGaWVsZFBhdGhJZD4gPSBbXVxuICBjb25zdCBzdGVwRGVwc0ZpZWxkUGF0aElkc0J5U3RlcElkOiBBcnJheTxSZWFkb25seUFycmF5PEZpZWxkUGF0aElkPj4gPSBbXVxuICBjb25zdCBzdGVwU2NoZWR1bGluZ0J5U3RlcElkOiBBcnJheTwnaW1tZWRpYXRlJyB8ICdkZWZlcnJlZCc+ID0gW11cblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHN0ZXBzQnlJZCkge1xuICAgIGNvbnN0IG91dCA9IG5vcm1hbGl6ZUZpZWxkUGF0aChlbnRyeS5maWVsZFBhdGgpXG4gICAgY29uc3Qgb3V0SWQgPSBvdXQgIT0gbnVsbCA/IGdldEZpZWxkUGF0aElkKGZpZWxkUGF0aElkUmVnaXN0cnksIG91dCkgOiB1bmRlZmluZWRcbiAgICBpZiAob3V0SWQgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBbU3RhdGVUcmFpdC5idWlsZF0gRmFpbGVkIHRvIG1hcCBjb252ZXJnZSBvdXRwdXQgZmllbGRQYXRoIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIgdG8gRmllbGRQYXRoSWQuYClcbiAgICB9XG5cbiAgICBjb25zdCBkZXBJZHM6IEFycmF5PEZpZWxkUGF0aElkPiA9IFtdXG4gICAgZm9yIChjb25zdCBkZXAgb2YgZ2V0Q29udmVyZ2VXcml0ZXJEZXBzKGVudHJ5KSkge1xuICAgICAgY29uc3QgZGVwUGF0aCA9IG5vcm1hbGl6ZUZpZWxkUGF0aChkZXApXG4gICAgICBpZiAoIWRlcFBhdGgpIGNvbnRpbnVlXG4gICAgICBjb25zdCBkZXBJZCA9IGdldEZpZWxkUGF0aElkKGZpZWxkUGF0aElkUmVnaXN0cnksIGRlcFBhdGgpXG4gICAgICBpZiAoZGVwSWQgIT0gbnVsbCkgZGVwSWRzLnB1c2goZGVwSWQpXG4gICAgfVxuXG4gICAgc3RlcE91dEZpZWxkUGF0aElkQnlTdGVwSWQucHVzaChvdXRJZClcbiAgICBzdGVwRGVwc0ZpZWxkUGF0aElkc0J5U3RlcElkLnB1c2goZGVwSWRzKVxuICAgIHN0ZXBTY2hlZHVsaW5nQnlTdGVwSWQucHVzaCgoZW50cnkubWV0YSBhcyBhbnkpPy5zY2hlZHVsaW5nID09PSAnZGVmZXJyZWQnID8gJ2RlZmVycmVkJyA6ICdpbW1lZGlhdGUnKVxuICB9XG5cbiAgY29uc3QgdG9wb09yZGVyID0gc3RlcHNCeUlkLm1hcCgoXywgaSkgPT4gaSlcbiAgY29uc3QgYnVpbGREdXJhdGlvbk1zID0gTWF0aC5tYXgoMCwgbm93UGVyZigpIC0gc3RhcnRlZEF0KVxuXG4gIHJldHVybiB7XG4gICAgZ2VuZXJhdGlvbixcbiAgICB3cml0ZXJzS2V5LFxuICAgIGRlcHNLZXksXG4gICAgZmllbGRQYXRocyxcbiAgICBmaWVsZFBhdGhJZFJlZ2lzdHJ5LFxuICAgIC4uLih0b3BvLmNvbmZpZ0Vycm9yID8geyBjb25maWdFcnJvcjogdG9wby5jb25maWdFcnJvciB9IDogbnVsbCksXG4gICAgc3RlcHNCeUlkLFxuICAgIHN0ZXBPdXRGaWVsZFBhdGhJZEJ5U3RlcElkLFxuICAgIHN0ZXBEZXBzRmllbGRQYXRoSWRzQnlTdGVwSWQsXG4gICAgc3RlcFNjaGVkdWxpbmdCeVN0ZXBJZCxcbiAgICB0b3BvT3JkZXIsXG4gICAgYnVpbGREdXJhdGlvbk1zLFxuICB9XG59XG5cbi8qKlxuICogXHU2ODM5XHU2MzZFIFN0YXRlVHJhaXRFbnRyeSBcdTY3ODRcdTkwMjBcdTY4MDdcdTUxQzZcdTUzMTZcdTc2ODQgRmllbGRUcmFpdFx1MzAwMlxuICpcbiAqIC0gXHU3NkVFXHU1MjREXHU0RUM1XHU1QkY5IGxpbmsvc291cmNlIFx1NTg2Qlx1NTE0NSBkZXBzIFx1NEZFMVx1NjA2Rlx1RkYwQ2NvbXB1dGVkIFx1NzY4NFx1NEY5RFx1OEQ1Nlx1NjY4Mlx1NEUwRFx1OTc1OVx1NjAwMVx1NTIwNlx1Njc5MFx1RkYxQlxuICogLSBcdTU0MEVcdTdFRURcdTgyRTVcdTVGMTVcdTUxNjVcdTY2M0VcdTVGMEZcdTRGOURcdThENTZcdTU4RjBcdTY2MEVcdUZGMENcdTUzRUZcdTRFRTVcdTU3MjhcdTZCNjRcdTU5MDRcdTYyNjlcdTVDNTVcdTMwMDJcbiAqL1xuY29uc3QgdG9GaWVsZFRyYWl0ID0gKGVudHJ5OiBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+KTogU3RhdGVUcmFpdEZpZWxkVHJhaXQgPT4ge1xuICBjb25zdCBkZXBzOiBBcnJheTxzdHJpbmc+ID0gW11cblxuICBpZiAoZW50cnkua2luZCA9PT0gJ2NvbXB1dGVkJykge1xuICAgIGNvbnN0IG1ldGEgPSBlbnRyeS5tZXRhIGFzIGFueVxuICAgIGNvbnN0IGxpc3QgPSBtZXRhLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgaWYgKGxpc3QpIGRlcHMucHVzaCguLi5saXN0KVxuICB9IGVsc2UgaWYgKGVudHJ5LmtpbmQgPT09ICdzb3VyY2UnKSB7XG4gICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgY29uc3QgbGlzdCA9IG1ldGEuZGVwcyBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICBpZiAobGlzdCkgZGVwcy5wdXNoKC4uLmxpc3QpXG4gIH0gZWxzZSBpZiAoZW50cnkua2luZCA9PT0gJ2xpbmsnKSB7XG4gICAgZGVwcy5wdXNoKGVudHJ5Lm1ldGEuZnJvbSBhcyBzdHJpbmcpXG4gIH0gZWxzZSBpZiAoZW50cnkua2luZCA9PT0gJ2NoZWNrJykge1xuICAgIGNvbnN0IG1ldGEgPSBlbnRyeS5tZXRhIGFzIGFueVxuICAgIGNvbnN0IHJ1bGVzID0gKG1ldGE/LnJ1bGVzID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHJ1bGVzKSkge1xuICAgICAgY29uc3QgcnVsZSA9IHJ1bGVzW25hbWVdXG4gICAgICBpZiAocnVsZSAmJiB0eXBlb2YgcnVsZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgY29uc3QgbGlzdCA9IHJ1bGUuZGVwcyBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICAgICAgaWYgKGxpc3QpIGRlcHMucHVzaCguLi5saXN0KVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZmllbGRJZDogZW50cnkuZmllbGRQYXRoLFxuICAgIGtpbmQ6IGVudHJ5LmtpbmQsXG4gICAgLy8gbWV0YSBcdTU3MjhcdThGRDBcdTg4NENcdTY1RjZcdTRGRERcdTYzMDFcdTRFMEUgRW50cnkubWV0YSBcdTRFMDBcdTgxRjRcdUZGMENcdTRGQkZcdTRFOEUgaW5zdGFsbCBcdTc2RjRcdTYzQTVcdTU5MERcdTc1MjhcdTMwMDJcbiAgICBtZXRhOiBlbnRyeS5tZXRhIGFzIGFueSxcbiAgICBkZXBzLFxuICB9XG59XG5cbi8qKlxuICogXHU0RUNFXHU1RjUyXHU0RTAwXHU1MzE2XHU3Njg0IEVudHJ5IFx1NTIxN1x1ODg2OFx1Njc4NFx1NUVGQSBGaWVsZCAvIE5vZGUgLyBFZGdlIC8gUmVzb3VyY2UgXHU5NkM2XHU1NDA4XHUzMDAyXG4gKi9cbmNvbnN0IGJ1aWxkR3JhcGggPSAoXG4gIGVudHJpZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj4sXG4gIG5vZGVNZXRhQnlGaWVsZFBhdGg6IFJlYWRvbmx5TWFwPHN0cmluZywgTWV0YS5UcmFpdE1ldGE+LFxuKToge1xuICByZWFkb25seSBncmFwaDogU3RhdGVUcmFpdEdyYXBoXG4gIHJlYWRvbmx5IHBsYW46IFN0YXRlVHJhaXRQbGFuXG59ID0+IHtcbiAgY29uc3QgZmllbGRNYXAgPSBuZXcgTWFwPHN0cmluZywgU3RhdGVUcmFpdEZpZWxkPigpXG4gIGNvbnN0IG5vZGVzOiBBcnJheTxTdGF0ZVRyYWl0R3JhcGhOb2RlPiA9IFtdXG4gIGNvbnN0IGVkZ2VzOiBBcnJheTxTdGF0ZVRyYWl0R3JhcGhFZGdlPiA9IFtdXG4gIGNvbnN0IHJlc291cmNlc0J5SWQgPSBuZXcgTWFwPHN0cmluZywgU3RhdGVUcmFpdFJlc291cmNlPigpXG4gIGNvbnN0IHBsYW5TdGVwczogQXJyYXk8U3RhdGVUcmFpdFBsYW5TdGVwPiA9IFtdXG5cbiAgY29uc3QgZW5zdXJlRmllbGQgPSAoZmllbGRQYXRoOiBzdHJpbmcpOiBTdGF0ZVRyYWl0RmllbGQgPT4ge1xuICAgIGxldCBmaWVsZCA9IGZpZWxkTWFwLmdldChmaWVsZFBhdGgpXG4gICAgaWYgKCFmaWVsZCkge1xuICAgICAgZmllbGQgPSB7XG4gICAgICAgIGlkOiBmaWVsZFBhdGgsXG4gICAgICAgIHBhdGg6IGZpZWxkUGF0aCxcbiAgICAgICAgdHJhaXRzOiBbXSxcbiAgICAgIH1cbiAgICAgIGZpZWxkTWFwLnNldChmaWVsZFBhdGgsIGZpZWxkKVxuICAgIH1cbiAgICByZXR1cm4gZmllbGRcbiAgfVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGNvbnN0IGZpZWxkUGF0aCA9IGVudHJ5LmZpZWxkUGF0aFxuICAgIGNvbnN0IGZpZWxkID0gZW5zdXJlRmllbGQoZmllbGRQYXRoKVxuICAgIGNvbnN0IHRyYWl0ID0gdG9GaWVsZFRyYWl0KGVudHJ5KVxuXG4gICAgOyhmaWVsZC50cmFpdHMgYXMgQXJyYXk8U3RhdGVUcmFpdEZpZWxkVHJhaXQ+KS5wdXNoKHRyYWl0KVxuXG4gICAgLy8gXHU5NDg4XHU1QkY5XHU0RTBEXHU1NDBDIGtpbmQgXHU2Nzg0XHU1RUZBIEdyYXBoIFx1OEZCOVx1NEUwRSBQbGFuIFx1NkI2NVx1OUFBNFx1MzAwMlxuICAgIGlmIChlbnRyeS5raW5kID09PSAnY29tcHV0ZWQnKSB7XG4gICAgICBjb25zdCBzdGVwSWQgPSBgY29tcHV0ZWQ6JHtmaWVsZFBhdGh9YFxuICAgICAgcGxhblN0ZXBzLnB1c2goe1xuICAgICAgICBpZDogc3RlcElkLFxuICAgICAgICBraW5kOiAnY29tcHV0ZWQtdXBkYXRlJyxcbiAgICAgICAgdGFyZ2V0RmllbGRQYXRoOiBmaWVsZFBhdGgsXG4gICAgICAgIC8vIFx1OEJGNFx1NjYwRVx1RkYxQVx1NUY1M1x1NTI0RFx1NzI0OFx1NjcyQ1x1NEUwRFx1OTc1OVx1NjAwMVx1NTIwNlx1Njc5MCBjb21wdXRlZCBcdTRGOURcdThENTZcdTVCNTdcdTZCQjVcdUZGMENzb3VyY2VGaWVsZFBhdGhzIFx1NzU1OVx1N0E3QVx1MzAwMlxuICAgICAgfSlcbiAgICAgIC8vIFx1ODJFNVx1NjYzRVx1NUYwRlx1NThGMFx1NjYwRSBkZXBzXHVGRjBDXHU1MjE5XHU4ODY1XHU1MTQ1IEdyYXBoIFx1OEZCOVx1RkYwOFx1NzUyOFx1NEU4RVx1OEJDQVx1NjVBRC9cdTUzQ0RcdTU0MTFcdTk1RURcdTUzMDVcdThCQTFcdTdCOTdcdUZGMDlcdTMwMDJcbiAgICAgIGNvbnN0IGRlcHMgPSAoZW50cnkubWV0YSBhcyBhbnkpLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgICBpZiAoZGVwcykge1xuICAgICAgICBmb3IgKGNvbnN0IGRlcCBvZiBkZXBzKSB7XG4gICAgICAgICAgZW5zdXJlRmllbGQoZGVwKVxuICAgICAgICAgIGVkZ2VzLnB1c2goe1xuICAgICAgICAgICAgaWQ6IGBjb21wdXRlZDoke2RlcH0tPiR7ZmllbGRQYXRofWAsXG4gICAgICAgICAgICBmcm9tOiBkZXAsXG4gICAgICAgICAgICB0bzogZmllbGRQYXRoLFxuICAgICAgICAgICAga2luZDogJ2NvbXB1dGVkJyxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSAnbGluaycpIHtcbiAgICAgIGNvbnN0IGZyb20gPSBlbnRyeS5tZXRhLmZyb20gYXMgc3RyaW5nXG4gICAgICBlbnN1cmVGaWVsZChmcm9tKVxuXG4gICAgICBjb25zdCBlZGdlSWQgPSBgbGluazoke2Zyb219LT4ke2ZpZWxkUGF0aH1gXG4gICAgICBlZGdlcy5wdXNoKHtcbiAgICAgICAgaWQ6IGVkZ2VJZCxcbiAgICAgICAgZnJvbSxcbiAgICAgICAgdG86IGZpZWxkUGF0aCxcbiAgICAgICAga2luZDogJ2xpbmsnLFxuICAgICAgfSlcblxuICAgICAgcGxhblN0ZXBzLnB1c2goe1xuICAgICAgICBpZDogYGxpbms6JHtmaWVsZFBhdGh9YCxcbiAgICAgICAga2luZDogJ2xpbmstcHJvcGFnYXRlJyxcbiAgICAgICAgdGFyZ2V0RmllbGRQYXRoOiBmaWVsZFBhdGgsXG4gICAgICAgIHNvdXJjZUZpZWxkUGF0aHM6IFtmcm9tXSxcbiAgICAgICAgZGVidWdJbmZvOiB7XG4gICAgICAgICAgZ3JhcGhFZGdlSWQ6IGVkZ2VJZCxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSAnc291cmNlJykge1xuICAgICAgY29uc3QgcmVzb3VyY2VJZCA9IGVudHJ5Lm1ldGEucmVzb3VyY2VcbiAgICAgIGNvbnN0IHJlc291cmNlTWV0YSA9IE1ldGEuc2FuaXRpemUoKGVudHJ5Lm1ldGEgYXMgYW55KS5tZXRhKVxuXG4gICAgICBjb25zdCBleGlzdGluZyA9IHJlc291cmNlc0J5SWQuZ2V0KHJlc291cmNlSWQpXG4gICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgY29uc3Qgb3duZXJGaWVsZHMgPSBbLi4uZXhpc3Rpbmcub3duZXJGaWVsZHMsIGZpZWxkUGF0aF1cbiAgICAgICAgbGV0IG1ldGEgPSBleGlzdGluZy5tZXRhXG4gICAgICAgIGxldCBtZXRhT3JpZ2luID0gZXhpc3RpbmcubWV0YU9yaWdpblxuICAgICAgICBsZXQgbWV0YUNvbmZsaWN0cyA9IGV4aXN0aW5nLm1ldGFDb25mbGljdHNcblxuICAgICAgICBpZiAocmVzb3VyY2VNZXRhKSB7XG4gICAgICAgICAgY29uc3QgbWVyZ2VkID0gTWV0YS5tZXJnZUNhbm9uaWNhbChcbiAgICAgICAgICAgIHsgbWV0YSwgb3JpZ2luOiBtZXRhT3JpZ2luLCBjb25mbGljdHM6IG1ldGFDb25mbGljdHMgfSxcbiAgICAgICAgICAgIHsgb3JpZ2luOiBmaWVsZFBhdGgsIG1ldGE6IHJlc291cmNlTWV0YSB9LFxuICAgICAgICAgIClcbiAgICAgICAgICBtZXRhID0gbWVyZ2VkLm1ldGFcbiAgICAgICAgICBtZXRhT3JpZ2luID0gbWVyZ2VkLm9yaWdpblxuICAgICAgICAgIG1ldGFDb25mbGljdHMgPSBtZXJnZWQuY29uZmxpY3RzXG4gICAgICAgIH1cblxuICAgICAgICByZXNvdXJjZXNCeUlkLnNldChyZXNvdXJjZUlkLCB7XG4gICAgICAgICAgLi4uZXhpc3RpbmcsXG4gICAgICAgICAgb3duZXJGaWVsZHMsXG4gICAgICAgICAgbWV0YSxcbiAgICAgICAgICBtZXRhT3JpZ2luLFxuICAgICAgICAgIG1ldGFDb25mbGljdHMsXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNvdXJjZXNCeUlkLnNldChyZXNvdXJjZUlkLCB7XG4gICAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAgICAvLyBcdTY2ODJcdTY1RjZcdTRGN0ZcdTc1MjhcdTdCODBcdTUzNTVcdTc2ODRcdTY4MDdcdThCQzZcdTVCNTdcdTdCMjZcdTRFMzJcdUZGMENcdTU0MEVcdTdFRURcdTUzRUZcdTY4MzlcdTYzNkUga2V5IFx1ODlDNFx1NTIxOVx1OEZEQlx1NEUwMFx1NkI2NVx1N0VEM1x1Njc4NFx1NTMxNlx1MzAwMlxuICAgICAgICAgIGtleVNlbGVjdG9yOiBgU3RhdGVUcmFpdC5zb3VyY2VAJHtmaWVsZFBhdGh9YCxcbiAgICAgICAgICBvd25lckZpZWxkczogW2ZpZWxkUGF0aF0sXG4gICAgICAgICAgbWV0YTogcmVzb3VyY2VNZXRhLFxuICAgICAgICAgIG1ldGFPcmlnaW46IHJlc291cmNlTWV0YSA/IGZpZWxkUGF0aCA6IHVuZGVmaW5lZCxcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgcGxhblN0ZXBzLnB1c2goe1xuICAgICAgICBpZDogYHNvdXJjZToke2ZpZWxkUGF0aH1gLFxuICAgICAgICBraW5kOiAnc291cmNlLXJlZnJlc2gnLFxuICAgICAgICB0YXJnZXRGaWVsZFBhdGg6IGZpZWxkUGF0aCxcbiAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAga2V5U2VsZWN0b3JJZDogYFN0YXRlVHJhaXQuc291cmNlQCR7ZmllbGRQYXRofWAsXG4gICAgICB9KVxuXG4gICAgICBjb25zdCBkZXBzID0gKGVudHJ5Lm1ldGEgYXMgYW55KS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgaWYgKGRlcHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgICAgIGVuc3VyZUZpZWxkKGRlcClcbiAgICAgICAgICBlZGdlcy5wdXNoKHtcbiAgICAgICAgICAgIGlkOiBgc291cmNlLWRlcDoke2RlcH0tPiR7ZmllbGRQYXRofWAsXG4gICAgICAgICAgICBmcm9tOiBkZXAsXG4gICAgICAgICAgICB0bzogZmllbGRQYXRoLFxuICAgICAgICAgICAga2luZDogJ3NvdXJjZS1kZXAnLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVudHJ5LmtpbmQgPT09ICdjaGVjaycpIHtcbiAgICAgIHBsYW5TdGVwcy5wdXNoKHtcbiAgICAgICAgaWQ6IGBjaGVjazoke2ZpZWxkUGF0aH1gLFxuICAgICAgICBraW5kOiAnY2hlY2stdmFsaWRhdGUnLFxuICAgICAgICB0YXJnZXRGaWVsZFBhdGg6IGZpZWxkUGF0aCxcbiAgICAgIH0pXG5cbiAgICAgIC8vIFx1ODJFNVx1ODlDNFx1NTIxOVx1NjYzRVx1NUYwRlx1NThGMFx1NjYwRSBkZXBzXHVGRjBDXHU1MjE5XHU4ODY1XHU1MTQ1IEdyYXBoIFx1OEZCOVx1RkYwOFx1NzUyOFx1NEU4RSBSZXZlcnNlQ2xvc3VyZSBzY29wZWQgdmFsaWRhdGVcdUZGMDlcdTMwMDJcbiAgICAgIGlmICh0cmFpdC5kZXBzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZm9yIChjb25zdCBkZXAgb2YgdHJhaXQuZGVwcykge1xuICAgICAgICAgIGVuc3VyZUZpZWxkKGRlcClcbiAgICAgICAgICBlZGdlcy5wdXNoKHtcbiAgICAgICAgICAgIGlkOiBgY2hlY2stZGVwOiR7ZGVwfS0+JHtmaWVsZFBhdGh9YCxcbiAgICAgICAgICAgIGZyb206IGRlcCxcbiAgICAgICAgICAgIHRvOiBmaWVsZFBhdGgsXG4gICAgICAgICAgICBraW5kOiAnY2hlY2stZGVwJyxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZm9yIChjb25zdCBmaWVsZCBvZiBmaWVsZE1hcC52YWx1ZXMoKSkge1xuICAgIG5vZGVzLnB1c2goe1xuICAgICAgaWQ6IGZpZWxkLmlkLFxuICAgICAgZmllbGQsXG4gICAgICB0cmFpdHM6IGZpZWxkLnRyYWl0cyxcbiAgICAgIG1ldGE6IG5vZGVNZXRhQnlGaWVsZFBhdGguZ2V0KGZpZWxkLmlkKSxcbiAgICB9KVxuICB9XG5cbiAgY29uc3QgZ3JhcGg6IFN0YXRlVHJhaXRHcmFwaCA9IHtcbiAgICBfdGFnOiAnU3RhdGVUcmFpdEdyYXBoJyxcbiAgICBub2RlcyxcbiAgICBlZGdlcyxcbiAgICByZXNvdXJjZXM6IEFycmF5LmZyb20ocmVzb3VyY2VzQnlJZC52YWx1ZXMoKSksXG4gIH1cblxuICBjb25zdCBwbGFuOiBTdGF0ZVRyYWl0UGxhbiA9IHtcbiAgICBfdGFnOiAnU3RhdGVUcmFpdFBsYW4nLFxuICAgIHN0ZXBzOiBwbGFuU3RlcHMsXG4gIH1cblxuICByZXR1cm4geyBncmFwaCwgcGxhbiB9XG59XG5cbi8qKlxuICogXHU5NDg4XHU1QkY5IGxpbmsgXHU4RkI5XHU4RkRCXHU4ODRDXHU3QjgwXHU1MzU1XHU3Njg0XHU3M0FGXHU4REVGXHU2OEMwXHU2RDRCXHUzMDAyXG4gKlxuICogLSBcdTRFQzVcdTgwMDNcdTg2NTEga2luZCA9IFwibGlua1wiIFx1NzY4NFx1OEZCOVx1RkYwQ2NvbXB1dGVkL3NvdXJjZSBcdTk5OTZcdTcyNDhcdTRFMERcdTUzQzJcdTRFMEVcdTczQUZcdTY4QzBcdTZENEJcdUZGMUJcbiAqIC0gXHU4MkU1XHU1M0QxXHU3M0IwXHU3M0FGXHU4REVGXHVGRjBDXHU2MjlCXHU1MUZBXHU1RTI2XHU2NzA5XHU4REVGXHU1Rjg0XHU0RkUxXHU2MDZGXHU3Njg0XHU5NTE5XHU4QkVGXHVGRjBDXHU5MDdGXHU1MTREXHU1NzI4XHU4RkQwXHU4ODRDXHU2NUY2XHU4RkRCXHU1MTY1XHU2NUUwXHU5NjUwXHU2NkY0XHU2NUIwXHUzMDAyXG4gKi9cbmNvbnN0IGFzc2VydE5vTGlua0N5Y2xlcyA9IChlZGdlczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0R3JhcGhFZGdlPik6IHZvaWQgPT4ge1xuICBjb25zdCBhZGphY2VuY3kgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KClcblxuICBmb3IgKGNvbnN0IGVkZ2Ugb2YgZWRnZXMpIHtcbiAgICBpZiAoZWRnZS5raW5kICE9PSAnbGluaycpIGNvbnRpbnVlXG4gICAgY29uc3QgbGlzdCA9IGFkamFjZW5jeS5nZXQoZWRnZS5mcm9tKSA/PyBbXVxuICAgIGxpc3QucHVzaChlZGdlLnRvKVxuICAgIGFkamFjZW5jeS5zZXQoZWRnZS5mcm9tLCBsaXN0KVxuICB9XG5cbiAgY29uc3QgdmlzaXRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gIGNvbnN0IHN0YWNrID0gbmV3IFNldDxzdHJpbmc+KClcblxuICBjb25zdCBkZnMgPSAobm9kZTogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgaWYgKHN0YWNrLmhhcyhub2RlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgW1N0YXRlVHJhaXQuYnVpbGRdIGxpbmsgY3ljbGUgZGV0ZWN0ZWQgYXQgZmllbGQgXCIke25vZGV9XCIuIGAgK1xuICAgICAgICAgICdQbGVhc2UgY2hlY2sgbGluayB0cmFpdHMgZm9yIGNpcmN1bGFyIGRlcGVuZGVuY2llcy4nLFxuICAgICAgKVxuICAgIH1cbiAgICBpZiAodmlzaXRlZC5oYXMobm9kZSkpIHJldHVyblxuICAgIHZpc2l0ZWQuYWRkKG5vZGUpXG4gICAgc3RhY2suYWRkKG5vZGUpXG5cbiAgICBjb25zdCBuZXh0cyA9IGFkamFjZW5jeS5nZXQobm9kZSlcbiAgICBpZiAobmV4dHMpIHtcbiAgICAgIGZvciAoY29uc3QgdG8gb2YgbmV4dHMpIHtcbiAgICAgICAgZGZzKHRvKVxuICAgICAgfVxuICAgIH1cblxuICAgIHN0YWNrLmRlbGV0ZShub2RlKVxuICB9XG5cbiAgZm9yIChjb25zdCBub2RlIG9mIGFkamFjZW5jeS5rZXlzKCkpIHtcbiAgICBpZiAoIXZpc2l0ZWQuaGFzKG5vZGUpKSB7XG4gICAgICBkZnMobm9kZSlcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgY29sbGVjdFNjaGVtYVBhdGhzID0gKFxuICBlbnRyaWVzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+LFxuKTogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0U2NoZW1hUGF0aFJlZj4gPT4ge1xuICBjb25zdCBieUtleSA9IG5ldyBNYXA8c3RyaW5nLCBTdGF0ZVRyYWl0U2NoZW1hUGF0aFJlZj4oKVxuXG4gIGNvbnN0IGFkZCA9IChyZWY6IFN0YXRlVHJhaXRTY2hlbWFQYXRoUmVmKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZWYucGF0aCkgcmV0dXJuXG4gICAgY29uc3QgayA9IGAke3JlZi5raW5kfXwke3JlZi5lbnRyeUtpbmR9fCR7cmVmLmVudHJ5RmllbGRQYXRofXwke3JlZi5ydWxlTmFtZSA/PyAnJ318JHtyZWYucGF0aH1gXG4gICAgYnlLZXkuc2V0KGssIHJlZilcbiAgfVxuXG4gIGNvbnN0IGdldENoZWNrV3JpdGViYWNrUGF0aCA9IChlbnRyeTogRXh0cmFjdDxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+LCB7IHJlYWRvbmx5IGtpbmQ6ICdjaGVjaycgfT4pOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IHdiID0gKGVudHJ5Lm1ldGEgYXMgYW55KT8ud3JpdGViYWNrXG4gICAgY29uc3QgcCA9IHdiICYmIHR5cGVvZiB3YiA9PT0gJ29iamVjdCcgPyAod2IgYXMgYW55KS5wYXRoIDogdW5kZWZpbmVkXG4gICAgY29uc3Qgd3JpdGViYWNrUGF0aCA9IHR5cGVvZiBwID09PSAnc3RyaW5nJyAmJiBwLnN0YXJ0c1dpdGgoJ2Vycm9ycy4nKSA/IHAgOiB1bmRlZmluZWRcblxuICAgIGlmICh3cml0ZWJhY2tQYXRoKSByZXR1cm4gd3JpdGViYWNrUGF0aFxuXG4gICAgY29uc3QgZmllbGRQYXRoID0gZW50cnkuZmllbGRQYXRoXG4gICAgaWYgKGZpZWxkUGF0aC5lbmRzV2l0aCgnW10nKSkge1xuICAgICAgcmV0dXJuIGBlcnJvcnMuJHtmaWVsZFBhdGguc2xpY2UoMCwgLTIpfWBcbiAgICB9XG4gICAgcmV0dXJuIGBlcnJvcnMuJHtmaWVsZFBhdGh9YFxuICB9XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgYWRkKHtcbiAgICAgIGtpbmQ6ICdmaWVsZFBhdGgnLFxuICAgICAgZW50cnlLaW5kOiBlbnRyeS5raW5kLFxuICAgICAgZW50cnlGaWVsZFBhdGg6IGVudHJ5LmZpZWxkUGF0aCxcbiAgICAgIHBhdGg6IGVudHJ5LmZpZWxkUGF0aCxcbiAgICB9KVxuXG4gICAgaWYgKGVudHJ5LmtpbmQgPT09ICdjb21wdXRlZCcgfHwgZW50cnkua2luZCA9PT0gJ3NvdXJjZScpIHtcbiAgICAgIGNvbnN0IGRlcHMgPSAoKGVudHJ5Lm1ldGEgYXMgYW55KT8uZGVwcyA/PyBbXSkgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+XG4gICAgICBmb3IgKGNvbnN0IGRlcCBvZiBkZXBzKSB7XG4gICAgICAgIGFkZCh7XG4gICAgICAgICAga2luZDogJ2RlcCcsXG4gICAgICAgICAgZW50cnlLaW5kOiBlbnRyeS5raW5kLFxuICAgICAgICAgIGVudHJ5RmllbGRQYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgICAgICAgcGF0aDogZGVwLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbnRyeS5raW5kID09PSAnbGluaycpIHtcbiAgICAgIGFkZCh7XG4gICAgICAgIGtpbmQ6ICdsaW5rX2Zyb20nLFxuICAgICAgICBlbnRyeUtpbmQ6ICdsaW5rJyxcbiAgICAgICAgZW50cnlGaWVsZFBhdGg6IGVudHJ5LmZpZWxkUGF0aCxcbiAgICAgICAgcGF0aDogZW50cnkubWV0YS5mcm9tIGFzIHN0cmluZyxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgaWYgKGVudHJ5LmtpbmQgPT09ICdjaGVjaycpIHtcbiAgICAgIGFkZCh7XG4gICAgICAgIGtpbmQ6ICdjaGVja193cml0ZWJhY2snLFxuICAgICAgICBlbnRyeUtpbmQ6ICdjaGVjaycsXG4gICAgICAgIGVudHJ5RmllbGRQYXRoOiBlbnRyeS5maWVsZFBhdGgsXG4gICAgICAgIHBhdGg6IGdldENoZWNrV3JpdGViYWNrUGF0aChlbnRyeSksXG4gICAgICB9KVxuXG4gICAgICBjb25zdCBydWxlcyA9ICgoZW50cnkubWV0YSBhcyBhbnkpPy5ydWxlcyA/PyB7fSkgYXMgUmVjb3JkPHN0cmluZywgYW55PlxuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHJ1bGVzKSkge1xuICAgICAgICBjb25zdCBydWxlID0gcnVsZXNbbmFtZV1cbiAgICAgICAgaWYgKCFydWxlIHx8IHR5cGVvZiBydWxlICE9PSAnb2JqZWN0JykgY29udGludWVcbiAgICAgICAgY29uc3QgZGVwcyA9IChydWxlLmRlcHMgPz8gW10pIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICAgICAgICBmb3IgKGNvbnN0IGRlcCBvZiBkZXBzKSB7XG4gICAgICAgICAgYWRkKHtcbiAgICAgICAgICAgIGtpbmQ6ICdkZXAnLFxuICAgICAgICAgICAgZW50cnlLaW5kOiAnY2hlY2snLFxuICAgICAgICAgICAgZW50cnlGaWVsZFBhdGg6IGVudHJ5LmZpZWxkUGF0aCxcbiAgICAgICAgICAgIHJ1bGVOYW1lOiBuYW1lLFxuICAgICAgICAgICAgcGF0aDogZGVwLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gQXJyYXkuZnJvbShieUtleS5lbnRyaWVzKCkpXG4gICAgLnNvcnQoKGEsIGIpID0+IGFbMF0ubG9jYWxlQ29tcGFyZShiWzBdKSlcbiAgICAubWFwKChbLCB2XSkgPT4gdilcbn1cblxuLyoqXG4gKiBcdTY4MzlcdTYzNkVcdTdFRDlcdTVCOUFcdTc2ODQgc3RhdGVTY2hlbWEgXHU0RTBFIHRyYWl0cyBzcGVjIFx1Njc4NFx1OTAyMCBTdGF0ZVRyYWl0UHJvZ3JhbVx1MzAwMlxuICpcbiAqIC0gXHU3RUFGXHU1MUZEXHU2NTcwXHVGRjFBXHU0RTBEXHU0RjlEXHU4RDU2XHU1OTE2XHU5MEU4IEVudiAvIFx1NTE2OFx1NUM0MFx1NzJCNlx1NjAwMVx1RkYxQlxuICogLSBcdTVGNTNcdTUyNERcdTVCOUVcdTczQjBcdTgwNUFcdTcxMjZcdTRFOEVcdUZGMUFcbiAqICAgLSBcdTRFQ0UgU3BlYyBcdTVGNTJcdTRFMDBcdTUzMTZcdTUxRkEgRW50cnkgXHU1MjE3XHU4ODY4XHVGRjFCXG4gKiAgIC0gXHU1N0ZBXHU0RThFIEVudHJ5IFx1Njc4NFx1NUVGQVx1OEY3Qlx1OTFDRlx1NzI0OCBHcmFwaCAvIFBsYW5cdUZGMUJcbiAqICAgLSBcdTVCRjkgbGluayBcdThGQjlcdTUwNUFcdTU3RkFcdTY3MkNcdTczQUZcdThERUZcdTY4QzBcdTZENEJcdTMwMDJcbiAqXG4gKiBcdTU0MEVcdTdFRURcdTgyRTVcdTk3MDBcdTg5ODFcdTY2RjRcdTdDQkVcdTdFQzZcdTc2ODRcdTRGOURcdThENTZcdTUyMDZcdTY3OTBcdUZGMDhcdTRGOEJcdTU5ODJcdTVCRjkgY29tcHV0ZWQva2V5IFx1NTA1QVx1OTc1OVx1NjAwMVx1ODlFM1x1Njc5MFx1RkYwOVx1RkYwQ1xuICogXHU1M0VGXHU0RUU1XHU1NzI4XHU2NzJDXHU2QTIxXHU1NzU3XHU1MTg1XHU2RjE0XHU4RkRCXHU1QjlFXHU3M0IwXHVGRjBDXHU4MDBDXHU0RTBEXHU1RjcxXHU1NENEXHU1QkY5XHU1OTE2IEFQSVx1MzAwMlxuICovXG5leHBvcnQgY29uc3QgYnVpbGQgPSA8UyBleHRlbmRzIG9iamVjdD4oXG4gIHN0YXRlU2NoZW1hOiBTY2hlbWEuU2NoZW1hPFMsIGFueT4sXG4gIHNwZWM6IFN0YXRlVHJhaXRTcGVjPFM+LFxuKTogU3RhdGVUcmFpdFByb2dyYW08Uz4gPT4ge1xuICBjb25zdCBlbnRyaWVzID0gbm9ybWFsaXplU3BlYyhzcGVjKSBhcyBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxTLCBzdHJpbmc+PlxuICBjb25zdCBub2RlTWV0YUJ5RmllbGRQYXRoID0gY29sbGVjdE5vZGVNZXRhKHNwZWMpXG5cbiAgLy8gUGhhc2UgNFx1RkYwOFVTMlx1RkYwOVx1RkYxQVx1NUYzQVx1NTIzNlx1NjYzRVx1NUYwRiBkZXBzXHVGRjA4R3JhcGgvZGlhZ25vc3RpY3MvcmVwbGF5IFx1NTNFQVx1OEJBNCBkZXBzIFx1NEY1Q1x1NEUzQVx1NEY5RFx1OEQ1Nlx1NEU4Qlx1NUI5RVx1NkU5MFx1RkYwOVx1MzAwMlxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ2NvbXB1dGVkJykge1xuICAgICAgY29uc3QgZGVwcyA9IChlbnRyeS5tZXRhIGFzIGFueSkuZGVwcyBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICAgIGlmIChkZXBzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBbU3RhdGVUcmFpdC5idWlsZF0gTWlzc2luZyBleHBsaWNpdCBkZXBzIGZvciBjb21wdXRlZCBcIiR7ZW50cnkuZmllbGRQYXRofVwiLiBgICtcbiAgICAgICAgICAgICdQbGVhc2UgdXNlIFN0YXRlVHJhaXQuY29tcHV0ZWQoeyBkZXBzOiBbLi4uXSwgZ2V0OiAuLi4gfSkuJyxcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW50cnkua2luZCA9PT0gJ3NvdXJjZScpIHtcbiAgICAgIGNvbnN0IGRlcHMgPSAoZW50cnkubWV0YSBhcyBhbnkpLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgICBpZiAoZGVwcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgW1N0YXRlVHJhaXQuYnVpbGRdIE1pc3NpbmcgZXhwbGljaXQgZGVwcyBmb3Igc291cmNlIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIuIGAgK1xuICAgICAgICAgICAgJ1BsZWFzZSBwcm92aWRlIG1ldGEuZGVwcyBmb3IgU3RhdGVUcmFpdC5zb3VyY2UoeyBkZXBzOiBbLi4uXSwgLi4uIH0pLicsXG4gICAgICAgIClcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVudHJ5LmtpbmQgPT09ICdjaGVjaycpIHtcbiAgICAgIGNvbnN0IHJ1bGVzID0gKChlbnRyeS5tZXRhIGFzIGFueSk/LnJ1bGVzID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXMocnVsZXMpKSB7XG4gICAgICAgIGNvbnN0IHJ1bGUgPSBydWxlc1tuYW1lXVxuICAgICAgICBpZiAodHlwZW9mIHJ1bGUgPT09ICdmdW5jdGlvbicgfHwgIXJ1bGUgfHwgdHlwZW9mIHJ1bGUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBNaXNzaW5nIGV4cGxpY2l0IGRlcHMgZm9yIGNoZWNrIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIgcnVsZSBcIiR7bmFtZX1cIi4gYCArXG4gICAgICAgICAgICAgICdQbGVhc2UgdXNlIHsgZGVwczogWy4uLl0sIHZhbGlkYXRlOiAuLi4gfSBmb3JtLicsXG4gICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICAgIGlmICgocnVsZSBhcyBhbnkpLmRlcHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBbU3RhdGVUcmFpdC5idWlsZF0gTWlzc2luZyBleHBsaWNpdCBkZXBzIGZvciBjaGVjayBcIiR7ZW50cnkuZmllbGRQYXRofVwiIHJ1bGUgXCIke25hbWV9XCIuIGAgK1xuICAgICAgICAgICAgICAnUGxlYXNlIHByb3ZpZGUgZGVwczogWy4uLl0uJyxcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCB7IGdyYXBoLCBwbGFuIH0gPSBidWlsZEdyYXBoKGVudHJpZXMsIG5vZGVNZXRhQnlGaWVsZFBhdGgpXG5cbiAgLy8gXHU5NDg4XHU1QkY5IGxpbmsgXHU4RkI5XHU4RkRCXHU4ODRDXHU0RTAwXHU2QjIxXHU3M0FGXHU4REVGXHU2OEMwXHU2RDRCXHVGRjBDXHU5MDdGXHU1MTREXHU2NjBFXHU2NjNFXHU3Njg0XHU5MTREXHU3RjZFXHU5NTE5XHU4QkVGXHUzMDAyXG4gIGFzc2VydE5vTGlua0N5Y2xlcyhncmFwaC5lZGdlcylcblxuICByZXR1cm4ge1xuICAgIHN0YXRlU2NoZW1hLFxuICAgIHNwZWMsXG4gICAgZW50cmllczogZW50cmllcyBhcyBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+LFxuICAgIGdyYXBoLFxuICAgIHBsYW4sXG4gICAgY29udmVyZ2VJcjogYnVpbGRDb252ZXJnZUlyKGVudHJpZXMgYXMgUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PiksXG4gICAgc2NoZW1hUGF0aHM6IGNvbGxlY3RTY2hlbWFQYXRocyhlbnRyaWVzIGFzIFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj4pLFxuICB9XG59XG4iLCAiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSAnZWZmZWN0J1xuaW1wb3J0IHR5cGUgeyBCb3VuZEFwaSB9IGZyb20gJy4uL3J1bnRpbWUvY29yZS9tb2R1bGUuanMnXG5pbXBvcnQgeyBnZXRCb3VuZEludGVybmFscyB9IGZyb20gJy4uL3J1bnRpbWUvY29yZS9ydW50aW1lSW50ZXJuYWxzQWNjZXNzb3IuanMnXG5pbXBvcnQgKiBhcyBTb3VyY2VSdW50aW1lIGZyb20gJy4vc291cmNlLmpzJ1xuaW1wb3J0IHR5cGUge1xuICBTdGF0ZVRyYWl0UHJvZ3JhbSxcbiAgU3RhdGVUcmFpdFBsYW5TdGVwLFxuICBTdGF0ZVRyYWl0RW50cnksXG4gIFRyYWl0Q29udmVyZ2VHZW5lcmF0aW9uQnVtcFJlYXNvbixcbn0gZnJvbSAnLi9tb2RlbC5qcydcblxuY29uc3QgYnVpbGRFbnRyeUluZGV4ID0gPFM+KFxuICBlbnRyaWVzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxTLCBzdHJpbmc+Pixcbik6IE1hcDxzdHJpbmcsIEFycmF5PFN0YXRlVHJhaXRFbnRyeTxTLCBzdHJpbmc+Pj4gPT4ge1xuICBjb25zdCBpbmRleCA9IG5ldyBNYXA8c3RyaW5nLCBBcnJheTxTdGF0ZVRyYWl0RW50cnk8Uywgc3RyaW5nPj4+KClcbiAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgY29uc3QgbGlzdCA9IGluZGV4LmdldChlbnRyeS5maWVsZFBhdGgpID8/IFtdXG4gICAgbGlzdC5wdXNoKGVudHJ5KVxuICAgIGluZGV4LnNldChlbnRyeS5maWVsZFBhdGgsIGxpc3QpXG4gIH1cbiAgcmV0dXJuIGluZGV4XG59XG5cbi8qKlxuICogXHU1NzI4XHU3RUQ5XHU1QjlBIEJvdW5kIEFQSSBcdTRFMEFcdTVCODlcdTg4QzUgU3RhdGVUcmFpdFByb2dyYW0gXHU2M0NGXHU4RkYwXHU3Njg0XHU4ODRDXHU0RTNBXHUzMDAyXG4gKlxuICogLSBQaGFzZSAyIFx1NjcwMFx1NUMwRlx1NUI5RVx1NzNCMFx1RkYxQVxuICogICAtIFx1NEUzQSBjb21wdXRlZCBcdTVCNTdcdTZCQjVcdTZDRThcdTUxOEMgd2F0Y2hlclx1RkYxQVx1NUY1MyBTdGF0ZSBcdTUzRDhcdTUzMTZcdTY1RjZcdTkxQ0RcdTdCOTdcdTc2RUVcdTY4MDdcdTVCNTdcdTZCQjVcdUZGMUJcbiAqICAgLSBcdTRFM0EgbGluayBcdTVCNTdcdTZCQjVcdTZDRThcdTUxOEMgd2F0Y2hlclx1RkYxQVx1NUY1M1x1NkU5MFx1NUI1N1x1NkJCNVx1NTNEOFx1NTMxNlx1NjVGNlx1NTQwQ1x1NkI2NVx1NzZFRVx1NjgwN1x1NUI1N1x1NkJCNVx1RkYxQlxuICogICAtIFx1NEUzQSBzb3VyY2UgXHU1QjU3XHU2QkI1XHU5ODg0XHU3NTU5XHU1MjM3XHU2NUIwXHU1MTY1XHU1M0UzXHVGRjA4XHU2NjgyXHU0RTBEXHU4OUU2XHU1M0QxXHU1OTE2XHU5MEU4XHU4QzAzXHU3NTI4XHVGRjA5XHUzMDAyXG4gKlxuICogXHU4QkY0XHU2NjBFXHVGRjFBXG4gKiAtIFx1NjI0MFx1NjcwOSB3YXRjaGVyIFx1OTBGRFx1OTAxQVx1OEZDNyBCb3VuZCBBUEkgYCRgIFx1NUI4OVx1ODhDNVx1RkYwQ1x1NEUwRFx1NzZGNFx1NjNBNVx1NEY5RFx1OEQ1NiBNb2R1bGVSdW50aW1lXHVGRjFCXG4gKiAtIFx1NkJDRlx1NEUyQSBQbGFuU3RlcCBcdTVCRjlcdTVFOTRcdTRFMDBcdTRFMkFcdTk1N0ZcdTc1MUZcdTU0N0RcdTU0NjhcdTY3MUYgRWZmZWN0XHVGRjBDXHU5MDFBXHU4RkM3IGZvcmtTY29wZWQgXHU2MzAyXHU4RjdEXHU1MjMwIFJ1bnRpbWUgU2NvcGVcdTMwMDJcbiAqL1xuZXhwb3J0IGNvbnN0IGluc3RhbGwgPSA8Uz4oXG4gIGJvdW5kOiBCb3VuZEFwaTxhbnksIGFueT4sXG4gIHByb2dyYW06IFN0YXRlVHJhaXRQcm9ncmFtPFM+LFxuKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgYW55PiA9PiB7XG4gIC8vIFx1NEYxOFx1NTE0OFx1NUMwNiBQcm9ncmFtIFx1NkNFOFx1NTE4Q1x1NTIzMCBSdW50aW1lXHVGRjA4XHU2NTM2XHU2NTVCXHU1RjE1XHU2NENFXHU1NzI4XHU0RThCXHU1MkExXHU2M0QwXHU0RUE0XHU1MjREXHU3RURGXHU0RTAwXHU2MjY3XHU4ODRDIGNvbXB1dGVkL2xpbmsvY2hlY2tcdUZGMDlcdTMwMDJcbiAgdHJ5IHtcbiAgICBjb25zdCBpbnRlcm5hbHMgPSBnZXRCb3VuZEludGVybmFscyhib3VuZCBhcyBhbnkpXG4gICAgOyhpbnRlcm5hbHMudHJhaXRzLnJlZ2lzdGVyU3RhdGVUcmFpdFByb2dyYW0gYXMgYW55KShwcm9ncmFtLCB7XG4gICAgICBidW1wUmVhc29uOiAnbG9naWNfaW5zdGFsbGVkJyBhcyBUcmFpdENvbnZlcmdlR2VuZXJhdGlvbkJ1bXBSZWFzb24sXG4gICAgfSlcbiAgfSBjYXRjaCB7XG4gICAgLy8gbm8tb3AgZm9yIGxlZ2FjeS9tb2NrZWQgYm91bmRcbiAgfVxuXG4gIGNvbnN0IGVudHJ5SW5kZXggPSBidWlsZEVudHJ5SW5kZXgocHJvZ3JhbS5lbnRyaWVzIGFzIGFueSlcblxuICBjb25zdCBpbnN0YWxsU3RlcCA9IChzdGVwOiBTdGF0ZVRyYWl0UGxhblN0ZXApOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBhbnk+ID0+IHtcbiAgICBpZiAoIXN0ZXAudGFyZ2V0RmllbGRQYXRoKSB7XG4gICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICB9XG5cbiAgICBpZiAoc3RlcC5raW5kICE9PSAnc291cmNlLXJlZnJlc2gnKSB7XG4gICAgICAvLyBjb21wdXRlZC9saW5rL2NoZWNrIFx1NURGMlx1NzUzMSBSdW50aW1lIFx1NTE4NVx1NjgzOFx1NTcyOFx1NEU4Qlx1NTJBMVx1N0E5N1x1NTNFM1x1NTE4NVx1NTkwNFx1NzQwNlx1RkYxQmluc3RhbGwgXHU5NjM2XHU2QkI1XHU0RUM1XHU0RkREXHU3NTU5IHNvdXJjZS5yZWZyZXNoIFx1NTE2NVx1NTNFM1x1MzAwMlxuICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgfVxuXG4gICAgY29uc3QgY2FuZGlkYXRlcyA9IGVudHJ5SW5kZXguZ2V0KHN0ZXAudGFyZ2V0RmllbGRQYXRoKVxuICAgIGlmICghY2FuZGlkYXRlcyB8fCBjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgLy8gUGxhbiBcdTRFMkRcdTVGMTVcdTc1MjhcdTRFODZcdTRFMERcdTVCNThcdTU3MjhcdTc2ODQgU3BlY1x1RkYxQVx1ODlDNlx1NEUzQVx1Njc4NFx1NUVGQVx1OTYzNlx1NkJCNVx1NzY4NCBidWdcdUZGMENcdThGRDlcdTkxQ0NcdTc2RjRcdTYzQTVcdTVGRkRcdTc1NjVcdThCRTVcdTZCNjVcdTlBQTRcdTMwMDJcbiAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgIH1cblxuICAgIGNvbnN0IGVudHJ5ID0gY2FuZGlkYXRlcy5maW5kKChlKSA9PiBlLmtpbmQgPT09ICdzb3VyY2UnKVxuXG4gICAgaWYgKCFlbnRyeSkge1xuICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgfVxuXG4gICAgcmV0dXJuIFNvdXJjZVJ1bnRpbWUuaW5zdGFsbFNvdXJjZVJlZnJlc2goYm91bmQsIHN0ZXAsIGVudHJ5IGFzIGFueSlcbiAgfVxuXG4gIHJldHVybiBFZmZlY3QuZm9yRWFjaChwcm9ncmFtLnBsYW4uc3RlcHMsIChzdGVwKSA9PiBpbnN0YWxsU3RlcChzdGVwKSkucGlwZShFZmZlY3QuYXNWb2lkKVxufVxuIiwgIi8vIFN0YXRlVHJhaXQgXHU1NDdEXHU1NDBEXHU3QTdBXHU5NUY0XHU2QTIxXHU1NzU3XHVGRjA4QGxvZ2l4L2NvcmUvU3RhdGVUcmFpdFx1RkYwOVx1RkYxQVxuLy8gLSBcdTYzRDBcdTRGOUIgdHJhaXRzIHNwZWMgXHU3Njg0IERTTFx1RkYwOGZyb20vbm9kZS9saXN0L2NvbXB1dGVkL3NvdXJjZS9saW5rXHVGRjA5XHVGRjFCXG4vLyAtIGJ1aWxkXHVGRjFBXHU1RjUyXHU0RTAwXHU1MzE2IHNwZWMgXHU1RTc2XHU3NTFGXHU2MjEwIFByb2dyYW0vR3JhcGgvUGxhblx1RkYxQlxuLy8gLSBpbnN0YWxsXHVGRjFBXHU1QzA2IFByb2dyYW0gXHU1Qjg5XHU4OEM1XHU1MjMwXHU4RkQwXHU4ODRDXHU2NUY2XHVGRjA4XHU2Q0U4XHU1MThDIHNvdXJjZS5yZWZyZXNoIFx1N0I0OVx1NTE2NVx1NTNFM1x1RkYwQ1x1NUU3Nlx1NTcyOFx1NEU4Qlx1NTJBMVx1N0E5N1x1NTNFM1x1NjI2N1x1ODg0QyBjb252ZXJnZS92YWxpZGF0ZVx1RkYwOVx1MzAwMlxuXG5pbXBvcnQgdHlwZSB7IFNjaGVtYSB9IGZyb20gJ2VmZmVjdCdcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gJ2VmZmVjdCdcbmltcG9ydCB0eXBlIHsgQm91bmRBcGkgfSBmcm9tICcuL0JvdW5kLmpzJ1xuaW1wb3J0ICogYXMgTW9kZWwgZnJvbSAnLi9pbnRlcm5hbC9zdGF0ZS10cmFpdC9tb2RlbC5qcydcbmltcG9ydCAqIGFzIEZpZWxkUGF0aCBmcm9tICcuL2ludGVybmFsL3N0YXRlLXRyYWl0L2ZpZWxkLXBhdGguanMnXG5pbXBvcnQgKiBhcyBSb3dJZCBmcm9tICcuL2ludGVybmFsL3N0YXRlLXRyYWl0L3Jvd2lkLmpzJ1xuaW1wb3J0ICogYXMgSW50ZXJuYWxCdWlsZCBmcm9tICcuL2ludGVybmFsL3N0YXRlLXRyYWl0L2J1aWxkLmpzJ1xuaW1wb3J0ICogYXMgSW50ZXJuYWxJbnN0YWxsIGZyb20gJy4vaW50ZXJuYWwvc3RhdGUtdHJhaXQvaW5zdGFsbC5qcydcbmltcG9ydCAqIGFzIEludGVybmFsSXIgZnJvbSAnLi9pbnRlcm5hbC9zdGF0ZS10cmFpdC9pci5qcydcblxuLy8gXHU1QkY5XHU1OTE2XHU2NkI0XHU5NzMyXHU3Njg0XHU2ODM4XHU1RkMzXHU3QzdCXHU1NzhCXHU1MjJCXHU1NDBEXHUzMDAyXG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0U3BlYzxTPiA9IE1vZGVsLlN0YXRlVHJhaXRTcGVjPFM+XG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0RW50cnk8UyA9IHVua25vd24sIFAgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+ID0gTW9kZWwuU3RhdGVUcmFpdEVudHJ5PFMsIFA+XG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0UHJvZ3JhbTxTPiA9IE1vZGVsLlN0YXRlVHJhaXRQcm9ncmFtPFM+XG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0R3JhcGggPSBNb2RlbC5TdGF0ZVRyYWl0R3JhcGhcbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRQbGFuID0gTW9kZWwuU3RhdGVUcmFpdFBsYW5cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXROb2RlPElucHV0ID0gdW5rbm93biwgQ3R4ID0gdW5rbm93bj4gPSBNb2RlbC5TdGF0ZVRyYWl0Tm9kZTxJbnB1dCwgQ3R4PlxuZXhwb3J0IHR5cGUgU3RhdGVUcmFpdExpc3Q8SXRlbSA9IHVua25vd24+ID0gTW9kZWwuU3RhdGVUcmFpdExpc3Q8SXRlbT5cbmV4cG9ydCB0eXBlIENoZWNrUnVsZTxJbnB1dCA9IHVua25vd24sIEN0eCA9IHVua25vd24+ID0gTW9kZWwuQ2hlY2tSdWxlPElucHV0LCBDdHg+XG5cbmV4cG9ydCB0eXBlIFN0YXRlRmllbGRQYXRoPFM+ID0gRmllbGRQYXRoLlN0YXRlRmllbGRQYXRoPFM+XG5leHBvcnQgdHlwZSBTdGF0ZUF0UGF0aDxTLCBQPiA9IEZpZWxkUGF0aC5TdGF0ZUF0UGF0aDxTLCBQPlxuXG5leHBvcnQgY29uc3QgJHJvb3QgPSAnJHJvb3QnIGFzIGNvbnN0XG5cbnR5cGUgRGVwc0FyZ3M8UyBleHRlbmRzIG9iamVjdCwgRGVwcyBleHRlbmRzIFJlYWRvbmx5QXJyYXk8U3RhdGVGaWVsZFBhdGg8Uz4+PiA9IHtcbiAgcmVhZG9ubHkgW0sgaW4ga2V5b2YgRGVwc106IFN0YXRlQXRQYXRoPFMsIERlcHNbS10+XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdC5mcm9tXHVGRjFBXG4gKiAtIFx1NjgzOVx1NjM2RSBTdGF0ZSBTY2hlbWEgXHU2NTM2XHU3QTg0XHU1M0VGXHU3NTI4XHU1QjU3XHU2QkI1XHU4REVGXHU1Rjg0XHVGRjBDXHU1RTc2XHU0RTNBIHRyYWl0cyBzcGVjIFx1NjNEMFx1NEY5Qlx1N0M3Qlx1NTc4Qlx1N0VBNlx1Njc1Rlx1RkYxQlxuICogLSBcdThGRDBcdTg4NENcdTY1RjZcdTRFQzVcdThGRDRcdTU2REVcdTUzOUZcdTU5Q0Igc3BlYyBcdTVCRjlcdThDNjFcdUZGMENcdTUxNzdcdTRGNTNcdTVGNTJcdTRFMDBcdTUzMTZcdTc1MzEgaW50ZXJuYWwgXHU1QzQyXHU1OTA0XHU3NDA2XHUzMDAyXG4gKi9cbmV4cG9ydCBjb25zdCBmcm9tID1cbiAgPFMgZXh0ZW5kcyBvYmplY3QsIEk+KF9zY2hlbWE6IFNjaGVtYS5TY2hlbWE8UywgST4pID0+XG4gIChzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPik6IFN0YXRlVHJhaXRTcGVjPFM+ID0+XG4gICAgc3BlY1xuXG5leHBvcnQgY29uc3Qgbm9kZSA9IDxJbnB1dCA9IHVua25vd24sIEN0eCA9IHVua25vd24+KFxuICBzcGVjOiBPbWl0PE1vZGVsLlN0YXRlVHJhaXROb2RlPElucHV0LCBDdHg+LCAnX3RhZyc+LFxuKTogTW9kZWwuU3RhdGVUcmFpdE5vZGU8SW5wdXQsIEN0eD4gPT4gKHtcbiAgX3RhZzogJ1N0YXRlVHJhaXROb2RlJyxcbiAgLi4uc3BlYyxcbn0pXG5cbmV4cG9ydCBjb25zdCBsaXN0ID0gPEl0ZW0gPSB1bmtub3duPihzcGVjOiBPbWl0PE1vZGVsLlN0YXRlVHJhaXRMaXN0PEl0ZW0+LCAnX3RhZyc+KTogTW9kZWwuU3RhdGVUcmFpdExpc3Q8SXRlbT4gPT4gKHtcbiAgX3RhZzogJ1N0YXRlVHJhaXRMaXN0JyxcbiAgLi4uc3BlYyxcbn0pXG5cbi8qKlxuICogU3RhdGVUcmFpdC5jb21wdXRlZFx1RkYxQVxuICogLSBcdTRFM0FcdTY3RDBcdTRFMkFcdTVCNTdcdTZCQjVcdTU4RjBcdTY2MEUgY29tcHV0ZWQgXHU4MEZEXHU1MjlCXHVGRjFCXG4gKiAtIFx1OTAxQVx1OEZDN1x1NjYzRVx1NUYwRiBkZXBzIFx1NEY1Q1x1NEUzQVx1NTUyRlx1NEUwMFx1NEY5RFx1OEQ1Nlx1NEU4Qlx1NUI5RVx1NkU5MFx1RkYwOFx1NzUyOFx1NEU4RVx1OEJDQVx1NjVBRC9cdTUzQ0RcdTU0MTFcdTk1RURcdTUzMDUvXHU1NDBFXHU3RUVEXHU1ODlFXHU5MUNGXHU4QzAzXHU1RUE2XHVGRjA5XHUzMDAyXG4gKi9cbmV4cG9ydCBjb25zdCBjb21wdXRlZCA9IDxcbiAgUyBleHRlbmRzIG9iamVjdCxcbiAgUCBleHRlbmRzIFN0YXRlRmllbGRQYXRoPFM+LFxuICBjb25zdCBEZXBzIGV4dGVuZHMgUmVhZG9ubHlBcnJheTxTdGF0ZUZpZWxkUGF0aDxTPj4sXG4+KGlucHV0OiB7XG4gIHJlYWRvbmx5IGRlcHM6IERlcHNcbiAgcmVhZG9ubHkgZ2V0OiAoLi4uZGVwc1ZhbHVlczogRGVwc0FyZ3M8UywgRGVwcz4pID0+IFN0YXRlQXRQYXRoPFMsIFA+XG4gIHJlYWRvbmx5IGVxdWFscz86IChwcmV2OiBTdGF0ZUF0UGF0aDxTLCBQPiwgbmV4dDogU3RhdGVBdFBhdGg8UywgUD4pID0+IGJvb2xlYW5cbiAgLyoqXG4gICAqIDA0M1x1RkYxQVx1NjYzRVx1NUYwRiBjb252ZXJnZSB0aW1lLXNsaWNpbmcgXHU4QzAzXHU1RUE2XHU1OEYwXHU2NjBFXHUzMDAyXG4gICAqIC0gdW5zZXRcdUZGMUFpbW1lZGlhdGVcdUZGMDhcdTlFRDhcdThCQTRcdTg4NENcdTRFM0FcdTRFMERcdTUzRDhcdUZGMDlcbiAgICogLSBkZWZlcnJlZFx1RkYxQVx1NTNFRlx1NUVGNlx1OEZERlx1NTIzMFx1NTQwRVx1N0VFRFx1N0E5N1x1NTNFM1x1NTQwOFx1NUU3Nlx1NjI2N1x1ODg0Q1x1RkYwOFx1OTcwMFx1NTQwQ1x1NjVGNlx1NTQyRlx1NzUyOCBydW50aW1lIHRpbWUtc2xpY2luZ1x1RkYwOVxuICAgKi9cbiAgcmVhZG9ubHkgc2NoZWR1bGluZz86IE1vZGVsLlRyYWl0Q29udmVyZ2VTY2hlZHVsaW5nXG59KTogU3RhdGVUcmFpdEVudHJ5PFMsIFA+ID0+IHtcbiAgY29uc3QgZGVyaXZlID0gKHN0YXRlOiBSZWFkb25seTxTPik6IFN0YXRlQXRQYXRoPFMsIFA+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gKGlucHV0LmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+KS5tYXAoKGRlcCkgPT4gUm93SWQuZ2V0QXRQYXRoKHN0YXRlIGFzIGFueSwgZGVwKSlcbiAgICByZXR1cm4gKGlucHV0LmdldCBhcyBhbnkpKC4uLmFyZ3MpXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBmaWVsZFBhdGg6IHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIFAsXG4gICAga2luZDogJ2NvbXB1dGVkJyxcbiAgICBtZXRhOiB7XG4gICAgICBkZXBzOiBpbnB1dC5kZXBzLFxuICAgICAgZGVyaXZlLFxuICAgICAgZXF1YWxzOiBpbnB1dC5lcXVhbHMsXG4gICAgICAuLi4oaW5wdXQuc2NoZWR1bGluZyA/IHsgc2NoZWR1bGluZzogaW5wdXQuc2NoZWR1bGluZyB9IDoge30pLFxuICAgIH0sXG4gIH0gYXMgU3RhdGVUcmFpdEVudHJ5PFMsIFA+XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdC5zb3VyY2VcdUZGMUFcbiAqIC0gXHU0RTNBXHU2N0QwXHU0RTJBXHU1QjU3XHU2QkI1XHU1OEYwXHU2NjBFXHU1OTE2XHU5MEU4XHU4RDQ0XHU2RTkwXHU2NzY1XHU2RTkwXHVGRjA4UmVzb3VyY2UgLyBRdWVyeSBcdTk2QzZcdTYyMTBcdTU3MjhcdTU0MEVcdTdFRUQgUGhhc2UgXHU0RTJEXHU1QjlFXHU3M0IwXHVGRjA5XHVGRjFCXG4gKiAtIFx1NTE4NVx1NjgzOFx1OEQxRlx1OEQyMyBrZXlIYXNoIGdhdGUgLyBjb25jdXJyZW5jeSAvIFJlcGxheU1vZGUgXHU4ODRDXHU0RTNBXHUzMDAyXG4gKi9cbmV4cG9ydCBjb25zdCBzb3VyY2UgPSA8UyBleHRlbmRzIG9iamVjdCwgUCBleHRlbmRzIFN0YXRlRmllbGRQYXRoPFM+PihtZXRhOiB7XG4gIHJlc291cmNlOiBzdHJpbmdcbiAgZGVwczogUmVhZG9ubHlBcnJheTxTdGF0ZUZpZWxkUGF0aDxTPj5cbiAga2V5OiAoc3RhdGU6IFJlYWRvbmx5PFM+KSA9PiB1bmtub3duXG4gIHRyaWdnZXJzPzogUmVhZG9ubHlBcnJheTwnb25Nb3VudCcgfCAnb25WYWx1ZUNoYW5nZScgfCAnbWFudWFsJz5cbiAgZGVib3VuY2VNcz86IG51bWJlclxuICBjb25jdXJyZW5jeT86ICdzd2l0Y2gnIHwgJ2V4aGF1c3QtdHJhaWxpbmcnXG4gIC8qKlxuICAgKiBcdTc1MjhcdTRFOEUgRGV2dG9vbHMvXHU2NTg3XHU2ODYzXHU3Njg0XHU1M0VGXHU1RThGXHU1MjE3XHU1MzE2XHU1MTQzXHU0RkUxXHU2MDZGXHVGRjA4XHU3NjdEXHU1NDBEXHU1MzU1XHU1QjU3XHU2QkI1XHU0RjFBXHU1NzI4IGJ1aWxkIFx1OTYzNlx1NkJCNVx1ODhBQlx1NjNEMFx1NTNENlx1RkYwOVx1MzAwMlxuICAgKi9cbiAgbWV0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG59KTogU3RhdGVUcmFpdEVudHJ5PFMsIFA+ID0+XG4gICh7XG4gICAgZmllbGRQYXRoOiB1bmRlZmluZWQgYXMgdW5rbm93biBhcyBQLFxuICAgIGtpbmQ6ICdzb3VyY2UnLFxuICAgIG1ldGEsXG4gIH0pIGFzIFN0YXRlVHJhaXRFbnRyeTxTLCBQPlxuXG4vKipcbiAqIFN0YXRlVHJhaXQubGlua1x1RkYxQVxuICogLSBcdTRFM0FcdTc2RUVcdTY4MDdcdTVCNTdcdTZCQjVcdTU4RjBcdTY2MEVcdTRFQ0VcdTUxNzZcdTRFRDZcdTVCNTdcdTZCQjVcdTgwNTRcdTUyQThcdTc2ODRcdTgwRkRcdTUyOUJcdUZGMUJcbiAqIC0gbWV0YS5mcm9tIFx1NTQwQ1x1NjgzN1x1NTNENyBTdGF0ZUZpZWxkUGF0aDxTPiBcdTdFQTZcdTY3NUZcdTMwMDJcbiAqL1xuZXhwb3J0IGNvbnN0IGxpbmsgPSA8UyBleHRlbmRzIG9iamVjdCwgUCBleHRlbmRzIFN0YXRlRmllbGRQYXRoPFM+PihtZXRhOiB7XG4gIGZyb206IFN0YXRlRmllbGRQYXRoPFM+XG4gIC8qKlxuICAgKiAwNDNcdUZGMUFcdTY2M0VcdTVGMEYgY29udmVyZ2UgdGltZS1zbGljaW5nIFx1OEMwM1x1NUVBNlx1NThGMFx1NjYwRVx1MzAwMlxuICAgKiAtIHVuc2V0XHVGRjFBaW1tZWRpYXRlXHVGRjA4XHU5RUQ4XHU4QkE0XHU4ODRDXHU0RTNBXHU0RTBEXHU1M0Q4XHVGRjA5XG4gICAqIC0gZGVmZXJyZWRcdUZGMUFcdTUzRUZcdTVFRjZcdThGREZcdTUyMzBcdTU0MEVcdTdFRURcdTdBOTdcdTUzRTNcdTU0MDhcdTVFNzZcdTYyNjdcdTg4NENcdUZGMDhcdTk3MDBcdTU0MENcdTY1RjZcdTU0MkZcdTc1MjggcnVudGltZSB0aW1lLXNsaWNpbmdcdUZGMDlcbiAgICovXG4gIHNjaGVkdWxpbmc/OiBNb2RlbC5UcmFpdENvbnZlcmdlU2NoZWR1bGluZ1xufSk6IFN0YXRlVHJhaXRFbnRyeTxTLCBQPiA9PlxuICAoe1xuICAgIGZpZWxkUGF0aDogdW5kZWZpbmVkIGFzIHVua25vd24gYXMgUCxcbiAgICBraW5kOiAnbGluaycsXG4gICAgbWV0YTogeyAuLi5tZXRhLCAuLi4obWV0YS5zY2hlZHVsaW5nID8geyBzY2hlZHVsaW5nOiBtZXRhLnNjaGVkdWxpbmcgfSA6IHt9KSB9LFxuICB9KSBhcyBTdGF0ZVRyYWl0RW50cnk8UywgUD5cblxuLyoqXG4gKiBTdGF0ZVRyYWl0LmJ1aWxkXHVGRjFBXG4gKiAtIFx1NUMwNiBTcGVjIFx1NUY1Mlx1NEUwMFx1NTMxNlx1NEUzQVx1NTNFRlx1NjI2N1x1ODg0QyBQcm9ncmFtXHVGRjA4XHU1NDJCIEdyYXBoL1BsYW5cdUZGMDlcdUZGMUJcbiAqIC0gRFNMIFx1NUM0Mlx1NEUwRSBidWlsZCBcdTVDNDJcdTc2ODRcdTdFQTZcdTY3NUZcdTRFRTUgYnVpbGQgXHU0RTNBXHU2NzAwXHU3RUM4XHU4OEMxXHU1MUIzXHVGRjA4XHU0RjhCXHU1OTgyXHU1RjNBXHU1MjM2XHU2NjNFXHU1RjBGIGRlcHNcdUZGMDlcdTMwMDJcbiAqL1xuZXhwb3J0IGNvbnN0IGJ1aWxkID0gPFMgZXh0ZW5kcyBvYmplY3Q+KFxuICBzdGF0ZVNjaGVtYTogU2NoZW1hLlNjaGVtYTxTLCBhbnk+LFxuICBzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPixcbik6IFN0YXRlVHJhaXRQcm9ncmFtPFM+ID0+IEludGVybmFsQnVpbGQuYnVpbGQoc3RhdGVTY2hlbWEsIHNwZWMpXG5cbi8qKlxuICogU3RhdGVUcmFpdC5pbnN0YWxsXHVGRjFBXG4gKiAtIFx1NTcyOFx1N0VEOVx1NUI5QSBCb3VuZCBBUEkgXHU0RTBBXHU1Qjg5XHU4OEM1IFByb2dyYW0gXHU2M0NGXHU4RkYwXHU3Njg0XHU4ODRDXHU0RTNBXHVGRjA4Y29tcHV0ZWQvbGluay9zb3VyY2UvY2hlY2sgXHU3QjQ5XHVGRjA5XHVGRjFCXG4gKiAtIFx1NkJDRlx1NEUyQSBQbGFuU3RlcCBcdTVCRjlcdTVFOTRcdTRFMDBcdTRFMkFcdTk1N0ZcdTc1MUZcdTU0N0RcdTU0NjhcdTY3MUYgRWZmZWN0XHVGRjBDXHU1RTc2XHU2MzAyXHU4RjdEXHU1MjMwIFJ1bnRpbWUgU2NvcGVcdTMwMDJcbiAqL1xuZXhwb3J0IGNvbnN0IGluc3RhbGwgPSA8UyBleHRlbmRzIG9iamVjdD4oXG4gIGJvdW5kOiBCb3VuZEFwaTxhbnksIGFueT4sXG4gIHByb2dyYW06IFN0YXRlVHJhaXRQcm9ncmFtPFM+LFxuKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgYW55PiA9PiBJbnRlcm5hbEluc3RhbGwuaW5zdGFsbChib3VuZCwgcHJvZ3JhbSlcblxuLyoqXG4gKiBTdGF0ZVRyYWl0LmV4cG9ydFN0YXRpY0lyXHVGRjFBXG4gKiAtIFx1NUJGQ1x1NTFGQVx1NjcwMFx1NUMwRiBTdGF0aWMgSVJcdUZGMDhcdTVCRjlcdTlGNTAgMDA5IFx1NzY4NCBjYW5vbmljYWwgRmllbGRQYXRoIFx1N0VBNlx1Njc1Rlx1RkYwOVx1RkYwQ1x1NEY5QiBEZXZ0b29scy9cdTVCRjlcdTlGNTBcdTVCOUVcdTlBOENcdTVCQTRcdTZEODhcdThEMzlcdUZGMUJcbiAqIC0gXHU4RkQ0XHU1NkRFXHU1MDNDXHU1RkM1XHU5ODdCXHU1M0VGIEpTT04uc3RyaW5naWZ5XHVGRjA4XHU3NTI4XHU0RThFXHU4QkMxXHU2MzZFXHU1MzA1L1x1NTZERVx1NjUzRVx1OTRGRVx1OERFRlx1RkYwOVx1MzAwMlxuICovXG5leHBvcnQgdHlwZSBTdGF0aWNJciA9IEludGVybmFsSXIuU3RhdGljSXJcblxuZXhwb3J0IGNvbnN0IGV4cG9ydFN0YXRpY0lyID0gKFxuICBwcm9ncmFtOiBTdGF0ZVRyYWl0UHJvZ3JhbTxhbnk+LFxuICBtb2R1bGVJZDogc3RyaW5nLFxuICBvcHRpb25zPzoge1xuICAgIHJlYWRvbmx5IHZlcnNpb24/OiBzdHJpbmdcbiAgfSxcbik6IFN0YXRpY0lyID0+XG4gIEludGVybmFsSXIuZXhwb3J0U3RhdGljSXIoe1xuICAgIHByb2dyYW0sXG4gICAgbW9kdWxlSWQsXG4gICAgdmVyc2lvbjogb3B0aW9ucz8udmVyc2lvbixcbiAgfSlcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE4QkEsSUFBTSxvQkFBb0IsQ0FBQyxVQUF3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
|