@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,836 @@
|
|
|
1
|
+
// @logix/core subpath bundles for @logix/sandbox
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
exportStaticIr
|
|
5
|
+
} from "./chunk-QGIM3FQK.js";
|
|
6
|
+
import {
|
|
7
|
+
installSourceRefresh
|
|
8
|
+
} from "./chunk-S3KBAE5Z.js";
|
|
9
|
+
import {
|
|
10
|
+
getAtPath
|
|
11
|
+
} from "./chunk-67RVISUC.js";
|
|
12
|
+
import {
|
|
13
|
+
compareFieldPath,
|
|
14
|
+
getFieldPathId,
|
|
15
|
+
makeFieldPathIdRegistry,
|
|
16
|
+
normalizeFieldPath
|
|
17
|
+
} from "./chunk-5XOBKSOT.js";
|
|
18
|
+
import {
|
|
19
|
+
getBoundInternals
|
|
20
|
+
} from "./chunk-6FKWRVP4.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 = [
|
|
132
|
+
...current.conflicts ?? []
|
|
133
|
+
];
|
|
134
|
+
const push = (conflict) => {
|
|
135
|
+
const exists = conflicts.some(
|
|
136
|
+
(c) => c.origin === conflict.origin && equals(c.meta, conflict.meta)
|
|
137
|
+
);
|
|
138
|
+
if (!exists) conflicts.push(conflict);
|
|
139
|
+
};
|
|
140
|
+
const existingCanonical = existing.canonical === true;
|
|
141
|
+
const incomingCanonical = incoming.meta.canonical === true;
|
|
142
|
+
if (!existingCanonical && incomingCanonical) {
|
|
143
|
+
push({
|
|
144
|
+
origin: current.origin ?? "unknown",
|
|
145
|
+
meta: existing
|
|
146
|
+
});
|
|
147
|
+
return {
|
|
148
|
+
meta: incoming.meta,
|
|
149
|
+
origin: incoming.origin,
|
|
150
|
+
conflicts
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
push({
|
|
154
|
+
origin: incoming.origin,
|
|
155
|
+
meta: incoming.meta
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
meta: existing,
|
|
159
|
+
origin: current.origin ?? incoming.origin,
|
|
160
|
+
conflicts
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// ../logix-core/src/internal/state-trait/model.ts
|
|
165
|
+
var normalizeSpec = (spec) => {
|
|
166
|
+
const entries = [];
|
|
167
|
+
const isNode = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitNode";
|
|
168
|
+
const isList = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitList";
|
|
169
|
+
const joinPath = (prefix, suffix) => {
|
|
170
|
+
if (!prefix) return suffix;
|
|
171
|
+
if (!suffix) return prefix;
|
|
172
|
+
return `${prefix}.${suffix}`;
|
|
173
|
+
};
|
|
174
|
+
const prefixDeps = (deps, prefix) => {
|
|
175
|
+
if (!deps || deps.length === 0) return [];
|
|
176
|
+
return deps.map((d) => prefix ? joinPath(prefix, d) : d);
|
|
177
|
+
};
|
|
178
|
+
const normalizeEntry = (entry, fieldPath, depPrefix) => {
|
|
179
|
+
if (entry.kind === "computed") {
|
|
180
|
+
const meta = entry.meta;
|
|
181
|
+
const rawDeps = meta.deps;
|
|
182
|
+
const deps = rawDeps !== void 0 ? prefixDeps(rawDeps, depPrefix) : void 0;
|
|
183
|
+
return {
|
|
184
|
+
...entry,
|
|
185
|
+
fieldPath,
|
|
186
|
+
meta: { ...meta, deps }
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (entry.kind === "source") {
|
|
190
|
+
const meta = entry.meta;
|
|
191
|
+
const rawDeps = meta.deps;
|
|
192
|
+
const deps = rawDeps !== void 0 ? prefixDeps(rawDeps, depPrefix) : void 0;
|
|
193
|
+
return {
|
|
194
|
+
...entry,
|
|
195
|
+
fieldPath,
|
|
196
|
+
meta: { ...meta, deps, _fieldPath: fieldPath }
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
if (entry.kind === "link") {
|
|
200
|
+
const meta = entry.meta;
|
|
201
|
+
const from2 = prefixDeps([meta.from], depPrefix)[0] ?? meta.from;
|
|
202
|
+
return {
|
|
203
|
+
...entry,
|
|
204
|
+
fieldPath,
|
|
205
|
+
meta: { ...meta, from: from2 }
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
...entry,
|
|
210
|
+
fieldPath
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
const expandNode = (scopeId, joinPrefix, node2, options) => {
|
|
214
|
+
const addEntry = (relativeTarget, raw) => {
|
|
215
|
+
const rel = raw.fieldPath ?? relativeTarget;
|
|
216
|
+
const fieldPath = joinPrefix ? joinPath(joinPrefix, String(rel)) : String(rel);
|
|
217
|
+
entries.push(normalizeEntry(raw, fieldPath, joinPrefix));
|
|
218
|
+
};
|
|
219
|
+
const expandMaybeRecord = (value) => {
|
|
220
|
+
if (!value) return;
|
|
221
|
+
if (typeof value.kind === "string") {
|
|
222
|
+
addEntry("", value);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const record = value;
|
|
226
|
+
for (const key in record) {
|
|
227
|
+
if (!Object.prototype.hasOwnProperty.call(record, key)) continue;
|
|
228
|
+
const entry = record[key];
|
|
229
|
+
if (!entry) continue;
|
|
230
|
+
addEntry(key, entry);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
expandMaybeRecord(node2.computed);
|
|
234
|
+
expandMaybeRecord(node2.source);
|
|
235
|
+
expandMaybeRecord(node2.link);
|
|
236
|
+
if (node2.check) {
|
|
237
|
+
const rules = {};
|
|
238
|
+
const checkDepsPrefix = options?.checkDepsPrefix ?? (joinPrefix.endsWith("[]") ? joinPrefix : "");
|
|
239
|
+
const prefixCheckDeps = (deps) => {
|
|
240
|
+
if (!deps || deps.length === 0) return [];
|
|
241
|
+
return deps.map(
|
|
242
|
+
(d) => d === "" ? scopeId : checkDepsPrefix ? joinPath(checkDepsPrefix, d) : d
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
for (const name of Object.keys(node2.check)) {
|
|
246
|
+
const rule = node2.check[name];
|
|
247
|
+
if (typeof rule === "function") {
|
|
248
|
+
rules[name] = rule;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (rule && typeof rule === "object") {
|
|
252
|
+
const meta = sanitize(rule.meta);
|
|
253
|
+
rules[name] = {
|
|
254
|
+
...rule,
|
|
255
|
+
deps: prefixCheckDeps(rule.deps),
|
|
256
|
+
meta
|
|
257
|
+
};
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
entries.push({
|
|
262
|
+
fieldPath: scopeId,
|
|
263
|
+
kind: "check",
|
|
264
|
+
meta: {
|
|
265
|
+
rules,
|
|
266
|
+
writeback: { kind: "errors" }
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
for (const key in spec) {
|
|
272
|
+
if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
|
|
273
|
+
const raw = spec[key];
|
|
274
|
+
if (!raw) continue;
|
|
275
|
+
if (isList(raw)) {
|
|
276
|
+
const listPath = key;
|
|
277
|
+
if (raw.item) {
|
|
278
|
+
expandNode(`${listPath}[]`, `${listPath}[]`, raw.item);
|
|
279
|
+
}
|
|
280
|
+
if (raw.list) {
|
|
281
|
+
expandNode(listPath, listPath, raw.list, {
|
|
282
|
+
checkDepsPrefix: `${listPath}[]`
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (isNode(raw)) {
|
|
288
|
+
if (key === "$root") {
|
|
289
|
+
expandNode("$root", "", raw);
|
|
290
|
+
} else {
|
|
291
|
+
expandNode(key, key, raw);
|
|
292
|
+
}
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const entry = raw;
|
|
296
|
+
const fieldPath = entry.fieldPath ?? key;
|
|
297
|
+
entries.push(normalizeEntry(entry, String(fieldPath), ""));
|
|
298
|
+
}
|
|
299
|
+
return entries;
|
|
300
|
+
};
|
|
301
|
+
var collectNodeMeta = (spec) => {
|
|
302
|
+
const out = /* @__PURE__ */ new Map();
|
|
303
|
+
const isNode = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitNode";
|
|
304
|
+
const isList = (value) => typeof value === "object" && value !== null && value._tag === "StateTraitList";
|
|
305
|
+
const add = (scopeId, node2) => {
|
|
306
|
+
const meta = sanitize(node2.meta);
|
|
307
|
+
if (meta) out.set(scopeId, meta);
|
|
308
|
+
};
|
|
309
|
+
for (const key in spec) {
|
|
310
|
+
if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
|
|
311
|
+
const raw = spec[key];
|
|
312
|
+
if (!raw) continue;
|
|
313
|
+
if (isList(raw)) {
|
|
314
|
+
const listPath = key;
|
|
315
|
+
if (raw.item) add(`${listPath}[]`, raw.item);
|
|
316
|
+
if (raw.list) add(listPath, raw.list);
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (isNode(raw)) {
|
|
320
|
+
if (key === "$root") add("$root", raw);
|
|
321
|
+
else add(key, raw);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return out;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// ../logix-core/src/internal/state-trait/build.ts
|
|
329
|
+
var nowPerf = () => typeof globalThis.performance !== "undefined" && typeof globalThis.performance.now === "function" ? globalThis.performance.now() : Date.now();
|
|
330
|
+
var getConvergeWriterDeps = (entry) => {
|
|
331
|
+
if (entry.kind === "computed") {
|
|
332
|
+
return entry.meta?.deps ?? [];
|
|
333
|
+
}
|
|
334
|
+
return [entry.meta.from];
|
|
335
|
+
};
|
|
336
|
+
var computeConvergeTopoOrder = (writers) => {
|
|
337
|
+
const writerByPath = /* @__PURE__ */ new Map();
|
|
338
|
+
for (const entry of writers) {
|
|
339
|
+
const existing = writerByPath.get(entry.fieldPath);
|
|
340
|
+
if (existing) {
|
|
341
|
+
return {
|
|
342
|
+
order: [],
|
|
343
|
+
configError: {
|
|
344
|
+
code: "MULTIPLE_WRITERS",
|
|
345
|
+
message: `[StateTrait.converge] Multiple writers for field "${entry.fieldPath}" (${existing.kind} + ${entry.kind}).`,
|
|
346
|
+
fields: [entry.fieldPath]
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
writerByPath.set(entry.fieldPath, entry);
|
|
351
|
+
}
|
|
352
|
+
const nodes = /* @__PURE__ */ new Set();
|
|
353
|
+
for (const entry of writers) {
|
|
354
|
+
nodes.add(entry.fieldPath);
|
|
355
|
+
}
|
|
356
|
+
const indegree = /* @__PURE__ */ new Map();
|
|
357
|
+
const forward = /* @__PURE__ */ new Map();
|
|
358
|
+
for (const node2 of nodes) {
|
|
359
|
+
indegree.set(node2, 0);
|
|
360
|
+
forward.set(node2, []);
|
|
361
|
+
}
|
|
362
|
+
for (const entry of writers) {
|
|
363
|
+
const to = entry.fieldPath;
|
|
364
|
+
const deps = getConvergeWriterDeps(entry);
|
|
365
|
+
for (const dep of deps) {
|
|
366
|
+
if (!nodes.has(dep)) continue;
|
|
367
|
+
forward.get(dep).push(to);
|
|
368
|
+
indegree.set(to, (indegree.get(to) ?? 0) + 1);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const queue = [];
|
|
372
|
+
for (const [node2, deg] of indegree.entries()) {
|
|
373
|
+
if (deg === 0) queue.push(node2);
|
|
374
|
+
}
|
|
375
|
+
const order = [];
|
|
376
|
+
while (queue.length) {
|
|
377
|
+
const n = queue.shift();
|
|
378
|
+
order.push(n);
|
|
379
|
+
const outs = forward.get(n);
|
|
380
|
+
for (const to of outs) {
|
|
381
|
+
const next = (indegree.get(to) ?? 0) - 1;
|
|
382
|
+
indegree.set(to, next);
|
|
383
|
+
if (next === 0) queue.push(to);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (order.length !== nodes.size) {
|
|
387
|
+
const remaining = Array.from(nodes).filter((n) => !order.includes(n));
|
|
388
|
+
return {
|
|
389
|
+
order: [],
|
|
390
|
+
configError: {
|
|
391
|
+
code: "CYCLE_DETECTED",
|
|
392
|
+
message: `[StateTrait.converge] Cycle detected in computed/link graph: ${remaining.join(", ")}`,
|
|
393
|
+
fields: remaining
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
return { order };
|
|
398
|
+
};
|
|
399
|
+
var buildConvergeIr = (entries) => {
|
|
400
|
+
const startedAt = nowPerf();
|
|
401
|
+
const generation = 0;
|
|
402
|
+
const writers = entries.filter(
|
|
403
|
+
(e) => e.kind === "computed" || e.kind === "link"
|
|
404
|
+
);
|
|
405
|
+
const writersKey = writers.map((entry) => `${entry.kind}:${entry.fieldPath}`).sort().join("|");
|
|
406
|
+
const depsKey = writers.map((entry) => {
|
|
407
|
+
const deps = getConvergeWriterDeps(entry).slice().sort().join(",");
|
|
408
|
+
return `${entry.kind}:${entry.fieldPath}=>${deps}`;
|
|
409
|
+
}).sort().join("|");
|
|
410
|
+
const writerByPath = /* @__PURE__ */ new Map();
|
|
411
|
+
for (const entry of writers) {
|
|
412
|
+
writerByPath.set(entry.fieldPath, entry);
|
|
413
|
+
}
|
|
414
|
+
const topo = writers.length > 0 ? computeConvergeTopoOrder(writers) : { order: [] };
|
|
415
|
+
const stepsById = topo.configError ? [] : topo.order.map((path) => writerByPath.get(path));
|
|
416
|
+
const fieldPathTable = /* @__PURE__ */ new Map();
|
|
417
|
+
const addPath = (path) => {
|
|
418
|
+
for (let i = 1; i <= path.length; i++) {
|
|
419
|
+
const prefix = path.slice(0, i);
|
|
420
|
+
const key = JSON.stringify(prefix);
|
|
421
|
+
if (!fieldPathTable.has(key)) fieldPathTable.set(key, prefix);
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
for (const entry of writers) {
|
|
425
|
+
const out = normalizeFieldPath(entry.fieldPath);
|
|
426
|
+
if (out) addPath(out);
|
|
427
|
+
for (const dep of getConvergeWriterDeps(entry)) {
|
|
428
|
+
const depPath = normalizeFieldPath(dep);
|
|
429
|
+
if (depPath) addPath(depPath);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
const fieldPaths = Array.from(fieldPathTable.values()).sort(compareFieldPath);
|
|
433
|
+
const fieldPathIdRegistry = makeFieldPathIdRegistry(fieldPaths);
|
|
434
|
+
const stepOutFieldPathIdByStepId = [];
|
|
435
|
+
const stepDepsFieldPathIdsByStepId = [];
|
|
436
|
+
for (const entry of stepsById) {
|
|
437
|
+
const out = normalizeFieldPath(entry.fieldPath);
|
|
438
|
+
const outId = out != null ? getFieldPathId(fieldPathIdRegistry, out) : void 0;
|
|
439
|
+
if (outId == null) {
|
|
440
|
+
throw new Error(
|
|
441
|
+
`[StateTrait.build] Failed to map converge output fieldPath "${entry.fieldPath}" to FieldPathId.`
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
const depIds = [];
|
|
445
|
+
for (const dep of getConvergeWriterDeps(entry)) {
|
|
446
|
+
const depPath = normalizeFieldPath(dep);
|
|
447
|
+
if (!depPath) continue;
|
|
448
|
+
const depId = getFieldPathId(fieldPathIdRegistry, depPath);
|
|
449
|
+
if (depId != null) depIds.push(depId);
|
|
450
|
+
}
|
|
451
|
+
stepOutFieldPathIdByStepId.push(outId);
|
|
452
|
+
stepDepsFieldPathIdsByStepId.push(depIds);
|
|
453
|
+
}
|
|
454
|
+
const topoOrder = stepsById.map((_, i) => i);
|
|
455
|
+
const buildDurationMs = Math.max(0, nowPerf() - startedAt);
|
|
456
|
+
return {
|
|
457
|
+
generation,
|
|
458
|
+
writersKey,
|
|
459
|
+
depsKey,
|
|
460
|
+
fieldPaths,
|
|
461
|
+
fieldPathIdRegistry,
|
|
462
|
+
...topo.configError ? { configError: topo.configError } : null,
|
|
463
|
+
stepsById,
|
|
464
|
+
stepOutFieldPathIdByStepId,
|
|
465
|
+
stepDepsFieldPathIdsByStepId,
|
|
466
|
+
topoOrder,
|
|
467
|
+
buildDurationMs
|
|
468
|
+
};
|
|
469
|
+
};
|
|
470
|
+
var toFieldTrait = (entry) => {
|
|
471
|
+
const deps = [];
|
|
472
|
+
if (entry.kind === "computed") {
|
|
473
|
+
const meta = entry.meta;
|
|
474
|
+
const list2 = meta.deps;
|
|
475
|
+
if (list2) deps.push(...list2);
|
|
476
|
+
} else if (entry.kind === "source") {
|
|
477
|
+
const meta = entry.meta;
|
|
478
|
+
const list2 = meta.deps;
|
|
479
|
+
if (list2) deps.push(...list2);
|
|
480
|
+
} else if (entry.kind === "link") {
|
|
481
|
+
deps.push(entry.meta.from);
|
|
482
|
+
} else if (entry.kind === "check") {
|
|
483
|
+
const meta = entry.meta;
|
|
484
|
+
const rules = meta?.rules ?? {};
|
|
485
|
+
for (const name of Object.keys(rules)) {
|
|
486
|
+
const rule = rules[name];
|
|
487
|
+
if (rule && typeof rule === "object") {
|
|
488
|
+
const list2 = rule.deps;
|
|
489
|
+
if (list2) deps.push(...list2);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
fieldId: entry.fieldPath,
|
|
495
|
+
kind: entry.kind,
|
|
496
|
+
// meta 在运行时保持与 Entry.meta 一致,便于 install 直接复用。
|
|
497
|
+
meta: entry.meta,
|
|
498
|
+
deps
|
|
499
|
+
};
|
|
500
|
+
};
|
|
501
|
+
var buildGraph = (entries, nodeMetaByFieldPath) => {
|
|
502
|
+
const fieldMap = /* @__PURE__ */ new Map();
|
|
503
|
+
const nodes = [];
|
|
504
|
+
const edges = [];
|
|
505
|
+
const resourcesById = /* @__PURE__ */ new Map();
|
|
506
|
+
const planSteps = [];
|
|
507
|
+
const ensureField = (fieldPath) => {
|
|
508
|
+
let field = fieldMap.get(fieldPath);
|
|
509
|
+
if (!field) {
|
|
510
|
+
field = {
|
|
511
|
+
id: fieldPath,
|
|
512
|
+
path: fieldPath,
|
|
513
|
+
traits: []
|
|
514
|
+
};
|
|
515
|
+
fieldMap.set(fieldPath, field);
|
|
516
|
+
}
|
|
517
|
+
return field;
|
|
518
|
+
};
|
|
519
|
+
for (const entry of entries) {
|
|
520
|
+
const fieldPath = entry.fieldPath;
|
|
521
|
+
const field = ensureField(fieldPath);
|
|
522
|
+
const trait = toFieldTrait(entry);
|
|
523
|
+
field.traits.push(trait);
|
|
524
|
+
if (entry.kind === "computed") {
|
|
525
|
+
const stepId = `computed:${fieldPath}`;
|
|
526
|
+
planSteps.push({
|
|
527
|
+
id: stepId,
|
|
528
|
+
kind: "computed-update",
|
|
529
|
+
targetFieldPath: fieldPath
|
|
530
|
+
// 说明:当前版本不静态分析 computed 依赖字段,sourceFieldPaths 留空。
|
|
531
|
+
});
|
|
532
|
+
const deps = entry.meta.deps;
|
|
533
|
+
if (deps) {
|
|
534
|
+
for (const dep of deps) {
|
|
535
|
+
ensureField(dep);
|
|
536
|
+
edges.push({
|
|
537
|
+
id: `computed:${dep}->${fieldPath}`,
|
|
538
|
+
from: dep,
|
|
539
|
+
to: fieldPath,
|
|
540
|
+
kind: "computed"
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
} else if (entry.kind === "link") {
|
|
545
|
+
const from2 = entry.meta.from;
|
|
546
|
+
ensureField(from2);
|
|
547
|
+
const edgeId = `link:${from2}->${fieldPath}`;
|
|
548
|
+
edges.push({
|
|
549
|
+
id: edgeId,
|
|
550
|
+
from: from2,
|
|
551
|
+
to: fieldPath,
|
|
552
|
+
kind: "link"
|
|
553
|
+
});
|
|
554
|
+
planSteps.push({
|
|
555
|
+
id: `link:${fieldPath}`,
|
|
556
|
+
kind: "link-propagate",
|
|
557
|
+
targetFieldPath: fieldPath,
|
|
558
|
+
sourceFieldPaths: [from2],
|
|
559
|
+
debugInfo: {
|
|
560
|
+
graphEdgeId: edgeId
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
} else if (entry.kind === "source") {
|
|
564
|
+
const resourceId = entry.meta.resource;
|
|
565
|
+
const resourceMeta = sanitize(entry.meta.meta);
|
|
566
|
+
const existing = resourcesById.get(resourceId);
|
|
567
|
+
if (existing) {
|
|
568
|
+
const ownerFields = [...existing.ownerFields, fieldPath];
|
|
569
|
+
let meta = existing.meta;
|
|
570
|
+
let metaOrigin = existing.metaOrigin;
|
|
571
|
+
let metaConflicts = existing.metaConflicts;
|
|
572
|
+
if (resourceMeta) {
|
|
573
|
+
const merged = mergeCanonical(
|
|
574
|
+
{ meta, origin: metaOrigin, conflicts: metaConflicts },
|
|
575
|
+
{ origin: fieldPath, meta: resourceMeta }
|
|
576
|
+
);
|
|
577
|
+
meta = merged.meta;
|
|
578
|
+
metaOrigin = merged.origin;
|
|
579
|
+
metaConflicts = merged.conflicts;
|
|
580
|
+
}
|
|
581
|
+
resourcesById.set(resourceId, {
|
|
582
|
+
...existing,
|
|
583
|
+
ownerFields,
|
|
584
|
+
meta,
|
|
585
|
+
metaOrigin,
|
|
586
|
+
metaConflicts
|
|
587
|
+
});
|
|
588
|
+
} else {
|
|
589
|
+
resourcesById.set(resourceId, {
|
|
590
|
+
resourceId,
|
|
591
|
+
// 暂时使用简单的标识字符串,后续可根据 key 规则进一步结构化。
|
|
592
|
+
keySelector: `StateTrait.source@${fieldPath}`,
|
|
593
|
+
ownerFields: [fieldPath],
|
|
594
|
+
meta: resourceMeta,
|
|
595
|
+
metaOrigin: resourceMeta ? fieldPath : void 0
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
planSteps.push({
|
|
599
|
+
id: `source:${fieldPath}`,
|
|
600
|
+
kind: "source-refresh",
|
|
601
|
+
targetFieldPath: fieldPath,
|
|
602
|
+
resourceId,
|
|
603
|
+
keySelectorId: `StateTrait.source@${fieldPath}`
|
|
604
|
+
});
|
|
605
|
+
const deps = entry.meta.deps;
|
|
606
|
+
if (deps) {
|
|
607
|
+
for (const dep of deps) {
|
|
608
|
+
ensureField(dep);
|
|
609
|
+
edges.push({
|
|
610
|
+
id: `source-dep:${dep}->${fieldPath}`,
|
|
611
|
+
from: dep,
|
|
612
|
+
to: fieldPath,
|
|
613
|
+
kind: "source-dep"
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
} else if (entry.kind === "check") {
|
|
618
|
+
planSteps.push({
|
|
619
|
+
id: `check:${fieldPath}`,
|
|
620
|
+
kind: "check-validate",
|
|
621
|
+
targetFieldPath: fieldPath
|
|
622
|
+
});
|
|
623
|
+
if (trait.deps.length > 0) {
|
|
624
|
+
for (const dep of trait.deps) {
|
|
625
|
+
ensureField(dep);
|
|
626
|
+
edges.push({
|
|
627
|
+
id: `check-dep:${dep}->${fieldPath}`,
|
|
628
|
+
from: dep,
|
|
629
|
+
to: fieldPath,
|
|
630
|
+
kind: "check-dep"
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
for (const field of fieldMap.values()) {
|
|
637
|
+
nodes.push({
|
|
638
|
+
id: field.id,
|
|
639
|
+
field,
|
|
640
|
+
traits: field.traits,
|
|
641
|
+
meta: nodeMetaByFieldPath.get(field.id)
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
const graph = {
|
|
645
|
+
_tag: "StateTraitGraph",
|
|
646
|
+
nodes,
|
|
647
|
+
edges,
|
|
648
|
+
resources: Array.from(resourcesById.values())
|
|
649
|
+
};
|
|
650
|
+
const plan = {
|
|
651
|
+
_tag: "StateTraitPlan",
|
|
652
|
+
steps: planSteps
|
|
653
|
+
};
|
|
654
|
+
return { graph, plan };
|
|
655
|
+
};
|
|
656
|
+
var assertNoLinkCycles = (edges) => {
|
|
657
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
658
|
+
for (const edge of edges) {
|
|
659
|
+
if (edge.kind !== "link") continue;
|
|
660
|
+
const list2 = adjacency.get(edge.from) ?? [];
|
|
661
|
+
list2.push(edge.to);
|
|
662
|
+
adjacency.set(edge.from, list2);
|
|
663
|
+
}
|
|
664
|
+
const visited = /* @__PURE__ */ new Set();
|
|
665
|
+
const stack = /* @__PURE__ */ new Set();
|
|
666
|
+
const dfs = (node2) => {
|
|
667
|
+
if (stack.has(node2)) {
|
|
668
|
+
throw new Error(
|
|
669
|
+
`[StateTrait.build] link cycle detected at field "${node2}". Please check link traits for circular dependencies.`
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
if (visited.has(node2)) return;
|
|
673
|
+
visited.add(node2);
|
|
674
|
+
stack.add(node2);
|
|
675
|
+
const nexts = adjacency.get(node2);
|
|
676
|
+
if (nexts) {
|
|
677
|
+
for (const to of nexts) {
|
|
678
|
+
dfs(to);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
stack.delete(node2);
|
|
682
|
+
};
|
|
683
|
+
for (const node2 of adjacency.keys()) {
|
|
684
|
+
if (!visited.has(node2)) {
|
|
685
|
+
dfs(node2);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
var build = (stateSchema, spec) => {
|
|
690
|
+
const entries = normalizeSpec(spec);
|
|
691
|
+
const nodeMetaByFieldPath = collectNodeMeta(spec);
|
|
692
|
+
for (const entry of entries) {
|
|
693
|
+
if (entry.kind === "computed") {
|
|
694
|
+
const deps = entry.meta.deps;
|
|
695
|
+
if (deps === void 0) {
|
|
696
|
+
throw new Error(
|
|
697
|
+
`[StateTrait.build] Missing explicit deps for computed "${entry.fieldPath}". Please use StateTrait.computed({ deps: [...], get: ... }).`
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
if (entry.kind === "source") {
|
|
702
|
+
const deps = entry.meta.deps;
|
|
703
|
+
if (deps === void 0) {
|
|
704
|
+
throw new Error(
|
|
705
|
+
`[StateTrait.build] Missing explicit deps for source "${entry.fieldPath}". Please provide meta.deps for StateTrait.source({ deps: [...], ... }).`
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
if (entry.kind === "check") {
|
|
710
|
+
const rules = entry.meta?.rules ?? {};
|
|
711
|
+
for (const name of Object.keys(rules)) {
|
|
712
|
+
const rule = rules[name];
|
|
713
|
+
if (typeof rule === "function" || !rule || typeof rule !== "object") {
|
|
714
|
+
throw new Error(
|
|
715
|
+
`[StateTrait.build] Missing explicit deps for check "${entry.fieldPath}" rule "${name}". Please use { deps: [...], validate: ... } form.`
|
|
716
|
+
);
|
|
717
|
+
}
|
|
718
|
+
if (rule.deps === void 0) {
|
|
719
|
+
throw new Error(
|
|
720
|
+
`[StateTrait.build] Missing explicit deps for check "${entry.fieldPath}" rule "${name}". Please provide deps: [...].`
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
const { graph, plan } = buildGraph(entries, nodeMetaByFieldPath);
|
|
727
|
+
assertNoLinkCycles(graph.edges);
|
|
728
|
+
return {
|
|
729
|
+
stateSchema,
|
|
730
|
+
spec,
|
|
731
|
+
entries,
|
|
732
|
+
graph,
|
|
733
|
+
plan,
|
|
734
|
+
convergeIr: buildConvergeIr(entries)
|
|
735
|
+
};
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
// ../logix-core/src/internal/state-trait/install.ts
|
|
739
|
+
import { Effect } from "../effect.js";
|
|
740
|
+
var buildEntryIndex = (entries) => {
|
|
741
|
+
const index = /* @__PURE__ */ new Map();
|
|
742
|
+
for (const entry of entries) {
|
|
743
|
+
const list2 = index.get(entry.fieldPath) ?? [];
|
|
744
|
+
list2.push(entry);
|
|
745
|
+
index.set(entry.fieldPath, list2);
|
|
746
|
+
}
|
|
747
|
+
return index;
|
|
748
|
+
};
|
|
749
|
+
var install = (bound, program) => {
|
|
750
|
+
try {
|
|
751
|
+
const internals = getBoundInternals(bound);
|
|
752
|
+
internals.traits.registerStateTraitProgram(program, {
|
|
753
|
+
bumpReason: "logic_installed"
|
|
754
|
+
});
|
|
755
|
+
} catch {
|
|
756
|
+
}
|
|
757
|
+
const entryIndex = buildEntryIndex(program.entries);
|
|
758
|
+
const installStep = (step) => {
|
|
759
|
+
if (!step.targetFieldPath) {
|
|
760
|
+
return Effect.void;
|
|
761
|
+
}
|
|
762
|
+
if (step.kind !== "source-refresh") {
|
|
763
|
+
return Effect.void;
|
|
764
|
+
}
|
|
765
|
+
const candidates = entryIndex.get(step.targetFieldPath);
|
|
766
|
+
if (!candidates || candidates.length === 0) {
|
|
767
|
+
return Effect.void;
|
|
768
|
+
}
|
|
769
|
+
const entry = candidates.find((e) => e.kind === "source");
|
|
770
|
+
if (!entry) {
|
|
771
|
+
return Effect.void;
|
|
772
|
+
}
|
|
773
|
+
return installSourceRefresh(
|
|
774
|
+
bound,
|
|
775
|
+
step,
|
|
776
|
+
entry
|
|
777
|
+
);
|
|
778
|
+
};
|
|
779
|
+
return Effect.forEach(program.plan.steps, (step) => installStep(step)).pipe(Effect.asVoid);
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
// ../logix-core/src/StateTrait.ts
|
|
783
|
+
var $root = "$root";
|
|
784
|
+
var from = (_schema) => (spec) => spec;
|
|
785
|
+
var node = (spec) => ({
|
|
786
|
+
_tag: "StateTraitNode",
|
|
787
|
+
...spec
|
|
788
|
+
});
|
|
789
|
+
var list = (spec) => ({
|
|
790
|
+
_tag: "StateTraitList",
|
|
791
|
+
...spec
|
|
792
|
+
});
|
|
793
|
+
var computed = (input) => {
|
|
794
|
+
const derive = (state) => {
|
|
795
|
+
const args = input.deps.map(
|
|
796
|
+
(dep) => getAtPath(state, dep)
|
|
797
|
+
);
|
|
798
|
+
return input.get(...args);
|
|
799
|
+
};
|
|
800
|
+
return {
|
|
801
|
+
fieldPath: void 0,
|
|
802
|
+
kind: "computed",
|
|
803
|
+
meta: { deps: input.deps, derive, equals: input.equals }
|
|
804
|
+
};
|
|
805
|
+
};
|
|
806
|
+
var source = (meta) => ({
|
|
807
|
+
fieldPath: void 0,
|
|
808
|
+
kind: "source",
|
|
809
|
+
meta
|
|
810
|
+
});
|
|
811
|
+
var link = (meta) => ({
|
|
812
|
+
fieldPath: void 0,
|
|
813
|
+
kind: "link",
|
|
814
|
+
meta
|
|
815
|
+
});
|
|
816
|
+
var build2 = (stateSchema, spec) => build(stateSchema, spec);
|
|
817
|
+
var install2 = (bound, program) => install(bound, program);
|
|
818
|
+
var exportStaticIr2 = (program, moduleId, options) => exportStaticIr({
|
|
819
|
+
program,
|
|
820
|
+
moduleId,
|
|
821
|
+
version: options?.version
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
export {
|
|
825
|
+
$root,
|
|
826
|
+
from,
|
|
827
|
+
node,
|
|
828
|
+
list,
|
|
829
|
+
computed,
|
|
830
|
+
source,
|
|
831
|
+
link,
|
|
832
|
+
build2 as build,
|
|
833
|
+
install2 as install,
|
|
834
|
+
exportStaticIr2 as exportStaticIr
|
|
835
|
+
};
|
|
836
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvbWV0YS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9zdGF0ZS10cmFpdC9tb2RlbC50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9zdGF0ZS10cmFpdC9idWlsZC50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9zdGF0ZS10cmFpdC9pbnN0YWxsLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL1N0YXRlVHJhaXQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImV4cG9ydCB0eXBlIFRyYWl0TWV0YSA9IFJlYWRvbmx5PHtcbiAgcmVhZG9ubHkgbGFiZWw/OiBzdHJpbmdcbiAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmdcbiAgcmVhZG9ubHkgdGFncz86IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICByZWFkb25seSBncm91cD86IHN0cmluZ1xuICByZWFkb25seSBkb2NzVXJsPzogc3RyaW5nXG4gIHJlYWRvbmx5IGNhY2hlR3JvdXA/OiBzdHJpbmdcbiAgLyoqXG4gICAqIFx1NjI2OVx1NUM1NVx1NkNFOFx1ODlFM1x1NEY0RFx1RkYxQVx1NEVDNVx1NjNBNVx1NTNENyBgeC0qYCBrZXlcdUZGMDhcdTc1MjhcdTRFOEUgUGhhbnRvbSBTb3VyY2UgLyBEcmlmdCBEZXRlY3Rpb24gXHU3QjQ5XHU4MEZEXHU1MjlCXHU3Njg0XHU5NTFBXHU3MEI5XHVGRjA5XHUzMDAyXG4gICAqXG4gICAqIFx1N0VBNlx1Njc1Rlx1RkYxQVxuICAgKiAtIFx1NUZDNVx1OTg3Qlx1NTNFRlx1NUU4Rlx1NTIxN1x1NTMxNlx1RkYwOEpTT04gXHU1MDNDXHVGRjA5XHVGRjFCXG4gICAqIC0gXHU1RkM1XHU5ODdCIFNsaW1cdUZGMDhcdTVFRkFcdThCQUVcdTUzRUFcdTY1M0VcdTVDMTFcdTkxQ0ZcdTUxNzNcdTk1MkVcdTYzRDBcdTc5M0FcdUZGMENcdTRFMERcdTg5ODFcdTU4NUVcdTU5MjdcdTVCRjlcdThDNjFcdUZGMDlcdTMwMDJcbiAgICovXG4gIHJlYWRvbmx5IGFubm90YXRpb25zPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgSnNvblZhbHVlPj5cbiAgLyoqXG4gICAqIFx1OEJFRFx1NEU0OVx1NjNEMFx1NzkzQVx1RkYxQVx1NUY1M1x1NTQwQ1x1NEUwMFx1NUI5RVx1NEY1M1x1RkYwOFx1NEY4Qlx1NTk4Mlx1NTQwQ1x1NEUwMCByZXNvdXJjZUlkXHVGRjA5XHU1MUZBXHU3M0IwXHU1OTFBXHU1OTA0IG1ldGEgXHU1OEYwXHU2NjBFXHU0RTE0XHU0RTBEXHU0RTAwXHU4MUY0XHU2NUY2XHVGRjBDXG4gICAqIGNhbm9uaWNhbD10cnVlIFx1NzY4NFx1NThGMFx1NjYwRVx1NEYxOFx1NTE0OFx1NjIxMFx1NEUzQVx1MjAxQ1x1NUM1NVx1NzkzQVx1NzUyOCBjYW5vbmljYWxcdTIwMURcdUZGMUJcdTUxNzZcdTRFRDZcdTU4RjBcdTY2MEVcdTRGMUFcdThCQjBcdTVGNTVcdTRFM0EgY29uZmxpY3RzXHUzMDAyXG4gICAqL1xuICByZWFkb25seSBjYW5vbmljYWw/OiBib29sZWFuXG59PlxuXG5leHBvcnQgdHlwZSBUcmFpdE1ldGFDb25mbGljdCA9IFJlYWRvbmx5PHtcbiAgcmVhZG9ubHkgb3JpZ2luOiBzdHJpbmdcbiAgcmVhZG9ubHkgbWV0YTogVHJhaXRNZXRhXG59PlxuXG5leHBvcnQgdHlwZSBKc29uUHJpbWl0aXZlID0gc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGxcbmV4cG9ydCB0eXBlIEpzb25WYWx1ZSA9XG4gIHwgSnNvblByaW1pdGl2ZVxuICB8IFJlYWRvbmx5QXJyYXk8SnNvblZhbHVlPlxuICB8IHsgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogSnNvblZhbHVlIH1cblxuY29uc3QgdW5pcVNvcnRlZFN0cmluZ3MgPSAoaW5wdXQ6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPik6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IHNldCA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gIGZvciAoY29uc3QgaXRlbSBvZiBpbnB1dCkge1xuICAgIGNvbnN0IHYgPSBpdGVtLnRyaW0oKVxuICAgIGlmICghdikgY29udGludWVcbiAgICBzZXQuYWRkKHYpXG4gIH1cbiAgcmV0dXJuIEFycmF5LmZyb20oc2V0KS5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG59XG5cbmNvbnN0IGlzUGxhaW5SZWNvcmQgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PlxuICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpXG5cbmNvbnN0IHNhbml0aXplSnNvblZhbHVlID0gKFxuICBpbnB1dDogdW5rbm93bixcbiAgZGVwdGg6IG51bWJlcixcbik6IEpzb25WYWx1ZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChpbnB1dCA9PT0gbnVsbCkgcmV0dXJuIG51bGxcblxuICBpZiAodHlwZW9mIGlucHV0ID09PSBcInN0cmluZ1wiKSByZXR1cm4gaW5wdXRcbiAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gXCJib29sZWFuXCIpIHJldHVybiBpbnB1dFxuICBpZiAodHlwZW9mIGlucHV0ID09PSBcIm51bWJlclwiKSB7XG4gICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShpbnB1dCkgPyBpbnB1dCA6IHVuZGVmaW5lZFxuICB9XG5cbiAgaWYgKGRlcHRoID49IDYpIHJldHVybiB1bmRlZmluZWRcblxuICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICBjb25zdCBvdXQ6IEFycmF5PEpzb25WYWx1ZT4gPSBbXVxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpbnB1dCkge1xuICAgICAgY29uc3QgdiA9IHNhbml0aXplSnNvblZhbHVlKGl0ZW0sIGRlcHRoICsgMSlcbiAgICAgIGlmICh2ICE9PSB1bmRlZmluZWQpIG91dC5wdXNoKHYpXG4gICAgfVxuICAgIHJldHVybiBvdXRcbiAgfVxuXG4gIGlmIChpc1BsYWluUmVjb3JkKGlucHV0KSkge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhpbnB1dCkuc29ydCgpXG4gICAgY29uc3Qgb3V0OiBSZWNvcmQ8c3RyaW5nLCBKc29uVmFsdWU+ID0ge31cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICBjb25zdCB2ID0gc2FuaXRpemVKc29uVmFsdWUoaW5wdXRba2V5XSwgZGVwdGggKyAxKVxuICAgICAgaWYgKHYgIT09IHVuZGVmaW5lZCkgb3V0W2tleV0gPSB2XG4gICAgfVxuICAgIHJldHVybiBvdXRcbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuZXhwb3J0IGNvbnN0IHNhbml0aXplID0gKGlucHV0OiB1bmtub3duKTogVHJhaXRNZXRhIHwgdW5kZWZpbmVkID0+IHtcbiAgaWYgKGlucHV0ID09PSBudWxsIHx8IGlucHV0ID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWRcbiAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGlucHV0KSkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIGNvbnN0IHJlY29yZCA9IGlucHV0IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fVxuXG4gIGNvbnN0IHBpY2tTdHJpbmcgPSAoa2V5OiBrZXlvZiBUcmFpdE1ldGEpOiB2b2lkID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IHJlY29yZFtrZXkgYXMgc3RyaW5nXVxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIpIHJldHVyblxuICAgIGNvbnN0IHRyaW1tZWQgPSB2YWx1ZS50cmltKClcbiAgICBpZiAoIXRyaW1tZWQpIHJldHVyblxuICAgIG91dFtrZXldID0gdHJpbW1lZFxuICB9XG5cbiAgcGlja1N0cmluZyhcImxhYmVsXCIpXG4gIHBpY2tTdHJpbmcoXCJkZXNjcmlwdGlvblwiKVxuICBwaWNrU3RyaW5nKFwiZ3JvdXBcIilcbiAgcGlja1N0cmluZyhcImRvY3NVcmxcIilcbiAgcGlja1N0cmluZyhcImNhY2hlR3JvdXBcIilcblxuICBjb25zdCBjYW5vbmljYWwgPSByZWNvcmQuY2Fub25pY2FsXG4gIGlmICh0eXBlb2YgY2Fub25pY2FsID09PSBcImJvb2xlYW5cIikge1xuICAgIG91dC5jYW5vbmljYWwgPSBjYW5vbmljYWxcbiAgfVxuXG4gIGNvbnN0IHRhZ3NSYXcgPSByZWNvcmQudGFnc1xuICBpZiAodHlwZW9mIHRhZ3NSYXcgPT09IFwic3RyaW5nXCIpIHtcbiAgICBjb25zdCB0YWdzID0gdW5pcVNvcnRlZFN0cmluZ3MoW3RhZ3NSYXddKVxuICAgIGlmICh0YWdzLmxlbmd0aCA+IDApIG91dC50YWdzID0gdGFnc1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodGFnc1JhdykpIHtcbiAgICBjb25zdCB0YWdzID0gdW5pcVNvcnRlZFN0cmluZ3ModGFnc1Jhdy5maWx0ZXIoKHgpOiB4IGlzIHN0cmluZyA9PiB0eXBlb2YgeCA9PT0gXCJzdHJpbmdcIikpXG4gICAgaWYgKHRhZ3MubGVuZ3RoID4gMCkgb3V0LnRhZ3MgPSB0YWdzXG4gIH1cblxuICBjb25zdCBhbm5vdGF0aW9uczogUmVjb3JkPHN0cmluZywgSnNvblZhbHVlPiA9IHt9XG5cbiAgLy8gbGVnYWN5OiBhbGxvdyBwYXNzaW5nIGB4LSpgIGtleXMgYXQgdGhlIHRvcC1sZXZlbCAodW50eXBlZCBpbnB1dCksIHRoZW4gbm9ybWFsaXplIGludG8gYGFubm90YXRpb25zYC5cbiAgY29uc3QgYW5ub3RhdGlvbktleXMgPSBPYmplY3Qua2V5cyhyZWNvcmQpXG4gICAgLmZpbHRlcigoaykgPT4gay5zdGFydHNXaXRoKFwieC1cIikpXG4gICAgLnNvcnQoKGEsIGIpID0+IGEubG9jYWxlQ29tcGFyZShiKSlcbiAgZm9yIChjb25zdCBrZXkgb2YgYW5ub3RhdGlvbktleXMpIHtcbiAgICBjb25zdCB2ID0gc2FuaXRpemVKc29uVmFsdWUocmVjb3JkW2tleV0sIDApXG4gICAgaWYgKHYgIT09IHVuZGVmaW5lZCkgYW5ub3RhdGlvbnNba2V5XSA9IHZcbiAgfVxuXG4gIC8vIHByZWZlcnJlZDogdHlwZWQgYGFubm90YXRpb25zYCBmaWVsZCAob25seSBhY2NlcHRzIGB4LSpgIGtleXMpLlxuICBjb25zdCBhbm5vdGF0aW9uc1JhdyA9IHJlY29yZC5hbm5vdGF0aW9uc1xuICBpZiAoaXNQbGFpblJlY29yZChhbm5vdGF0aW9uc1JhdykpIHtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoYW5ub3RhdGlvbnNSYXcpXG4gICAgICAuZmlsdGVyKChrKSA9PiBrLnN0YXJ0c1dpdGgoXCJ4LVwiKSlcbiAgICAgIC5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgY29uc3QgdiA9IHNhbml0aXplSnNvblZhbHVlKGFubm90YXRpb25zUmF3W2tleV0sIDApXG4gICAgICBpZiAodiAhPT0gdW5kZWZpbmVkKSBhbm5vdGF0aW9uc1trZXldID0gdlxuICAgIH1cbiAgfVxuXG4gIGlmIChPYmplY3Qua2V5cyhhbm5vdGF0aW9ucykubGVuZ3RoID4gMCkgb3V0LmFubm90YXRpb25zID0gYW5ub3RhdGlvbnNcblxuICByZXR1cm4gT2JqZWN0LmtleXMob3V0KS5sZW5ndGggPiAwID8gKG91dCBhcyBUcmFpdE1ldGEpIDogdW5kZWZpbmVkXG59XG5cbmNvbnN0IHN0YWJsZVN0cmluZ2lmeSA9IChtZXRhOiBUcmFpdE1ldGEpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge31cbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKG1ldGEpLnNvcnQoKVxuICBmb3IgKGNvbnN0IGsgb2Yga2V5cykge1xuICAgIG91dFtrXSA9IChtZXRhIGFzIGFueSlba11cbiAgfVxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob3V0KVxufVxuXG5leHBvcnQgY29uc3QgZXF1YWxzID0gKGE6IFRyYWl0TWV0YSB8IHVuZGVmaW5lZCwgYjogVHJhaXRNZXRhIHwgdW5kZWZpbmVkKTogYm9vbGVhbiA9PiB7XG4gIGlmIChhID09PSBiKSByZXR1cm4gdHJ1ZVxuICBpZiAoIWEgfHwgIWIpIHJldHVybiBmYWxzZVxuICByZXR1cm4gc3RhYmxlU3RyaW5naWZ5KGEpID09PSBzdGFibGVTdHJpbmdpZnkoYilcbn1cblxuZXhwb3J0IHR5cGUgQ2Fub25pY2FsTWVyZ2VJbnB1dCA9IFJlYWRvbmx5PHtcbiAgcmVhZG9ubHkgbWV0YT86IFRyYWl0TWV0YVxuICByZWFkb25seSBvcmlnaW4/OiBzdHJpbmdcbiAgcmVhZG9ubHkgY29uZmxpY3RzPzogUmVhZG9ubHlBcnJheTxUcmFpdE1ldGFDb25mbGljdD5cbn0+XG5cbmV4cG9ydCB0eXBlIENhbm9uaWNhbE1lcmdlUmVzdWx0ID0gUmVhZG9ubHk8e1xuICByZWFkb25seSBtZXRhPzogVHJhaXRNZXRhXG4gIHJlYWRvbmx5IG9yaWdpbj86IHN0cmluZ1xuICByZWFkb25seSBjb25mbGljdHM/OiBSZWFkb25seUFycmF5PFRyYWl0TWV0YUNvbmZsaWN0PlxufT5cblxuZXhwb3J0IGNvbnN0IG1lcmdlQ2Fub25pY2FsID0gKFxuICBjdXJyZW50OiBDYW5vbmljYWxNZXJnZUlucHV0LFxuICBpbmNvbWluZzogUmVhZG9ubHk8eyByZWFkb25seSBvcmlnaW46IHN0cmluZzsgcmVhZG9ubHkgbWV0YTogVHJhaXRNZXRhIH0+LFxuKTogQ2Fub25pY2FsTWVyZ2VSZXN1bHQgPT4ge1xuICBjb25zdCBleGlzdGluZyA9IGN1cnJlbnQubWV0YVxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1ldGE6IGluY29taW5nLm1ldGEsXG4gICAgICBvcmlnaW46IGluY29taW5nLm9yaWdpbixcbiAgICAgIGNvbmZsaWN0czogY3VycmVudC5jb25mbGljdHMsXG4gICAgfVxuICB9XG5cbiAgaWYgKGVxdWFscyhleGlzdGluZywgaW5jb21pbmcubWV0YSkpIHtcbiAgICByZXR1cm4gY3VycmVudFxuICB9XG5cbiAgY29uc3QgY29uZmxpY3RzOiBBcnJheTxUcmFpdE1ldGFDb25mbGljdD4gPSBbXG4gICAgLi4uKChjdXJyZW50LmNvbmZsaWN0cyA/PyBbXSkgYXMgUmVhZG9ubHlBcnJheTxUcmFpdE1ldGFDb25mbGljdD4pLFxuICBdXG5cbiAgY29uc3QgcHVzaCA9IChjb25mbGljdDogVHJhaXRNZXRhQ29uZmxpY3QpOiB2b2lkID0+IHtcbiAgICBjb25zdCBleGlzdHMgPSBjb25mbGljdHMuc29tZShcbiAgICAgIChjKSA9PiBjLm9yaWdpbiA9PT0gY29uZmxpY3Qub3JpZ2luICYmIGVxdWFscyhjLm1ldGEsIGNvbmZsaWN0Lm1ldGEpLFxuICAgIClcbiAgICBpZiAoIWV4aXN0cykgY29uZmxpY3RzLnB1c2goY29uZmxpY3QpXG4gIH1cblxuICBjb25zdCBleGlzdGluZ0Nhbm9uaWNhbCA9IGV4aXN0aW5nLmNhbm9uaWNhbCA9PT0gdHJ1ZVxuICBjb25zdCBpbmNvbWluZ0Nhbm9uaWNhbCA9IGluY29taW5nLm1ldGEuY2Fub25pY2FsID09PSB0cnVlXG5cbiAgaWYgKCFleGlzdGluZ0Nhbm9uaWNhbCAmJiBpbmNvbWluZ0Nhbm9uaWNhbCkge1xuICAgIHB1c2goe1xuICAgICAgb3JpZ2luOiBjdXJyZW50Lm9yaWdpbiA/PyBcInVua25vd25cIixcbiAgICAgIG1ldGE6IGV4aXN0aW5nLFxuICAgIH0pXG4gICAgcmV0dXJuIHtcbiAgICAgIG1ldGE6IGluY29taW5nLm1ldGEsXG4gICAgICBvcmlnaW46IGluY29taW5nLm9yaWdpbixcbiAgICAgIGNvbmZsaWN0cyxcbiAgICB9XG4gIH1cblxuICBwdXNoKHtcbiAgICBvcmlnaW46IGluY29taW5nLm9yaWdpbixcbiAgICBtZXRhOiBpbmNvbWluZy5tZXRhLFxuICB9KVxuXG4gIHJldHVybiB7XG4gICAgbWV0YTogZXhpc3RpbmcsXG4gICAgb3JpZ2luOiBjdXJyZW50Lm9yaWdpbiA/PyBpbmNvbWluZy5vcmlnaW4sXG4gICAgY29uZmxpY3RzLFxuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBTY2hlbWEgfSBmcm9tIFwiZWZmZWN0XCJcbmltcG9ydCB0eXBlIHsgU3RhdGVBdFBhdGgsIFN0YXRlRmllbGRQYXRoIH0gZnJvbSBcIi4vZmllbGQtcGF0aC5qc1wiXG5pbXBvcnQgdHlwZSB7IERpcnR5QWxsUmVhc29uIH0gZnJvbSBcIi4uL2ZpZWxkLXBhdGguanNcIlxuaW1wb3J0ICogYXMgTWV0YSBmcm9tIFwiLi9tZXRhLmpzXCJcbmltcG9ydCB0eXBlIHsgQ29udmVyZ2VTdGF0aWNJclJlZ2lzdHJ5IH0gZnJvbSBcIi4vY29udmVyZ2UtaXIuanNcIlxuXG4vLyBTdGF0ZVRyYWl0IGNvcmUgbW9kZWxcdTMwMDJcbi8vIFx1NTE3N1x1NEY1M1x1NUI1N1x1NkJCNVx1OEJFRFx1NEU0OVx1NEUwRSBkYXRhLW1vZGVsLm1kIC8gcmVmZXJlbmNlcy9zdGF0ZS10cmFpdC1jb3JlLm1kIFx1NEZERFx1NjMwMVx1NUJGOVx1OUY1MFx1MzAwMlxuXG4vKipcbiAqIFN0YXRlVHJhaXRTcGVjPFM+XHVGRjFBXG4gKiAtIE1vZHVsZSBcdTU2RkVcdTdFQjhcdTRFMkQgdHJhaXRzIFx1NjlGRFx1NEY0RFx1NzY4NFx1NjgwN1x1NTFDNlx1NUY2Mlx1NjAwMVx1RkYxQlxuICogLSBrZXkgXHU1M0Q3IFN0YXRlRmllbGRQYXRoPFM+IFx1N0VBNlx1Njc1Rlx1RkYwQ3ZhbHVlIFx1NEUzQVx1NUJGOVx1NUU5NCBzY29wZSBcdTc2ODRcdTU4RjBcdTY2MEVcdUZGMDhFbnRyeSAvIE5vZGUgLyBMaXN0XHVGRjA5XHUzMDAyXG4gKi9cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRTcGVjPFM+ID0gUyBleHRlbmRzIG9iamVjdFxuICA/IHtcbiAgICAgIFtQYXRoIGluIFN0YXRlRmllbGRQYXRoPFM+IHwgXCIkcm9vdFwiXT86IFN0YXRlVHJhaXRTcGVjVmFsdWU8UywgUGF0aD5cbiAgICB9XG4gIDogbmV2ZXJcblxuZXhwb3J0IHR5cGUgU3RhdGVUcmFpdEtpbmQgPSBcImNvbXB1dGVkXCIgfCBcInNvdXJjZVwiIHwgXCJsaW5rXCIgfCBcImNoZWNrXCJcblxuZXhwb3J0IGludGVyZmFjZSBDb21wdXRlZE1ldGE8UywgUD4ge1xuICAvKipcbiAgICogXHU2NjNFXHU1RjBGXHU0RjlEXHU4RDU2XHU1QjU3XHU2QkI1XHU4REVGXHU1Rjg0XHU5NkM2XHU1NDA4XHVGRjA4XHU1RkM1XHU5ODdCXHVGRjA5XHVGRjFBXG4gICAqXG4gICAqIC0gZGVwcyBcdTY2MkZcdTU1MkZcdTRFMDBcdTRGOURcdThENTZcdTRFOEJcdTVCOUVcdTZFOTBcdUZGMUFHcmFwaC9SZXZlcnNlQ2xvc3VyZS9cdTU4OUVcdTkxQ0ZcdThDMDNcdTVFQTYvXHU2MDI3XHU4MEZEXHU0RjE4XHU1MzE2XHU5MEZEXHU1M0VBXHU4QkE0IGRlcHNcdUZGMUJcbiAgICogLSBEU0wgXHU0RkE3IGBTdGF0ZVRyYWl0LmNvbXB1dGVkKHsgZGVwcywgZ2V0IH0pYCBcdTc2ODQgYGdldGAgXHU5MUM3XHU3NTI4IGRlcHMtYXMtYXJnc1x1RkYwQ1x1NEUwRFx1NjZCNFx1OTczMiBgKHN0YXRlKSA9PiAuLi5gXHVGRjFCXG4gICAqIC0gYnVpbGQgXHU5NjM2XHU2QkI1XHU0RjFBXHU1QzA2IGBnZXQoLi4uZGVwc1ZhbHVlcylgIFx1OTY0RFx1ODlFM1x1NEUzQSBgZGVyaXZlKHN0YXRlKWAgXHU0RjlCXHU4RkQwXHU4ODRDXHU2NUY2XHU2MjY3XHU4ODRDXHVGRjBDXHU0RjQ2XHU0RjlEXHU4RDU2XHU4QkZCXHU5NkM2XHU0RUNEXHU0RUU1IGRlcHMgXHU0RTNBXHU1MUM2XHVGRjFCXG4gICAqIC0gZGV2LW1vZGUgXHU0RTBCXHU4MkU1IGBkZXJpdmUoc3RhdGUpYCBcdTc2ODRcdTVCOUVcdTk2NDVcdThCRkJcdTUzRDZcdTRFMEUgZGVwcyBcdTRFMERcdTRFMDBcdTgxRjRcdUZGMENcdTRGMUFcdTRFQTdcdTc1MUYgYGRlcHNfbWlzbWF0Y2hgIFx1OEJDQVx1NjVBRFx1NTQ0QVx1OEI2Nlx1MzAwMlxuICAgKlxuICAgKiAtIFx1NUJGOVx1NEU4RSBSb290IFx1ODlDNFx1NTIxOVx1RkYxQWRlcHMgXHU0RTNBIFN0YXRlRmllbGRQYXRoPFN0YXRlPlx1RkYxQlxuICAgKiAtIFx1NUJGOVx1NEU4RSBsaXN0Lml0ZW0gc2NvcGVcdUZGMUFkZXBzIFx1NEUzQSBTdGF0ZUZpZWxkUGF0aDxJdGVtPlx1RkYwOFx1NzZGOFx1NUJGOVx1OERFRlx1NUY4NFx1RkYwQ2J1aWxkIFx1OTYzNlx1NkJCNVx1NEYxQVx1NTI0RFx1N0YwMFx1NTMxNlx1RkYwOVx1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgZGVwczogUmVhZG9ubHlBcnJheTxTdGF0ZUZpZWxkUGF0aDxTPj5cbiAgcmVhZG9ubHkgZGVyaXZlOiAoc3RhdGU6IFJlYWRvbmx5PFM+KSA9PiBTdGF0ZUF0UGF0aDxTLCBQPlxuICAvKipcbiAgICogXHU1M0VGXHU5MDA5XHVGRjFBXHU3QjQ5XHU0RUY3XHU1MjI0XHU1QjlBXHVGRjA4XHU3NTI4XHU0RThFXHU4REYzXHU4RkM3XHU2NUUwXHU1M0Q4XHU1MzE2XHU1MTk5XHU1NkRFXHVGRjA5XHUzMDAyXG4gICAqL1xuICByZWFkb25seSBlcXVhbHM/OiAocHJldjogU3RhdGVBdFBhdGg8UywgUD4sIG5leHQ6IFN0YXRlQXRQYXRoPFMsIFA+KSA9PiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU291cmNlTWV0YTxTLCBQPiB7XG4gIHJlYWRvbmx5IGRlcHM6IFJlYWRvbmx5QXJyYXk8U3RhdGVGaWVsZFBhdGg8Uz4+XG4gIC8qKlxuICAgKiBcdTkwM0JcdThGOTFcdThENDRcdTZFOTBcdTY4MDdcdThCQzZcdUZGMDhcdTU5ODIgXCJ1c2VyL3Byb2ZpbGVcIlx1RkYwOVx1MzAwMlxuICAgKlxuICAgKiAtIFN0YXRlVHJhaXQuc291cmNlIERTTCBcdTRFMkRcdTc2ODQgYHJlc291cmNlYCBcdTVCNTdcdTZCQjVcdTU3MjggYnVpbGQgXHU5NjM2XHU2QkI1XHU0RjFBXHU4NDNEXHU1NzI4XHU2QjY0XHU1OTA0XHVGRjFCXG4gICAqIC0gZGF0YS1tb2RlbC5tZCBcdTRFMkRcdThCQjBcdTRFM0EgcmVzb3VyY2VJZFx1RkYwQ1x1OEZEOVx1OTFDQ1x1NkNCRlx1NzUyOCBEU0wgXHU1NDdEXHU1NDBEXHU5MDdGXHU1MTREXHU2REY3XHU2REM2XHUzMDAyXG4gICAqL1xuICByZWFkb25seSByZXNvdXJjZTogc3RyaW5nXG4gIC8qKlxuICAgKiBcdTRFQ0VcdTVCOENcdTY1NzQgU3RhdGUgXHU4QkExXHU3Qjk3XHU4QkJGXHU5NUVFXHU4QkU1XHU4RDQ0XHU2RTkwXHU2MjQwXHU5NzAwIGtleSBcdTc2ODRcdTg5QzRcdTUyMTlcdTMwMDJcbiAgICpcbiAgICogLSBcdTUxNDFcdThCQjhcdThGRDRcdTU2REUgdW5kZWZpbmVkXHVGRjFBXHU4ODY4XHU3OTNBXHU4QkU1XHU4RDQ0XHU2RTkwXHU1NzI4XHU1RjUzXHU1MjREIHN0YXRlIFx1NEUwQlx1NjcyQVx1NkZDMFx1NkQzQlx1RkYwOFx1NUU5NFx1NTZERVx1NjUzNlx1NEUzQSBpZGxlXHVGRjA5XHUzMDAyXG4gICAqL1xuICByZWFkb25seSBrZXk6IChzdGF0ZTogUmVhZG9ubHk8Uz4pID0+IHVua25vd25cbiAgcmVhZG9ubHkgdHJpZ2dlcnM/OiBSZWFkb25seUFycmF5PFwib25Nb3VudFwiIHwgXCJvblZhbHVlQ2hhbmdlXCIgfCBcIm1hbnVhbFwiPlxuICByZWFkb25seSBkZWJvdW5jZU1zPzogbnVtYmVyXG4gIHJlYWRvbmx5IGNvbmN1cnJlbmN5PzogXCJzd2l0Y2hcIiB8IFwiZXhoYXVzdC10cmFpbGluZ1wiXG4gIC8qKlxuICAgKiBcdTc1MjhcdTRFOEUgRGV2dG9vbHMvXHU2NTg3XHU2ODYzXHU3Njg0XHU1M0VGXHU1RThGXHU1MjE3XHU1MzE2XHU1MTQzXHU0RkUxXHU2MDZGXHVGRjA4XHU3NjdEXHU1NDBEXHU1MzU1XHU1QjU3XHU2QkI1XHVGRjA5XHUzMDAyXG4gICAqL1xuICByZWFkb25seSBtZXRhPzogTWV0YS5UcmFpdE1ldGFcbiAgLyoqXG4gICAqIFx1OTg4NFx1NzU1OVx1RkYxQVx1NTcyOCBidWlsZCBcdTk2MzZcdTZCQjVcdTUzRUZcdTU4NkJcdTUxNDVcdThCRTUgVHJhaXQgXHU2MjQwXHU1NzI4XHU1QjU3XHU2QkI1XHU4REVGXHU1Rjg0XHVGRjBDXHU0RkJGXHU0RThFXHU4QzAzXHU4QkQ1XHUzMDAyXG4gICAqL1xuICByZWFkb25seSBfZmllbGRQYXRoPzogUFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpbmtNZXRhPFM+IHtcbiAgLyoqXG4gICAqIFx1NkU5MFx1NUI1N1x1NkJCNVx1OERFRlx1NUY4NFx1RkYwQ1x1NTQwQ1x1NjgzN1x1NTNENyBTdGF0ZUZpZWxkUGF0aDxTPiBcdTdFQTZcdTY3NUZcdTMwMDJcbiAgICovXG4gIHJlYWRvbmx5IGZyb206IFN0YXRlRmllbGRQYXRoPFM+XG59XG5cbmV4cG9ydCB0eXBlIENoZWNrUnVsZTxJbnB1dCA9IHVua25vd24sIEN0eCA9IHVua25vd24+ID1cbiAge1xuICAgIHJlYWRvbmx5IGRlcHM6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxuICAgIC8qKlxuICAgICAqIHZhbGlkYXRlT25cdUZGMUFcbiAgICAgKiAtIFx1NEVDNVx1NUY3MVx1NTRDRFx1ODFFQVx1NTJBOFx1NjgyMVx1OUE4Q1x1OTYzNlx1NkJCNVx1RkYwOG9uQ2hhbmdlL29uQmx1clx1RkYwOVx1RkYxQnN1Ym1pdC9tYW51YWwgXHU1OUNCXHU3RUM4XHU2MjY3XHU4ODRDXHVGRjFCXG4gICAgICogLSBcdTRFM0FcdTdBN0FcdTY1NzBcdTdFQzRcdTg4NjhcdTc5M0FcdTc5ODFcdTc1MjhcdTgxRUFcdTUyQThcdTY4MjFcdTlBOENcdUZGMDhcdTRFQzUgc3VibWl0L21hbnVhbCBcdTYyNjdcdTg4NENcdUZGMDlcdTMwMDJcbiAgICAgKi9cbiAgICByZWFkb25seSB2YWxpZGF0ZU9uPzogUmVhZG9ubHlBcnJheTxcIm9uQ2hhbmdlXCIgfCBcIm9uQmx1clwiPlxuICAgIHJlYWRvbmx5IHZhbGlkYXRlOiAoaW5wdXQ6IElucHV0LCBjdHg6IEN0eCkgPT4gdW5rbm93blxuICAgIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxuICB9XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hlY2tNZXRhPElucHV0ID0gdW5rbm93biwgQ3R4ID0gdW5rbm93bj4ge1xuICAvKipcbiAgICogXHU1NDdEXHU1NDBEXHU4OUM0XHU1MjE5XHU5NkM2XHU1NDA4XHVGRjA4XHU4QkIwXHU1RjU1XHU3NTI4XHU0RThFXHU3ODZFXHU1QjlBXHU2MDI3XHU1NDA4XHU1RTc2XHU0RTBFXHU4QkNBXHU2NUFEXHU1QzU1XHU3OTNBXHVGRjA5XHUzMDAyXG4gICAqL1xuICByZWFkb25seSBydWxlczogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgQ2hlY2tSdWxlPElucHV0LCBDdHg+Pj5cbiAgLyoqXG4gICAqIFx1OTUxOVx1OEJFRlx1NjgxMVx1NTE5OVx1NTZERVx1RkYwOFBoYXNlIDJcdUZGMUFcdTRFQzVcdTU2RkFcdTUzMTZcdTdFRDNcdTY3ODRcdUZGMUJcdTUxNzdcdTRGNTNcdTUxOTlcdTU2REVcdThCRURcdTRFNDlcdTU3MjhcdTU0MEVcdTdFRUQgUGhhc2UgXHU1QjlFXHU3M0IwXHVGRjA5XHUzMDAyXG4gICAqL1xuICByZWFkb25seSB3cml0ZWJhY2s/OiB7XG4gICAgcmVhZG9ubHkga2luZDogXCJlcnJvcnNcIlxuICAgIHJlYWRvbmx5IHBhdGg/OiBzdHJpbmdcbiAgfVxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRFbnRyeTxTLCBQPlx1RkYxQVxuICogLSBcdTg4NjhcdTc5M0FcdTY3RDBcdTRFMkFcdTVCNTdcdTZCQjVcdThERUZcdTVGODQgUCBcdTRFMEFcdTc2ODRcdTRFMDBcdTk4NzkgVHJhaXQgXHU5MTREXHU3RjZFXHVGRjFCXG4gKiAtIGtpbmQgXHU0RTBFIG1ldGEgXHU2MjEwXHU1QkY5XHU1MUZBXHU3M0IwXHVGRjBDXHU3NTI4XHU0RThFXHU1NzI4IGJ1aWxkL2luc3RhbGwgXHU5NjM2XHU2QkI1XHU1MjA2XHU2RDNFXHU4ODRDXHU0RTNBXHUzMDAyXG4gKi9cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRFbnRyeTxcbiAgUyA9IHVua25vd24sXG4gIFAgZXh0ZW5kcyBzdHJpbmcgPSBTdGF0ZUZpZWxkUGF0aDxTPlxuPiA9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgZmllbGRQYXRoOiBQXG4gICAgICByZWFkb25seSBraW5kOiBcImNvbXB1dGVkXCJcbiAgICAgIHJlYWRvbmx5IG1ldGE6IENvbXB1dGVkTWV0YTxTLCBQPlxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBmaWVsZFBhdGg6IFBcbiAgICAgIHJlYWRvbmx5IGtpbmQ6IFwic291cmNlXCJcbiAgICAgIHJlYWRvbmx5IG1ldGE6IFNvdXJjZU1ldGE8UywgUD5cbiAgICB9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgZmllbGRQYXRoOiBQXG4gICAgICByZWFkb25seSBraW5kOiBcImxpbmtcIlxuICAgICAgcmVhZG9ubHkgbWV0YTogTGlua01ldGE8Uz5cbiAgICB9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgZmllbGRQYXRoOiBQXG4gICAgICByZWFkb25seSBraW5kOiBcImNoZWNrXCJcbiAgICAgIHJlYWRvbmx5IG1ldGE6IENoZWNrTWV0YTx1bmtub3duLCB1bmtub3duPlxuICAgIH1cblxuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0Tm9kZTxJbnB1dCA9IHVua25vd24sIEN0eCA9IHVua25vd24+IHtcbiAgcmVhZG9ubHkgX3RhZzogXCJTdGF0ZVRyYWl0Tm9kZVwiXG4gIHJlYWRvbmx5IGNvbXB1dGVkPzpcbiAgICB8IFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55PlxuICAgIHwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgU3RhdGVUcmFpdEVudHJ5PElucHV0LCBhbnk+Pj5cbiAgcmVhZG9ubHkgc291cmNlPzpcbiAgICB8IFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55PlxuICAgIHwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgU3RhdGVUcmFpdEVudHJ5PElucHV0LCBhbnk+Pj5cbiAgcmVhZG9ubHkgbGluaz86XG4gICAgfCBTdGF0ZVRyYWl0RW50cnk8SW5wdXQsIGFueT5cbiAgICB8IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxJbnB1dCwgYW55Pj4+XG4gIHJlYWRvbmx5IGNoZWNrPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgQ2hlY2tSdWxlPElucHV0LCBDdHg+Pj5cbiAgcmVhZG9ubHkgbWV0YT86IE1ldGEuVHJhaXRNZXRhXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdExpc3Q8SXRlbSA9IHVua25vd24+IHtcbiAgcmVhZG9ubHkgX3RhZzogXCJTdGF0ZVRyYWl0TGlzdFwiXG4gIHJlYWRvbmx5IGl0ZW0/OiBTdGF0ZVRyYWl0Tm9kZTxJdGVtLCBhbnk+XG4gIHJlYWRvbmx5IGxpc3Q/OiBTdGF0ZVRyYWl0Tm9kZTxSZWFkb25seUFycmF5PEl0ZW0+LCBhbnk+XG4gIHJlYWRvbmx5IGlkZW50aXR5SGludD86IHtcbiAgICByZWFkb25seSB0cmFja0J5Pzogc3RyaW5nXG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgU3RhdGVUcmFpdFNwZWNWYWx1ZTxTLCBQIGV4dGVuZHMgc3RyaW5nPiA9XG4gIHwgU3RhdGVUcmFpdEVudHJ5PFMsIFA+XG4gIHwgU3RhdGVUcmFpdE5vZGU8YW55LCBhbnk+XG4gIHwgU3RhdGVUcmFpdExpc3Q8YW55PlxuXG4vKipcbiAqIFN0YXRlVHJhaXRGaWVsZFx1RkYxQVxuICogLSBcdTg4NjhcdTc5M0EgU3RhdGUgXHU0RTJEXHU3Njg0XHU0RTAwXHU0RTJBXHU1QjU3XHU2QkI1XHU4MjgyXHU3MEI5XHVGRjA4XHU0RTBEXHU4QkJBXHU2NjJGXHU1NDI2XHU2MzAyIFRyYWl0XHVGRjA5XHVGRjFCXG4gKiAtIFx1NzUzMSBidWlsZCBcdTk2MzZcdTZCQjVcdTRFQ0UgU3RhdGVUcmFpdFNwZWMgXHU1RjUyXHU0RTAwXHU1MzE2XHU4MDBDXHU2NzY1XHUzMDAyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdEZpZWxkIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZ1xuICByZWFkb25seSBwYXRoOiBzdHJpbmdcbiAgcmVhZG9ubHkgZGlzcGxheU5hbWU/OiBzdHJpbmdcbiAgcmVhZG9ubHkgdmFsdWVUeXBlPzogc3RyaW5nXG4gIHJlYWRvbmx5IHRyYWl0czogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RmllbGRUcmFpdD5cbn1cblxuLyoqXG4gKiBTdGF0ZVRyYWl0RmllbGRUcmFpdFx1RkYxQVxuICogLSBcdTY3RDBcdTRFMkFcdTVCNTdcdTZCQjVcdTRFMEFcdTc2ODRcdTRFMDBcdTk4NzkgVHJhaXRcdUZGMDhjb21wdXRlZCAvIHNvdXJjZSAvIGxpbmtcdUZGMDlcdTc2ODRcdTdFRDNcdTY3ODRcdTUzMTZcdTYzQ0ZcdThGRjBcdUZGMUJcbiAqIC0gbWV0YSBcdTRFMEUgU3RhdGVUcmFpdEVudHJ5Lm1ldGEgXHU1QkY5XHU5RjUwXHVGRjBDZGVwcyBcdTg4NjhcdTc5M0FcdThCRTUgVHJhaXQgXHU2MjQwXHU0RjlEXHU4RDU2XHU3Njg0XHU1QjU3XHU2QkI1XHU4REVGXHU1Rjg0XHU5NkM2XHU1NDA4XHUzMDAyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdEZpZWxkVHJhaXQge1xuICByZWFkb25seSBmaWVsZElkOiBzdHJpbmdcbiAgcmVhZG9ubHkga2luZDogU3RhdGVUcmFpdEtpbmRcbiAgcmVhZG9ubHkgbWV0YTpcbiAgICB8IENvbXB1dGVkTWV0YTx1bmtub3duLCBzdHJpbmc+XG4gICAgfCBTb3VyY2VNZXRhPHVua25vd24sIHN0cmluZz5cbiAgICB8IExpbmtNZXRhPHVua25vd24+XG4gICAgfCBDaGVja01ldGE8dW5rbm93biwgdW5rbm93bj5cbiAgcmVhZG9ubHkgZGVwczogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdFJlc291cmNlXHVGRjFBXG4gKiAtIFx1NjNDRlx1OEZGMCBzb3VyY2UgXHU1NzhCIFRyYWl0IFx1NjI0MFx1NEY5RFx1OEQ1Nlx1NzY4NFx1OTAzQlx1OEY5MVx1OEQ0NFx1NkU5MFx1NTE0M1x1NEZFMVx1NjA2Rlx1RkYxQlxuICogLSBSZXNvdXJjZVNwZWMgXHU3Njg0XHU1MTc3XHU0RjUzXHU1QjlFXHU3M0IwXHU3NTMxIFJlc291cmNlIFx1NTQ3RFx1NTQwRFx1N0E3QVx1OTVGNFx1OEQxRlx1OEQyM1x1RkYwQ1x1OEZEOVx1OTFDQ1x1NTNFQVx1NEZERFx1NzU1OSBUcmFpdCBcdTg5QzZcdTg5RDJcdTc2ODRcdTRGOURcdThENTZcdTRGRTFcdTYwNkZcdTMwMDJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0UmVzb3VyY2Uge1xuICByZWFkb25seSByZXNvdXJjZUlkOiBzdHJpbmdcbiAgcmVhZG9ubHkga2V5U2VsZWN0b3I6IHN0cmluZ1xuICByZWFkb25seSBrZXlFeGFtcGxlPzogdW5rbm93blxuICByZWFkb25seSBvd25lckZpZWxkczogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG4gIHJlYWRvbmx5IG1ldGE/OiBNZXRhLlRyYWl0TWV0YVxuICByZWFkb25seSBtZXRhT3JpZ2luPzogc3RyaW5nXG4gIHJlYWRvbmx5IG1ldGFDb25mbGljdHM/OiBSZWFkb25seUFycmF5PE1ldGEuVHJhaXRNZXRhQ29uZmxpY3Q+XG59XG5cbi8qKlxuICogR3JhcGggTm9kZSAvIEVkZ2VcdUZGMUFcbiAqIC0gXHU4MjgyXHU3MEI5XHU5MDFBXHU1RTM4XHU1QkY5XHU1RTk0XHU0RTAwXHU0RTJBXHU1QjU3XHU2QkI1XHVGRjFCXG4gKiAtIFx1OEZCOVx1ODg2OFx1NzkzQVx1NUI1N1x1NkJCNVx1NEU0Qlx1OTVGNFx1NjIxNlx1NUI1N1x1NkJCNVx1NEUwRVx1OEQ0NFx1NkU5MFx1NEU0Qlx1OTVGNFx1NzY4NFx1NEY5RFx1OEQ1Nlx1NTE3M1x1N0NGQlx1MzAwMlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRHcmFwaE5vZGUge1xuICByZWFkb25seSBpZDogc3RyaW5nXG4gIHJlYWRvbmx5IGZpZWxkOiBTdGF0ZVRyYWl0RmllbGRcbiAgcmVhZG9ubHkgdHJhaXRzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRGaWVsZFRyYWl0PlxuICByZWFkb25seSBtZXRhPzogTWV0YS5UcmFpdE1ldGFcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0R3JhcGhFZGdlIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZ1xuICByZWFkb25seSBmcm9tOiBzdHJpbmdcbiAgcmVhZG9ubHkgdG86IHN0cmluZ1xuICByZWFkb25seSBraW5kOiBcImNvbXB1dGVkXCIgfCBcImxpbmtcIiB8IFwic291cmNlLWRlcFwiIHwgXCJjaGVjay1kZXBcIlxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXRHcmFwaFx1RkYxQVxuICogLSBTdGF0ZVRyYWl0IFx1NUYxNVx1NjRDRVx1NzY4NFx1N0VEM1x1Njc4NFx1ODlDNlx1NTZGRVx1RkYwQ1x1NEUwMFx1NUYyMFx1NTMwNVx1NTQyQlx1ODI4Mlx1NzBCOVx1NEUwRVx1NEY5RFx1OEQ1Nlx1OEZCOVx1NzY4NFx1NTZGRVx1RkYxQlxuICogLSBcdTRGOUIgRGV2dG9vbHMgLyBTdHVkaW8gXHU0RTBFIFJ1bnRpbWUgXHU1MDVBXHU3RUQzXHU2Nzg0XHU1MjA2XHU2NzkwXHU0RTBFXHU1M0VGXHU4OUM2XHU1MzE2XHU0RjdGXHU3NTI4XHUzMDAyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFpdEdyYXBoIHtcbiAgcmVhZG9ubHkgX3RhZzogXCJTdGF0ZVRyYWl0R3JhcGhcIlxuICByZWFkb25seSBub2RlczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0R3JhcGhOb2RlPlxuICByZWFkb25seSBlZGdlczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0R3JhcGhFZGdlPlxuICByZWFkb25seSByZXNvdXJjZXM6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdFJlc291cmNlPlxuICByZWFkb25seSBtZXRhPzoge1xuICAgIHJlYWRvbmx5IG1vZHVsZUlkPzogc3RyaW5nXG4gICAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZ1xuICB9XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdFBsYW5TdGVwXHVGRjFBXG4gKiAtIFN0YXRlVHJhaXQuaW5zdGFsbCAvIFJ1bnRpbWUgXHU2MjY3XHU4ODRDXHU2NUY2XHU3Njg0XHU2NzAwXHU1QzBGXHU2MzA3XHU0RUU0XHU1MzU1XHU1MTQzXHVGRjFCXG4gKiAtIFx1NzUzMSBHcmFwaCBcdTYzQThcdTVCRkNcdTgwMENcdTY3NjVcdUZGMENcdTc1MjhcdTRFOEVcdTU3MjhcdThGRDBcdTg4NENcdTY1RjZcdTVCODlcdTg4QzUgd2F0Y2hlciBcdTYyMTZcdTg5RTZcdTUzRDFcdTU5MTZcdTkwRThcdThDMDNcdTc1MjhcdTMwMDJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYWl0UGxhblN0ZXAge1xuICByZWFkb25seSBpZDogc3RyaW5nXG4gIHJlYWRvbmx5IGtpbmQ6IFwiY29tcHV0ZWQtdXBkYXRlXCIgfCBcImxpbmstcHJvcGFnYXRlXCIgfCBcInNvdXJjZS1yZWZyZXNoXCIgfCBcImNoZWNrLXZhbGlkYXRlXCJcbiAgcmVhZG9ubHkgdGFyZ2V0RmllbGRQYXRoPzogc3RyaW5nXG4gIHJlYWRvbmx5IHNvdXJjZUZpZWxkUGF0aHM/OiBSZWFkb25seUFycmF5PHN0cmluZz5cbiAgcmVhZG9ubHkgcmVzb3VyY2VJZD86IHN0cmluZ1xuICByZWFkb25seSBrZXlTZWxlY3RvcklkPzogc3RyaW5nXG4gIHJlYWRvbmx5IGRlYnVnSW5mbz86IHtcbiAgICByZWFkb25seSBncmFwaE5vZGVJZD86IHN0cmluZ1xuICAgIHJlYWRvbmx5IGdyYXBoRWRnZUlkPzogc3RyaW5nXG4gIH1cbn1cblxuLyoqXG4gKiBTdGF0ZVRyYWl0UGxhblx1RkYxQVxuICogLSBcdTZDNDdcdTYwM0JcdTY3RDBcdTZBMjFcdTU3NTdcdTYyNDBcdTY3MDkgVHJhaXQgXHU4ODRDXHU0RTNBXHU3Njg0XHU2MjY3XHU4ODRDXHU4QkExXHU1MjEyXHVGRjFCXG4gKiAtIGluc3RhbGwgXHU5NjM2XHU2QkI1XHU2MzA5IFBsYW4gXHU1QzA2XHU4ODRDXHU0RTNBXHU2MzAyXHU4RjdEXHU1MjMwIEJvdW5kIEFQSSAvIEVmZmVjdE9wIFx1N0JBMVx1OTA1M1x1NEUwQVx1MzAwMlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRQbGFuIHtcbiAgcmVhZG9ubHkgX3RhZzogXCJTdGF0ZVRyYWl0UGxhblwiXG4gIHJlYWRvbmx5IG1vZHVsZUlkPzogc3RyaW5nXG4gIHJlYWRvbmx5IHN0ZXBzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRQbGFuU3RlcD5cbiAgcmVhZG9ubHkgbWV0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdFByb2dyYW08Uz5cdUZGMUFcbiAqIC0gU3RhdGVUcmFpdCBcdTVGMTVcdTY0Q0VcdTc2ODQgUHJvZ3JhbSBcdThGOTNcdTUxRkFcdUZGMENcdTY2MkYgUnVudGltZSAvIERldnRvb2xzIFx1NzY4NFx1N0VERlx1NEUwMFx1NTE2NVx1NTNFM1x1RkYxQlxuICogLSBzdGF0ZVNjaGVtYSBcdTRFMEUgc3BlYyBcdTRGRERcdTc1NTlcdTUzOUZcdTU5Q0JcdThGOTNcdTUxNjVcdUZGMENncmFwaC9wbGFuIFx1NEUzQVx1NTE4NVx1OTBFOCBJUlx1MzAwMlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhaXRQcm9ncmFtPFM+IHtcbiAgcmVhZG9ubHkgc3RhdGVTY2hlbWE6IFNjaGVtYS5TY2hlbWE8UywgYW55PlxuICByZWFkb25seSBzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPlxuICAvKipcbiAgICogUHJvZ3JhbS5lbnRyaWVzXHVGRjFBXG4gICAqIC0gYnVpbGQgXHU5NjM2XHU2QkI1XHU0RUNFIHNwZWNcdUZGMDhcdTU0MkIgbm9kZS9saXN0LyRyb290XHVGRjA5XHU1RjUyXHU0RTAwXHU1MzE2XHU1Rjk3XHU1MjMwXHU3Njg0XHU2NzAwXHU1QzBGXHU4OUM0XHU1MjE5XHU5NkM2XHU1NDA4XHVGRjFCXG4gICAqIC0gUGhhc2UgMiBcdTUxNDhcdTRGRERcdThCQzFcdTIwMUNcdTUzRUZcdThCRkJcdTUzRUZcdThCQ0FcdTY1QURcdTc2ODRcdTdFRDNcdTY3ODRcdTIwMURcdUZGMENcdTU0MEVcdTdFRUQgUGhhc2UgXHU2MjREXHU2M0E1XHU1MTY1XHU2MjY3XHU4ODRDXHU0RTBFXHU2NTM2XHU2NTVCXHU4QkVEXHU0RTQ5XHUzMDAyXG4gICAqL1xuICByZWFkb25seSBlbnRyaWVzOiBSZWFkb25seUFycmF5PFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4+XG4gIHJlYWRvbmx5IGdyYXBoOiBTdGF0ZVRyYWl0R3JhcGhcbiAgcmVhZG9ubHkgcGxhbjogU3RhdGVUcmFpdFBsYW5cbiAgcmVhZG9ubHkgY29udmVyZ2VJcj86IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeVxufVxuXG4vKipcbiAqIFx1NEVDRSBTdGF0ZVRyYWl0U3BlYyBcdTY3ODRcdTVFRkFcdTVGNTJcdTRFMDBcdTUzMTZcdTc2ODQgZW50cnkgXHU1MjE3XHU4ODY4XHUzMDAyXG4gKlxuICogLSBQaGFzZSAyXHVGRjFBXHU2NTJGXHU2MzAxIG5vZGUvbGlzdC8kcm9vdCBcdTc2ODRcdTdFRDNcdTY3ODRcdTVDNTVcdTVGMDBcdUZGMENcdTVFNzZcdTU3MjhcdTVGQzVcdTg5ODFcdTY1RjZcdTg4NjVcdTUxNjgvXHU1MjREXHU3RjAwXHU1MzE2IGZpZWxkUGF0aCBcdTRFMEUgZGVwc1x1RkYxQlxuICogLSBcdTU0MEVcdTdFRUQgUGhhc2UgXHU1M0VGXHU1NzI4XHU2QjY0XHU1OTA0XHU2MjY5XHU1QzU1XHU2ODIxXHU5QThDXHU5MDNCXHU4RjkxXHVGRjA4XHU0RjhCXHU1OTgyXHU2OEMwXHU2RDRCXHU5MUNEXHU1OTBEXHU1QjlBXHU0RTQ5XHUzMDAxXHU4OTg2XHU3NkQ2XHU2NzNBXHU1MjM2XHU3QjQ5XHVGRjA5XHUzMDAyXG4gKi9cbmV4cG9ydCBjb25zdCBub3JtYWxpemVTcGVjID0gPFM+KFxuICBzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPixcbik6IFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj4gPT4ge1xuICBjb25zdCBlbnRyaWVzOiBBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PiA9IFtdXG5cbiAgY29uc3QgaXNOb2RlID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgU3RhdGVUcmFpdE5vZGU8YW55LCBhbnk+ID0+XG4gICAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsICYmICh2YWx1ZSBhcyBhbnkpLl90YWcgPT09IFwiU3RhdGVUcmFpdE5vZGVcIlxuXG4gIGNvbnN0IGlzTGlzdCA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFN0YXRlVHJhaXRMaXN0PGFueT4gPT5cbiAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgKHZhbHVlIGFzIGFueSkuX3RhZyA9PT0gXCJTdGF0ZVRyYWl0TGlzdFwiXG5cbiAgY29uc3Qgam9pblBhdGggPSAocHJlZml4OiBzdHJpbmcsIHN1ZmZpeDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICBpZiAoIXByZWZpeCkgcmV0dXJuIHN1ZmZpeFxuICAgIGlmICghc3VmZml4KSByZXR1cm4gcHJlZml4XG4gICAgcmV0dXJuIGAke3ByZWZpeH0uJHtzdWZmaXh9YFxuICB9XG5cbiAgY29uc3QgcHJlZml4RGVwcyA9IChcbiAgICBkZXBzOiBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWQsXG4gICAgcHJlZml4OiBzdHJpbmcsXG4gICk6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiA9PiB7XG4gICAgaWYgKCFkZXBzIHx8IGRlcHMubGVuZ3RoID09PSAwKSByZXR1cm4gW11cbiAgICByZXR1cm4gZGVwcy5tYXAoKGQpID0+IChwcmVmaXggPyBqb2luUGF0aChwcmVmaXgsIGQpIDogZCkpXG4gIH1cblxuICBjb25zdCBub3JtYWxpemVFbnRyeSA9IChcbiAgICBlbnRyeTogU3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPixcbiAgICBmaWVsZFBhdGg6IHN0cmluZyxcbiAgICBkZXBQcmVmaXg6IHN0cmluZyxcbiAgKTogU3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPiA9PiB7XG4gICAgaWYgKGVudHJ5LmtpbmQgPT09IFwiY29tcHV0ZWRcIikge1xuICAgICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgICBjb25zdCByYXdEZXBzID0gbWV0YS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgY29uc3QgZGVwcyA9XG4gICAgICAgIHJhd0RlcHMgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gcHJlZml4RGVwcyhyYXdEZXBzLCBkZXBQcmVmaXgpXG4gICAgICAgICAgOiB1bmRlZmluZWRcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLihlbnRyeSBhcyBhbnkpLFxuICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgIG1ldGE6IHsgLi4ubWV0YSwgZGVwcyB9LFxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW50cnkua2luZCA9PT0gXCJzb3VyY2VcIikge1xuICAgICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgICBjb25zdCByYXdEZXBzID0gbWV0YS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgY29uc3QgZGVwcyA9XG4gICAgICAgIHJhd0RlcHMgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gcHJlZml4RGVwcyhyYXdEZXBzLCBkZXBQcmVmaXgpXG4gICAgICAgICAgOiB1bmRlZmluZWRcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLihlbnRyeSBhcyBhbnkpLFxuICAgICAgICBmaWVsZFBhdGgsXG4gICAgICAgIG1ldGE6IHsgLi4ubWV0YSwgZGVwcywgX2ZpZWxkUGF0aDogZmllbGRQYXRoIH0sXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbnRyeS5raW5kID09PSBcImxpbmtcIikge1xuICAgICAgY29uc3QgbWV0YSA9IGVudHJ5Lm1ldGEgYXMgYW55XG4gICAgICBjb25zdCBmcm9tID0gcHJlZml4RGVwcyhbbWV0YS5mcm9tIGFzIHN0cmluZ10sIGRlcFByZWZpeClbMF0gPz8gbWV0YS5mcm9tXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi4oZW50cnkgYXMgYW55KSxcbiAgICAgICAgZmllbGRQYXRoLFxuICAgICAgICBtZXRhOiB7IC4uLm1ldGEsIGZyb20gfSxcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY2hlY2tcdUZGMUFQaGFzZSAyIFx1NEVDNVx1OEMwM1x1NjU3NCBmaWVsZFBhdGhcdUZGMENkZXBzIFx1NEVDRFx1NzUzMSBtZXRhLnJ1bGVzIFx1NTcyOCBidWlsZCBcdTk2MzZcdTZCQjVcdTZDNDdcdTYwM0JcdTMwMDJcbiAgICByZXR1cm4ge1xuICAgICAgLi4uKGVudHJ5IGFzIGFueSksXG4gICAgICBmaWVsZFBhdGgsXG4gICAgfVxuICB9XG5cbiAgY29uc3QgZXhwYW5kTm9kZSA9IChcbiAgICBzY29wZUlkOiBzdHJpbmcsXG4gICAgam9pblByZWZpeDogc3RyaW5nLFxuICAgIG5vZGU6IFN0YXRlVHJhaXROb2RlPGFueSwgYW55PixcbiAgICBvcHRpb25zPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBjaGVjayBkZXBzIFx1NTI0RFx1N0YwMFx1RkYxQVx1NzUyOFx1NEU4RSBsaXN0LXNjb3BlIGNoZWNrIFx1NzY4NFx1OUVEOFx1OEJBNFx1OEJFRFx1NEU0OVx1RkYwOGRlcHMgXHU3NkY4XHU1QkY5XHUyMDFDXHU4ODRDXHU1MTQzXHU3RDIwXHUyMDFEXHU4MDBDXHU5NzVFIGxpc3QgXHU2ODM5XHVGRjA5XHUzMDAyXG4gICAgICAgKlxuICAgICAgICogLSBpdGVtIHNjb3BlXHVGRjFBZGVwc1ByZWZpeCA9IGAke2xpc3RQYXRofVtdYFx1RkYwOFx1NEUwRSBqb2luUHJlZml4IFx1NEUwMFx1ODFGNFx1RkYwOVx1RkYxQlxuICAgICAgICogLSBsaXN0IHNjb3BlXHVGRjFBZmllbGRQYXRoID0gYCR7bGlzdFBhdGh9YFx1RkYwQ1x1NEY0NiBkZXBzUHJlZml4IFx1NUU5NFx1NEUzQSBgJHtsaXN0UGF0aH1bXWBcdTMwMDJcbiAgICAgICAqL1xuICAgICAgcmVhZG9ubHkgY2hlY2tEZXBzUHJlZml4Pzogc3RyaW5nXG4gICAgfSxcbiAgKTogdm9pZCA9PiB7XG4gICAgY29uc3QgYWRkRW50cnkgPSAocmVsYXRpdmVUYXJnZXQ6IHN0cmluZywgcmF3OiBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+KTogdm9pZCA9PiB7XG4gICAgICBjb25zdCByZWwgPSAocmF3IGFzIGFueSkuZmllbGRQYXRoID8/IHJlbGF0aXZlVGFyZ2V0XG4gICAgICBjb25zdCBmaWVsZFBhdGggPSBqb2luUHJlZml4ID8gam9pblBhdGgoam9pblByZWZpeCwgU3RyaW5nKHJlbCkpIDogU3RyaW5nKHJlbClcbiAgICAgIGVudHJpZXMucHVzaChub3JtYWxpemVFbnRyeShyYXcsIGZpZWxkUGF0aCwgam9pblByZWZpeCkpXG4gICAgfVxuXG4gICAgY29uc3QgZXhwYW5kTWF5YmVSZWNvcmQgPSAoXG4gICAgICB2YWx1ZTpcbiAgICAgICAgfCBTdGF0ZVRyYWl0RW50cnk8YW55LCBhbnk+XG4gICAgICAgIHwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgU3RhdGVUcmFpdEVudHJ5PGFueSwgYW55Pj4+XG4gICAgICAgIHwgdW5kZWZpbmVkLFxuICAgICk6IHZvaWQgPT4ge1xuICAgICAgaWYgKCF2YWx1ZSkgcmV0dXJuXG4gICAgICBpZiAodHlwZW9mICh2YWx1ZSBhcyBhbnkpLmtpbmQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgYWRkRW50cnkoXCJcIiwgdmFsdWUgYXMgYW55KVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY29yZCA9IHZhbHVlIGFzIFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFN0YXRlVHJhaXRFbnRyeTxhbnksIGFueT4+PlxuICAgICAgZm9yIChjb25zdCBrZXkgaW4gcmVjb3JkKSB7XG4gICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY29yZCwga2V5KSkgY29udGludWVcbiAgICAgICAgY29uc3QgZW50cnkgPSByZWNvcmRba2V5XVxuICAgICAgICBpZiAoIWVudHJ5KSBjb250aW51ZVxuICAgICAgICBhZGRFbnRyeShrZXksIGVudHJ5IGFzIGFueSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBleHBhbmRNYXliZVJlY29yZChub2RlLmNvbXB1dGVkKVxuICAgIGV4cGFuZE1heWJlUmVjb3JkKG5vZGUuc291cmNlKVxuICAgIGV4cGFuZE1heWJlUmVjb3JkKG5vZGUubGluaylcblxuICAgIGlmIChub2RlLmNoZWNrKSB7XG4gICAgICBjb25zdCBydWxlczogUmVjb3JkPHN0cmluZywgQ2hlY2tSdWxlPGFueSwgYW55Pj4gPSB7fVxuICAgICAgY29uc3QgY2hlY2tEZXBzUHJlZml4ID1cbiAgICAgICAgb3B0aW9ucz8uY2hlY2tEZXBzUHJlZml4ID8/IChqb2luUHJlZml4LmVuZHNXaXRoKFwiW11cIikgPyBqb2luUHJlZml4IDogXCJcIilcblxuICAgICAgY29uc3QgcHJlZml4Q2hlY2tEZXBzID0gKFxuICAgICAgICBkZXBzOiBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWQsXG4gICAgICApOiBSZWFkb25seUFycmF5PHN0cmluZz4gPT4ge1xuICAgICAgICBpZiAoIWRlcHMgfHwgZGVwcy5sZW5ndGggPT09IDApIHJldHVybiBbXVxuICAgICAgICByZXR1cm4gZGVwcy5tYXAoKGQpID0+XG4gICAgICAgICAgZCA9PT0gXCJcIiA/IHNjb3BlSWQgOiAoY2hlY2tEZXBzUHJlZml4ID8gam9pblBhdGgoY2hlY2tEZXBzUHJlZml4LCBkKSA6IGQpLFxuICAgICAgICApXG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXMobm9kZS5jaGVjaykpIHtcbiAgICAgICAgY29uc3QgcnVsZSA9IChub2RlLmNoZWNrIGFzIGFueSlbbmFtZV0gYXMgQ2hlY2tSdWxlPGFueSwgYW55PlxuICAgICAgICBpZiAodHlwZW9mIHJ1bGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIHJ1bGVzW25hbWVdID0gcnVsZVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJ1bGUgJiYgdHlwZW9mIHJ1bGUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICBjb25zdCBtZXRhID0gTWV0YS5zYW5pdGl6ZSgocnVsZSBhcyBhbnkpLm1ldGEpXG4gICAgICAgICAgcnVsZXNbbmFtZV0gPSB7XG4gICAgICAgICAgICAuLi5ydWxlLFxuICAgICAgICAgICAgZGVwczogcHJlZml4Q2hlY2tEZXBzKHJ1bGUuZGVwcyksXG4gICAgICAgICAgICBtZXRhLFxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG4gICAgICAgIC8vIFx1OTc1RVx1NkNENVx1OEY5M1x1NTE2NVx1RkYxQVx1NUZGRFx1NzU2NVx1RkYwOFx1NTQwRVx1N0VFRCBQaGFzZSBcdTVDMDZcdTU3MjggYnVpbGQgXHU5NjM2XHU2QkI1XHU2M0QwXHU1MzQ3XHU0RTNBXHU5MTREXHU3RjZFXHU5NTE5XHU4QkVGXHVGRjA5XHUzMDAyXG4gICAgICB9XG5cbiAgICAgIGVudHJpZXMucHVzaCh7XG4gICAgICAgIGZpZWxkUGF0aDogc2NvcGVJZCxcbiAgICAgICAga2luZDogXCJjaGVja1wiLFxuICAgICAgICBtZXRhOiB7XG4gICAgICAgICAgcnVsZXMsXG4gICAgICAgICAgd3JpdGViYWNrOiB7IGtpbmQ6IFwiZXJyb3JzXCIgfSxcbiAgICAgICAgfSxcbiAgICAgIH0gYXMgU3RhdGVUcmFpdEVudHJ5PGFueSwgYW55PilcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjKSB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3BlYywga2V5KSkgY29udGludWVcbiAgICBjb25zdCByYXcgPSBzcGVjW2tleSBhcyBrZXlvZiB0eXBlb2Ygc3BlY10gYXMgU3RhdGVUcmFpdFNwZWNWYWx1ZTxTLCBhbnk+IHwgdW5kZWZpbmVkXG4gICAgaWYgKCFyYXcpIGNvbnRpbnVlXG5cbiAgICBpZiAoaXNMaXN0KHJhdykpIHtcbiAgICAgIGNvbnN0IGxpc3RQYXRoID0ga2V5XG4gICAgICBpZiAocmF3Lml0ZW0pIHtcbiAgICAgICAgZXhwYW5kTm9kZShgJHtsaXN0UGF0aH1bXWAsIGAke2xpc3RQYXRofVtdYCwgcmF3Lml0ZW0pXG4gICAgICB9XG4gICAgICBpZiAocmF3Lmxpc3QpIHtcbiAgICAgICAgZXhwYW5kTm9kZShsaXN0UGF0aCwgbGlzdFBhdGgsIHJhdy5saXN0LCB7XG4gICAgICAgICAgY2hlY2tEZXBzUHJlZml4OiBgJHtsaXN0UGF0aH1bXWAsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmIChpc05vZGUocmF3KSkge1xuICAgICAgaWYgKGtleSA9PT0gXCIkcm9vdFwiKSB7XG4gICAgICAgIGV4cGFuZE5vZGUoXCIkcm9vdFwiLCBcIlwiLCByYXcpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleHBhbmROb2RlKGtleSwga2V5LCByYXcpXG4gICAgICB9XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGNvbnN0IGVudHJ5ID0gcmF3IGFzIGFueSBhcyBTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+XG4gICAgY29uc3QgZmllbGRQYXRoID0gKGVudHJ5IGFzIGFueSkuZmllbGRQYXRoID8/IGtleVxuICAgIGVudHJpZXMucHVzaChub3JtYWxpemVFbnRyeShlbnRyeSwgU3RyaW5nKGZpZWxkUGF0aCksIFwiXCIpKVxuICB9XG5cbiAgcmV0dXJuIGVudHJpZXNcbn1cblxuLyoqXG4gKiBjb2xsZWN0Tm9kZU1ldGFcdUZGMUFcbiAqIC0gXHU0RUNFIFN0YXRlVHJhaXRTcGVjIFx1NEUyRFx1NjNEMFx1NTNENiBTdGF0ZVRyYWl0Tm9kZS5tZXRhXHVGRjA4XHU3NjdEXHU1NDBEXHU1MzU1XHU1QjU3XHU2QkI1XHVGRjA5XHVGRjBDXHU0RjlCIERldnRvb2xzIFx1OEZEQlx1ODg0Q1x1N0VEM1x1Njc4NFx1NUM1NVx1NzkzQVx1RkYxQlxuICogLSBtZXRhIFx1NEVDNVx1NzUyOFx1NEU4RVx1OEJDQVx1NjVBRFx1NEUwRVx1NUM1NVx1NzkzQVx1RkYwQ1x1NEUwRFx1NTNDMlx1NEUwRVx1OEZEMFx1ODg0Q1x1NjVGNlx1OEJFRFx1NEU0OVx1MzAwMlxuICovXG5leHBvcnQgY29uc3QgY29sbGVjdE5vZGVNZXRhID0gPFM+KFxuICBzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPixcbik6IFJlYWRvbmx5TWFwPHN0cmluZywgTWV0YS5UcmFpdE1ldGE+ID0+IHtcbiAgY29uc3Qgb3V0ID0gbmV3IE1hcDxzdHJpbmcsIE1ldGEuVHJhaXRNZXRhPigpXG5cbiAgY29uc3QgaXNOb2RlID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgU3RhdGVUcmFpdE5vZGU8YW55LCBhbnk+ID0+XG4gICAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsICYmICh2YWx1ZSBhcyBhbnkpLl90YWcgPT09IFwiU3RhdGVUcmFpdE5vZGVcIlxuXG4gIGNvbnN0IGlzTGlzdCA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFN0YXRlVHJhaXRMaXN0PGFueT4gPT5cbiAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgKHZhbHVlIGFzIGFueSkuX3RhZyA9PT0gXCJTdGF0ZVRyYWl0TGlzdFwiXG5cbiAgY29uc3QgYWRkID0gKHNjb3BlSWQ6IHN0cmluZywgbm9kZTogU3RhdGVUcmFpdE5vZGU8YW55LCBhbnk+KTogdm9pZCA9PiB7XG4gICAgY29uc3QgbWV0YSA9IE1ldGEuc2FuaXRpemUobm9kZS5tZXRhKVxuICAgIGlmIChtZXRhKSBvdXQuc2V0KHNjb3BlSWQsIG1ldGEpXG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjKSB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3BlYywga2V5KSkgY29udGludWVcbiAgICBjb25zdCByYXcgPSBzcGVjW2tleSBhcyBrZXlvZiB0eXBlb2Ygc3BlY10gYXMgU3RhdGVUcmFpdFNwZWNWYWx1ZTxTLCBhbnk+IHwgdW5kZWZpbmVkXG4gICAgaWYgKCFyYXcpIGNvbnRpbnVlXG5cbiAgICBpZiAoaXNMaXN0KHJhdykpIHtcbiAgICAgIGNvbnN0IGxpc3RQYXRoID0ga2V5XG4gICAgICBpZiAocmF3Lml0ZW0pIGFkZChgJHtsaXN0UGF0aH1bXWAsIHJhdy5pdGVtKVxuICAgICAgaWYgKHJhdy5saXN0KSBhZGQobGlzdFBhdGgsIHJhdy5saXN0KVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoaXNOb2RlKHJhdykpIHtcbiAgICAgIGlmIChrZXkgPT09IFwiJHJvb3RcIikgYWRkKFwiJHJvb3RcIiwgcmF3KVxuICAgICAgZWxzZSBhZGQoa2V5LCByYXcpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cblxuLy8gLS0tLSBDb252ZXJnZSAoMDEzKSBldmlkZW5jZSBtb2RlbCAtLS0tXG5cbmV4cG9ydCB0eXBlIFRyYWl0Q29udmVyZ2VSZXF1ZXN0ZWRNb2RlID0gXCJhdXRvXCIgfCBcImZ1bGxcIiB8IFwiZGlydHlcIlxuZXhwb3J0IHR5cGUgVHJhaXRDb252ZXJnZUV4ZWN1dGVkTW9kZSA9IFwiZnVsbFwiIHwgXCJkaXJ0eVwiXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlT3V0Y29tZSA9IFwiQ29udmVyZ2VkXCIgfCBcIk5vb3BcIiB8IFwiRGVncmFkZWRcIlxuXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlQ29uZmlnU2NvcGUgPVxuICB8IFwicHJvdmlkZXJcIlxuICB8IFwicnVudGltZV9tb2R1bGVcIlxuICB8IFwicnVudGltZV9kZWZhdWx0XCJcbiAgfCBcImJ1aWx0aW5cIlxuXG5leHBvcnQgdHlwZSBUcmFpdENvbnZlcmdlUmVhc29uID1cbiAgfCBcImNvbGRfc3RhcnRcIlxuICB8IFwiY2FjaGVfaGl0XCJcbiAgfCBcImNhY2hlX21pc3NcIlxuICB8IFwiYnVkZ2V0X2N1dG9mZlwiXG4gIHwgXCJuZWFyX2Z1bGxcIlxuICB8IFwidW5rbm93bl93cml0ZVwiXG4gIHwgXCJkaXJ0eV9hbGxcIlxuICB8IFwiZ2VuZXJhdGlvbl9idW1wZWRcIlxuICB8IFwibG93X2hpdF9yYXRlX3Byb3RlY3Rpb25cIlxuICB8IFwibW9kdWxlX292ZXJyaWRlXCJcblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlU3RlcFN0YXRzIHtcbiAgcmVhZG9ubHkgdG90YWxTdGVwczogbnVtYmVyXG4gIHJlYWRvbmx5IGV4ZWN1dGVkU3RlcHM6IG51bWJlclxuICByZWFkb25seSBza2lwcGVkU3RlcHM6IG51bWJlclxuICByZWFkb25seSBjaGFuZ2VkU3RlcHM6IG51bWJlclxuICByZWFkb25seSBhZmZlY3RlZFN0ZXBzPzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZURpcnR5U3VtbWFyeSB7XG4gIHJlYWRvbmx5IGRpcnR5QWxsOiBib29sZWFuXG4gIHJlYWRvbmx5IHJlYXNvbj86IERpcnR5QWxsUmVhc29uXG4gIHJlYWRvbmx5IHJvb3RDb3VudD86IG51bWJlclxuICByZWFkb25seSByb290SWRzPzogUmVhZG9ubHlBcnJheTxudW1iZXI+XG4gIHJlYWRvbmx5IHJvb3RJZHNUcnVuY2F0ZWQ/OiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZVBsYW5DYWNoZUV2aWRlbmNlIHtcbiAgcmVhZG9ubHkgY2FwYWNpdHk6IG51bWJlclxuICByZWFkb25seSBzaXplOiBudW1iZXJcbiAgcmVhZG9ubHkgaGl0czogbnVtYmVyXG4gIHJlYWRvbmx5IG1pc3NlczogbnVtYmVyXG4gIHJlYWRvbmx5IGV2aWN0czogbnVtYmVyXG4gIHJlYWRvbmx5IGhpdDogYm9vbGVhblxuICByZWFkb25seSBrZXlTaXplPzogbnVtYmVyXG4gIHJlYWRvbmx5IG1pc3NSZWFzb24/OiBcImNvbGRfc3RhcnRcIiB8IFwiZ2VuZXJhdGlvbl9idW1wZWRcIiB8IFwibm90X2NhY2hlZFwiIHwgXCJ1bmtub3duXCJcbiAgcmVhZG9ubHkgZGlzYWJsZWQ/OiBib29sZWFuXG4gIHJlYWRvbmx5IGRpc2FibGVSZWFzb24/OiBcImxvd19oaXRfcmF0ZVwiIHwgXCJnZW5lcmF0aW9uX3RocmFzaFwiIHwgXCJtYW51YWxfb3ZlcnJpZGVcIiB8IFwidW5rbm93blwiXG59XG5cbmV4cG9ydCB0eXBlIFRyYWl0Q29udmVyZ2VHZW5lcmF0aW9uQnVtcFJlYXNvbiA9XG4gIHwgXCJ3cml0ZXJzX2NoYW5nZWRcIlxuICB8IFwiZGVwc19jaGFuZ2VkXCJcbiAgfCBcImxvZ2ljX2luc3RhbGxlZFwiXG4gIHwgXCJsb2dpY191bmluc3RhbGxlZFwiXG4gIHwgXCJpbXBvcnRzX2NoYW5nZWRcIlxuICB8IFwidW5rbm93blwiXG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZUdlbmVyYXRpb25FdmlkZW5jZSB7XG4gIHJlYWRvbmx5IGdlbmVyYXRpb246IG51bWJlclxuICByZWFkb25seSBnZW5lcmF0aW9uQnVtcENvdW50PzogbnVtYmVyXG4gIHJlYWRvbmx5IGxhc3RCdW1wUmVhc29uPzogVHJhaXRDb252ZXJnZUdlbmVyYXRpb25CdW1wUmVhc29uXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhaXRDb252ZXJnZVN0YXRpY0lyRXZpZGVuY2Uge1xuICByZWFkb25seSBmaWVsZFBhdGhDb3VudDogbnVtYmVyXG4gIHJlYWRvbmx5IHN0ZXBDb3VudDogbnVtYmVyXG4gIHJlYWRvbmx5IGJ1aWxkRHVyYXRpb25Ncz86IG51bWJlclxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWl0Q29udmVyZ2VIb3RzcG90IHtcbiAgcmVhZG9ubHkga2luZD86IHN0cmluZ1xuICByZWFkb25seSBzdGVwSWQ6IG51bWJlclxuICByZWFkb25seSBvdXRGaWVsZFBhdGhJZD86IG51bWJlclxuICByZWFkb25seSBkdXJhdGlvbk1zOiBudW1iZXJcbiAgcmVhZG9ubHkgY2hhbmdlZDogYm9vbGVhblxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWl0Q29udmVyZ2VEZWNpc2lvblN1bW1hcnkge1xuICByZWFkb25seSByZXF1ZXN0ZWRNb2RlOiBUcmFpdENvbnZlcmdlUmVxdWVzdGVkTW9kZVxuICByZWFkb25seSBleGVjdXRlZE1vZGU6IFRyYWl0Q29udmVyZ2VFeGVjdXRlZE1vZGVcbiAgcmVhZG9ubHkgb3V0Y29tZTogVHJhaXRDb252ZXJnZU91dGNvbWVcbiAgcmVhZG9ubHkgY29uZmlnU2NvcGU6IFRyYWl0Q29udmVyZ2VDb25maWdTY29wZVxuICByZWFkb25seSBzdGF0aWNJckRpZ2VzdDogc3RyaW5nXG4gIHJlYWRvbmx5IGV4ZWN1dGlvbkJ1ZGdldE1zOiBudW1iZXJcbiAgcmVhZG9ubHkgZXhlY3V0aW9uRHVyYXRpb25NczogbnVtYmVyXG4gIHJlYWRvbmx5IGRlY2lzaW9uQnVkZ2V0TXM/OiBudW1iZXJcbiAgcmVhZG9ubHkgZGVjaXNpb25EdXJhdGlvbk1zPzogbnVtYmVyXG4gIHJlYWRvbmx5IHJlYXNvbnM6IFJlYWRvbmx5QXJyYXk8VHJhaXRDb252ZXJnZVJlYXNvbj5cbiAgcmVhZG9ubHkgc3RlcFN0YXRzOiBUcmFpdENvbnZlcmdlU3RlcFN0YXRzXG4gIHJlYWRvbmx5IGRpcnR5PzogVHJhaXRDb252ZXJnZURpcnR5U3VtbWFyeVxuICByZWFkb25seSBjYWNoZT86IFRyYWl0Q29udmVyZ2VQbGFuQ2FjaGVFdmlkZW5jZVxuICByZWFkb25seSBnZW5lcmF0aW9uPzogVHJhaXRDb252ZXJnZUdlbmVyYXRpb25FdmlkZW5jZVxuICByZWFkb25seSBzdGF0aWNJcj86IFRyYWl0Q29udmVyZ2VTdGF0aWNJckV2aWRlbmNlXG4gIHJlYWRvbmx5IHRocmVzaG9sZHM/OiB7IHJlYWRvbmx5IGZsb29yUmF0aW8/OiBudW1iZXIgfVxuICByZWFkb25seSB0b3AzPzogUmVhZG9ubHlBcnJheTxUcmFpdENvbnZlcmdlSG90c3BvdD5cbn1cbiIsICJpbXBvcnQgdHlwZSB7IFNjaGVtYSB9IGZyb20gXCJlZmZlY3RcIlxuaW1wb3J0IHtcbiAgdHlwZSBTdGF0ZVRyYWl0UHJvZ3JhbSxcbiAgdHlwZSBTdGF0ZVRyYWl0U3BlYyxcbiAgdHlwZSBTdGF0ZVRyYWl0RW50cnksXG4gIHR5cGUgU3RhdGVUcmFpdEdyYXBoLFxuICB0eXBlIFN0YXRlVHJhaXRHcmFwaEVkZ2UsXG4gIHR5cGUgU3RhdGVUcmFpdEdyYXBoTm9kZSxcbiAgdHlwZSBTdGF0ZVRyYWl0RmllbGQsXG4gIHR5cGUgU3RhdGVUcmFpdEZpZWxkVHJhaXQsXG4gIHR5cGUgU3RhdGVUcmFpdFBsYW4sXG4gIHR5cGUgU3RhdGVUcmFpdFBsYW5TdGVwLFxuICB0eXBlIFN0YXRlVHJhaXRSZXNvdXJjZSxcbiAgY29sbGVjdE5vZGVNZXRhLFxuICBub3JtYWxpemVTcGVjLFxufSBmcm9tIFwiLi9tb2RlbC5qc1wiXG5pbXBvcnQgKiBhcyBNZXRhIGZyb20gXCIuL21ldGEuanNcIlxuaW1wb3J0IHtcbiAgY29tcGFyZUZpZWxkUGF0aCxcbiAgZ2V0RmllbGRQYXRoSWQsXG4gIG1ha2VGaWVsZFBhdGhJZFJlZ2lzdHJ5LFxuICBub3JtYWxpemVGaWVsZFBhdGgsXG4gIHR5cGUgRmllbGRQYXRoLFxuICB0eXBlIEZpZWxkUGF0aElkLFxufSBmcm9tIFwiLi4vZmllbGQtcGF0aC5qc1wiXG5pbXBvcnQgdHlwZSB7IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeSB9IGZyb20gXCIuL2NvbnZlcmdlLWlyLmpzXCJcblxuY29uc3Qgbm93UGVyZiA9ICgpOiBudW1iZXIgPT5cbiAgdHlwZW9mIGdsb2JhbFRoaXMucGVyZm9ybWFuY2UgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgdHlwZW9mIGdsb2JhbFRoaXMucGVyZm9ybWFuY2Uubm93ID09PSBcImZ1bmN0aW9uXCJcbiAgICA/IGdsb2JhbFRoaXMucGVyZm9ybWFuY2Uubm93KClcbiAgICA6IERhdGUubm93KClcblxudHlwZSBDb252ZXJnZVdyaXRlciA9IEV4dHJhY3Q8XG4gIFN0YXRlVHJhaXRFbnRyeTxhbnksIHN0cmluZz4sXG4gIHsgcmVhZG9ubHkga2luZDogXCJjb21wdXRlZFwiIHwgXCJsaW5rXCIgfVxuPlxuXG5jb25zdCBnZXRDb252ZXJnZVdyaXRlckRlcHMgPSAoZW50cnk6IENvbnZlcmdlV3JpdGVyKTogUmVhZG9ubHlBcnJheTxzdHJpbmc+ID0+IHtcbiAgaWYgKGVudHJ5LmtpbmQgPT09IFwiY29tcHV0ZWRcIikge1xuICAgIHJldHVybiAoKGVudHJ5Lm1ldGEgYXMgYW55KT8uZGVwcyA/PyBbXSkgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+XG4gIH1cbiAgcmV0dXJuIFtlbnRyeS5tZXRhLmZyb20gYXMgc3RyaW5nXVxufVxuXG5jb25zdCBjb21wdXRlQ29udmVyZ2VUb3BvT3JkZXIgPSAoXG4gIHdyaXRlcnM6IFJlYWRvbmx5QXJyYXk8Q29udmVyZ2VXcml0ZXI+LFxuKTogeyByZWFkb25seSBvcmRlcjogUmVhZG9ubHlBcnJheTxzdHJpbmc+OyByZWFkb25seSBjb25maWdFcnJvcj86IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeVtcImNvbmZpZ0Vycm9yXCJdIH0gPT4ge1xuICBjb25zdCB3cml0ZXJCeVBhdGggPSBuZXcgTWFwPHN0cmluZywgQ29udmVyZ2VXcml0ZXI+KClcbiAgZm9yIChjb25zdCBlbnRyeSBvZiB3cml0ZXJzKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB3cml0ZXJCeVBhdGguZ2V0KGVudHJ5LmZpZWxkUGF0aClcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9yZGVyOiBbXSxcbiAgICAgICAgY29uZmlnRXJyb3I6IHtcbiAgICAgICAgICBjb2RlOiBcIk1VTFRJUExFX1dSSVRFUlNcIixcbiAgICAgICAgICBtZXNzYWdlOiBgW1N0YXRlVHJhaXQuY29udmVyZ2VdIE11bHRpcGxlIHdyaXRlcnMgZm9yIGZpZWxkIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIgKCR7ZXhpc3Rpbmcua2luZH0gKyAke2VudHJ5LmtpbmR9KS5gLFxuICAgICAgICAgIGZpZWxkczogW2VudHJ5LmZpZWxkUGF0aF0sXG4gICAgICAgIH0sXG4gICAgICB9XG4gICAgfVxuICAgIHdyaXRlckJ5UGF0aC5zZXQoZW50cnkuZmllbGRQYXRoLCBlbnRyeSlcbiAgfVxuXG4gIGNvbnN0IG5vZGVzID0gbmV3IFNldDxzdHJpbmc+KClcbiAgZm9yIChjb25zdCBlbnRyeSBvZiB3cml0ZXJzKSB7XG4gICAgbm9kZXMuYWRkKGVudHJ5LmZpZWxkUGF0aClcbiAgfVxuXG4gIGNvbnN0IGluZGVncmVlID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKVxuICBjb25zdCBmb3J3YXJkID0gbmV3IE1hcDxzdHJpbmcsIEFycmF5PHN0cmluZz4+KClcblxuICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZXMpIHtcbiAgICBpbmRlZ3JlZS5zZXQobm9kZSwgMClcbiAgICBmb3J3YXJkLnNldChub2RlLCBbXSlcbiAgfVxuXG4gIGZvciAoY29uc3QgZW50cnkgb2Ygd3JpdGVycykge1xuICAgIGNvbnN0IHRvID0gZW50cnkuZmllbGRQYXRoXG4gICAgY29uc3QgZGVwcyA9IGdldENvbnZlcmdlV3JpdGVyRGVwcyhlbnRyeSlcbiAgICBmb3IgKGNvbnN0IGRlcCBvZiBkZXBzKSB7XG4gICAgICBpZiAoIW5vZGVzLmhhcyhkZXApKSBjb250aW51ZVxuICAgICAgZm9yd2FyZC5nZXQoZGVwKSEucHVzaCh0bylcbiAgICAgIGluZGVncmVlLnNldCh0bywgKGluZGVncmVlLmdldCh0bykgPz8gMCkgKyAxKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHF1ZXVlOiBBcnJheTxzdHJpbmc+ID0gW11cbiAgZm9yIChjb25zdCBbbm9kZSwgZGVnXSBvZiBpbmRlZ3JlZS5lbnRyaWVzKCkpIHtcbiAgICBpZiAoZGVnID09PSAwKSBxdWV1ZS5wdXNoKG5vZGUpXG4gIH1cblxuICBjb25zdCBvcmRlcjogQXJyYXk8c3RyaW5nPiA9IFtdXG4gIHdoaWxlIChxdWV1ZS5sZW5ndGgpIHtcbiAgICBjb25zdCBuID0gcXVldWUuc2hpZnQoKSFcbiAgICBvcmRlci5wdXNoKG4pXG4gICAgY29uc3Qgb3V0cyA9IGZvcndhcmQuZ2V0KG4pIVxuICAgIGZvciAoY29uc3QgdG8gb2Ygb3V0cykge1xuICAgICAgY29uc3QgbmV4dCA9IChpbmRlZ3JlZS5nZXQodG8pID8/IDApIC0gMVxuICAgICAgaW5kZWdyZWUuc2V0KHRvLCBuZXh0KVxuICAgICAgaWYgKG5leHQgPT09IDApIHF1ZXVlLnB1c2godG8pXG4gICAgfVxuICB9XG5cbiAgaWYgKG9yZGVyLmxlbmd0aCAhPT0gbm9kZXMuc2l6ZSkge1xuICAgIGNvbnN0IHJlbWFpbmluZyA9IEFycmF5LmZyb20obm9kZXMpLmZpbHRlcigobikgPT4gIW9yZGVyLmluY2x1ZGVzKG4pKVxuICAgIHJldHVybiB7XG4gICAgICBvcmRlcjogW10sXG4gICAgICBjb25maWdFcnJvcjoge1xuICAgICAgICBjb2RlOiBcIkNZQ0xFX0RFVEVDVEVEXCIsXG4gICAgICAgIG1lc3NhZ2U6IGBbU3RhdGVUcmFpdC5jb252ZXJnZV0gQ3ljbGUgZGV0ZWN0ZWQgaW4gY29tcHV0ZWQvbGluayBncmFwaDogJHtyZW1haW5pbmcuam9pbihcIiwgXCIpfWAsXG4gICAgICAgIGZpZWxkczogcmVtYWluaW5nLFxuICAgICAgfSxcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBvcmRlciB9XG59XG5cbmNvbnN0IGJ1aWxkQ29udmVyZ2VJciA9IChcbiAgZW50cmllczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+Pixcbik6IENvbnZlcmdlU3RhdGljSXJSZWdpc3RyeSA9PiB7XG4gIGNvbnN0IHN0YXJ0ZWRBdCA9IG5vd1BlcmYoKVxuICBjb25zdCBnZW5lcmF0aW9uID0gMFxuXG4gIGNvbnN0IHdyaXRlcnMgPSBlbnRyaWVzLmZpbHRlcihcbiAgICAoZSk6IGUgaXMgQ29udmVyZ2VXcml0ZXIgPT4gZS5raW5kID09PSBcImNvbXB1dGVkXCIgfHwgZS5raW5kID09PSBcImxpbmtcIixcbiAgKVxuXG4gIGNvbnN0IHdyaXRlcnNLZXkgPSB3cml0ZXJzXG4gICAgLm1hcCgoZW50cnkpID0+IGAke2VudHJ5LmtpbmR9OiR7ZW50cnkuZmllbGRQYXRofWApXG4gICAgLnNvcnQoKVxuICAgIC5qb2luKFwifFwiKVxuXG4gIGNvbnN0IGRlcHNLZXkgPSB3cml0ZXJzXG4gICAgLm1hcCgoZW50cnkpID0+IHtcbiAgICAgIGNvbnN0IGRlcHMgPSBnZXRDb252ZXJnZVdyaXRlckRlcHMoZW50cnkpLnNsaWNlKCkuc29ydCgpLmpvaW4oXCIsXCIpXG4gICAgICByZXR1cm4gYCR7ZW50cnkua2luZH06JHtlbnRyeS5maWVsZFBhdGh9PT4ke2RlcHN9YFxuICAgIH0pXG4gICAgLnNvcnQoKVxuICAgIC5qb2luKFwifFwiKVxuXG4gIGNvbnN0IHdyaXRlckJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBDb252ZXJnZVdyaXRlcj4oKVxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHdyaXRlcnMpIHtcbiAgICB3cml0ZXJCeVBhdGguc2V0KGVudHJ5LmZpZWxkUGF0aCwgZW50cnkpXG4gIH1cblxuICBjb25zdCB0b3BvID0gd3JpdGVycy5sZW5ndGggPiAwID8gY29tcHV0ZUNvbnZlcmdlVG9wb09yZGVyKHdyaXRlcnMpIDogeyBvcmRlcjogW10gYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IH1cbiAgY29uc3Qgc3RlcHNCeUlkOiBBcnJheTxDb252ZXJnZVdyaXRlcj4gPSB0b3BvLmNvbmZpZ0Vycm9yXG4gICAgPyBbXVxuICAgIDogdG9wby5vcmRlci5tYXAoKHBhdGgpID0+IHdyaXRlckJ5UGF0aC5nZXQocGF0aCkhKVxuXG4gIGNvbnN0IGZpZWxkUGF0aFRhYmxlID0gbmV3IE1hcDxzdHJpbmcsIEZpZWxkUGF0aD4oKVxuICBjb25zdCBhZGRQYXRoID0gKHBhdGg6IEZpZWxkUGF0aCk6IHZvaWQgPT4ge1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IHBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHByZWZpeCA9IHBhdGguc2xpY2UoMCwgaSlcbiAgICAgIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KHByZWZpeClcbiAgICAgIGlmICghZmllbGRQYXRoVGFibGUuaGFzKGtleSkpIGZpZWxkUGF0aFRhYmxlLnNldChrZXksIHByZWZpeClcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHdyaXRlcnMpIHtcbiAgICBjb25zdCBvdXQgPSBub3JtYWxpemVGaWVsZFBhdGgoZW50cnkuZmllbGRQYXRoKVxuICAgIGlmIChvdXQpIGFkZFBhdGgob3V0KVxuICAgIGZvciAoY29uc3QgZGVwIG9mIGdldENvbnZlcmdlV3JpdGVyRGVwcyhlbnRyeSkpIHtcbiAgICAgIGNvbnN0IGRlcFBhdGggPSBub3JtYWxpemVGaWVsZFBhdGgoZGVwKVxuICAgICAgaWYgKGRlcFBhdGgpIGFkZFBhdGgoZGVwUGF0aClcbiAgICB9XG4gIH1cblxuICBjb25zdCBmaWVsZFBhdGhzID0gQXJyYXkuZnJvbShmaWVsZFBhdGhUYWJsZS52YWx1ZXMoKSkuc29ydChjb21wYXJlRmllbGRQYXRoKVxuICBjb25zdCBmaWVsZFBhdGhJZFJlZ2lzdHJ5ID0gbWFrZUZpZWxkUGF0aElkUmVnaXN0cnkoZmllbGRQYXRocylcblxuICBjb25zdCBzdGVwT3V0RmllbGRQYXRoSWRCeVN0ZXBJZDogQXJyYXk8RmllbGRQYXRoSWQ+ID0gW11cbiAgY29uc3Qgc3RlcERlcHNGaWVsZFBhdGhJZHNCeVN0ZXBJZDogQXJyYXk8UmVhZG9ubHlBcnJheTxGaWVsZFBhdGhJZD4+ID0gW11cblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHN0ZXBzQnlJZCkge1xuICAgIGNvbnN0IG91dCA9IG5vcm1hbGl6ZUZpZWxkUGF0aChlbnRyeS5maWVsZFBhdGgpXG4gICAgY29uc3Qgb3V0SWQgPVxuICAgICAgb3V0ICE9IG51bGwgPyBnZXRGaWVsZFBhdGhJZChmaWVsZFBhdGhJZFJlZ2lzdHJ5LCBvdXQpIDogdW5kZWZpbmVkXG4gICAgaWYgKG91dElkID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBGYWlsZWQgdG8gbWFwIGNvbnZlcmdlIG91dHB1dCBmaWVsZFBhdGggXCIke2VudHJ5LmZpZWxkUGF0aH1cIiB0byBGaWVsZFBhdGhJZC5gLFxuICAgICAgKVxuICAgIH1cblxuICAgIGNvbnN0IGRlcElkczogQXJyYXk8RmllbGRQYXRoSWQ+ID0gW11cbiAgICBmb3IgKGNvbnN0IGRlcCBvZiBnZXRDb252ZXJnZVdyaXRlckRlcHMoZW50cnkpKSB7XG4gICAgICBjb25zdCBkZXBQYXRoID0gbm9ybWFsaXplRmllbGRQYXRoKGRlcClcbiAgICAgIGlmICghZGVwUGF0aCkgY29udGludWVcbiAgICAgIGNvbnN0IGRlcElkID0gZ2V0RmllbGRQYXRoSWQoZmllbGRQYXRoSWRSZWdpc3RyeSwgZGVwUGF0aClcbiAgICAgIGlmIChkZXBJZCAhPSBudWxsKSBkZXBJZHMucHVzaChkZXBJZClcbiAgICB9XG5cbiAgICBzdGVwT3V0RmllbGRQYXRoSWRCeVN0ZXBJZC5wdXNoKG91dElkKVxuICAgIHN0ZXBEZXBzRmllbGRQYXRoSWRzQnlTdGVwSWQucHVzaChkZXBJZHMpXG4gIH1cblxuICBjb25zdCB0b3BvT3JkZXIgPSBzdGVwc0J5SWQubWFwKChfLCBpKSA9PiBpKVxuICBjb25zdCBidWlsZER1cmF0aW9uTXMgPSBNYXRoLm1heCgwLCBub3dQZXJmKCkgLSBzdGFydGVkQXQpXG5cbiAgcmV0dXJuIHtcbiAgICBnZW5lcmF0aW9uLFxuICAgIHdyaXRlcnNLZXksXG4gICAgZGVwc0tleSxcbiAgICBmaWVsZFBhdGhzLFxuICAgIGZpZWxkUGF0aElkUmVnaXN0cnksXG4gICAgLi4uKHRvcG8uY29uZmlnRXJyb3IgPyB7IGNvbmZpZ0Vycm9yOiB0b3BvLmNvbmZpZ0Vycm9yIH0gOiBudWxsKSxcbiAgICBzdGVwc0J5SWQsXG4gICAgc3RlcE91dEZpZWxkUGF0aElkQnlTdGVwSWQsXG4gICAgc3RlcERlcHNGaWVsZFBhdGhJZHNCeVN0ZXBJZCxcbiAgICB0b3BvT3JkZXIsXG4gICAgYnVpbGREdXJhdGlvbk1zLFxuICB9XG59XG5cbi8qKlxuICogXHU2ODM5XHU2MzZFIFN0YXRlVHJhaXRFbnRyeSBcdTY3ODRcdTkwMjBcdTY4MDdcdTUxQzZcdTUzMTZcdTc2ODQgRmllbGRUcmFpdFx1MzAwMlxuICpcbiAqIC0gXHU3NkVFXHU1MjREXHU0RUM1XHU1QkY5IGxpbmsvc291cmNlIFx1NTg2Qlx1NTE0NSBkZXBzIFx1NEZFMVx1NjA2Rlx1RkYwQ2NvbXB1dGVkIFx1NzY4NFx1NEY5RFx1OEQ1Nlx1NjY4Mlx1NEUwRFx1OTc1OVx1NjAwMVx1NTIwNlx1Njc5MFx1RkYxQlxuICogLSBcdTU0MEVcdTdFRURcdTgyRTVcdTVGMTVcdTUxNjVcdTY2M0VcdTVGMEZcdTRGOURcdThENTZcdTU4RjBcdTY2MEVcdUZGMENcdTUzRUZcdTRFRTVcdTU3MjhcdTZCNjRcdTU5MDRcdTYyNjlcdTVDNTVcdTMwMDJcbiAqL1xuY29uc3QgdG9GaWVsZFRyYWl0ID0gKFxuICBlbnRyeTogU3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPixcbik6IFN0YXRlVHJhaXRGaWVsZFRyYWl0ID0+IHtcbiAgY29uc3QgZGVwczogQXJyYXk8c3RyaW5nPiA9IFtdXG5cbiAgaWYgKGVudHJ5LmtpbmQgPT09IFwiY29tcHV0ZWRcIikge1xuICAgIGNvbnN0IG1ldGEgPSBlbnRyeS5tZXRhIGFzIGFueVxuICAgIGNvbnN0IGxpc3QgPSBtZXRhLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgaWYgKGxpc3QpIGRlcHMucHVzaCguLi5saXN0KVxuICB9IGVsc2UgaWYgKGVudHJ5LmtpbmQgPT09IFwic291cmNlXCIpIHtcbiAgICBjb25zdCBtZXRhID0gZW50cnkubWV0YSBhcyBhbnlcbiAgICBjb25zdCBsaXN0ID0gbWV0YS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgIGlmIChsaXN0KSBkZXBzLnB1c2goLi4ubGlzdClcbiAgfSBlbHNlIGlmIChlbnRyeS5raW5kID09PSBcImxpbmtcIikge1xuICAgIGRlcHMucHVzaChlbnRyeS5tZXRhLmZyb20gYXMgc3RyaW5nKVxuICB9IGVsc2UgaWYgKGVudHJ5LmtpbmQgPT09IFwiY2hlY2tcIikge1xuICAgIGNvbnN0IG1ldGEgPSBlbnRyeS5tZXRhIGFzIGFueVxuICAgIGNvbnN0IHJ1bGVzID0gKG1ldGE/LnJ1bGVzID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHJ1bGVzKSkge1xuICAgICAgY29uc3QgcnVsZSA9IHJ1bGVzW25hbWVdXG4gICAgICBpZiAocnVsZSAmJiB0eXBlb2YgcnVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBjb25zdCBsaXN0ID0gcnVsZS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgICBpZiAobGlzdCkgZGVwcy5wdXNoKC4uLmxpc3QpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBmaWVsZElkOiBlbnRyeS5maWVsZFBhdGgsXG4gICAga2luZDogZW50cnkua2luZCxcbiAgICAvLyBtZXRhIFx1NTcyOFx1OEZEMFx1ODg0Q1x1NjVGNlx1NEZERFx1NjMwMVx1NEUwRSBFbnRyeS5tZXRhIFx1NEUwMFx1ODFGNFx1RkYwQ1x1NEZCRlx1NEU4RSBpbnN0YWxsIFx1NzZGNFx1NjNBNVx1NTkwRFx1NzUyOFx1MzAwMlxuICAgIG1ldGE6IGVudHJ5Lm1ldGEgYXMgYW55LFxuICAgIGRlcHMsXG4gIH1cbn1cblxuLyoqXG4gKiBcdTRFQ0VcdTVGNTJcdTRFMDBcdTUzMTZcdTc2ODQgRW50cnkgXHU1MjE3XHU4ODY4XHU2Nzg0XHU1RUZBIEZpZWxkIC8gTm9kZSAvIEVkZ2UgLyBSZXNvdXJjZSBcdTk2QzZcdTU0MDhcdTMwMDJcbiAqL1xuY29uc3QgYnVpbGRHcmFwaCA9IChcbiAgZW50cmllczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PixcbiAgbm9kZU1ldGFCeUZpZWxkUGF0aDogUmVhZG9ubHlNYXA8c3RyaW5nLCBNZXRhLlRyYWl0TWV0YT4sXG4pOiB7XG4gIHJlYWRvbmx5IGdyYXBoOiBTdGF0ZVRyYWl0R3JhcGhcbiAgcmVhZG9ubHkgcGxhbjogU3RhdGVUcmFpdFBsYW5cbn0gPT4ge1xuICBjb25zdCBmaWVsZE1hcCA9IG5ldyBNYXA8c3RyaW5nLCBTdGF0ZVRyYWl0RmllbGQ+KClcbiAgY29uc3Qgbm9kZXM6IEFycmF5PFN0YXRlVHJhaXRHcmFwaE5vZGU+ID0gW11cbiAgY29uc3QgZWRnZXM6IEFycmF5PFN0YXRlVHJhaXRHcmFwaEVkZ2U+ID0gW11cbiAgY29uc3QgcmVzb3VyY2VzQnlJZCA9IG5ldyBNYXA8c3RyaW5nLCBTdGF0ZVRyYWl0UmVzb3VyY2U+KClcbiAgY29uc3QgcGxhblN0ZXBzOiBBcnJheTxTdGF0ZVRyYWl0UGxhblN0ZXA+ID0gW11cblxuICBjb25zdCBlbnN1cmVGaWVsZCA9IChmaWVsZFBhdGg6IHN0cmluZyk6IFN0YXRlVHJhaXRGaWVsZCA9PiB7XG4gICAgbGV0IGZpZWxkID0gZmllbGRNYXAuZ2V0KGZpZWxkUGF0aClcbiAgICBpZiAoIWZpZWxkKSB7XG4gICAgICBmaWVsZCA9IHtcbiAgICAgICAgaWQ6IGZpZWxkUGF0aCxcbiAgICAgICAgcGF0aDogZmllbGRQYXRoLFxuICAgICAgICB0cmFpdHM6IFtdLFxuICAgICAgfVxuICAgICAgZmllbGRNYXAuc2V0KGZpZWxkUGF0aCwgZmllbGQpXG4gICAgfVxuICAgIHJldHVybiBmaWVsZFxuICB9XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgY29uc3QgZmllbGRQYXRoID0gZW50cnkuZmllbGRQYXRoXG4gICAgY29uc3QgZmllbGQgPSBlbnN1cmVGaWVsZChmaWVsZFBhdGgpXG4gICAgY29uc3QgdHJhaXQgPSB0b0ZpZWxkVHJhaXQoZW50cnkpXG5cbiAgICA7KGZpZWxkLnRyYWl0cyBhcyBBcnJheTxTdGF0ZVRyYWl0RmllbGRUcmFpdD4pLnB1c2godHJhaXQpXG5cbiAgICAvLyBcdTk0ODhcdTVCRjlcdTRFMERcdTU0MEMga2luZCBcdTY3ODRcdTVFRkEgR3JhcGggXHU4RkI5XHU0RTBFIFBsYW4gXHU2QjY1XHU5QUE0XHUzMDAyXG4gICAgaWYgKGVudHJ5LmtpbmQgPT09IFwiY29tcHV0ZWRcIikge1xuICAgICAgY29uc3Qgc3RlcElkID0gYGNvbXB1dGVkOiR7ZmllbGRQYXRofWBcbiAgICAgIHBsYW5TdGVwcy5wdXNoKHtcbiAgICAgICAgaWQ6IHN0ZXBJZCxcbiAgICAgICAga2luZDogXCJjb21wdXRlZC11cGRhdGVcIixcbiAgICAgICAgdGFyZ2V0RmllbGRQYXRoOiBmaWVsZFBhdGgsXG4gICAgICAgIC8vIFx1OEJGNFx1NjYwRVx1RkYxQVx1NUY1M1x1NTI0RFx1NzI0OFx1NjcyQ1x1NEUwRFx1OTc1OVx1NjAwMVx1NTIwNlx1Njc5MCBjb21wdXRlZCBcdTRGOURcdThENTZcdTVCNTdcdTZCQjVcdUZGMENzb3VyY2VGaWVsZFBhdGhzIFx1NzU1OVx1N0E3QVx1MzAwMlxuICAgICAgfSlcbiAgICAgIC8vIFx1ODJFNVx1NjYzRVx1NUYwRlx1NThGMFx1NjYwRSBkZXBzXHVGRjBDXHU1MjE5XHU4ODY1XHU1MTQ1IEdyYXBoIFx1OEZCOVx1RkYwOFx1NzUyOFx1NEU4RVx1OEJDQVx1NjVBRC9cdTUzQ0RcdTU0MTFcdTk1RURcdTUzMDVcdThCQTFcdTdCOTdcdUZGMDlcdTMwMDJcbiAgICAgIGNvbnN0IGRlcHMgPSAoZW50cnkubWV0YSBhcyBhbnkpLmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkXG4gICAgICBpZiAoZGVwcykge1xuICAgICAgICBmb3IgKGNvbnN0IGRlcCBvZiBkZXBzKSB7XG4gICAgICAgICAgZW5zdXJlRmllbGQoZGVwKVxuICAgICAgICAgIGVkZ2VzLnB1c2goe1xuICAgICAgICAgICAgaWQ6IGBjb21wdXRlZDoke2RlcH0tPiR7ZmllbGRQYXRofWAsXG4gICAgICAgICAgICBmcm9tOiBkZXAsXG4gICAgICAgICAgICB0bzogZmllbGRQYXRoLFxuICAgICAgICAgICAga2luZDogXCJjb21wdXRlZFwiLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVudHJ5LmtpbmQgPT09IFwibGlua1wiKSB7XG4gICAgICBjb25zdCBmcm9tID0gZW50cnkubWV0YS5mcm9tIGFzIHN0cmluZ1xuICAgICAgZW5zdXJlRmllbGQoZnJvbSlcblxuICAgICAgY29uc3QgZWRnZUlkID0gYGxpbms6JHtmcm9tfS0+JHtmaWVsZFBhdGh9YFxuICAgICAgZWRnZXMucHVzaCh7XG4gICAgICAgIGlkOiBlZGdlSWQsXG4gICAgICAgIGZyb20sXG4gICAgICAgIHRvOiBmaWVsZFBhdGgsXG4gICAgICAgIGtpbmQ6IFwibGlua1wiLFxuICAgICAgfSlcblxuICAgICAgcGxhblN0ZXBzLnB1c2goe1xuICAgICAgICBpZDogYGxpbms6JHtmaWVsZFBhdGh9YCxcbiAgICAgICAga2luZDogXCJsaW5rLXByb3BhZ2F0ZVwiLFxuICAgICAgICB0YXJnZXRGaWVsZFBhdGg6IGZpZWxkUGF0aCxcbiAgICAgICAgc291cmNlRmllbGRQYXRoczogW2Zyb21dLFxuICAgICAgICBkZWJ1Z0luZm86IHtcbiAgICAgICAgICBncmFwaEVkZ2VJZDogZWRnZUlkLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9IGVsc2UgaWYgKGVudHJ5LmtpbmQgPT09IFwic291cmNlXCIpIHtcbiAgICAgIGNvbnN0IHJlc291cmNlSWQgPSBlbnRyeS5tZXRhLnJlc291cmNlXG4gICAgICBjb25zdCByZXNvdXJjZU1ldGEgPSBNZXRhLnNhbml0aXplKChlbnRyeS5tZXRhIGFzIGFueSkubWV0YSlcblxuICAgICAgY29uc3QgZXhpc3RpbmcgPSByZXNvdXJjZXNCeUlkLmdldChyZXNvdXJjZUlkKVxuICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgIGNvbnN0IG93bmVyRmllbGRzID0gWy4uLmV4aXN0aW5nLm93bmVyRmllbGRzLCBmaWVsZFBhdGhdXG4gICAgICAgIGxldCBtZXRhID0gZXhpc3RpbmcubWV0YVxuICAgICAgICBsZXQgbWV0YU9yaWdpbiA9IGV4aXN0aW5nLm1ldGFPcmlnaW5cbiAgICAgICAgbGV0IG1ldGFDb25mbGljdHMgPSBleGlzdGluZy5tZXRhQ29uZmxpY3RzXG5cbiAgICAgICAgaWYgKHJlc291cmNlTWV0YSkge1xuICAgICAgICAgIGNvbnN0IG1lcmdlZCA9IE1ldGEubWVyZ2VDYW5vbmljYWwoXG4gICAgICAgICAgICB7IG1ldGEsIG9yaWdpbjogbWV0YU9yaWdpbiwgY29uZmxpY3RzOiBtZXRhQ29uZmxpY3RzIH0sXG4gICAgICAgICAgICB7IG9yaWdpbjogZmllbGRQYXRoLCBtZXRhOiByZXNvdXJjZU1ldGEgfSxcbiAgICAgICAgICApXG4gICAgICAgICAgbWV0YSA9IG1lcmdlZC5tZXRhXG4gICAgICAgICAgbWV0YU9yaWdpbiA9IG1lcmdlZC5vcmlnaW5cbiAgICAgICAgICBtZXRhQ29uZmxpY3RzID0gbWVyZ2VkLmNvbmZsaWN0c1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzb3VyY2VzQnlJZC5zZXQocmVzb3VyY2VJZCwge1xuICAgICAgICAgIC4uLmV4aXN0aW5nLFxuICAgICAgICAgIG93bmVyRmllbGRzLFxuICAgICAgICAgIG1ldGEsXG4gICAgICAgICAgbWV0YU9yaWdpbixcbiAgICAgICAgICBtZXRhQ29uZmxpY3RzLFxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb3VyY2VzQnlJZC5zZXQocmVzb3VyY2VJZCwge1xuICAgICAgICAgIHJlc291cmNlSWQsXG4gICAgICAgICAgLy8gXHU2NjgyXHU2NUY2XHU0RjdGXHU3NTI4XHU3QjgwXHU1MzU1XHU3Njg0XHU2ODA3XHU4QkM2XHU1QjU3XHU3QjI2XHU0RTMyXHVGRjBDXHU1NDBFXHU3RUVEXHU1M0VGXHU2ODM5XHU2MzZFIGtleSBcdTg5QzRcdTUyMTlcdThGREJcdTRFMDBcdTZCNjVcdTdFRDNcdTY3ODRcdTUzMTZcdTMwMDJcbiAgICAgICAgICBrZXlTZWxlY3RvcjogYFN0YXRlVHJhaXQuc291cmNlQCR7ZmllbGRQYXRofWAsXG4gICAgICAgICAgb3duZXJGaWVsZHM6IFtmaWVsZFBhdGhdLFxuICAgICAgICAgIG1ldGE6IHJlc291cmNlTWV0YSxcbiAgICAgICAgICBtZXRhT3JpZ2luOiByZXNvdXJjZU1ldGEgPyBmaWVsZFBhdGggOiB1bmRlZmluZWQsXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIHBsYW5TdGVwcy5wdXNoKHtcbiAgICAgICAgaWQ6IGBzb3VyY2U6JHtmaWVsZFBhdGh9YCxcbiAgICAgICAga2luZDogXCJzb3VyY2UtcmVmcmVzaFwiLFxuICAgICAgICB0YXJnZXRGaWVsZFBhdGg6IGZpZWxkUGF0aCxcbiAgICAgICAgcmVzb3VyY2VJZCxcbiAgICAgICAga2V5U2VsZWN0b3JJZDogYFN0YXRlVHJhaXQuc291cmNlQCR7ZmllbGRQYXRofWAsXG4gICAgICB9KVxuXG4gICAgICBjb25zdCBkZXBzID0gKGVudHJ5Lm1ldGEgYXMgYW55KS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgaWYgKGRlcHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgICAgIGVuc3VyZUZpZWxkKGRlcClcbiAgICAgICAgICBlZGdlcy5wdXNoKHtcbiAgICAgICAgICAgIGlkOiBgc291cmNlLWRlcDoke2RlcH0tPiR7ZmllbGRQYXRofWAsXG4gICAgICAgICAgICBmcm9tOiBkZXAsXG4gICAgICAgICAgICB0bzogZmllbGRQYXRoLFxuICAgICAgICAgICAga2luZDogXCJzb3VyY2UtZGVwXCIsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZW50cnkua2luZCA9PT0gXCJjaGVja1wiKSB7XG4gICAgICBwbGFuU3RlcHMucHVzaCh7XG4gICAgICAgIGlkOiBgY2hlY2s6JHtmaWVsZFBhdGh9YCxcbiAgICAgICAga2luZDogXCJjaGVjay12YWxpZGF0ZVwiLFxuICAgICAgICB0YXJnZXRGaWVsZFBhdGg6IGZpZWxkUGF0aCxcbiAgICAgIH0pXG5cbiAgICAgIC8vIFx1ODJFNVx1ODlDNFx1NTIxOVx1NjYzRVx1NUYwRlx1NThGMFx1NjYwRSBkZXBzXHVGRjBDXHU1MjE5XHU4ODY1XHU1MTQ1IEdyYXBoIFx1OEZCOVx1RkYwOFx1NzUyOFx1NEU4RSBSZXZlcnNlQ2xvc3VyZSBzY29wZWQgdmFsaWRhdGVcdUZGMDlcdTMwMDJcbiAgICAgIGlmICh0cmFpdC5kZXBzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZm9yIChjb25zdCBkZXAgb2YgdHJhaXQuZGVwcykge1xuICAgICAgICAgIGVuc3VyZUZpZWxkKGRlcClcbiAgICAgICAgICBlZGdlcy5wdXNoKHtcbiAgICAgICAgICAgIGlkOiBgY2hlY2stZGVwOiR7ZGVwfS0+JHtmaWVsZFBhdGh9YCxcbiAgICAgICAgICAgIGZyb206IGRlcCxcbiAgICAgICAgICAgIHRvOiBmaWVsZFBhdGgsXG4gICAgICAgICAgICBraW5kOiBcImNoZWNrLWRlcFwiLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkTWFwLnZhbHVlcygpKSB7XG4gICAgbm9kZXMucHVzaCh7XG4gICAgICBpZDogZmllbGQuaWQsXG4gICAgICBmaWVsZCxcbiAgICAgIHRyYWl0czogZmllbGQudHJhaXRzLFxuICAgICAgbWV0YTogbm9kZU1ldGFCeUZpZWxkUGF0aC5nZXQoZmllbGQuaWQpLFxuICAgIH0pXG4gIH1cblxuICBjb25zdCBncmFwaDogU3RhdGVUcmFpdEdyYXBoID0ge1xuICAgIF90YWc6IFwiU3RhdGVUcmFpdEdyYXBoXCIsXG4gICAgbm9kZXMsXG4gICAgZWRnZXMsXG4gICAgcmVzb3VyY2VzOiBBcnJheS5mcm9tKHJlc291cmNlc0J5SWQudmFsdWVzKCkpLFxuICB9XG5cbiAgY29uc3QgcGxhbjogU3RhdGVUcmFpdFBsYW4gPSB7XG4gICAgX3RhZzogXCJTdGF0ZVRyYWl0UGxhblwiLFxuICAgIHN0ZXBzOiBwbGFuU3RlcHMsXG4gIH1cblxuICByZXR1cm4geyBncmFwaCwgcGxhbiB9XG59XG5cbi8qKlxuICogXHU5NDg4XHU1QkY5IGxpbmsgXHU4RkI5XHU4RkRCXHU4ODRDXHU3QjgwXHU1MzU1XHU3Njg0XHU3M0FGXHU4REVGXHU2OEMwXHU2RDRCXHUzMDAyXG4gKlxuICogLSBcdTRFQzVcdTgwMDNcdTg2NTEga2luZCA9IFwibGlua1wiIFx1NzY4NFx1OEZCOVx1RkYwQ2NvbXB1dGVkL3NvdXJjZSBcdTk5OTZcdTcyNDhcdTRFMERcdTUzQzJcdTRFMEVcdTczQUZcdTY4QzBcdTZENEJcdUZGMUJcbiAqIC0gXHU4MkU1XHU1M0QxXHU3M0IwXHU3M0FGXHU4REVGXHVGRjBDXHU2MjlCXHU1MUZBXHU1RTI2XHU2NzA5XHU4REVGXHU1Rjg0XHU0RkUxXHU2MDZGXHU3Njg0XHU5NTE5XHU4QkVGXHVGRjBDXHU5MDdGXHU1MTREXHU1NzI4XHU4RkQwXHU4ODRDXHU2NUY2XHU4RkRCXHU1MTY1XHU2NUUwXHU5NjUwXHU2NkY0XHU2NUIwXHUzMDAyXG4gKi9cbmNvbnN0IGFzc2VydE5vTGlua0N5Y2xlcyA9IChlZGdlczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0R3JhcGhFZGdlPik6IHZvaWQgPT4ge1xuICBjb25zdCBhZGphY2VuY3kgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KClcblxuICBmb3IgKGNvbnN0IGVkZ2Ugb2YgZWRnZXMpIHtcbiAgICBpZiAoZWRnZS5raW5kICE9PSBcImxpbmtcIikgY29udGludWVcbiAgICBjb25zdCBsaXN0ID0gYWRqYWNlbmN5LmdldChlZGdlLmZyb20pID8/IFtdXG4gICAgbGlzdC5wdXNoKGVkZ2UudG8pXG4gICAgYWRqYWNlbmN5LnNldChlZGdlLmZyb20sIGxpc3QpXG4gIH1cblxuICBjb25zdCB2aXNpdGVkID0gbmV3IFNldDxzdHJpbmc+KClcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU2V0PHN0cmluZz4oKVxuXG4gIGNvbnN0IGRmcyA9IChub2RlOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICBpZiAoc3RhY2suaGFzKG5vZGUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBbU3RhdGVUcmFpdC5idWlsZF0gbGluayBjeWNsZSBkZXRlY3RlZCBhdCBmaWVsZCBcIiR7bm9kZX1cIi4gYCArXG4gICAgICAgICAgXCJQbGVhc2UgY2hlY2sgbGluayB0cmFpdHMgZm9yIGNpcmN1bGFyIGRlcGVuZGVuY2llcy5cIixcbiAgICAgIClcbiAgICB9XG4gICAgaWYgKHZpc2l0ZWQuaGFzKG5vZGUpKSByZXR1cm5cbiAgICB2aXNpdGVkLmFkZChub2RlKVxuICAgIHN0YWNrLmFkZChub2RlKVxuXG4gICAgY29uc3QgbmV4dHMgPSBhZGphY2VuY3kuZ2V0KG5vZGUpXG4gICAgaWYgKG5leHRzKSB7XG4gICAgICBmb3IgKGNvbnN0IHRvIG9mIG5leHRzKSB7XG4gICAgICAgIGRmcyh0bylcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzdGFjay5kZWxldGUobm9kZSlcbiAgfVxuXG4gIGZvciAoY29uc3Qgbm9kZSBvZiBhZGphY2VuY3kua2V5cygpKSB7XG4gICAgaWYgKCF2aXNpdGVkLmhhcyhub2RlKSkge1xuICAgICAgZGZzKG5vZGUpXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogXHU2ODM5XHU2MzZFXHU3RUQ5XHU1QjlBXHU3Njg0IHN0YXRlU2NoZW1hIFx1NEUwRSB0cmFpdHMgc3BlYyBcdTY3ODRcdTkwMjAgU3RhdGVUcmFpdFByb2dyYW1cdTMwMDJcbiAqXG4gKiAtIFx1N0VBRlx1NTFGRFx1NjU3MFx1RkYxQVx1NEUwRFx1NEY5RFx1OEQ1Nlx1NTkxNlx1OTBFOCBFbnYgLyBcdTUxNjhcdTVDNDBcdTcyQjZcdTYwMDFcdUZGMUJcbiAqIC0gXHU1RjUzXHU1MjREXHU1QjlFXHU3M0IwXHU4MDVBXHU3MTI2XHU0RThFXHVGRjFBXG4gKiAgIC0gXHU0RUNFIFNwZWMgXHU1RjUyXHU0RTAwXHU1MzE2XHU1MUZBIEVudHJ5IFx1NTIxN1x1ODg2OFx1RkYxQlxuICogICAtIFx1NTdGQVx1NEU4RSBFbnRyeSBcdTY3ODRcdTVFRkFcdThGN0JcdTkxQ0ZcdTcyNDggR3JhcGggLyBQbGFuXHVGRjFCXG4gKiAgIC0gXHU1QkY5IGxpbmsgXHU4RkI5XHU1MDVBXHU1N0ZBXHU2NzJDXHU3M0FGXHU4REVGXHU2OEMwXHU2RDRCXHUzMDAyXG4gKlxuICogXHU1NDBFXHU3RUVEXHU4MkU1XHU5NzAwXHU4OTgxXHU2NkY0XHU3Q0JFXHU3RUM2XHU3Njg0XHU0RjlEXHU4RDU2XHU1MjA2XHU2NzkwXHVGRjA4XHU0RjhCXHU1OTgyXHU1QkY5IGNvbXB1dGVkL2tleSBcdTUwNUFcdTk3NTlcdTYwMDFcdTg5RTNcdTY3OTBcdUZGMDlcdUZGMENcbiAqIFx1NTNFRlx1NEVFNVx1NTcyOFx1NjcyQ1x1NkEyMVx1NTc1N1x1NTE4NVx1NkYxNFx1OEZEQlx1NUI5RVx1NzNCMFx1RkYwQ1x1ODAwQ1x1NEUwRFx1NUY3MVx1NTRDRFx1NUJGOVx1NTkxNiBBUElcdTMwMDJcbiAqL1xuZXhwb3J0IGNvbnN0IGJ1aWxkID0gPFMgZXh0ZW5kcyBvYmplY3Q+KFxuICBzdGF0ZVNjaGVtYTogU2NoZW1hLlNjaGVtYTxTLCBhbnk+LFxuICBzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPixcbik6IFN0YXRlVHJhaXRQcm9ncmFtPFM+ID0+IHtcbiAgY29uc3QgZW50cmllcyA9IG5vcm1hbGl6ZVNwZWMoc3BlYykgYXMgUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8Uywgc3RyaW5nPj5cbiAgY29uc3Qgbm9kZU1ldGFCeUZpZWxkUGF0aCA9IGNvbGxlY3ROb2RlTWV0YShzcGVjKVxuXG4gIC8vIFBoYXNlIDRcdUZGMDhVUzJcdUZGMDlcdUZGMUFcdTVGM0FcdTUyMzZcdTY2M0VcdTVGMEYgZGVwc1x1RkYwOEdyYXBoL2RpYWdub3N0aWNzL3JlcGxheSBcdTUzRUFcdThCQTQgZGVwcyBcdTRGNUNcdTRFM0FcdTRGOURcdThENTZcdTRFOEJcdTVCOUVcdTZFOTBcdUZGMDlcdTMwMDJcbiAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgaWYgKGVudHJ5LmtpbmQgPT09IFwiY29tcHV0ZWRcIikge1xuICAgICAgY29uc3QgZGVwcyA9IChlbnRyeS5tZXRhIGFzIGFueSkuZGVwcyBhcyBSZWFkb25seUFycmF5PHN0cmluZz4gfCB1bmRlZmluZWRcbiAgICAgIGlmIChkZXBzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBbU3RhdGVUcmFpdC5idWlsZF0gTWlzc2luZyBleHBsaWNpdCBkZXBzIGZvciBjb21wdXRlZCBcIiR7ZW50cnkuZmllbGRQYXRofVwiLiBgICtcbiAgICAgICAgICAgIFwiUGxlYXNlIHVzZSBTdGF0ZVRyYWl0LmNvbXB1dGVkKHsgZGVwczogWy4uLl0sIGdldDogLi4uIH0pLlwiLFxuICAgICAgICApXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbnRyeS5raW5kID09PSBcInNvdXJjZVwiKSB7XG4gICAgICBjb25zdCBkZXBzID0gKGVudHJ5Lm1ldGEgYXMgYW55KS5kZXBzIGFzIFJlYWRvbmx5QXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZFxuICAgICAgaWYgKGRlcHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBNaXNzaW5nIGV4cGxpY2l0IGRlcHMgZm9yIHNvdXJjZSBcIiR7ZW50cnkuZmllbGRQYXRofVwiLiBgICtcbiAgICAgICAgICAgIFwiUGxlYXNlIHByb3ZpZGUgbWV0YS5kZXBzIGZvciBTdGF0ZVRyYWl0LnNvdXJjZSh7IGRlcHM6IFsuLi5dLCAuLi4gfSkuXCIsXG4gICAgICAgIClcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVudHJ5LmtpbmQgPT09IFwiY2hlY2tcIikge1xuICAgICAgY29uc3QgcnVsZXMgPSAoKGVudHJ5Lm1ldGEgYXMgYW55KT8ucnVsZXMgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhydWxlcykpIHtcbiAgICAgICAgY29uc3QgcnVsZSA9IHJ1bGVzW25hbWVdXG4gICAgICAgIGlmICh0eXBlb2YgcnVsZSA9PT0gXCJmdW5jdGlvblwiIHx8ICFydWxlIHx8IHR5cGVvZiBydWxlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBNaXNzaW5nIGV4cGxpY2l0IGRlcHMgZm9yIGNoZWNrIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIgcnVsZSBcIiR7bmFtZX1cIi4gYCArXG4gICAgICAgICAgICAgIFwiUGxlYXNlIHVzZSB7IGRlcHM6IFsuLi5dLCB2YWxpZGF0ZTogLi4uIH0gZm9ybS5cIixcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgaWYgKChydWxlIGFzIGFueSkuZGVwcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFtTdGF0ZVRyYWl0LmJ1aWxkXSBNaXNzaW5nIGV4cGxpY2l0IGRlcHMgZm9yIGNoZWNrIFwiJHtlbnRyeS5maWVsZFBhdGh9XCIgcnVsZSBcIiR7bmFtZX1cIi4gYCArXG4gICAgICAgICAgICAgIFwiUGxlYXNlIHByb3ZpZGUgZGVwczogWy4uLl0uXCIsXG4gICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgeyBncmFwaCwgcGxhbiB9ID0gYnVpbGRHcmFwaChlbnRyaWVzLCBub2RlTWV0YUJ5RmllbGRQYXRoKVxuXG4gIC8vIFx1OTQ4OFx1NUJGOSBsaW5rIFx1OEZCOVx1OEZEQlx1ODg0Q1x1NEUwMFx1NkIyMVx1NzNBRlx1OERFRlx1NjhDMFx1NkQ0Qlx1RkYwQ1x1OTA3Rlx1NTE0RFx1NjYwRVx1NjYzRVx1NzY4NFx1OTE0RFx1N0Y2RVx1OTUxOVx1OEJFRlx1MzAwMlxuICBhc3NlcnROb0xpbmtDeWNsZXMoZ3JhcGguZWRnZXMpXG5cbiAgcmV0dXJuIHtcbiAgICBzdGF0ZVNjaGVtYSxcbiAgICBzcGVjLFxuICAgIGVudHJpZXM6IGVudHJpZXMgYXMgUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8YW55LCBzdHJpbmc+PixcbiAgICBncmFwaCxcbiAgICBwbGFuLFxuICAgIGNvbnZlcmdlSXI6IGJ1aWxkQ29udmVyZ2VJcihlbnRyaWVzIGFzIFJlYWRvbmx5QXJyYXk8U3RhdGVUcmFpdEVudHJ5PGFueSwgc3RyaW5nPj4pLFxuICB9XG59XG4iLCAiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcImVmZmVjdFwiXG5pbXBvcnQgdHlwZSB7IEJvdW5kQXBpIH0gZnJvbSBcIi4uL3J1bnRpbWUvY29yZS9tb2R1bGUuanNcIlxuaW1wb3J0IHsgZ2V0Qm91bmRJbnRlcm5hbHMgfSBmcm9tIFwiLi4vcnVudGltZS9jb3JlL3J1bnRpbWVJbnRlcm5hbHNBY2Nlc3Nvci5qc1wiXG5pbXBvcnQgKiBhcyBTb3VyY2VSdW50aW1lIGZyb20gXCIuL3NvdXJjZS5qc1wiXG5pbXBvcnQgdHlwZSB7XG4gIFN0YXRlVHJhaXRQcm9ncmFtLFxuICBTdGF0ZVRyYWl0UGxhblN0ZXAsXG4gIFN0YXRlVHJhaXRFbnRyeSxcbiAgVHJhaXRDb252ZXJnZUdlbmVyYXRpb25CdW1wUmVhc29uLFxufSBmcm9tIFwiLi9tb2RlbC5qc1wiXG5cbmNvbnN0IGJ1aWxkRW50cnlJbmRleCA9IDxTPihcbiAgZW50cmllczogUmVhZG9ubHlBcnJheTxTdGF0ZVRyYWl0RW50cnk8Uywgc3RyaW5nPj4sXG4pOiBNYXA8c3RyaW5nLCBBcnJheTxTdGF0ZVRyYWl0RW50cnk8Uywgc3RyaW5nPj4+ID0+IHtcbiAgY29uc3QgaW5kZXggPSBuZXcgTWFwPHN0cmluZywgQXJyYXk8U3RhdGVUcmFpdEVudHJ5PFMsIHN0cmluZz4+PigpXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGNvbnN0IGxpc3QgPSBpbmRleC5nZXQoZW50cnkuZmllbGRQYXRoKSA/PyBbXVxuICAgIGxpc3QucHVzaChlbnRyeSlcbiAgICBpbmRleC5zZXQoZW50cnkuZmllbGRQYXRoLCBsaXN0KVxuICB9XG4gIHJldHVybiBpbmRleFxufVxuXG4vKipcbiAqIFx1NTcyOFx1N0VEOVx1NUI5QSBCb3VuZCBBUEkgXHU0RTBBXHU1Qjg5XHU4OEM1IFN0YXRlVHJhaXRQcm9ncmFtIFx1NjNDRlx1OEZGMFx1NzY4NFx1ODg0Q1x1NEUzQVx1MzAwMlxuICpcbiAqIC0gUGhhc2UgMiBcdTY3MDBcdTVDMEZcdTVCOUVcdTczQjBcdUZGMUFcbiAqICAgLSBcdTRFM0EgY29tcHV0ZWQgXHU1QjU3XHU2QkI1XHU2Q0U4XHU1MThDIHdhdGNoZXJcdUZGMUFcdTVGNTMgU3RhdGUgXHU1M0Q4XHU1MzE2XHU2NUY2XHU5MUNEXHU3Qjk3XHU3NkVFXHU2ODA3XHU1QjU3XHU2QkI1XHVGRjFCXG4gKiAgIC0gXHU0RTNBIGxpbmsgXHU1QjU3XHU2QkI1XHU2Q0U4XHU1MThDIHdhdGNoZXJcdUZGMUFcdTVGNTNcdTZFOTBcdTVCNTdcdTZCQjVcdTUzRDhcdTUzMTZcdTY1RjZcdTU0MENcdTZCNjVcdTc2RUVcdTY4MDdcdTVCNTdcdTZCQjVcdUZGMUJcbiAqICAgLSBcdTRFM0Egc291cmNlIFx1NUI1N1x1NkJCNVx1OTg4NFx1NzU1OVx1NTIzN1x1NjVCMFx1NTE2NVx1NTNFM1x1RkYwOFx1NjY4Mlx1NEUwRFx1ODlFNlx1NTNEMVx1NTkxNlx1OTBFOFx1OEMwM1x1NzUyOFx1RkYwOVx1MzAwMlxuICpcbiAqIFx1OEJGNFx1NjYwRVx1RkYxQVxuICogLSBcdTYyNDBcdTY3MDkgd2F0Y2hlciBcdTkwRkRcdTkwMUFcdThGQzcgQm91bmQgQVBJIGAkYCBcdTVCODlcdTg4QzVcdUZGMENcdTRFMERcdTc2RjRcdTYzQTVcdTRGOURcdThENTYgTW9kdWxlUnVudGltZVx1RkYxQlxuICogLSBcdTZCQ0ZcdTRFMkEgUGxhblN0ZXAgXHU1QkY5XHU1RTk0XHU0RTAwXHU0RTJBXHU5NTdGXHU3NTFGXHU1NDdEXHU1NDY4XHU2NzFGIEVmZmVjdFx1RkYwQ1x1OTAxQVx1OEZDNyBmb3JrU2NvcGVkIFx1NjMwMlx1OEY3RFx1NTIzMCBSdW50aW1lIFNjb3BlXHUzMDAyXG4gKi9cbmV4cG9ydCBjb25zdCBpbnN0YWxsID0gPFM+KFxuICBib3VuZDogQm91bmRBcGk8YW55LCBhbnk+LFxuICBwcm9ncmFtOiBTdGF0ZVRyYWl0UHJvZ3JhbTxTPixcbik6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIGFueT4gPT4ge1xuICAvLyBcdTRGMThcdTUxNDhcdTVDMDYgUHJvZ3JhbSBcdTZDRThcdTUxOENcdTUyMzAgUnVudGltZVx1RkYwOFx1NjUzNlx1NjU1Qlx1NUYxNVx1NjRDRVx1NTcyOFx1NEU4Qlx1NTJBMVx1NjNEMFx1NEVBNFx1NTI0RFx1N0VERlx1NEUwMFx1NjI2N1x1ODg0QyBjb21wdXRlZC9saW5rL2NoZWNrXHVGRjA5XHUzMDAyXG4gIHRyeSB7XG4gICAgY29uc3QgaW50ZXJuYWxzID0gZ2V0Qm91bmRJbnRlcm5hbHMoYm91bmQgYXMgYW55KVxuICAgIDsoaW50ZXJuYWxzLnRyYWl0cy5yZWdpc3RlclN0YXRlVHJhaXRQcm9ncmFtIGFzIGFueSkocHJvZ3JhbSwge1xuICAgICAgYnVtcFJlYXNvbjogXCJsb2dpY19pbnN0YWxsZWRcIiBhcyBUcmFpdENvbnZlcmdlR2VuZXJhdGlvbkJ1bXBSZWFzb24sXG4gICAgfSlcbiAgfSBjYXRjaCB7XG4gICAgLy8gbm8tb3AgZm9yIGxlZ2FjeS9tb2NrZWQgYm91bmRcbiAgfVxuXG4gIGNvbnN0IGVudHJ5SW5kZXggPSBidWlsZEVudHJ5SW5kZXgocHJvZ3JhbS5lbnRyaWVzIGFzIGFueSlcblxuICBjb25zdCBpbnN0YWxsU3RlcCA9IChcbiAgICBzdGVwOiBTdGF0ZVRyYWl0UGxhblN0ZXAsXG4gICk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIGFueT4gPT4ge1xuICAgIGlmICghc3RlcC50YXJnZXRGaWVsZFBhdGgpIHtcbiAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgIH1cblxuICAgIGlmIChzdGVwLmtpbmQgIT09IFwic291cmNlLXJlZnJlc2hcIikge1xuICAgICAgLy8gY29tcHV0ZWQvbGluay9jaGVjayBcdTVERjJcdTc1MzEgUnVudGltZSBcdTUxODVcdTY4MzhcdTU3MjhcdTRFOEJcdTUyQTFcdTdBOTdcdTUzRTNcdTUxODVcdTU5MDRcdTc0MDZcdUZGMUJpbnN0YWxsIFx1OTYzNlx1NkJCNVx1NEVDNVx1NEZERFx1NzU1OSBzb3VyY2UucmVmcmVzaCBcdTUxNjVcdTUzRTNcdTMwMDJcbiAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgIH1cblxuICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSBlbnRyeUluZGV4LmdldChzdGVwLnRhcmdldEZpZWxkUGF0aClcbiAgICBpZiAoIWNhbmRpZGF0ZXMgfHwgY2FuZGlkYXRlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIC8vIFBsYW4gXHU0RTJEXHU1RjE1XHU3NTI4XHU0RTg2XHU0RTBEXHU1QjU4XHU1NzI4XHU3Njg0IFNwZWNcdUZGMUFcdTg5QzZcdTRFM0FcdTY3ODRcdTVFRkFcdTk2MzZcdTZCQjVcdTc2ODQgYnVnXHVGRjBDXHU4RkQ5XHU5MUNDXHU3NkY0XHU2M0E1XHU1RkZEXHU3NTY1XHU4QkU1XHU2QjY1XHU5QUE0XHUzMDAyXG4gICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICB9XG5cbiAgICBjb25zdCBlbnRyeSA9IGNhbmRpZGF0ZXMuZmluZCgoZSkgPT4gZS5raW5kID09PSBcInNvdXJjZVwiKVxuXG4gICAgaWYgKCFlbnRyeSkge1xuICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgfVxuXG4gICAgcmV0dXJuIFNvdXJjZVJ1bnRpbWUuaW5zdGFsbFNvdXJjZVJlZnJlc2goXG4gICAgICBib3VuZCxcbiAgICAgIHN0ZXAsXG4gICAgICBlbnRyeSBhcyBhbnksXG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIEVmZmVjdC5mb3JFYWNoKHByb2dyYW0ucGxhbi5zdGVwcywgKHN0ZXApID0+IGluc3RhbGxTdGVwKHN0ZXApKS5waXBlKEVmZmVjdC5hc1ZvaWQpXG59XG4iLCAiLy8gU3RhdGVUcmFpdCBcdTU0N0RcdTU0MERcdTdBN0FcdTk1RjRcdTZBMjFcdTU3NTdcdUZGMDhAbG9naXgvY29yZS9TdGF0ZVRyYWl0XHVGRjA5XHVGRjFBXG4vLyAtIFx1NjNEMFx1NEY5QiB0cmFpdHMgc3BlYyBcdTc2ODQgRFNMXHVGRjA4ZnJvbS9ub2RlL2xpc3QvY29tcHV0ZWQvc291cmNlL2xpbmtcdUZGMDlcdUZGMUJcbi8vIC0gYnVpbGRcdUZGMUFcdTVGNTJcdTRFMDBcdTUzMTYgc3BlYyBcdTVFNzZcdTc1MUZcdTYyMTAgUHJvZ3JhbS9HcmFwaC9QbGFuXHVGRjFCXG4vLyAtIGluc3RhbGxcdUZGMUFcdTVDMDYgUHJvZ3JhbSBcdTVCODlcdTg4QzVcdTUyMzBcdThGRDBcdTg4NENcdTY1RjZcdUZGMDhcdTZDRThcdTUxOEMgc291cmNlLnJlZnJlc2ggXHU3QjQ5XHU1MTY1XHU1M0UzXHVGRjBDXHU1RTc2XHU1NzI4XHU0RThCXHU1MkExXHU3QTk3XHU1M0UzXHU2MjY3XHU4ODRDIGNvbnZlcmdlL3ZhbGlkYXRlXHVGRjA5XHUzMDAyXG5cbmltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSBcImVmZmVjdFwiXG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiZWZmZWN0XCJcbmltcG9ydCB0eXBlIHsgQm91bmRBcGkgfSBmcm9tIFwiLi9Cb3VuZC5qc1wiXG5pbXBvcnQgKiBhcyBNb2RlbCBmcm9tIFwiLi9pbnRlcm5hbC9zdGF0ZS10cmFpdC9tb2RlbC5qc1wiXG5pbXBvcnQgKiBhcyBGaWVsZFBhdGggZnJvbSBcIi4vaW50ZXJuYWwvc3RhdGUtdHJhaXQvZmllbGQtcGF0aC5qc1wiXG5pbXBvcnQgKiBhcyBSb3dJZCBmcm9tIFwiLi9pbnRlcm5hbC9zdGF0ZS10cmFpdC9yb3dpZC5qc1wiXG5pbXBvcnQgKiBhcyBJbnRlcm5hbEJ1aWxkIGZyb20gXCIuL2ludGVybmFsL3N0YXRlLXRyYWl0L2J1aWxkLmpzXCJcbmltcG9ydCAqIGFzIEludGVybmFsSW5zdGFsbCBmcm9tIFwiLi9pbnRlcm5hbC9zdGF0ZS10cmFpdC9pbnN0YWxsLmpzXCJcbmltcG9ydCAqIGFzIEludGVybmFsSXIgZnJvbSBcIi4vaW50ZXJuYWwvc3RhdGUtdHJhaXQvaXIuanNcIlxuXG4vLyBcdTVCRjlcdTU5MTZcdTY2QjRcdTk3MzJcdTc2ODRcdTY4MzhcdTVGQzNcdTdDN0JcdTU3OEJcdTUyMkJcdTU0MERcdTMwMDJcbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRTcGVjPFM+ID0gTW9kZWwuU3RhdGVUcmFpdFNwZWM8Uz5cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRFbnRyeTxTID0gdW5rbm93biwgUCBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gPVxuICBNb2RlbC5TdGF0ZVRyYWl0RW50cnk8UywgUD5cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRQcm9ncmFtPFM+ID0gTW9kZWwuU3RhdGVUcmFpdFByb2dyYW08Uz5cbmV4cG9ydCB0eXBlIFN0YXRlVHJhaXRHcmFwaCA9IE1vZGVsLlN0YXRlVHJhaXRHcmFwaFxuZXhwb3J0IHR5cGUgU3RhdGVUcmFpdFBsYW4gPSBNb2RlbC5TdGF0ZVRyYWl0UGxhblxuZXhwb3J0IHR5cGUgU3RhdGVUcmFpdE5vZGU8SW5wdXQgPSB1bmtub3duLCBDdHggPSB1bmtub3duPiA9IE1vZGVsLlN0YXRlVHJhaXROb2RlPElucHV0LCBDdHg+XG5leHBvcnQgdHlwZSBTdGF0ZVRyYWl0TGlzdDxJdGVtID0gdW5rbm93bj4gPSBNb2RlbC5TdGF0ZVRyYWl0TGlzdDxJdGVtPlxuZXhwb3J0IHR5cGUgQ2hlY2tSdWxlPElucHV0ID0gdW5rbm93biwgQ3R4ID0gdW5rbm93bj4gPSBNb2RlbC5DaGVja1J1bGU8SW5wdXQsIEN0eD5cblxuZXhwb3J0IHR5cGUgU3RhdGVGaWVsZFBhdGg8Uz4gPSBGaWVsZFBhdGguU3RhdGVGaWVsZFBhdGg8Uz5cbmV4cG9ydCB0eXBlIFN0YXRlQXRQYXRoPFMsIFA+ID0gRmllbGRQYXRoLlN0YXRlQXRQYXRoPFMsIFA+XG5cbmV4cG9ydCBjb25zdCAkcm9vdCA9IFwiJHJvb3RcIiBhcyBjb25zdFxuXG50eXBlIERlcHNBcmdzPFMgZXh0ZW5kcyBvYmplY3QsIERlcHMgZXh0ZW5kcyBSZWFkb25seUFycmF5PFN0YXRlRmllbGRQYXRoPFM+Pj4gPSB7XG4gIHJlYWRvbmx5IFtLIGluIGtleW9mIERlcHNdOiBTdGF0ZUF0UGF0aDxTLCBEZXBzW0tdPlxufVxuXG4vKipcbiAqIFN0YXRlVHJhaXQuZnJvbVx1RkYxQVxuICogLSBcdTY4MzlcdTYzNkUgU3RhdGUgU2NoZW1hIFx1NjUzNlx1N0E4NFx1NTNFRlx1NzUyOFx1NUI1N1x1NkJCNVx1OERFRlx1NUY4NFx1RkYwQ1x1NUU3Nlx1NEUzQSB0cmFpdHMgc3BlYyBcdTYzRDBcdTRGOUJcdTdDN0JcdTU3OEJcdTdFQTZcdTY3NUZcdUZGMUJcbiAqIC0gXHU4RkQwXHU4ODRDXHU2NUY2XHU0RUM1XHU4RkQ0XHU1NkRFXHU1MzlGXHU1OUNCIHNwZWMgXHU1QkY5XHU4QzYxXHVGRjBDXHU1MTc3XHU0RjUzXHU1RjUyXHU0RTAwXHU1MzE2XHU3NTMxIGludGVybmFsIFx1NUM0Mlx1NTkwNFx1NzQwNlx1MzAwMlxuICovXG5leHBvcnQgY29uc3QgZnJvbSA9IDxTIGV4dGVuZHMgb2JqZWN0LCBJPihcbiAgX3NjaGVtYTogU2NoZW1hLlNjaGVtYTxTLCBJPixcbikgPT5cbihzcGVjOiBTdGF0ZVRyYWl0U3BlYzxTPik6IFN0YXRlVHJhaXRTcGVjPFM+ID0+XG4gIHNwZWNcblxuZXhwb3J0IGNvbnN0IG5vZGUgPSA8SW5wdXQgPSB1bmtub3duLCBDdHggPSB1bmtub3duPihcbiAgc3BlYzogT21pdDxNb2RlbC5TdGF0ZVRyYWl0Tm9kZTxJbnB1dCwgQ3R4PiwgXCJfdGFnXCI+LFxuKTogTW9kZWwuU3RhdGVUcmFpdE5vZGU8SW5wdXQsIEN0eD4gPT4gKHtcbiAgX3RhZzogXCJTdGF0ZVRyYWl0Tm9kZVwiLFxuICAuLi5zcGVjLFxufSlcblxuZXhwb3J0IGNvbnN0IGxpc3QgPSA8SXRlbSA9IHVua25vd24+KFxuICBzcGVjOiBPbWl0PE1vZGVsLlN0YXRlVHJhaXRMaXN0PEl0ZW0+LCBcIl90YWdcIj4sXG4pOiBNb2RlbC5TdGF0ZVRyYWl0TGlzdDxJdGVtPiA9PiAoe1xuICBfdGFnOiBcIlN0YXRlVHJhaXRMaXN0XCIsXG4gIC4uLnNwZWMsXG59KVxuXG4vKipcbiAqIFN0YXRlVHJhaXQuY29tcHV0ZWRcdUZGMUFcbiAqIC0gXHU0RTNBXHU2N0QwXHU0RTJBXHU1QjU3XHU2QkI1XHU1OEYwXHU2NjBFIGNvbXB1dGVkIFx1ODBGRFx1NTI5Qlx1RkYxQlxuICogLSBcdTkwMUFcdThGQzdcdTY2M0VcdTVGMEYgZGVwcyBcdTRGNUNcdTRFM0FcdTU1MkZcdTRFMDBcdTRGOURcdThENTZcdTRFOEJcdTVCOUVcdTZFOTBcdUZGMDhcdTc1MjhcdTRFOEVcdThCQ0FcdTY1QUQvXHU1M0NEXHU1NDExXHU5NUVEXHU1MzA1L1x1NTQwRVx1N0VFRFx1NTg5RVx1OTFDRlx1OEMwM1x1NUVBNlx1RkYwOVx1MzAwMlxuICovXG5leHBvcnQgY29uc3QgY29tcHV0ZWQgPSA8XG4gIFMgZXh0ZW5kcyBvYmplY3QsXG4gIFAgZXh0ZW5kcyBTdGF0ZUZpZWxkUGF0aDxTPixcbiAgY29uc3QgRGVwcyBleHRlbmRzIFJlYWRvbmx5QXJyYXk8U3RhdGVGaWVsZFBhdGg8Uz4+LFxuPihcbiAgaW5wdXQ6IHtcbiAgICByZWFkb25seSBkZXBzOiBEZXBzXG4gICAgcmVhZG9ubHkgZ2V0OiAoLi4uZGVwc1ZhbHVlczogRGVwc0FyZ3M8UywgRGVwcz4pID0+IFN0YXRlQXRQYXRoPFMsIFA+XG4gICAgcmVhZG9ubHkgZXF1YWxzPzogKHByZXY6IFN0YXRlQXRQYXRoPFMsIFA+LCBuZXh0OiBTdGF0ZUF0UGF0aDxTLCBQPikgPT4gYm9vbGVhblxuICB9LFxuKTogU3RhdGVUcmFpdEVudHJ5PFMsIFA+ID0+IHtcbiAgY29uc3QgZGVyaXZlID0gKHN0YXRlOiBSZWFkb25seTxTPik6IFN0YXRlQXRQYXRoPFMsIFA+ID0+IHtcbiAgICBjb25zdCBhcmdzID0gKGlucHV0LmRlcHMgYXMgUmVhZG9ubHlBcnJheTxzdHJpbmc+KS5tYXAoKGRlcCkgPT5cbiAgICAgIFJvd0lkLmdldEF0UGF0aChzdGF0ZSBhcyBhbnksIGRlcCksXG4gICAgKVxuICAgIHJldHVybiAoaW5wdXQuZ2V0IGFzIGFueSkoLi4uYXJncylcbiAgfVxuICByZXR1cm4ge1xuICAgIGZpZWxkUGF0aDogdW5kZWZpbmVkIGFzIHVua25vd24gYXMgUCxcbiAgICBraW5kOiBcImNvbXB1dGVkXCIsXG4gICAgbWV0YTogeyBkZXBzOiBpbnB1dC5kZXBzLCBkZXJpdmUsIGVxdWFsczogaW5wdXQuZXF1YWxzIH0sXG4gIH0gYXMgU3RhdGVUcmFpdEVudHJ5PFMsIFA+XG59XG5cbi8qKlxuICogU3RhdGVUcmFpdC5zb3VyY2VcdUZGMUFcbiAqIC0gXHU0RTNBXHU2N0QwXHU0RTJBXHU1QjU3XHU2QkI1XHU1OEYwXHU2NjBFXHU1OTE2XHU5MEU4XHU4RDQ0XHU2RTkwXHU2NzY1XHU2RTkwXHVGRjA4UmVzb3VyY2UgLyBRdWVyeSBcdTk2QzZcdTYyMTBcdTU3MjhcdTU0MEVcdTdFRUQgUGhhc2UgXHU0RTJEXHU1QjlFXHU3M0IwXHVGRjA5XHVGRjFCXG4gKiAtIFx1NTE4NVx1NjgzOFx1OEQxRlx1OEQyMyBrZXlIYXNoIGdhdGUgLyBjb25jdXJyZW5jeSAvIFJlcGxheU1vZGUgXHU4ODRDXHU0RTNBXHUzMDAyXG4gKi9cbmV4cG9ydCBjb25zdCBzb3VyY2UgPSA8UyBleHRlbmRzIG9iamVjdCwgUCBleHRlbmRzIFN0YXRlRmllbGRQYXRoPFM+PihtZXRhOiB7XG4gIHJlc291cmNlOiBzdHJpbmdcbiAgZGVwczogUmVhZG9ubHlBcnJheTxTdGF0ZUZpZWxkUGF0aDxTPj5cbiAga2V5OiAoc3RhdGU6IFJlYWRvbmx5PFM+KSA9PiB1bmtub3duXG4gIHRyaWdnZXJzPzogUmVhZG9ubHlBcnJheTxcIm9uTW91bnRcIiB8IFwib25WYWx1ZUNoYW5nZVwiIHwgXCJtYW51YWxcIj5cbiAgZGVib3VuY2VNcz86IG51bWJlclxuICBjb25jdXJyZW5jeT86IFwic3dpdGNoXCIgfCBcImV4aGF1c3QtdHJhaWxpbmdcIlxuICAvKipcbiAgICogXHU3NTI4XHU0RThFIERldnRvb2xzL1x1NjU4N1x1Njg2M1x1NzY4NFx1NTNFRlx1NUU4Rlx1NTIxN1x1NTMxNlx1NTE0M1x1NEZFMVx1NjA2Rlx1RkYwOFx1NzY3RFx1NTQwRFx1NTM1NVx1NUI1N1x1NkJCNVx1NEYxQVx1NTcyOCBidWlsZCBcdTk2MzZcdTZCQjVcdTg4QUJcdTYzRDBcdTUzRDZcdUZGMDlcdTMwMDJcbiAgICovXG4gIG1ldGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxufSk6IFN0YXRlVHJhaXRFbnRyeTxTLCBQPiA9PlxuICAoe1xuICAgIGZpZWxkUGF0aDogdW5kZWZpbmVkIGFzIHVua25vd24gYXMgUCxcbiAgICBraW5kOiBcInNvdXJjZVwiLFxuICAgIG1ldGEsXG4gIH0gYXMgU3RhdGVUcmFpdEVudHJ5PFMsIFA+KVxuXG4vKipcbiAqIFN0YXRlVHJhaXQubGlua1x1RkYxQVxuICogLSBcdTRFM0FcdTc2RUVcdTY4MDdcdTVCNTdcdTZCQjVcdTU4RjBcdTY2MEVcdTRFQ0VcdTUxNzZcdTRFRDZcdTVCNTdcdTZCQjVcdTgwNTRcdTUyQThcdTc2ODRcdTgwRkRcdTUyOUJcdUZGMUJcbiAqIC0gbWV0YS5mcm9tIFx1NTQwQ1x1NjgzN1x1NTNENyBTdGF0ZUZpZWxkUGF0aDxTPiBcdTdFQTZcdTY3NUZcdTMwMDJcbiAqL1xuZXhwb3J0IGNvbnN0IGxpbmsgPSA8UyBleHRlbmRzIG9iamVjdCwgUCBleHRlbmRzIFN0YXRlRmllbGRQYXRoPFM+PihtZXRhOiB7XG4gIGZyb206IFN0YXRlRmllbGRQYXRoPFM+XG59KTogU3RhdGVUcmFpdEVudHJ5PFMsIFA+ID0+XG4gICh7XG4gICAgZmllbGRQYXRoOiB1bmRlZmluZWQgYXMgdW5rbm93biBhcyBQLFxuICAgIGtpbmQ6IFwibGlua1wiLFxuICAgIG1ldGEsXG4gIH0gYXMgU3RhdGVUcmFpdEVudHJ5PFMsIFA+KVxuXG4vKipcbiAqIFN0YXRlVHJhaXQuYnVpbGRcdUZGMUFcbiAqIC0gXHU1QzA2IFNwZWMgXHU1RjUyXHU0RTAwXHU1MzE2XHU0RTNBXHU1M0VGXHU2MjY3XHU4ODRDIFByb2dyYW1cdUZGMDhcdTU0MkIgR3JhcGgvUGxhblx1RkYwOVx1RkYxQlxuICogLSBEU0wgXHU1QzQyXHU0RTBFIGJ1aWxkIFx1NUM0Mlx1NzY4NFx1N0VBNlx1Njc1Rlx1NEVFNSBidWlsZCBcdTRFM0FcdTY3MDBcdTdFQzhcdTg4QzFcdTUxQjNcdUZGMDhcdTRGOEJcdTU5ODJcdTVGM0FcdTUyMzZcdTY2M0VcdTVGMEYgZGVwc1x1RkYwOVx1MzAwMlxuICovXG5leHBvcnQgY29uc3QgYnVpbGQgPSA8UyBleHRlbmRzIG9iamVjdD4oXG4gIHN0YXRlU2NoZW1hOiBTY2hlbWEuU2NoZW1hPFMsIGFueT4sXG4gIHNwZWM6IFN0YXRlVHJhaXRTcGVjPFM+LFxuKTogU3RhdGVUcmFpdFByb2dyYW08Uz4gPT4gSW50ZXJuYWxCdWlsZC5idWlsZChzdGF0ZVNjaGVtYSwgc3BlYylcblxuLyoqXG4gKiBTdGF0ZVRyYWl0Lmluc3RhbGxcdUZGMUFcbiAqIC0gXHU1NzI4XHU3RUQ5XHU1QjlBIEJvdW5kIEFQSSBcdTRFMEFcdTVCODlcdTg4QzUgUHJvZ3JhbSBcdTYzQ0ZcdThGRjBcdTc2ODRcdTg4NENcdTRFM0FcdUZGMDhjb21wdXRlZC9saW5rL3NvdXJjZS9jaGVjayBcdTdCNDlcdUZGMDlcdUZGMUJcbiAqIC0gXHU2QkNGXHU0RTJBIFBsYW5TdGVwIFx1NUJGOVx1NUU5NFx1NEUwMFx1NEUyQVx1OTU3Rlx1NzUxRlx1NTQ3RFx1NTQ2OFx1NjcxRiBFZmZlY3RcdUZGMENcdTVFNzZcdTYzMDJcdThGN0RcdTUyMzAgUnVudGltZSBTY29wZVx1MzAwMlxuICovXG5leHBvcnQgY29uc3QgaW5zdGFsbCA9IDxTIGV4dGVuZHMgb2JqZWN0PihcbiAgYm91bmQ6IEJvdW5kQXBpPGFueSwgYW55PixcbiAgcHJvZ3JhbTogU3RhdGVUcmFpdFByb2dyYW08Uz4sXG4pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBhbnk+ID0+IEludGVybmFsSW5zdGFsbC5pbnN0YWxsKGJvdW5kLCBwcm9ncmFtKVxuXG4vKipcbiAqIFN0YXRlVHJhaXQuZXhwb3J0U3RhdGljSXJcdUZGMUFcbiAqIC0gXHU1QkZDXHU1MUZBXHU2NzAwXHU1QzBGIFN0YXRpYyBJUlx1RkYwOFx1NUJGOVx1OUY1MCAwMDkgXHU3Njg0IGNhbm9uaWNhbCBGaWVsZFBhdGggXHU3RUE2XHU2NzVGXHVGRjA5XHVGRjBDXHU0RjlCIERldnRvb2xzL1x1NUJGOVx1OUY1MFx1NUI5RVx1OUE4Q1x1NUJBNFx1NkQ4OFx1OEQzOVx1RkYxQlxuICogLSBcdThGRDRcdTU2REVcdTUwM0NcdTVGQzVcdTk4N0JcdTUzRUYgSlNPTi5zdHJpbmdpZnlcdUZGMDhcdTc1MjhcdTRFOEVcdThCQzFcdTYzNkVcdTUzMDUvXHU1NkRFXHU2NTNFXHU5NEZFXHU4REVGXHVGRjA5XHUzMDAyXG4gKi9cbmV4cG9ydCB0eXBlIFN0YXRpY0lyID0gSW50ZXJuYWxJci5TdGF0aWNJclxuXG5leHBvcnQgY29uc3QgZXhwb3J0U3RhdGljSXIgPSAoXG4gIHByb2dyYW06IFN0YXRlVHJhaXRQcm9ncmFtPGFueT4sXG4gIG1vZHVsZUlkOiBzdHJpbmcsXG4gIG9wdGlvbnM/OiB7XG4gICAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZ1xuICB9LFxuKTogU3RhdGljSXIgPT5cbiAgSW50ZXJuYWxJci5leHBvcnRTdGF0aWNJcih7XG4gICAgcHJvZ3JhbSxcbiAgICBtb2R1bGVJZCxcbiAgICB2ZXJzaW9uOiBvcHRpb25zPy52ZXJzaW9uLFxuICB9KVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWlDQSxJQUFNLG9CQUFvQixDQUFDLFVBQXdEO0FBQ2pGLFFBQU0sTUFBTSxvQkFBSSxJQUFZO0FBQzVCLGFBQVcsUUFBUSxPQUFPO0FBQ3hCLFVBQU0sSUFBSSxLQUFLLEtBQUs7QUFDcEIsUUFBSSxDQUFDLEVBQUc7QUFDUixRQUFJLElBQUksQ0FBQztBQUFBLEVBQ1g7QUFDQSxTQUFPLE1BQU0sS0FBSyxHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUcsTUFBTSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0FBQzFEO0FBRUEsSUFBTSxnQkFBZ0IsQ0FBQyxVQUNyQixPQUFPLFVBQVUsWUFBWSxVQUFVLFFBQVEsQ0FB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LENBQUMsUUFDaEQsVUFBVSxPQUFjLEdBQUc7QUFBQSxJQUNuQztBQUNBLFdBQVEsTUFBTSxJQUFZLEdBQUcsSUFBSTtBQUFBLEVBQ25DO0FBQ0EsU0FBTztBQUFBLElBQ0wsV0FBVztBQUFBLElBQ1gsTUFBTTtBQUFBLElBQ04sTUFBTSxFQUFFLE1BQU0sTUFBTSxNQUFNLFFBQVEsUUFBUSxNQUFNLE9BQU87QUFBQSxFQUN6RDtBQUNGO0FBT08sSUFBTSxTQUFTLENBQWdELFVBWW5FO0FBQUEsRUFDQyxXQUFXO0FBQUEsRUFDWCxNQUFNO0FBQUEsRUFDTjtBQUNGO0FBT0ssSUFBTSxPQUFPLENBQWdELFVBR2pFO0FBQUEsRUFDQyxXQUFXO0FBQUEsRUFDWCxNQUFNO0FBQUEsRUFDTjtBQUNGO0FBT0ssSUFBTUMsU0FBUSxDQUNuQixhQUNBLFNBQ3VDLE1BQU0sYUFBYSxJQUFJO0FBT3pELElBQU1DLFdBQVUsQ0FDckIsT0FDQSxZQUNvRCxRQUFRLE9BQU8sT0FBTztBQVNyRSxJQUFNQyxrQkFBaUIsQ0FDNUIsU0FDQSxVQUNBLFlBSVcsZUFBZTtBQUFBLEVBQ3hCO0FBQUEsRUFDQTtBQUFBLEVBQ0EsU0FBUyxTQUFTO0FBQ3BCLENBQUM7IiwKICAibmFtZXMiOiBbImZyb20iLCAibm9kZSIsICJub2RlIiwgImxpc3QiLCAiZnJvbSIsICJsaXN0IiwgImJ1aWxkIiwgImluc3RhbGwiLCAiZXhwb3J0U3RhdGljSXIiXQp9Cg==
|