@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,397 @@
|
|
|
1
|
+
// @logix/core subpath bundles for @logix/sandbox
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// ../logix-core/src/internal/state-trait/rowid.ts
|
|
5
|
+
var parseSegments = (path) => {
|
|
6
|
+
if (!path) return [];
|
|
7
|
+
return path.split(".").map(
|
|
8
|
+
(seg) => /^[0-9]+$/.test(seg) ? Number(seg) : seg
|
|
9
|
+
);
|
|
10
|
+
};
|
|
11
|
+
var getAtPath = (state, path) => {
|
|
12
|
+
if (!path || state == null) return state;
|
|
13
|
+
const segments = parseSegments(path);
|
|
14
|
+
let current = state;
|
|
15
|
+
for (const seg of segments) {
|
|
16
|
+
if (current == null) return void 0;
|
|
17
|
+
if (typeof seg === "number") {
|
|
18
|
+
current = Array.isArray(current) ? current[seg] : current[String(seg)];
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
current = current[seg];
|
|
22
|
+
}
|
|
23
|
+
return current;
|
|
24
|
+
};
|
|
25
|
+
var setAtPathMutating = (draft, path, value) => {
|
|
26
|
+
if (!path) return;
|
|
27
|
+
const segments = parseSegments(path);
|
|
28
|
+
if (segments.length === 0) return;
|
|
29
|
+
let current = draft;
|
|
30
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
31
|
+
const key = segments[i];
|
|
32
|
+
const nextKey = segments[i + 1];
|
|
33
|
+
const next = current?.[key];
|
|
34
|
+
if (next == null || typeof next !== "object") {
|
|
35
|
+
current[key] = typeof nextKey === "number" ? [] : {};
|
|
36
|
+
}
|
|
37
|
+
current = current[key];
|
|
38
|
+
}
|
|
39
|
+
const last = segments[segments.length - 1];
|
|
40
|
+
current[last] = value;
|
|
41
|
+
};
|
|
42
|
+
var unsetAtPathMutating = (draft, path) => {
|
|
43
|
+
if (!path) return;
|
|
44
|
+
const segments = parseSegments(path);
|
|
45
|
+
if (segments.length === 0) return;
|
|
46
|
+
let current = draft;
|
|
47
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
48
|
+
const key = segments[i];
|
|
49
|
+
const next = current?.[key];
|
|
50
|
+
if (next == null || typeof next !== "object") {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
current = next;
|
|
54
|
+
}
|
|
55
|
+
const last = segments[segments.length - 1];
|
|
56
|
+
if (Array.isArray(current) && typeof last === "number") {
|
|
57
|
+
current[last] = void 0;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (current && typeof current === "object") {
|
|
61
|
+
delete current[last];
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var parseListItemFieldPath = (fieldPath) => {
|
|
65
|
+
const raw = typeof fieldPath === "string" ? fieldPath.trim() : "";
|
|
66
|
+
if (!raw) return void 0;
|
|
67
|
+
const segments = raw.split(".").filter(Boolean);
|
|
68
|
+
let lastListSeg = -1;
|
|
69
|
+
for (let i = 0; i < segments.length; i++) {
|
|
70
|
+
if (segments[i].endsWith("[]")) lastListSeg = i;
|
|
71
|
+
}
|
|
72
|
+
if (lastListSeg < 0) return void 0;
|
|
73
|
+
const strip = (seg) => seg.endsWith("[]") ? seg.slice(0, -2) : seg;
|
|
74
|
+
const listPath = segments.slice(0, lastListSeg + 1).map(strip).join(".");
|
|
75
|
+
const itemPath = segments.slice(lastListSeg + 1).map(strip).join(".");
|
|
76
|
+
return { listPath, itemPath };
|
|
77
|
+
};
|
|
78
|
+
var toListItemValuePath = (listPath, index, itemPath) => itemPath ? `${listPath}.${index}.${itemPath}` : `${listPath}.${index}`;
|
|
79
|
+
var readTrackBy = (item, trackBy) => {
|
|
80
|
+
if (!item || typeof item !== "object") return void 0;
|
|
81
|
+
const segments = trackBy.split(".");
|
|
82
|
+
let current = item;
|
|
83
|
+
for (const seg of segments) {
|
|
84
|
+
if (current == null) return void 0;
|
|
85
|
+
current = current[seg];
|
|
86
|
+
}
|
|
87
|
+
return current;
|
|
88
|
+
};
|
|
89
|
+
var didReorderByReference = (prevItems, nextItems) => {
|
|
90
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
91
|
+
for (let i = 0; i < prevItems.length; i++) {
|
|
92
|
+
const item = prevItems[i];
|
|
93
|
+
const list = buckets.get(item) ?? [];
|
|
94
|
+
list.push(i);
|
|
95
|
+
buckets.set(item, list);
|
|
96
|
+
}
|
|
97
|
+
for (let nextIndex = 0; nextIndex < nextItems.length; nextIndex++) {
|
|
98
|
+
const item = nextItems[nextIndex];
|
|
99
|
+
const q = buckets.get(item);
|
|
100
|
+
if (!q || q.length === 0) continue;
|
|
101
|
+
const prevIndex = q.shift();
|
|
102
|
+
if (prevIndex !== nextIndex) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
};
|
|
108
|
+
var hasStableTrackByKeys = (items, trackBy) => items.every((item) => readTrackBy(item, trackBy) !== void 0);
|
|
109
|
+
var isSameTrackBySequence = (prevItems, nextItems, trackBy) => {
|
|
110
|
+
if (prevItems.length !== nextItems.length) return false;
|
|
111
|
+
for (let i = 0; i < prevItems.length; i++) {
|
|
112
|
+
if (!Object.is(
|
|
113
|
+
readTrackBy(prevItems[i], trackBy),
|
|
114
|
+
readTrackBy(nextItems[i], trackBy)
|
|
115
|
+
)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
};
|
|
121
|
+
var reconcileIds = (prev, nextItems, trackBy, makeRowId) => {
|
|
122
|
+
const nextRowId = makeRowId ?? /* @__PURE__ */ (() => {
|
|
123
|
+
let rowSeq = 0;
|
|
124
|
+
return () => {
|
|
125
|
+
rowSeq += 1;
|
|
126
|
+
return `r${rowSeq}`;
|
|
127
|
+
};
|
|
128
|
+
})();
|
|
129
|
+
if (!prev) {
|
|
130
|
+
return {
|
|
131
|
+
ids: nextItems.map(() => nextRowId()),
|
|
132
|
+
removed: []
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (prev.itemsRef === nextItems) {
|
|
136
|
+
return {
|
|
137
|
+
ids: prev.ids,
|
|
138
|
+
removed: []
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const sameLength = prev.itemsRef.length === nextItems.length;
|
|
142
|
+
if (sameLength) {
|
|
143
|
+
if (trackBy) {
|
|
144
|
+
const canUseKeys = hasStableTrackByKeys(prev.itemsRef, trackBy) && hasStableTrackByKeys(nextItems, trackBy);
|
|
145
|
+
if (canUseKeys) {
|
|
146
|
+
if (isSameTrackBySequence(prev.itemsRef, nextItems, trackBy)) {
|
|
147
|
+
return {
|
|
148
|
+
ids: prev.ids,
|
|
149
|
+
removed: []
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
if (!didReorderByReference(prev.itemsRef, nextItems)) {
|
|
154
|
+
return {
|
|
155
|
+
ids: prev.ids,
|
|
156
|
+
removed: []
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} else if (!didReorderByReference(prev.itemsRef, nextItems)) {
|
|
161
|
+
return {
|
|
162
|
+
ids: prev.ids,
|
|
163
|
+
removed: []
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const keyOf = (item) => {
|
|
168
|
+
if (!trackBy) return item;
|
|
169
|
+
const k = readTrackBy(item, trackBy);
|
|
170
|
+
return k !== void 0 ? k : item;
|
|
171
|
+
};
|
|
172
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
173
|
+
for (let i = 0; i < prev.itemsRef.length; i++) {
|
|
174
|
+
const key = keyOf(prev.itemsRef[i]);
|
|
175
|
+
const list = buckets.get(key) ?? [];
|
|
176
|
+
list.push(prev.ids[i]);
|
|
177
|
+
buckets.set(key, list);
|
|
178
|
+
}
|
|
179
|
+
const ids = [];
|
|
180
|
+
for (let i = 0; i < nextItems.length; i++) {
|
|
181
|
+
const key = keyOf(nextItems[i]);
|
|
182
|
+
const list = buckets.get(key);
|
|
183
|
+
if (list && list.length > 0) {
|
|
184
|
+
ids.push(list.shift());
|
|
185
|
+
} else {
|
|
186
|
+
ids.push(nextRowId());
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const removed = [];
|
|
190
|
+
for (const list of buckets.values()) {
|
|
191
|
+
removed.push(...list);
|
|
192
|
+
}
|
|
193
|
+
return { ids, removed };
|
|
194
|
+
};
|
|
195
|
+
var buildIndexById = (ids) => {
|
|
196
|
+
const map = /* @__PURE__ */ new Map();
|
|
197
|
+
for (let i = 0; i < ids.length; i++) {
|
|
198
|
+
map.set(ids[i], i);
|
|
199
|
+
}
|
|
200
|
+
return map;
|
|
201
|
+
};
|
|
202
|
+
var RowIdStore = class {
|
|
203
|
+
constructor(instanceId) {
|
|
204
|
+
this.instanceId = instanceId;
|
|
205
|
+
this.lists = /* @__PURE__ */ new Map();
|
|
206
|
+
this.removalListeners = /* @__PURE__ */ new Map();
|
|
207
|
+
this.rowIdIndex = /* @__PURE__ */ new Map();
|
|
208
|
+
this.nextRowSeq = 0;
|
|
209
|
+
this.listKey = (listPath, parentRowId) => parentRowId ? `${listPath}@@${parentRowId}` : listPath;
|
|
210
|
+
this.makeRowId = () => {
|
|
211
|
+
this.nextRowSeq += 1;
|
|
212
|
+
return this.instanceId ? `${this.instanceId}::r${this.nextRowSeq}` : `r${this.nextRowSeq}`;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
notifyRemoved(listPath, rowId) {
|
|
216
|
+
const listeners = this.removalListeners.get(listPath);
|
|
217
|
+
if (!listeners || listeners.size === 0) return;
|
|
218
|
+
for (const fn of listeners) {
|
|
219
|
+
try {
|
|
220
|
+
fn(rowId);
|
|
221
|
+
} catch {
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
removeDescendants(parentRowId) {
|
|
226
|
+
const keys = [];
|
|
227
|
+
for (const [k, st] of this.lists.entries()) {
|
|
228
|
+
if (st.parentRowId === parentRowId) keys.push(k);
|
|
229
|
+
}
|
|
230
|
+
for (const key of keys) {
|
|
231
|
+
const st = this.lists.get(key);
|
|
232
|
+
if (!st) continue;
|
|
233
|
+
this.lists.delete(key);
|
|
234
|
+
for (let i = 0; i < st.ids.length; i++) {
|
|
235
|
+
const rowId = st.ids[i];
|
|
236
|
+
this.rowIdIndex.delete(rowId);
|
|
237
|
+
this.notifyRemoved(st.listPath, rowId);
|
|
238
|
+
this.removeDescendants(rowId);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
onRemoved(listPath, listener) {
|
|
243
|
+
const set = this.removalListeners.get(listPath) ?? /* @__PURE__ */ new Set();
|
|
244
|
+
set.add(listener);
|
|
245
|
+
this.removalListeners.set(listPath, set);
|
|
246
|
+
return () => {
|
|
247
|
+
const current = this.removalListeners.get(listPath);
|
|
248
|
+
if (!current) return;
|
|
249
|
+
current.delete(listener);
|
|
250
|
+
if (current.size === 0) this.removalListeners.delete(listPath);
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
getRowId(listPath, index, parentRowId) {
|
|
254
|
+
const state = this.lists.get(this.listKey(listPath, parentRowId));
|
|
255
|
+
return state ? state.ids[index] : void 0;
|
|
256
|
+
}
|
|
257
|
+
getIndex(listPath, rowId) {
|
|
258
|
+
const info = this.rowIdIndex.get(rowId);
|
|
259
|
+
if (!info) return void 0;
|
|
260
|
+
if (info.listPath !== listPath) return void 0;
|
|
261
|
+
return info.index;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* ensureList:
|
|
265
|
+
* - 让指定 listPath 的 RowID 映射与当前 items 对齐;
|
|
266
|
+
* - 返回最新的 ids(index -> RowId)。
|
|
267
|
+
*/
|
|
268
|
+
ensureList(listPath, items, trackBy, parentRowId) {
|
|
269
|
+
const key = this.listKey(listPath, parentRowId);
|
|
270
|
+
const prev = this.lists.get(key);
|
|
271
|
+
const { ids, removed } = reconcileIds(prev, items, trackBy ?? prev?.trackBy, this.makeRowId);
|
|
272
|
+
const next = {
|
|
273
|
+
listPath,
|
|
274
|
+
parentRowId,
|
|
275
|
+
itemsRef: items,
|
|
276
|
+
ids,
|
|
277
|
+
indexById: buildIndexById(ids),
|
|
278
|
+
trackBy: trackBy ?? prev?.trackBy
|
|
279
|
+
};
|
|
280
|
+
this.lists.set(key, next);
|
|
281
|
+
if (removed.length > 0) {
|
|
282
|
+
for (const rowId of removed) {
|
|
283
|
+
this.rowIdIndex.delete(rowId);
|
|
284
|
+
this.notifyRemoved(listPath, rowId);
|
|
285
|
+
this.removeDescendants(rowId);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
for (let i = 0; i < ids.length; i++) {
|
|
289
|
+
const rowId = ids[i];
|
|
290
|
+
this.rowIdIndex.set(rowId, { key, listPath, index: i });
|
|
291
|
+
}
|
|
292
|
+
return ids;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* updateAll:
|
|
296
|
+
* - 在每次提交后对齐所有已知 list 的 RowID 映射;
|
|
297
|
+
* - configs 来自 StateTraitProgram.spec 中的 list 声明(可携带 trackBy)。
|
|
298
|
+
*/
|
|
299
|
+
updateAll(state, configs) {
|
|
300
|
+
const cfgByPath = /* @__PURE__ */ new Map();
|
|
301
|
+
const paths = [];
|
|
302
|
+
for (const cfg of configs) {
|
|
303
|
+
if (!cfg || typeof cfg.path !== "string") continue;
|
|
304
|
+
const p = cfg.path.trim();
|
|
305
|
+
if (!p) continue;
|
|
306
|
+
cfgByPath.set(p, cfg);
|
|
307
|
+
paths.push(p);
|
|
308
|
+
}
|
|
309
|
+
const pathSet = new Set(paths);
|
|
310
|
+
const parentOf = (path) => {
|
|
311
|
+
const segments = path.split(".").filter(Boolean);
|
|
312
|
+
let best;
|
|
313
|
+
for (let i = 1; i < segments.length; i++) {
|
|
314
|
+
const prefix = segments.slice(0, i).join(".");
|
|
315
|
+
if (pathSet.has(prefix)) best = prefix;
|
|
316
|
+
}
|
|
317
|
+
return best;
|
|
318
|
+
};
|
|
319
|
+
const parentByPath = /* @__PURE__ */ new Map();
|
|
320
|
+
const suffixByPath = /* @__PURE__ */ new Map();
|
|
321
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
322
|
+
for (const path of paths) {
|
|
323
|
+
const parent = parentOf(path);
|
|
324
|
+
parentByPath.set(path, parent);
|
|
325
|
+
const suffix = parent ? path.slice(parent.length + 1) : path;
|
|
326
|
+
suffixByPath.set(path, suffix);
|
|
327
|
+
const list = childrenByParent.get(parent) ?? [];
|
|
328
|
+
list.push(path);
|
|
329
|
+
childrenByParent.set(parent, list);
|
|
330
|
+
}
|
|
331
|
+
const roots = (childrenByParent.get(void 0) ?? []).slice().sort((a, b) => a.localeCompare(b));
|
|
332
|
+
const visit = (listPath, parentRowId, listValue) => {
|
|
333
|
+
const cfg = cfgByPath.get(listPath);
|
|
334
|
+
const items = Array.isArray(listValue) ? listValue : [];
|
|
335
|
+
const ids = this.ensureList(listPath, items, cfg?.trackBy, parentRowId);
|
|
336
|
+
const children = (childrenByParent.get(listPath) ?? []).slice().sort((a, b) => a.localeCompare(b));
|
|
337
|
+
if (children.length === 0) return;
|
|
338
|
+
for (let i = 0; i < items.length; i++) {
|
|
339
|
+
const row = items[i];
|
|
340
|
+
const rowId = ids[i];
|
|
341
|
+
if (!rowId) continue;
|
|
342
|
+
for (const childPath of children) {
|
|
343
|
+
const suffix = suffixByPath.get(childPath) ?? "";
|
|
344
|
+
const childValue = suffix ? getAtPath(row, suffix) : void 0;
|
|
345
|
+
visit(childPath, rowId, childValue);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
for (const root of roots) {
|
|
350
|
+
const value = getAtPath(state, root);
|
|
351
|
+
visit(root, void 0, value);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
var collectListConfigs = (spec) => {
|
|
356
|
+
const configs = [];
|
|
357
|
+
for (const key in spec) {
|
|
358
|
+
if (!Object.prototype.hasOwnProperty.call(spec, key)) continue;
|
|
359
|
+
const raw = spec[key];
|
|
360
|
+
if (!raw || typeof raw !== "object") continue;
|
|
361
|
+
const tag = raw._tag;
|
|
362
|
+
if (tag !== "StateTraitList") continue;
|
|
363
|
+
const trackBy = raw.identityHint?.trackBy;
|
|
364
|
+
configs.push({
|
|
365
|
+
path: key,
|
|
366
|
+
trackBy: typeof trackBy === "string" ? trackBy : void 0
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
return configs;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// ../logix-core/src/internal/runtime/core/ReplayLog.ts
|
|
373
|
+
import { Context, Effect, Layer } from "../effect.js";
|
|
374
|
+
var ReplayLog = class extends Context.Tag("@logix/core/ReplayLog")() {
|
|
375
|
+
};
|
|
376
|
+
var snapshot = Effect.gen(function* () {
|
|
377
|
+
const log = yield* ReplayLog;
|
|
378
|
+
return yield* log.snapshot;
|
|
379
|
+
});
|
|
380
|
+
var resetCursor = Effect.gen(
|
|
381
|
+
function* () {
|
|
382
|
+
const log = yield* ReplayLog;
|
|
383
|
+
yield* log.resetCursor;
|
|
384
|
+
}
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
export {
|
|
388
|
+
ReplayLog,
|
|
389
|
+
getAtPath,
|
|
390
|
+
setAtPathMutating,
|
|
391
|
+
unsetAtPathMutating,
|
|
392
|
+
parseListItemFieldPath,
|
|
393
|
+
toListItemValuePath,
|
|
394
|
+
RowIdStore,
|
|
395
|
+
collectListConfigs
|
|
396
|
+
};
|
|
397
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvc3RhdGUtdHJhaXQvcm93aWQudHMiLCAiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL1JlcGxheUxvZy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0IHR5cGUgUm93SWQgPSBzdHJpbmdcblxuZXhwb3J0IGludGVyZmFjZSBMaXN0Q29uZmlnIHtcbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nXG4gIHJlYWRvbmx5IHRyYWNrQnk/OiBzdHJpbmdcbn1cblxuZXhwb3J0IHR5cGUgTGlzdFJlbW92YWxMaXN0ZW5lciA9IChyb3dJZDogUm93SWQpID0+IHZvaWRcblxudHlwZSBTZWdtZW50ID0gc3RyaW5nIHwgbnVtYmVyXG5cbmNvbnN0IHBhcnNlU2VnbWVudHMgPSAocGF0aDogc3RyaW5nKTogUmVhZG9ubHlBcnJheTxTZWdtZW50PiA9PiB7XG4gIGlmICghcGF0aCkgcmV0dXJuIFtdXG4gIHJldHVybiBwYXRoLnNwbGl0KFwiLlwiKS5tYXAoKHNlZykgPT5cbiAgICAvXlswLTldKyQvLnRlc3Qoc2VnKSA/IE51bWJlcihzZWcpIDogc2VnLFxuICApXG59XG5cbmV4cG9ydCBjb25zdCBnZXRBdFBhdGggPSAoc3RhdGU6IGFueSwgcGF0aDogc3RyaW5nKTogYW55ID0+IHtcbiAgaWYgKCFwYXRoIHx8IHN0YXRlID09IG51bGwpIHJldHVybiBzdGF0ZVxuICBjb25zdCBzZWdtZW50cyA9IHBhcnNlU2VnbWVudHMocGF0aClcbiAgbGV0IGN1cnJlbnQ6IGFueSA9IHN0YXRlXG4gIGZvciAoY29uc3Qgc2VnIG9mIHNlZ21lbnRzKSB7XG4gICAgaWYgKGN1cnJlbnQgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGlmICh0eXBlb2Ygc2VnID09PSBcIm51bWJlclwiKSB7XG4gICAgICBjdXJyZW50ID0gQXJyYXkuaXNBcnJheShjdXJyZW50KSA/IGN1cnJlbnRbc2VnXSA6IGN1cnJlbnRbU3RyaW5nKHNlZyldXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBjdXJyZW50ID0gY3VycmVudFtzZWddXG4gIH1cbiAgcmV0dXJuIGN1cnJlbnRcbn1cblxuZXhwb3J0IGNvbnN0IHNldEF0UGF0aE11dGF0aW5nID0gKGRyYWZ0OiBhbnksIHBhdGg6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQgPT4ge1xuICBpZiAoIXBhdGgpIHJldHVyblxuICBjb25zdCBzZWdtZW50cyA9IHBhcnNlU2VnbWVudHMocGF0aClcbiAgaWYgKHNlZ21lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgbGV0IGN1cnJlbnQ6IGFueSA9IGRyYWZ0XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgY29uc3Qga2V5ID0gc2VnbWVudHNbaV0hXG4gICAgY29uc3QgbmV4dEtleSA9IHNlZ21lbnRzW2kgKyAxXSFcblxuICAgIGNvbnN0IG5leHQgPSBjdXJyZW50Py5ba2V5IGFzIGFueV1cbiAgICBpZiAobmV4dCA9PSBudWxsIHx8IHR5cGVvZiBuZXh0ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICBjdXJyZW50W2tleSBhcyBhbnldID0gdHlwZW9mIG5leHRLZXkgPT09IFwibnVtYmVyXCIgPyBbXSA6IHt9XG4gICAgfVxuICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleSBhcyBhbnldXG4gIH1cblxuICBjb25zdCBsYXN0ID0gc2VnbWVudHNbc2VnbWVudHMubGVuZ3RoIC0gMV0hXG4gIGN1cnJlbnRbbGFzdCBhcyBhbnldID0gdmFsdWVcbn1cblxuZXhwb3J0IGNvbnN0IHVuc2V0QXRQYXRoTXV0YXRpbmcgPSAoZHJhZnQ6IGFueSwgcGF0aDogc3RyaW5nKTogdm9pZCA9PiB7XG4gIGlmICghcGF0aCkgcmV0dXJuXG4gIGNvbnN0IHNlZ21lbnRzID0gcGFyc2VTZWdtZW50cyhwYXRoKVxuICBpZiAoc2VnbWVudHMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICBsZXQgY3VycmVudDogYW55ID0gZHJhZnRcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICBjb25zdCBrZXkgPSBzZWdtZW50c1tpXSFcbiAgICBjb25zdCBuZXh0ID0gY3VycmVudD8uW2tleSBhcyBhbnldXG4gICAgaWYgKG5leHQgPT0gbnVsbCB8fCB0eXBlb2YgbmV4dCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGN1cnJlbnQgPSBuZXh0XG4gIH1cblxuICBjb25zdCBsYXN0ID0gc2VnbWVudHNbc2VnbWVudHMubGVuZ3RoIC0gMV0hXG4gIGlmIChBcnJheS5pc0FycmF5KGN1cnJlbnQpICYmIHR5cGVvZiBsYXN0ID09PSBcIm51bWJlclwiKSB7XG4gICAgY3VycmVudFtsYXN0XSA9IHVuZGVmaW5lZFxuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKGN1cnJlbnQgJiYgdHlwZW9mIGN1cnJlbnQgPT09IFwib2JqZWN0XCIpIHtcbiAgICBkZWxldGUgY3VycmVudFtsYXN0IGFzIGFueV1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgam9pblBhdGggPSAocHJlZml4OiBzdHJpbmcsIHN1ZmZpeDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgaWYgKCFwcmVmaXgpIHJldHVybiBzdWZmaXhcbiAgaWYgKCFzdWZmaXgpIHJldHVybiBwcmVmaXhcbiAgcmV0dXJuIGAke3ByZWZpeH0uJHtzdWZmaXh9YFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpc3RJdGVtRmllbGRQYXRoIHtcbiAgcmVhZG9ubHkgbGlzdFBhdGg6IHN0cmluZ1xuICByZWFkb25seSBpdGVtUGF0aDogc3RyaW5nXG59XG5cbi8qKlxuICogcGFyc2VMaXN0SXRlbUZpZWxkUGF0aFx1RkYxQVxuICogLSBcdThCQzZcdTUyMkJcdTVGNjJcdTU5ODIgXCJpdGVtc1tdLnByb2ZpbGVSZXNvdXJjZVwiIFx1NzY4NCBsaXN0Lml0ZW0gXHU1QjU3XHU2QkI1XHU4REVGXHU1Rjg0XHVGRjFCXG4gKiAtIFx1NjUyRlx1NjMwMVx1NTkxQVx1NUM0Mlx1NUQ0Q1x1NTk1N1x1NjU3MFx1N0VDNFx1RkYxQVx1OEZENFx1NTZERVx1MjAxQ1x1NjcwMFx1NTE4NVx1NUM0MiBsaXN0XHUyMDFEXHU3Njg0IGxpc3RQYXRoIFx1NEUwRVx1NTE3NiBpdGVtUGF0aFx1MzAwMlxuICovXG5leHBvcnQgY29uc3QgcGFyc2VMaXN0SXRlbUZpZWxkUGF0aCA9IChmaWVsZFBhdGg6IHN0cmluZyk6IExpc3RJdGVtRmllbGRQYXRoIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgcmF3ID0gdHlwZW9mIGZpZWxkUGF0aCA9PT0gXCJzdHJpbmdcIiA/IGZpZWxkUGF0aC50cmltKCkgOiBcIlwiXG4gIGlmICghcmF3KSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3Qgc2VnbWVudHMgPSByYXcuc3BsaXQoXCIuXCIpLmZpbHRlcihCb29sZWFuKVxuICBsZXQgbGFzdExpc3RTZWcgPSAtMVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHNlZ21lbnRzW2ldIS5lbmRzV2l0aChcIltdXCIpKSBsYXN0TGlzdFNlZyA9IGlcbiAgfVxuICBpZiAobGFzdExpc3RTZWcgPCAwKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3Qgc3RyaXAgPSAoc2VnOiBzdHJpbmcpOiBzdHJpbmcgPT4gKHNlZy5lbmRzV2l0aChcIltdXCIpID8gc2VnLnNsaWNlKDAsIC0yKSA6IHNlZylcblxuICBjb25zdCBsaXN0UGF0aCA9IHNlZ21lbnRzXG4gICAgLnNsaWNlKDAsIGxhc3RMaXN0U2VnICsgMSlcbiAgICAubWFwKHN0cmlwKVxuICAgIC5qb2luKFwiLlwiKVxuXG4gIGNvbnN0IGl0ZW1QYXRoID0gc2VnbWVudHNcbiAgICAuc2xpY2UobGFzdExpc3RTZWcgKyAxKVxuICAgIC5tYXAoc3RyaXApXG4gICAgLmpvaW4oXCIuXCIpXG5cbiAgcmV0dXJuIHsgbGlzdFBhdGgsIGl0ZW1QYXRoIH1cbn1cblxuZXhwb3J0IGNvbnN0IHRvTGlzdEl0ZW1WYWx1ZVBhdGggPSAoXG4gIGxpc3RQYXRoOiBzdHJpbmcsXG4gIGluZGV4OiBudW1iZXIsXG4gIGl0ZW1QYXRoOiBzdHJpbmcsXG4pOiBzdHJpbmcgPT5cbiAgaXRlbVBhdGggPyBgJHtsaXN0UGF0aH0uJHtpbmRleH0uJHtpdGVtUGF0aH1gIDogYCR7bGlzdFBhdGh9LiR7aW5kZXh9YFxuXG50eXBlIExpc3RTdGF0ZSA9IHtcbiAgcmVhZG9ubHkgbGlzdFBhdGg6IHN0cmluZ1xuICByZWFkb25seSBwYXJlbnRSb3dJZD86IFJvd0lkXG4gIHJlYWRvbmx5IGl0ZW1zUmVmOiBSZWFkb25seUFycmF5PHVua25vd24+XG4gIHJlYWRvbmx5IGlkczogUmVhZG9ubHlBcnJheTxSb3dJZD5cbiAgcmVhZG9ubHkgaW5kZXhCeUlkOiBSZWFkb25seU1hcDxSb3dJZCwgbnVtYmVyPlxuICByZWFkb25seSB0cmFja0J5Pzogc3RyaW5nXG59XG5cbmNvbnN0IHJlYWRUcmFja0J5ID0gKGl0ZW06IHVua25vd24sIHRyYWNrQnk6IHN0cmluZyk6IHVua25vd24gPT4ge1xuICBpZiAoIWl0ZW0gfHwgdHlwZW9mIGl0ZW0gIT09IFwib2JqZWN0XCIpIHJldHVybiB1bmRlZmluZWRcbiAgY29uc3Qgc2VnbWVudHMgPSB0cmFja0J5LnNwbGl0KFwiLlwiKVxuICBsZXQgY3VycmVudDogYW55ID0gaXRlbVxuICBmb3IgKGNvbnN0IHNlZyBvZiBzZWdtZW50cykge1xuICAgIGlmIChjdXJyZW50ID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcbiAgICBjdXJyZW50ID0gY3VycmVudFtzZWcgYXMgYW55XVxuICB9XG4gIHJldHVybiBjdXJyZW50XG59XG5cbmNvbnN0IGRpZFJlb3JkZXJCeVJlZmVyZW5jZSA9IChcbiAgcHJldkl0ZW1zOiBSZWFkb25seUFycmF5PHVua25vd24+LFxuICBuZXh0SXRlbXM6IFJlYWRvbmx5QXJyYXk8dW5rbm93bj4sXG4pOiBib29sZWFuID0+IHtcbiAgY29uc3QgYnVja2V0cyA9IG5ldyBNYXA8dW5rbm93biwgQXJyYXk8bnVtYmVyPj4oKVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXZJdGVtcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGl0ZW0gPSBwcmV2SXRlbXNbaV1cbiAgICBjb25zdCBsaXN0ID0gYnVja2V0cy5nZXQoaXRlbSkgPz8gW11cbiAgICBsaXN0LnB1c2goaSlcbiAgICBidWNrZXRzLnNldChpdGVtLCBsaXN0KVxuICB9XG5cbiAgZm9yIChsZXQgbmV4dEluZGV4ID0gMDsgbmV4dEluZGV4IDwgbmV4dEl0ZW1zLmxlbmd0aDsgbmV4dEluZGV4KyspIHtcbiAgICBjb25zdCBpdGVtID0gbmV4dEl0ZW1zW25leHRJbmRleF1cbiAgICBjb25zdCBxID0gYnVja2V0cy5nZXQoaXRlbSlcbiAgICBpZiAoIXEgfHwgcS5sZW5ndGggPT09IDApIGNvbnRpbnVlXG4gICAgY29uc3QgcHJldkluZGV4ID0gcS5zaGlmdCgpIVxuICAgIGlmIChwcmV2SW5kZXggIT09IG5leHRJbmRleCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxuY29uc3QgaGFzU3RhYmxlVHJhY2tCeUtleXMgPSAoXG4gIGl0ZW1zOiBSZWFkb25seUFycmF5PHVua25vd24+LFxuICB0cmFja0J5OiBzdHJpbmcsXG4pOiBib29sZWFuID0+IGl0ZW1zLmV2ZXJ5KChpdGVtKSA9PiByZWFkVHJhY2tCeShpdGVtLCB0cmFja0J5KSAhPT0gdW5kZWZpbmVkKVxuXG5jb25zdCBpc1NhbWVUcmFja0J5U2VxdWVuY2UgPSAoXG4gIHByZXZJdGVtczogUmVhZG9ubHlBcnJheTx1bmtub3duPixcbiAgbmV4dEl0ZW1zOiBSZWFkb25seUFycmF5PHVua25vd24+LFxuICB0cmFja0J5OiBzdHJpbmcsXG4pOiBib29sZWFuID0+IHtcbiAgaWYgKHByZXZJdGVtcy5sZW5ndGggIT09IG5leHRJdGVtcy5sZW5ndGgpIHJldHVybiBmYWxzZVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXZJdGVtcy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChcbiAgICAgICFPYmplY3QuaXMoXG4gICAgICAgIHJlYWRUcmFja0J5KHByZXZJdGVtc1tpXSwgdHJhY2tCeSksXG4gICAgICAgIHJlYWRUcmFja0J5KG5leHRJdGVtc1tpXSwgdHJhY2tCeSksXG4gICAgICApXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuY29uc3QgcmVjb25jaWxlSWRzID0gKFxuICBwcmV2OiBMaXN0U3RhdGUgfCB1bmRlZmluZWQsXG4gIG5leHRJdGVtczogUmVhZG9ubHlBcnJheTx1bmtub3duPixcbiAgdHJhY2tCeT86IHN0cmluZyxcbiAgbWFrZVJvd0lkPzogKCkgPT4gUm93SWQsXG4pOiB7IHJlYWRvbmx5IGlkczogUmVhZG9ubHlBcnJheTxSb3dJZD47IHJlYWRvbmx5IHJlbW92ZWQ6IFJlYWRvbmx5QXJyYXk8Um93SWQ+IH0gPT4ge1xuICBjb25zdCBuZXh0Um93SWQgPVxuICAgIG1ha2VSb3dJZCA/P1xuICAgICgoKSA9PiB7XG4gICAgICBsZXQgcm93U2VxID0gMFxuICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgcm93U2VxICs9IDFcbiAgICAgICAgcmV0dXJuIGByJHtyb3dTZXF9YFxuICAgICAgfVxuICAgIH0pKClcblxuICBpZiAoIXByZXYpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWRzOiBuZXh0SXRlbXMubWFwKCgpID0+IG5leHRSb3dJZCgpKSxcbiAgICAgIHJlbW92ZWQ6IFtdLFxuICAgIH1cbiAgfVxuXG4gIGlmIChwcmV2Lml0ZW1zUmVmID09PSBuZXh0SXRlbXMpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWRzOiBwcmV2LmlkcyxcbiAgICAgIHJlbW92ZWQ6IFtdLFxuICAgIH1cbiAgfVxuXG4gIC8vIFx1OTFDRFx1ODk4MVx1RkYxQVx1NEZERFx1NjMwMSBSb3dJZCBcdTU3MjhcdTIwMUNcdTk3NUVcdTdFRDNcdTY3ODRcdTUzRDhcdTY2RjRcdTIwMURcdUZGMDhcdTRFQzVcdTVCNTdcdTZCQjVcdTY2RjRcdTY1QjAvXHU1QkY5XHU4QzYxXHU1MTRCXHU5Njg2XHVGRjA5XHU0RTBCXHU3Njg0XHU3QTMzXHU1QjlBXHU2MDI3XHVGRjBDXG4gIC8vIFx1NTQyNlx1NTIxOSBpbi1mbGlnaHQgLyBcdTdGMTNcdTVCNTggXHU0RjFBXHU4OEFCXHU2NUUwXHU2MTBGXHU0RTQ5XHU1NzMwXHU1OTMxXHU2NTQ4XHUzMDAyXG4gIGNvbnN0IHNhbWVMZW5ndGggPSBwcmV2Lml0ZW1zUmVmLmxlbmd0aCA9PT0gbmV4dEl0ZW1zLmxlbmd0aFxuICBpZiAoc2FtZUxlbmd0aCkge1xuICAgIC8vIHRyYWNrQnkgXHU1NzNBXHU2NjZGXHVGRjFBXHU4MkU1IGtleSBcdTVFOEZcdTUyMTdcdTRFMDBcdTgxRjRcdUZGMENcdTUyMTlcdTUzRUZcdTc2RjRcdTYzQTVcdTU5MERcdTc1MjhcdTY1RTcgaWRzXHVGRjFCXG4gICAgLy8gXHU1NDI2XHU1MjE5XHU1RkM1XHU5ODdCXHU4RDcwIGtleS1iYXNlZCByZWNvbmNpbGVcdUZGMDhcdTkwN0ZcdTUxNEQgY2xvbmUgKyByZW9yZGVyIFx1NjVGNlx1OEJFRlx1NTIyNFx1NEUzQVx1MjAxQ1x1NjcyQVx1OTFDRFx1NjM5Mlx1MjAxRFx1RkYwOVx1MzAwMlxuICAgIGlmICh0cmFja0J5KSB7XG4gICAgICBjb25zdCBjYW5Vc2VLZXlzID1cbiAgICAgICAgaGFzU3RhYmxlVHJhY2tCeUtleXMocHJldi5pdGVtc1JlZiwgdHJhY2tCeSkgJiZcbiAgICAgICAgaGFzU3RhYmxlVHJhY2tCeUtleXMobmV4dEl0ZW1zLCB0cmFja0J5KVxuICAgICAgaWYgKGNhblVzZUtleXMpIHtcbiAgICAgICAgaWYgKGlzU2FtZVRyYWNrQnlTZXF1ZW5jZShwcmV2Lml0ZW1zUmVmLCBuZXh0SXRlbXMsIHRyYWNrQnkpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlkczogcHJldi5pZHMsXG4gICAgICAgICAgICByZW1vdmVkOiBbXSxcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHRyYWNrQnkga2V5IFx1NEUwRFx1NTNFRlx1NzUyOFx1NjVGNlx1OTAwMFx1NTZERVx1NTIzMFx1NUYxNVx1NzUyOFx1N0VBN1x1NEZBNlx1NkQ0Qlx1RkYwOFx1NUMzRFx1OTFDRlx1NEZERFx1NjMwMVx1MjAxQ1x1NTE0Qlx1OTY4Nlx1NEY0Nlx1NEUwRFx1OTFDRFx1NjM5Mlx1MjAxRFx1NzY4NFx1N0EzM1x1NUI5QVx1NjAyN1x1RkYwOVx1MzAwMlxuICAgICAgICBpZiAoIWRpZFJlb3JkZXJCeVJlZmVyZW5jZShwcmV2Lml0ZW1zUmVmLCBuZXh0SXRlbXMpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlkczogcHJldi5pZHMsXG4gICAgICAgICAgICByZW1vdmVkOiBbXSxcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFkaWRSZW9yZGVyQnlSZWZlcmVuY2UocHJldi5pdGVtc1JlZiwgbmV4dEl0ZW1zKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaWRzOiBwcmV2LmlkcyxcbiAgICAgICAgcmVtb3ZlZDogW10sXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3Qga2V5T2YgPSAoaXRlbTogdW5rbm93bik6IHVua25vd24gPT4ge1xuICAgIGlmICghdHJhY2tCeSkgcmV0dXJuIGl0ZW1cbiAgICBjb25zdCBrID0gcmVhZFRyYWNrQnkoaXRlbSwgdHJhY2tCeSlcbiAgICByZXR1cm4gayAhPT0gdW5kZWZpbmVkID8gayA6IGl0ZW1cbiAgfVxuXG4gIGNvbnN0IGJ1Y2tldHMgPSBuZXcgTWFwPHVua25vd24sIEFycmF5PFJvd0lkPj4oKVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXYuaXRlbXNSZWYubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBrZXkgPSBrZXlPZihwcmV2Lml0ZW1zUmVmW2ldKVxuICAgIGNvbnN0IGxpc3QgPSBidWNrZXRzLmdldChrZXkpID8/IFtdXG4gICAgbGlzdC5wdXNoKHByZXYuaWRzW2ldISlcbiAgICBidWNrZXRzLnNldChrZXksIGxpc3QpXG4gIH1cblxuICBjb25zdCBpZHM6IEFycmF5PFJvd0lkPiA9IFtdXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbmV4dEl0ZW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qga2V5ID0ga2V5T2YobmV4dEl0ZW1zW2ldKVxuICAgIGNvbnN0IGxpc3QgPSBidWNrZXRzLmdldChrZXkpXG4gICAgaWYgKGxpc3QgJiYgbGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICBpZHMucHVzaChsaXN0LnNoaWZ0KCkhKVxuICAgIH0gZWxzZSB7XG4gICAgICBpZHMucHVzaChuZXh0Um93SWQoKSlcbiAgICB9XG4gIH1cblxuICBjb25zdCByZW1vdmVkOiBBcnJheTxSb3dJZD4gPSBbXVxuICBmb3IgKGNvbnN0IGxpc3Qgb2YgYnVja2V0cy52YWx1ZXMoKSkge1xuICAgIHJlbW92ZWQucHVzaCguLi5saXN0KVxuICB9XG5cbiAgcmV0dXJuIHsgaWRzLCByZW1vdmVkIH1cbn1cblxuY29uc3QgYnVpbGRJbmRleEJ5SWQgPSAoaWRzOiBSZWFkb25seUFycmF5PFJvd0lkPik6IFJlYWRvbmx5TWFwPFJvd0lkLCBudW1iZXI+ID0+IHtcbiAgY29uc3QgbWFwID0gbmV3IE1hcDxSb3dJZCwgbnVtYmVyPigpXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgbWFwLnNldChpZHNbaV0hLCBpKVxuICB9XG4gIHJldHVybiBtYXBcbn1cblxuZXhwb3J0IGNsYXNzIFJvd0lkU3RvcmUge1xuICBwcml2YXRlIHJlYWRvbmx5IGxpc3RzID0gbmV3IE1hcDxzdHJpbmcsIExpc3RTdGF0ZT4oKVxuICBwcml2YXRlIHJlYWRvbmx5IHJlbW92YWxMaXN0ZW5lcnMgPSBuZXcgTWFwPHN0cmluZywgU2V0PExpc3RSZW1vdmFsTGlzdGVuZXI+PigpXG4gIHByaXZhdGUgcmVhZG9ubHkgcm93SWRJbmRleCA9IG5ldyBNYXA8Um93SWQsIHsgcmVhZG9ubHkga2V5OiBzdHJpbmc7IHJlYWRvbmx5IGxpc3RQYXRoOiBzdHJpbmc7IHJlYWRvbmx5IGluZGV4OiBudW1iZXIgfT4oKVxuICBwcml2YXRlIG5leHRSb3dTZXEgPSAwXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBpbnN0YW5jZUlkPzogc3RyaW5nLFxuICApIHt9XG5cbiAgcHJpdmF0ZSBsaXN0S2V5ID0gKGxpc3RQYXRoOiBzdHJpbmcsIHBhcmVudFJvd0lkPzogUm93SWQpOiBzdHJpbmcgPT5cbiAgICBwYXJlbnRSb3dJZCA/IGAke2xpc3RQYXRofUBAJHtwYXJlbnRSb3dJZH1gIDogbGlzdFBhdGhcblxuICBwcml2YXRlIG1ha2VSb3dJZCA9ICgpOiBSb3dJZCA9PiB7XG4gICAgdGhpcy5uZXh0Um93U2VxICs9IDFcbiAgICByZXR1cm4gdGhpcy5pbnN0YW5jZUlkID8gYCR7dGhpcy5pbnN0YW5jZUlkfTo6ciR7dGhpcy5uZXh0Um93U2VxfWAgOiBgciR7dGhpcy5uZXh0Um93U2VxfWBcbiAgfVxuXG4gIHByaXZhdGUgbm90aWZ5UmVtb3ZlZChsaXN0UGF0aDogc3RyaW5nLCByb3dJZDogUm93SWQpOiB2b2lkIHtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLnJlbW92YWxMaXN0ZW5lcnMuZ2V0KGxpc3RQYXRoKVxuICAgIGlmICghbGlzdGVuZXJzIHx8IGxpc3RlbmVycy5zaXplID09PSAwKSByZXR1cm5cbiAgICBmb3IgKGNvbnN0IGZuIG9mIGxpc3RlbmVycykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZm4ocm93SWQpXG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gbGlzdGVuZXIgZmFpbHVyZXMgc2hvdWxkIG5ldmVyIGJyZWFrIHJ1bnRpbWUgYmVoYXZpb3JcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZURlc2NlbmRhbnRzKHBhcmVudFJvd0lkOiBSb3dJZCk6IHZvaWQge1xuICAgIGNvbnN0IGtleXM6IEFycmF5PHN0cmluZz4gPSBbXVxuICAgIGZvciAoY29uc3QgW2ssIHN0XSBvZiB0aGlzLmxpc3RzLmVudHJpZXMoKSkge1xuICAgICAgaWYgKHN0LnBhcmVudFJvd0lkID09PSBwYXJlbnRSb3dJZCkga2V5cy5wdXNoKGspXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgY29uc3Qgc3QgPSB0aGlzLmxpc3RzLmdldChrZXkpXG4gICAgICBpZiAoIXN0KSBjb250aW51ZVxuICAgICAgdGhpcy5saXN0cy5kZWxldGUoa2V5KVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdC5pZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgcm93SWQgPSBzdC5pZHNbaV0hXG4gICAgICAgIHRoaXMucm93SWRJbmRleC5kZWxldGUocm93SWQpXG4gICAgICAgIHRoaXMubm90aWZ5UmVtb3ZlZChzdC5saXN0UGF0aCwgcm93SWQpXG4gICAgICAgIHRoaXMucmVtb3ZlRGVzY2VuZGFudHMocm93SWQpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25SZW1vdmVkKGxpc3RQYXRoOiBzdHJpbmcsIGxpc3RlbmVyOiBMaXN0UmVtb3ZhbExpc3RlbmVyKTogKCkgPT4gdm9pZCB7XG4gICAgY29uc3Qgc2V0ID0gdGhpcy5yZW1vdmFsTGlzdGVuZXJzLmdldChsaXN0UGF0aCkgPz8gbmV3IFNldDxMaXN0UmVtb3ZhbExpc3RlbmVyPigpXG4gICAgc2V0LmFkZChsaXN0ZW5lcilcbiAgICB0aGlzLnJlbW92YWxMaXN0ZW5lcnMuc2V0KGxpc3RQYXRoLCBzZXQpXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnJlbW92YWxMaXN0ZW5lcnMuZ2V0KGxpc3RQYXRoKVxuICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm5cbiAgICAgIGN1cnJlbnQuZGVsZXRlKGxpc3RlbmVyKVxuICAgICAgaWYgKGN1cnJlbnQuc2l6ZSA9PT0gMCkgdGhpcy5yZW1vdmFsTGlzdGVuZXJzLmRlbGV0ZShsaXN0UGF0aClcbiAgICB9XG4gIH1cblxuICBnZXRSb3dJZChsaXN0UGF0aDogc3RyaW5nLCBpbmRleDogbnVtYmVyLCBwYXJlbnRSb3dJZD86IFJvd0lkKTogUm93SWQgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5saXN0cy5nZXQodGhpcy5saXN0S2V5KGxpc3RQYXRoLCBwYXJlbnRSb3dJZCkpXG4gICAgcmV0dXJuIHN0YXRlID8gc3RhdGUuaWRzW2luZGV4XSA6IHVuZGVmaW5lZFxuICB9XG5cbiAgZ2V0SW5kZXgobGlzdFBhdGg6IHN0cmluZywgcm93SWQ6IFJvd0lkKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBpbmZvID0gdGhpcy5yb3dJZEluZGV4LmdldChyb3dJZClcbiAgICBpZiAoIWluZm8pIHJldHVybiB1bmRlZmluZWRcbiAgICBpZiAoaW5mby5saXN0UGF0aCAhPT0gbGlzdFBhdGgpIHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4gaW5mby5pbmRleFxuICB9XG5cbiAgLyoqXG4gICAqIGVuc3VyZUxpc3RcdUZGMUFcbiAgICogLSBcdThCQTlcdTYzMDdcdTVCOUEgbGlzdFBhdGggXHU3Njg0IFJvd0lEIFx1NjYyMFx1NUMwNFx1NEUwRVx1NUY1M1x1NTI0RCBpdGVtcyBcdTVCRjlcdTlGNTBcdUZGMUJcbiAgICogLSBcdThGRDRcdTU2REVcdTY3MDBcdTY1QjBcdTc2ODQgaWRzXHVGRjA4aW5kZXggLT4gUm93SWRcdUZGMDlcdTMwMDJcbiAgICovXG4gIGVuc3VyZUxpc3QoXG4gICAgbGlzdFBhdGg6IHN0cmluZyxcbiAgICBpdGVtczogUmVhZG9ubHlBcnJheTx1bmtub3duPixcbiAgICB0cmFja0J5Pzogc3RyaW5nLFxuICAgIHBhcmVudFJvd0lkPzogUm93SWQsXG4gICk6IFJlYWRvbmx5QXJyYXk8Um93SWQ+IHtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmxpc3RLZXkobGlzdFBhdGgsIHBhcmVudFJvd0lkKVxuICAgIGNvbnN0IHByZXYgPSB0aGlzLmxpc3RzLmdldChrZXkpXG4gICAgY29uc3QgeyBpZHMsIHJlbW92ZWQgfSA9IHJlY29uY2lsZUlkcyhwcmV2LCBpdGVtcywgdHJhY2tCeSA/PyBwcmV2Py50cmFja0J5LCB0aGlzLm1ha2VSb3dJZClcblxuICAgIGNvbnN0IG5leHQ6IExpc3RTdGF0ZSA9IHtcbiAgICAgIGxpc3RQYXRoLFxuICAgICAgcGFyZW50Um93SWQsXG4gICAgICBpdGVtc1JlZjogaXRlbXMsXG4gICAgICBpZHMsXG4gICAgICBpbmRleEJ5SWQ6IGJ1aWxkSW5kZXhCeUlkKGlkcyksXG4gICAgICB0cmFja0J5OiB0cmFja0J5ID8/IHByZXY/LnRyYWNrQnksXG4gICAgfVxuICAgIHRoaXMubGlzdHMuc2V0KGtleSwgbmV4dClcblxuICAgIGlmIChyZW1vdmVkLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3Qgcm93SWQgb2YgcmVtb3ZlZCkge1xuICAgICAgICB0aGlzLnJvd0lkSW5kZXguZGVsZXRlKHJvd0lkKVxuICAgICAgICB0aGlzLm5vdGlmeVJlbW92ZWQobGlzdFBhdGgsIHJvd0lkKVxuICAgICAgICB0aGlzLnJlbW92ZURlc2NlbmRhbnRzKHJvd0lkKVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFx1NTIzN1x1NjVCMCByb3dJZCBcdTIxOTIgaW5kZXggXHU3Njg0XHU1M0NEXHU1NDExXHU2NjIwXHU1QzA0XHVGRjA4XHU1MTQxXHU4QkI4IGluZGV4IFx1NTNEOFx1NTMxNlx1RkYwOVx1MzAwMlxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByb3dJZCA9IGlkc1tpXSFcbiAgICAgIHRoaXMucm93SWRJbmRleC5zZXQocm93SWQsIHsga2V5LCBsaXN0UGF0aCwgaW5kZXg6IGkgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gaWRzXG4gIH1cblxuICAvKipcbiAgICogdXBkYXRlQWxsXHVGRjFBXG4gICAqIC0gXHU1NzI4XHU2QkNGXHU2QjIxXHU2M0QwXHU0RUE0XHU1NDBFXHU1QkY5XHU5RjUwXHU2MjQwXHU2NzA5XHU1REYyXHU3N0U1IGxpc3QgXHU3Njg0IFJvd0lEIFx1NjYyMFx1NUMwNFx1RkYxQlxuICAgKiAtIGNvbmZpZ3MgXHU2NzY1XHU4MUVBIFN0YXRlVHJhaXRQcm9ncmFtLnNwZWMgXHU0RTJEXHU3Njg0IGxpc3QgXHU1OEYwXHU2NjBFXHVGRjA4XHU1M0VGXHU2NDNBXHU1RTI2IHRyYWNrQnlcdUZGMDlcdTMwMDJcbiAgICovXG4gIHVwZGF0ZUFsbChzdGF0ZTogdW5rbm93biwgY29uZmlnczogUmVhZG9ubHlBcnJheTxMaXN0Q29uZmlnPik6IHZvaWQge1xuICAgIGNvbnN0IGNmZ0J5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBMaXN0Q29uZmlnPigpXG4gICAgY29uc3QgcGF0aHM6IEFycmF5PHN0cmluZz4gPSBbXVxuICAgIGZvciAoY29uc3QgY2ZnIG9mIGNvbmZpZ3MpIHtcbiAgICAgIGlmICghY2ZnIHx8IHR5cGVvZiBjZmcucGF0aCAhPT0gXCJzdHJpbmdcIikgY29udGludWVcbiAgICAgIGNvbnN0IHAgPSBjZmcucGF0aC50cmltKClcbiAgICAgIGlmICghcCkgY29udGludWVcbiAgICAgIGNmZ0J5UGF0aC5zZXQocCwgY2ZnKVxuICAgICAgcGF0aHMucHVzaChwKVxuICAgIH1cblxuICAgIGNvbnN0IHBhdGhTZXQgPSBuZXcgU2V0KHBhdGhzKVxuXG4gICAgY29uc3QgcGFyZW50T2YgPSAocGF0aDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgICAgIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdChcIi5cIikuZmlsdGVyKEJvb2xlYW4pXG4gICAgICBsZXQgYmVzdDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHByZWZpeCA9IHNlZ21lbnRzLnNsaWNlKDAsIGkpLmpvaW4oXCIuXCIpXG4gICAgICAgIGlmIChwYXRoU2V0LmhhcyhwcmVmaXgpKSBiZXN0ID0gcHJlZml4XG4gICAgICB9XG4gICAgICByZXR1cm4gYmVzdFxuICAgIH1cblxuICAgIGNvbnN0IHBhcmVudEJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+KClcbiAgICBjb25zdCBzdWZmaXhCeVBhdGggPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpXG4gICAgY29uc3QgY2hpbGRyZW5CeVBhcmVudCA9IG5ldyBNYXA8c3RyaW5nIHwgdW5kZWZpbmVkLCBBcnJheTxzdHJpbmc+PigpXG5cbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IHBhcmVudE9mKHBhdGgpXG4gICAgICBwYXJlbnRCeVBhdGguc2V0KHBhdGgsIHBhcmVudClcbiAgICAgIGNvbnN0IHN1ZmZpeCA9IHBhcmVudCA/IHBhdGguc2xpY2UocGFyZW50Lmxlbmd0aCArIDEpIDogcGF0aFxuICAgICAgc3VmZml4QnlQYXRoLnNldChwYXRoLCBzdWZmaXgpXG4gICAgICBjb25zdCBsaXN0ID0gY2hpbGRyZW5CeVBhcmVudC5nZXQocGFyZW50KSA/PyBbXVxuICAgICAgbGlzdC5wdXNoKHBhdGgpXG4gICAgICBjaGlsZHJlbkJ5UGFyZW50LnNldChwYXJlbnQsIGxpc3QpXG4gICAgfVxuXG4gICAgLy8gcm9vdHMgZmlyc3QgKGFuZCBkZXRlcm1pbmlzdGljIHRyYXZlcnNhbClcbiAgICBjb25zdCByb290cyA9IChjaGlsZHJlbkJ5UGFyZW50LmdldCh1bmRlZmluZWQpID8/IFtdKS5zbGljZSgpLnNvcnQoKGEsIGIpID0+IGEubG9jYWxlQ29tcGFyZShiKSlcblxuICAgIGNvbnN0IHZpc2l0ID0gKGxpc3RQYXRoOiBzdHJpbmcsIHBhcmVudFJvd0lkOiBSb3dJZCB8IHVuZGVmaW5lZCwgbGlzdFZhbHVlOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgICBjb25zdCBjZmcgPSBjZmdCeVBhdGguZ2V0KGxpc3RQYXRoKVxuICAgICAgY29uc3QgaXRlbXMgPSBBcnJheS5pc0FycmF5KGxpc3RWYWx1ZSkgPyAobGlzdFZhbHVlIGFzIFJlYWRvbmx5QXJyYXk8dW5rbm93bj4pIDogW11cbiAgICAgIGNvbnN0IGlkcyA9IHRoaXMuZW5zdXJlTGlzdChsaXN0UGF0aCwgaXRlbXMsIGNmZz8udHJhY2tCeSwgcGFyZW50Um93SWQpXG5cbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gKGNoaWxkcmVuQnlQYXJlbnQuZ2V0KGxpc3RQYXRoKSA/PyBbXSkuc2xpY2UoKS5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG4gICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCByb3cgPSBpdGVtc1tpXVxuICAgICAgICBjb25zdCByb3dJZCA9IGlkc1tpXVxuICAgICAgICBpZiAoIXJvd0lkKSBjb250aW51ZVxuICAgICAgICBmb3IgKGNvbnN0IGNoaWxkUGF0aCBvZiBjaGlsZHJlbikge1xuICAgICAgICAgIGNvbnN0IHN1ZmZpeCA9IHN1ZmZpeEJ5UGF0aC5nZXQoY2hpbGRQYXRoKSA/PyBcIlwiXG4gICAgICAgICAgY29uc3QgY2hpbGRWYWx1ZSA9IHN1ZmZpeCA/IGdldEF0UGF0aChyb3cgYXMgYW55LCBzdWZmaXgpIDogdW5kZWZpbmVkXG4gICAgICAgICAgdmlzaXQoY2hpbGRQYXRoLCByb3dJZCwgY2hpbGRWYWx1ZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgcm9vdCBvZiByb290cykge1xuICAgICAgY29uc3QgdmFsdWUgPSBnZXRBdFBhdGgoc3RhdGUgYXMgYW55LCByb290KVxuICAgICAgdmlzaXQocm9vdCwgdW5kZWZpbmVkLCB2YWx1ZSlcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGNvbGxlY3RMaXN0Q29uZmlncyA9IChzcGVjOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFJlYWRvbmx5QXJyYXk8TGlzdENvbmZpZz4gPT4ge1xuICBjb25zdCBjb25maWdzOiBBcnJheTxMaXN0Q29uZmlnPiA9IFtdXG4gIGZvciAoY29uc3Qga2V5IGluIHNwZWMpIHtcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzcGVjLCBrZXkpKSBjb250aW51ZVxuICAgIGNvbnN0IHJhdyA9IHNwZWNba2V5XVxuICAgIGlmICghcmF3IHx8IHR5cGVvZiByYXcgIT09IFwib2JqZWN0XCIpIGNvbnRpbnVlXG4gICAgY29uc3QgdGFnID0gKHJhdyBhcyBhbnkpLl90YWdcbiAgICBpZiAodGFnICE9PSBcIlN0YXRlVHJhaXRMaXN0XCIpIGNvbnRpbnVlXG4gICAgY29uc3QgdHJhY2tCeSA9IChyYXcgYXMgYW55KS5pZGVudGl0eUhpbnQ/LnRyYWNrQnlcbiAgICBjb25maWdzLnB1c2goe1xuICAgICAgcGF0aDoga2V5LFxuICAgICAgdHJhY2tCeTogdHlwZW9mIHRyYWNrQnkgPT09IFwic3RyaW5nXCIgPyB0cmFja0J5IDogdW5kZWZpbmVkLFxuICAgIH0pXG4gIH1cbiAgcmV0dXJuIGNvbmZpZ3Ncbn1cbiIsICJpbXBvcnQgeyBDb250ZXh0LCBFZmZlY3QsIExheWVyIH0gZnJvbSBcImVmZmVjdFwiXG5cbmV4cG9ydCB0eXBlIFJlc291cmNlU25hcHNob3RQaGFzZSA9IFwiaWRsZVwiIHwgXCJsb2FkaW5nXCIgfCBcInN1Y2Nlc3NcIiB8IFwiZXJyb3JcIlxuXG5leHBvcnQgdHlwZSBSZXBsYXlMb2dFdmVudCA9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgX3RhZzogXCJSZXNvdXJjZVNuYXBzaG90XCJcbiAgICAgIHJlYWRvbmx5IHJlc291cmNlSWQ6IHN0cmluZ1xuICAgICAgcmVhZG9ubHkgZmllbGRQYXRoOiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IGtleUhhc2g/OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IHBoYXNlOiBSZXNvdXJjZVNuYXBzaG90UGhhc2VcbiAgICAgIHJlYWRvbmx5IHNuYXBzaG90OiB1bmtub3duXG4gICAgICByZWFkb25seSB0aW1lc3RhbXA6IG51bWJlclxuICAgICAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IGluc3RhbmNlSWQ/OiBzdHJpbmdcbiAgICB9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgX3RhZzogXCJJbnZhbGlkYXRlUmVxdWVzdFwiXG4gICAgICByZWFkb25seSB0aW1lc3RhbXA6IG51bWJlclxuICAgICAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IGluc3RhbmNlSWQ/OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IGtpbmQ6IFwicmVzb3VyY2VcIiB8IFwicXVlcnlcIlxuICAgICAgcmVhZG9ubHkgdGFyZ2V0OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IG1ldGE/OiB1bmtub3duXG4gICAgfVxuXG5leHBvcnQgdHlwZSBSZXNvdXJjZVNuYXBzaG90RXZlbnQgPSBFeHRyYWN0PFJlcGxheUxvZ0V2ZW50LCB7IHJlYWRvbmx5IF90YWc6IFwiUmVzb3VyY2VTbmFwc2hvdFwiIH0+XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwbGF5TG9nU2VydmljZSB7XG4gIHJlYWRvbmx5IHJlY29yZDogKGV2ZW50OiBSZXBsYXlMb2dFdmVudCkgPT4gRWZmZWN0LkVmZmVjdDx2b2lkPlxuICByZWFkb25seSBzbmFwc2hvdDogRWZmZWN0LkVmZmVjdDxSZWFkb25seUFycmF5PFJlcGxheUxvZ0V2ZW50Pj5cbiAgcmVhZG9ubHkgcmVzZXRDdXJzb3I6IEVmZmVjdC5FZmZlY3Q8dm9pZD5cbiAgcmVhZG9ubHkgY29uc3VtZU5leHQ6IChcbiAgICBwcmVkaWNhdGU6IChldmVudDogUmVwbGF5TG9nRXZlbnQpID0+IGJvb2xlYW4sXG4gICkgPT4gRWZmZWN0LkVmZmVjdDxSZXBsYXlMb2dFdmVudCB8IHVuZGVmaW5lZD5cbiAgcmVhZG9ubHkgY29uc3VtZU5leHRSZXNvdXJjZVNuYXBzaG90OiAocGFyYW1zOiB7XG4gICAgcmVhZG9ubHkgcmVzb3VyY2VJZDogc3RyaW5nXG4gICAgcmVhZG9ubHkgZmllbGRQYXRoOiBzdHJpbmdcbiAgICByZWFkb25seSBrZXlIYXNoPzogc3RyaW5nXG4gICAgcmVhZG9ubHkgcGhhc2U/OiBSZXNvdXJjZVNuYXBzaG90UGhhc2VcbiAgfSkgPT4gRWZmZWN0LkVmZmVjdDxSZXNvdXJjZVNuYXBzaG90RXZlbnQgfCB1bmRlZmluZWQ+XG59XG5cbmV4cG9ydCBjbGFzcyBSZXBsYXlMb2cgZXh0ZW5kcyBDb250ZXh0LlRhZyhcIkBsb2dpeC9jb3JlL1JlcGxheUxvZ1wiKTxcbiAgUmVwbGF5TG9nLFxuICBSZXBsYXlMb2dTZXJ2aWNlXG4+KCkge31cblxuZXhwb3J0IGNvbnN0IG1ha2UgPSAoXG4gIGluaXRpYWw/OiBSZWFkb25seUFycmF5PFJlcGxheUxvZ0V2ZW50Pixcbik6IFJlcGxheUxvZ1NlcnZpY2UgPT4ge1xuICBjb25zdCBldmVudHM6IEFycmF5PFJlcGxheUxvZ0V2ZW50PiA9IGluaXRpYWwgPyBBcnJheS5mcm9tKGluaXRpYWwpIDogW11cbiAgbGV0IGN1cnNvciA9IDBcblxuICBjb25zdCBjb25zdW1lTmV4dCA9IChcbiAgICBwcmVkaWNhdGU6IChldmVudDogUmVwbGF5TG9nRXZlbnQpID0+IGJvb2xlYW4sXG4gICk6IEVmZmVjdC5FZmZlY3Q8UmVwbGF5TG9nRXZlbnQgfCB1bmRlZmluZWQ+ID0+XG4gICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgZm9yIChsZXQgaSA9IGN1cnNvcjsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBldmVudCA9IGV2ZW50c1tpXVxuICAgICAgICBpZiAoIXByZWRpY2F0ZShldmVudCkpIGNvbnRpbnVlXG4gICAgICAgIGN1cnNvciA9IGkgKyAxXG4gICAgICAgIHJldHVybiBldmVudFxuICAgICAgfVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH0pXG5cbiAgY29uc3QgY29uc3VtZU5leHRSZXNvdXJjZVNuYXBzaG90ID0gKHBhcmFtczoge1xuICAgIHJlYWRvbmx5IHJlc291cmNlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IGZpZWxkUGF0aDogc3RyaW5nXG4gICAgcmVhZG9ubHkga2V5SGFzaD86IHN0cmluZ1xuICAgIHJlYWRvbmx5IHBoYXNlPzogUmVzb3VyY2VTbmFwc2hvdFBoYXNlXG4gIH0pOiBFZmZlY3QuRWZmZWN0PFJlc291cmNlU25hcHNob3RFdmVudCB8IHVuZGVmaW5lZD4gPT5cbiAgICBjb25zdW1lTmV4dCgoZXZlbnQpOiBldmVudCBpcyBSZXNvdXJjZVNuYXBzaG90RXZlbnQgPT4ge1xuICAgICAgaWYgKGV2ZW50Ll90YWcgIT09IFwiUmVzb3VyY2VTbmFwc2hvdFwiKSByZXR1cm4gZmFsc2VcbiAgICAgIGlmIChldmVudC5yZXNvdXJjZUlkICE9PSBwYXJhbXMucmVzb3VyY2VJZCkgcmV0dXJuIGZhbHNlXG4gICAgICBpZiAoZXZlbnQuZmllbGRQYXRoICE9PSBwYXJhbXMuZmllbGRQYXRoKSByZXR1cm4gZmFsc2VcbiAgICAgIGlmIChwYXJhbXMua2V5SGFzaCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LmtleUhhc2ggIT09IHBhcmFtcy5rZXlIYXNoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgICAgaWYgKHBhcmFtcy5waGFzZSAhPT0gdW5kZWZpbmVkICYmIGV2ZW50LnBoYXNlICE9PSBwYXJhbXMucGhhc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH0pLnBpcGUoRWZmZWN0Lm1hcCgoZXZlbnQpID0+IGV2ZW50IGFzIFJlc291cmNlU25hcHNob3RFdmVudCB8IHVuZGVmaW5lZCkpXG5cbiAgcmV0dXJuIHtcbiAgICByZWNvcmQ6IChldmVudCkgPT4gRWZmZWN0LnN5bmMoKCkgPT4gZXZlbnRzLnB1c2goZXZlbnQpKSxcbiAgICBzbmFwc2hvdDogRWZmZWN0LnN5bmMoKCkgPT4gZXZlbnRzLnNsaWNlKCkpLFxuICAgIHJlc2V0Q3Vyc29yOiBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgICBjdXJzb3IgPSAwXG4gICAgfSksXG4gICAgY29uc3VtZU5leHQsXG4gICAgY29uc3VtZU5leHRSZXNvdXJjZVNuYXBzaG90LFxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBsYXllciA9IChcbiAgaW5pdGlhbD86IFJlYWRvbmx5QXJyYXk8UmVwbGF5TG9nRXZlbnQ+LFxuKTogTGF5ZXIuTGF5ZXI8UmVwbGF5TG9nLCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLnN1Y2NlZWQoUmVwbGF5TG9nLCBtYWtlKGluaXRpYWwpKVxuXG5leHBvcnQgY29uc3QgcmVjb3JkID0gKFxuICBldmVudDogUmVwbGF5TG9nRXZlbnQsXG4pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBSZXBsYXlMb2c+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBsb2cgPSB5aWVsZCogUmVwbGF5TG9nXG4gICAgeWllbGQqIGxvZy5yZWNvcmQoZXZlbnQpXG4gIH0pXG5cbmV4cG9ydCBjb25zdCBzbmFwc2hvdDogRWZmZWN0LkVmZmVjdDxcbiAgUmVhZG9ubHlBcnJheTxSZXBsYXlMb2dFdmVudD4sXG4gIG5ldmVyLFxuICBSZXBsYXlMb2dcbj4gPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gIGNvbnN0IGxvZyA9IHlpZWxkKiBSZXBsYXlMb2dcbiAgcmV0dXJuIHlpZWxkKiBsb2cuc25hcHNob3Rcbn0pXG5cbmV4cG9ydCBjb25zdCByZXNldEN1cnNvcjogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgUmVwbGF5TG9nPiA9IEVmZmVjdC5nZW4oXG4gIGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3QgbG9nID0geWllbGQqIFJlcGxheUxvZ1xuICAgIHlpZWxkKiBsb2cucmVzZXRDdXJzb3JcbiAgfSxcbilcblxuZXhwb3J0IGNvbnN0IGNvbnN1bWVOZXh0UmVzb3VyY2VTbmFwc2hvdCA9IChwYXJhbXM6IHtcbiAgcmVhZG9ubHkgcmVzb3VyY2VJZDogc3RyaW5nXG4gIHJlYWRvbmx5IGZpZWxkUGF0aDogc3RyaW5nXG4gIHJlYWRvbmx5IGtleUhhc2g/OiBzdHJpbmdcbiAgcmVhZG9ubHkgcGhhc2U/OiBSZXNvdXJjZVNuYXBzaG90UGhhc2Vcbn0pOiBFZmZlY3QuRWZmZWN0PFJlc291cmNlU25hcHNob3RFdmVudCB8IHVuZGVmaW5lZCwgbmV2ZXIsIFJlcGxheUxvZz4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IGxvZyA9IHlpZWxkKiBSZXBsYXlMb2dcbiAgICByZXR1cm4geWllbGQqIGxvZy5jb25zdW1lTmV4dFJlc291cmNlU25hcHNob3QocGFyYW1zKVxuICB9KVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7OztBQVdBLElBQU0sZ0JBQWdCLENBQUMsU0FBeUM7QUFDOUQsTUFBSSxDQUFDLEtBQU0sUUFBTyxDQUFDO0FBQ25CLFNBQU8sS0FBSyxNQUFNLEdBQUcsRUFBRTtBQUFBLElBQUksQ0FBQyxRQUMxQixXQUFXLEtBQUssR0FBRyxJQUFJLE9BQU8sR0FBRyxJQUFJO0FBQUEsRUFDdkM7QUFDRjtBQUVPLElBQU0sWUFBWSxDQUFDLE9BQVksU0FBc0I7QUFDMUQsTUFBSSxDQUFDLFFBQVEsU0FBUyxLQUFNLFFBQU87QUFDbkMsUUFBTSxXQUFXLGNBQWMsSUFBSTtBQUNuQyxNQUFJLFVBQWU7QUFDbkIs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
|