@jayf0x/fluidity-js 0.2.5 → 0.2.6
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/AGENTS.md +140 -54
- package/CONTRIBUTING.md +32 -1
- package/dist/index.js +109 -106
- package/llms.txt +32 -38
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var aC = Object.defineProperty;
|
|
2
2
|
var uC = (e, g, C) => g in e ? aC(e, g, { enumerable: !0, configurable: !0, writable: !0, value: C }) : e[g] = C;
|
|
3
|
-
var
|
|
3
|
+
var nI = (e, g, C) => (uC(e, typeof g != "symbol" ? g + "" : g, C), C), kI = (e, g, C) => {
|
|
4
4
|
if (!g.has(e))
|
|
5
5
|
throw TypeError("Cannot " + C);
|
|
6
6
|
};
|
|
@@ -56,7 +56,10 @@ const CC = {
|
|
|
56
56
|
shine: 0.5,
|
|
57
57
|
waterColor: "#090017",
|
|
58
58
|
glowColor: "#b04721"
|
|
59
|
-
},
|
|
59
|
+
}, gI = {
|
|
60
|
+
dpr: typeof window < "u" ? 1 / (window.devicePixelRatio || 1) : 1,
|
|
61
|
+
sim: 0.5
|
|
62
|
+
}, iC = {
|
|
60
63
|
backgroundColor: "#0a0a0a",
|
|
61
64
|
backgroundSize: "cover",
|
|
62
65
|
mouseEnabled: !0,
|
|
@@ -130,7 +133,7 @@ const CC = {
|
|
|
130
133
|
waterColor: "#0f0f0f"
|
|
131
134
|
}
|
|
132
135
|
};
|
|
133
|
-
function
|
|
136
|
+
function bI(e) {
|
|
134
137
|
if (Array.isArray(e))
|
|
135
138
|
return e;
|
|
136
139
|
const g = e.slice(1, 7);
|
|
@@ -144,10 +147,10 @@ function nI(e) {
|
|
|
144
147
|
parseInt(g.slice(4, 6), 16) / 255
|
|
145
148
|
];
|
|
146
149
|
}
|
|
147
|
-
function
|
|
150
|
+
function uI(e = {}, g, C = CC) {
|
|
148
151
|
return { ...g ? { ...C, ...pC[g] } : C, ...e };
|
|
149
152
|
}
|
|
150
|
-
function
|
|
153
|
+
function II(e, g, C, i, s = "cover") {
|
|
151
154
|
let l;
|
|
152
155
|
s === "cover" ? l = Math.max(C / e, i / g) : s === "contain" ? l = Math.min(C / e, i / g) : typeof s == "string" && s.endsWith("%") ? l = Math.min(C / e, i / g) * (parseFloat(s) / 100) : typeof s == "string" && s.endsWith("px") ? l = parseFloat(s) / Math.max(e, g) : typeof s == "number" ? l = s : l = Math.max(C / e, i / g);
|
|
153
156
|
const t = e * l, S = g * l;
|
|
@@ -158,7 +161,7 @@ function ZC(e, g, C, i, s = null, l = "cover") {
|
|
|
158
161
|
((b) => {
|
|
159
162
|
if (s) {
|
|
160
163
|
A.clearRect(0, 0, g, C), A.fillStyle = "black", A.fillRect(0, 0, g, C);
|
|
161
|
-
const { x: B, y: K, drawW: W, drawH: x } =
|
|
164
|
+
const { x: B, y: K, drawW: W, drawH: x } = II(
|
|
162
165
|
s.width,
|
|
163
166
|
s.height,
|
|
164
167
|
g,
|
|
@@ -170,36 +173,36 @@ function ZC(e, g, C, i, s = null, l = "cover") {
|
|
|
170
173
|
A.fillStyle = "black", A.fillRect(0, 0, g, C);
|
|
171
174
|
A.fillStyle = b, A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
|
|
172
175
|
})(u);
|
|
173
|
-
const Z =
|
|
176
|
+
const Z = SI(e, a);
|
|
174
177
|
A.fillStyle = "black", A.fillRect(0, 0, g, C), A.fillStyle = "white", A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
|
|
175
|
-
const r =
|
|
178
|
+
const r = SI(e, a);
|
|
176
179
|
return { backgroundTex: Z, obstacleTex: r, coverageTex: r };
|
|
177
180
|
}
|
|
178
181
|
function BC(e, g, C, i, s = 0, l = "cover", t = null, S = "cover") {
|
|
179
|
-
const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: p, y: a, drawW: A, drawH: m } =
|
|
182
|
+
const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: p, y: a, drawW: A, drawH: m } = II(g.width, g.height, C, i, l);
|
|
180
183
|
if (c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), t) {
|
|
181
184
|
const {
|
|
182
185
|
x: B,
|
|
183
186
|
y: K,
|
|
184
187
|
drawW: W,
|
|
185
188
|
drawH: x
|
|
186
|
-
} =
|
|
189
|
+
} = II(t.width, t.height, C, i, S);
|
|
187
190
|
c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, B, K, W, x), c.filter = "none";
|
|
188
191
|
}
|
|
189
192
|
c.drawImage(g, p, a, A, m);
|
|
190
|
-
const Z =
|
|
193
|
+
const Z = SI(e, u);
|
|
191
194
|
c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.filter = `brightness(${s}) blur(8px)`, c.drawImage(g, p, a, A, m), c.filter = "none";
|
|
192
|
-
const r =
|
|
195
|
+
const r = SI(e, u);
|
|
193
196
|
c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.fillStyle = "white", c.fillRect(
|
|
194
197
|
Math.max(0, p),
|
|
195
198
|
Math.max(0, a),
|
|
196
199
|
Math.min(A, C - Math.max(0, p)),
|
|
197
200
|
Math.min(m, i - Math.max(0, a))
|
|
198
201
|
);
|
|
199
|
-
const b =
|
|
202
|
+
const b = SI(e, u);
|
|
200
203
|
return { backgroundTex: Z, obstacleTex: r, coverageTex: b };
|
|
201
204
|
}
|
|
202
|
-
function
|
|
205
|
+
function SI(e, g) {
|
|
203
206
|
const C = e.createTexture();
|
|
204
207
|
return e.bindTexture(e.TEXTURE_2D, C), e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL, !0), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, g), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), C;
|
|
205
208
|
}
|
|
@@ -208,7 +211,7 @@ function GC(e, g, C, i, s = null, l = "cover") {
|
|
|
208
211
|
((b) => {
|
|
209
212
|
if (s) {
|
|
210
213
|
A.clearRect(0, 0, g, C), A.fillStyle = "black", A.fillRect(0, 0, g, C);
|
|
211
|
-
const { x: B, y: K, drawW: W, drawH: x } =
|
|
214
|
+
const { x: B, y: K, drawW: W, drawH: x } = II(
|
|
212
215
|
s.width,
|
|
213
216
|
s.height,
|
|
214
217
|
g,
|
|
@@ -220,9 +223,9 @@ function GC(e, g, C, i, s = null, l = "cover") {
|
|
|
220
223
|
A.fillStyle = "black", A.fillRect(0, 0, g, C);
|
|
221
224
|
A.fillStyle = b, A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
|
|
222
225
|
})(u);
|
|
223
|
-
const Z =
|
|
226
|
+
const Z = aI(e, a, g, C);
|
|
224
227
|
A.fillStyle = "black", A.fillRect(0, 0, g, C), A.fillStyle = "white", A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
|
|
225
|
-
const r =
|
|
228
|
+
const r = aI(e, a, g, C);
|
|
226
229
|
return {
|
|
227
230
|
backgroundTex: Z,
|
|
228
231
|
backgroundView: Z.createView(),
|
|
@@ -234,9 +237,9 @@ function GC(e, g, C, i, s = null, l = "cover") {
|
|
|
234
237
|
};
|
|
235
238
|
}
|
|
236
239
|
function rC(e, g, C, i, s = 0, l = "cover", t = null, S = "cover") {
|
|
237
|
-
const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: p, y: a, drawW: A, drawH: m } =
|
|
240
|
+
const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: p, y: a, drawW: A, drawH: m } = II(g.width, g.height, C, i, l);
|
|
238
241
|
if (c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), t) {
|
|
239
|
-
const { x: B, y: K, drawW: W, drawH: x } =
|
|
242
|
+
const { x: B, y: K, drawW: W, drawH: x } = II(
|
|
240
243
|
t.width,
|
|
241
244
|
t.height,
|
|
242
245
|
C,
|
|
@@ -246,11 +249,11 @@ function rC(e, g, C, i, s = 0, l = "cover", t = null, S = "cover") {
|
|
|
246
249
|
c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, B, K, W, x), c.filter = "none";
|
|
247
250
|
}
|
|
248
251
|
c.drawImage(g, p, a, A, m);
|
|
249
|
-
const Z =
|
|
252
|
+
const Z = aI(e, u, C, i);
|
|
250
253
|
c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.filter = `brightness(${s}) blur(8px)`, c.drawImage(g, p, a, A, m), c.filter = "none";
|
|
251
|
-
const r =
|
|
254
|
+
const r = aI(e, u, C, i);
|
|
252
255
|
c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.fillStyle = "white", c.fillRect(Math.max(0, p), Math.max(0, a), Math.min(A, C - Math.max(0, p)), Math.min(m, i - Math.max(0, a)));
|
|
253
|
-
const b =
|
|
256
|
+
const b = aI(e, u, C, i);
|
|
254
257
|
return {
|
|
255
258
|
backgroundTex: Z,
|
|
256
259
|
backgroundView: Z.createView(),
|
|
@@ -261,7 +264,7 @@ function rC(e, g, C, i, s = 0, l = "cover", t = null, S = "cover") {
|
|
|
261
264
|
sharedCoverage: !1
|
|
262
265
|
};
|
|
263
266
|
}
|
|
264
|
-
function
|
|
267
|
+
function aI(e, g, C, i) {
|
|
265
268
|
const s = e.createTexture({
|
|
266
269
|
size: [C, i],
|
|
267
270
|
format: "rgba8unorm",
|
|
@@ -577,9 +580,9 @@ async function XC(e, g = !0) {
|
|
|
577
580
|
}
|
|
578
581
|
class Zg {
|
|
579
582
|
constructor(g, C, i) {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
+
nI(this, "program");
|
|
584
|
+
nI(this, "uniforms", {});
|
|
585
|
+
nI(this, "_gl");
|
|
583
586
|
this._gl = g, this.program = g.createProgram(), g.attachShader(this.program, this._compile(g.VERTEX_SHADER, C)), g.attachShader(this.program, this._compile(g.FRAGMENT_SHADER, i)), g.linkProgram(this.program);
|
|
584
587
|
const s = g.getProgramParameter(this.program, g.ACTIVE_UNIFORMS);
|
|
585
588
|
for (let l = 0; l < s; l++) {
|
|
@@ -1077,7 +1080,7 @@ function jI(e, g, C, i, s, l) {
|
|
|
1077
1080
|
const t = new Float32Array([C, i, s, l]);
|
|
1078
1081
|
e.queue.writeBuffer(g, 0, t);
|
|
1079
1082
|
}
|
|
1080
|
-
function
|
|
1083
|
+
function wI(e, g, C, i) {
|
|
1081
1084
|
const s = new Float32Array([C, i, 0, 0]);
|
|
1082
1085
|
e.queue.writeBuffer(g, 0, s);
|
|
1083
1086
|
}
|
|
@@ -1085,7 +1088,7 @@ function QC(e, g, C, i, s, l) {
|
|
|
1085
1088
|
const t = new Float32Array([C, i, s, l]);
|
|
1086
1089
|
e.queue.writeBuffer(g, 0, t);
|
|
1087
1090
|
}
|
|
1088
|
-
function
|
|
1091
|
+
function LI(e, g, C, i, s, l, t, S, u, c, p) {
|
|
1089
1092
|
const a = new Float32Array(12);
|
|
1090
1093
|
a[0] = C, a[1] = i, a[2] = s, a[3] = l, a[4] = t, a[5] = S, a[6] = u, a[7] = 0, a[8] = c, a[9] = p, a[10] = 0, a[11] = 0, e.queue.writeBuffer(g, 0, a);
|
|
1091
1094
|
}
|
|
@@ -1115,8 +1118,8 @@ function OC(e, g, C, i, s) {
|
|
|
1115
1118
|
});
|
|
1116
1119
|
l.setPipeline(g), l.setBindGroup(0, C), l.setVertexBuffer(0, i), l.draw(6), l.end();
|
|
1117
1120
|
}
|
|
1118
|
-
const PI = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), jC = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout,
|
|
1119
|
-
var yg, j,
|
|
1121
|
+
const PI = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), jC = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, AI = 0.016, _I = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };
|
|
1122
|
+
var yg, j, mI, Vg, Og, k, H, Ig, Cg, ig, og, z, eg, D, jg, Hg, Pg, M, h, rg, sg, ng, E, Xg, vg, Rg, Wg, Yg, Ag, cg, Ug, xg, kg, V, X, P, _, F, _g, dg, N, bg, Sg, w, U, lg, Mg, pI, fg, VI, eC, Dg, cI, ZI, DI, wg, Ng, Fg, dI, BI, FI, GI, JI, HI, sC, XI, lC, vI, tC, RI, oC, WI, AC;
|
|
1120
1123
|
const NI = class NI {
|
|
1121
1124
|
// ── Constructor ─────────────────────────────────────────────────────────────
|
|
1122
1125
|
constructor(g, C = {}, i = {}, s, l = !0) {
|
|
@@ -1128,11 +1131,11 @@ const NI = class NI {
|
|
|
1128
1131
|
// Private — shared helpers
|
|
1129
1132
|
// ---------------------------------------------------------------------------
|
|
1130
1133
|
d(this, Dg);
|
|
1131
|
-
d(this,
|
|
1134
|
+
d(this, ZI);
|
|
1132
1135
|
d(this, wg);
|
|
1133
1136
|
d(this, Fg);
|
|
1134
|
-
d(this, ZI);
|
|
1135
1137
|
d(this, BI);
|
|
1138
|
+
d(this, GI);
|
|
1136
1139
|
// ---------------------------------------------------------------------------
|
|
1137
1140
|
// Private — frame dispatch
|
|
1138
1141
|
// ---------------------------------------------------------------------------
|
|
@@ -1156,7 +1159,7 @@ const NI = class NI {
|
|
|
1156
1159
|
d(this, yg, void 0);
|
|
1157
1160
|
// ── WebGL path ──────────────────────────────────────────────────────────────
|
|
1158
1161
|
d(this, j, null);
|
|
1159
|
-
d(this,
|
|
1162
|
+
d(this, mI, null);
|
|
1160
1163
|
d(this, Vg, null);
|
|
1161
1164
|
d(this, Og, null);
|
|
1162
1165
|
d(this, k, null);
|
|
@@ -1216,13 +1219,13 @@ const NI = class NI {
|
|
|
1216
1219
|
d(this, U, null);
|
|
1217
1220
|
d(this, lg, null);
|
|
1218
1221
|
d(this, Mg, !1);
|
|
1219
|
-
d(this,
|
|
1222
|
+
d(this, pI, !1);
|
|
1220
1223
|
d(this, fg, !0);
|
|
1221
|
-
if (o(this, yg, g), o(this, _g, Math.max(0.1, Math.min(1, i.dpr ?? 1))), o(this, dg, Math.max(0.1, Math.min(1, i.sim ?? 0.5))), o(this, Sg,
|
|
1224
|
+
if (o(this, yg, g), o(this, _g, Math.max(0.1, Math.min(1, i.dpr ?? 1))), o(this, dg, Math.max(0.1, Math.min(1, i.sim ?? 0.5))), o(this, Sg, uI(C)), o(this, fg, l), s)
|
|
1222
1225
|
o(this, D, s), L(this, VI, eC).call(this, s);
|
|
1223
1226
|
else {
|
|
1224
1227
|
const { gl: t, ext: S } = HC(g, l);
|
|
1225
|
-
o(this, j, t), o(this,
|
|
1228
|
+
o(this, j, t), o(this, mI, S), o(this, Vg, vC(t)), o(this, Og, RC(t)), t.clearColor(0, 0, 0, l ? 0 : 1);
|
|
1226
1229
|
}
|
|
1227
1230
|
}
|
|
1228
1231
|
/**
|
|
@@ -1237,18 +1240,18 @@ const NI = class NI {
|
|
|
1237
1240
|
// Public API
|
|
1238
1241
|
// ---------------------------------------------------------------------------
|
|
1239
1242
|
setTextSource(g) {
|
|
1240
|
-
o(this, U, { type: "text", opts: g }), L(this, Dg,
|
|
1243
|
+
o(this, U, { type: "text", opts: g }), L(this, Dg, cI).call(this), L(this, wg, Ng).call(this), L(this, Fg, dI).call(this);
|
|
1241
1244
|
}
|
|
1242
1245
|
async setImageSource(g, C = 0, i = "cover") {
|
|
1243
1246
|
const s = await zI(g);
|
|
1244
|
-
if (I(this,
|
|
1247
|
+
if (I(this, pI)) {
|
|
1245
1248
|
s.close();
|
|
1246
1249
|
return;
|
|
1247
1250
|
}
|
|
1248
|
-
o(this, U, { type: "image", bitmap: s, effect: C, size: i }), L(this, Dg,
|
|
1251
|
+
o(this, U, { type: "image", bitmap: s, effect: C, size: i }), L(this, Dg, cI).call(this), L(this, wg, Ng).call(this), L(this, Fg, dI).call(this);
|
|
1249
1252
|
}
|
|
1250
1253
|
setImageBitmap(g, C = 0, i = "cover") {
|
|
1251
|
-
o(this, U, { type: "image", bitmap: g, effect: C, size: i }), L(this, Dg,
|
|
1254
|
+
o(this, U, { type: "image", bitmap: g, effect: C, size: i }), L(this, Dg, cI).call(this), L(this, wg, Ng).call(this), L(this, Fg, dI).call(this);
|
|
1252
1255
|
}
|
|
1253
1256
|
setBackground(g, C = "cover") {
|
|
1254
1257
|
I(this, N) && I(this, N) !== g && I(this, N).close(), o(this, N, g), o(this, bg, C ?? "cover"), I(this, U) && I(this, V) > 0 && I(this, X) > 0 && L(this, wg, Ng).call(this);
|
|
@@ -1273,17 +1276,17 @@ const NI = class NI {
|
|
|
1273
1276
|
if (i !== void 0 ? o(this, F, i) : typeof window < "u" && window.devicePixelRatio && o(this, F, window.devicePixelRatio), g !== void 0 && g > 0) {
|
|
1274
1277
|
if (C === void 0 || C <= 0)
|
|
1275
1278
|
return;
|
|
1276
|
-
o(this, V, I(this, yg).width = g), o(this, X, I(this, yg).height = C), o(this, P, Math.max(1, Math.round(g * I(this, dg)))), o(this, _, Math.max(1, Math.round(C * I(this, dg)))), L(this,
|
|
1279
|
+
o(this, V, I(this, yg).width = g), o(this, X, I(this, yg).height = C), o(this, P, Math.max(1, Math.round(g * I(this, dg)))), o(this, _, Math.max(1, Math.round(C * I(this, dg)))), L(this, ZI, DI).call(this);
|
|
1277
1280
|
} else
|
|
1278
|
-
L(this, Dg,
|
|
1279
|
-
I(this, U) && L(this, wg, Ng).call(this), L(this, Fg,
|
|
1281
|
+
L(this, Dg, cI).call(this);
|
|
1282
|
+
I(this, U) && L(this, wg, Ng).call(this), L(this, Fg, dI).call(this);
|
|
1280
1283
|
}
|
|
1281
1284
|
updateConfig(g) {
|
|
1282
1285
|
Object.assign(I(this, Sg), g);
|
|
1283
1286
|
}
|
|
1284
1287
|
destroy() {
|
|
1285
1288
|
var g, C, i, s, l, t, S, u, c, p, a;
|
|
1286
|
-
if (o(this,
|
|
1289
|
+
if (o(this, pI, !0), this.stop(), L(this, BI, FI).call(this), L(this, GI, JI).call(this), I(this, N) && (I(this, N).close(), o(this, N, null)), I(this, D))
|
|
1287
1290
|
(g = I(this, Xg)) == null || g.destroy(), (C = I(this, vg)) == null || C.destroy(), (i = I(this, Rg)) == null || i.destroy(), (s = I(this, Wg)) == null || s.destroy(), (l = I(this, Yg)) == null || l.destroy(), (t = I(this, Ag)) == null || t.destroy(), (S = I(this, cg)) == null || S.destroy(), (u = I(this, Ug)) == null || u.destroy(), (c = I(this, xg)) == null || c.destroy(), (p = I(this, kg)) == null || p.destroy(), (a = I(this, Hg)) == null || a.destroy(), I(this, D).device.destroy();
|
|
1288
1291
|
else {
|
|
1289
1292
|
const A = I(this, j);
|
|
@@ -1311,23 +1314,23 @@ const NI = class NI {
|
|
|
1311
1314
|
return I(this, lg) !== null;
|
|
1312
1315
|
}
|
|
1313
1316
|
};
|
|
1314
|
-
yg = new WeakMap(), j = new WeakMap(),
|
|
1317
|
+
yg = new WeakMap(), j = new WeakMap(), mI = new WeakMap(), Vg = new WeakMap(), Og = new WeakMap(), k = new WeakMap(), H = new WeakMap(), Ig = new WeakMap(), Cg = new WeakMap(), ig = new WeakMap(), og = new WeakMap(), z = new WeakMap(), eg = new WeakMap(), D = new WeakMap(), jg = new WeakMap(), Hg = new WeakMap(), Pg = new WeakMap(), M = new WeakMap(), h = new WeakMap(), rg = new WeakMap(), sg = new WeakMap(), ng = new WeakMap(), E = new WeakMap(), Xg = new WeakMap(), vg = new WeakMap(), Rg = new WeakMap(), Wg = new WeakMap(), Yg = new WeakMap(), Ag = new WeakMap(), cg = new WeakMap(), Ug = new WeakMap(), xg = new WeakMap(), kg = new WeakMap(), V = new WeakMap(), X = new WeakMap(), P = new WeakMap(), _ = new WeakMap(), F = new WeakMap(), _g = new WeakMap(), dg = new WeakMap(), N = new WeakMap(), bg = new WeakMap(), Sg = new WeakMap(), w = new WeakMap(), U = new WeakMap(), lg = new WeakMap(), Mg = new WeakMap(), pI = new WeakMap(), fg = new WeakMap(), VI = new WeakSet(), eC = function(g) {
|
|
1315
1318
|
const { device: C, format: i } = g;
|
|
1316
1319
|
o(this, jg, zC(C, i, I(this, fg))), o(this, Hg, JC(C)), o(this, Pg, NC(C)), o(this, Xg, gg(C, 16)), o(this, vg, gg(C, 16)), o(this, Rg, gg(C, 16)), o(this, Wg, gg(C, 16)), o(this, Yg, gg(C, 16)), o(this, Ag, gg(C, 48)), o(this, cg, gg(C, 48)), o(this, Ug, gg(C, 16)), o(this, xg, gg(C, 16)), o(this, kg, gg(C, 64));
|
|
1317
|
-
}, Dg = new WeakSet(),
|
|
1320
|
+
}, Dg = new WeakSet(), cI = function() {
|
|
1318
1321
|
const g = I(this, yg);
|
|
1319
|
-
"clientWidth" in g && g.clientWidth > 0 ? (o(this, F, (typeof window < "u" && window.devicePixelRatio || 1) * I(this, _g)), o(this, V, g.width = Math.round(g.clientWidth * I(this, F))), o(this, X, g.height = Math.round(g.clientHeight * I(this, F)))) : (o(this, V, g.width), o(this, X, g.height)), !(I(this, V) === 0 || I(this, X) === 0) && (o(this, P, Math.max(1, Math.round(I(this, V) * I(this, dg)))), o(this, _, Math.max(1, Math.round(I(this, X) * I(this, dg)))), L(this,
|
|
1320
|
-
},
|
|
1321
|
-
if (L(this,
|
|
1322
|
+
"clientWidth" in g && g.clientWidth > 0 ? (o(this, F, (typeof window < "u" && window.devicePixelRatio || 1) * I(this, _g)), o(this, V, g.width = Math.round(g.clientWidth * I(this, F))), o(this, X, g.height = Math.round(g.clientHeight * I(this, F)))) : (o(this, V, g.width), o(this, X, g.height)), !(I(this, V) === 0 || I(this, X) === 0) && (o(this, P, Math.max(1, Math.round(I(this, V) * I(this, dg)))), o(this, _, Math.max(1, Math.round(I(this, X) * I(this, dg)))), L(this, ZI, DI).call(this));
|
|
1323
|
+
}, ZI = new WeakSet(), DI = function() {
|
|
1324
|
+
if (L(this, BI, FI).call(this), I(this, D)) {
|
|
1322
1325
|
const { device: g } = I(this, D), C = "rgba16float", i = I(this, P), s = I(this, _);
|
|
1323
1326
|
o(this, M, fI(g, C, i, s)), o(this, h, fI(g, C, i, s)), o(this, sg, fI(g, C, i, s)), o(this, rg, KI(g, C, i, s)), o(this, ng, KI(g, C, i, s));
|
|
1324
1327
|
} else {
|
|
1325
|
-
const g = I(this, j), C = I(this,
|
|
1328
|
+
const g = I(this, j), C = I(this, mI), i = I(this, P), s = I(this, _);
|
|
1326
1329
|
o(this, k, MI(g, C, i, s)), o(this, H, MI(g, C, i, s)), o(this, Cg, MI(g, C, i, s)), o(this, Ig, hI(g, C, i, s)), o(this, ig, hI(g, C, i, s));
|
|
1327
1330
|
}
|
|
1328
1331
|
}, wg = new WeakSet(), Ng = function() {
|
|
1329
1332
|
if (!(!I(this, U) || I(this, V) === 0 || I(this, X) === 0)) {
|
|
1330
|
-
if (L(this,
|
|
1333
|
+
if (L(this, GI, JI).call(this), I(this, D)) {
|
|
1331
1334
|
const { device: g } = I(this, D);
|
|
1332
1335
|
I(this, U).type === "text" ? o(this, E, GC(
|
|
1333
1336
|
g,
|
|
@@ -1374,9 +1377,9 @@ yg = new WeakMap(), j = new WeakMap(), uI = new WeakMap(), Vg = new WeakMap(), O
|
|
|
1374
1377
|
}
|
|
1375
1378
|
o(this, Mg, !0);
|
|
1376
1379
|
}
|
|
1377
|
-
}, Fg = new WeakSet(),
|
|
1380
|
+
}, Fg = new WeakSet(), dI = function() {
|
|
1378
1381
|
I(this, Mg) && !this.isRunning && this.start();
|
|
1379
|
-
},
|
|
1382
|
+
}, BI = new WeakSet(), FI = function() {
|
|
1380
1383
|
var g, C, i, s, l, t, S, u;
|
|
1381
1384
|
if (I(this, D))
|
|
1382
1385
|
(g = I(this, M)) == null || g.dispose(), (C = I(this, h)) == null || C.dispose(), (i = I(this, sg)) == null || i.dispose(), (s = I(this, rg)) == null || s.tex.destroy(), (l = I(this, ng)) == null || l.tex.destroy(), o(this, M, o(this, h, o(this, sg, null))), o(this, rg, o(this, ng, null));
|
|
@@ -1384,7 +1387,7 @@ yg = new WeakMap(), j = new WeakMap(), uI = new WeakMap(), Vg = new WeakMap(), O
|
|
|
1384
1387
|
const c = I(this, j);
|
|
1385
1388
|
(t = I(this, k)) == null || t.dispose(), (S = I(this, H)) == null || S.dispose(), (u = I(this, Cg)) == null || u.dispose(), I(this, Ig) && (c.deleteTexture(I(this, Ig).tex), c.deleteFramebuffer(I(this, Ig).fbo)), I(this, ig) && (c.deleteTexture(I(this, ig).tex), c.deleteFramebuffer(I(this, ig).fbo)), o(this, k, o(this, H, o(this, Cg, o(this, Ig, o(this, ig, null)))));
|
|
1386
1389
|
}
|
|
1387
|
-
},
|
|
1390
|
+
}, GI = new WeakSet(), JI = function() {
|
|
1388
1391
|
if (I(this, D))
|
|
1389
1392
|
I(this, E) && (I(this, E).backgroundTex.destroy(), I(this, E).obstacleTex.destroy(), I(this, E).sharedCoverage || I(this, E).coverageTex.destroy(), o(this, E, null));
|
|
1390
1393
|
else {
|
|
@@ -1399,15 +1402,15 @@ yg = new WeakMap(), j = new WeakMap(), uI = new WeakMap(), Vg = new WeakMap(), O
|
|
|
1399
1402
|
return;
|
|
1400
1403
|
I(this, w).x += (I(this, w).targetX - I(this, w).x) * 0.15, I(this, w).y += (I(this, w).targetY - I(this, w).y) * 0.15;
|
|
1401
1404
|
const u = I(this, P), c = I(this, _), p = I(this, V), a = I(this, X), A = 1 / u, m = 1 / c;
|
|
1402
|
-
jI(C, I(this, Xg), A, m,
|
|
1405
|
+
jI(C, I(this, Xg), A, m, AI, t.velocityDissipation), wI(C, I(this, Rg), A, m), wI(C, I(this, Wg), A, m), wI(C, I(this, Yg), A, m), wI(C, I(this, Ug), A, m), QC(C, I(this, xg), A, m, t.curl, AI), EC(
|
|
1403
1406
|
C,
|
|
1404
1407
|
I(this, kg),
|
|
1405
1408
|
1 / p,
|
|
1406
1409
|
1 / a,
|
|
1407
1410
|
t.refraction,
|
|
1408
1411
|
t.specularExp,
|
|
1409
|
-
|
|
1410
|
-
|
|
1412
|
+
bI(t.waterColor),
|
|
1413
|
+
bI(t.glowColor),
|
|
1411
1414
|
t.shine,
|
|
1412
1415
|
t.warpStrength ?? 0.015,
|
|
1413
1416
|
_I[t.algorithm] ?? 0,
|
|
@@ -1426,7 +1429,7 @@ yg = new WeakMap(), j = new WeakMap(), uI = new WeakMap(), Vg = new WeakMap(), O
|
|
|
1426
1429
|
}
|
|
1427
1430
|
I(this, h).swap();
|
|
1428
1431
|
{
|
|
1429
|
-
jI(C, I(this, vg), A, m,
|
|
1432
|
+
jI(C, I(this, vg), A, m, AI, t.densityDissipation);
|
|
1430
1433
|
const B = r(i.advection, [
|
|
1431
1434
|
{ binding: 0, resource: { buffer: I(this, vg) } },
|
|
1432
1435
|
b,
|
|
@@ -1456,7 +1459,7 @@ yg = new WeakMap(), j = new WeakMap(), uI = new WeakMap(), Vg = new WeakMap(), O
|
|
|
1456
1459
|
}
|
|
1457
1460
|
if (I(this, h).swap(), I(this, w).moved) {
|
|
1458
1461
|
const B = I(this, w).x * I(this, F) / p, K = I(this, w).y * I(this, F) / a;
|
|
1459
|
-
|
|
1462
|
+
LI(
|
|
1460
1463
|
C,
|
|
1461
1464
|
I(this, Ag),
|
|
1462
1465
|
A,
|
|
@@ -1477,7 +1480,7 @@ yg = new WeakMap(), j = new WeakMap(), uI = new WeakMap(), Vg = new WeakMap(), O
|
|
|
1477
1480
|
]);
|
|
1478
1481
|
O(Z, i.splat, W, s, I(this, h).write.view);
|
|
1479
1482
|
}
|
|
1480
|
-
I(this, h).swap(),
|
|
1483
|
+
I(this, h).swap(), LI(
|
|
1481
1484
|
C,
|
|
1482
1485
|
I(this, cg),
|
|
1483
1486
|
A,
|
|
@@ -1545,7 +1548,7 @@ yg = new WeakMap(), j = new WeakMap(), uI = new WeakMap(), Vg = new WeakMap(), O
|
|
|
1545
1548
|
C.queue.submit([Z.finish()]);
|
|
1546
1549
|
}, vI = new WeakSet(), tC = function(g, C, i, s, l) {
|
|
1547
1550
|
const S = I(this, D).device, u = I(this, jg).splat, c = I(this, Hg), p = I(this, Pg), a = I(this, Sg), A = I(this, P), m = I(this, _), Z = 1 / A, r = 1 / m, b = S.createCommandEncoder(), B = { binding: 1, resource: p }, K = (Q) => S.createBindGroup({ layout: u.getBindGroupLayout(0), entries: Q }), W = g * I(this, F) / I(this, V), x = C * I(this, F) / I(this, X);
|
|
1548
|
-
|
|
1551
|
+
LI(
|
|
1549
1552
|
S,
|
|
1550
1553
|
I(this, Ag),
|
|
1551
1554
|
Z,
|
|
@@ -1566,7 +1569,7 @@ yg = new WeakMap(), j = new WeakMap(), uI = new WeakMap(), Vg = new WeakMap(), O
|
|
|
1566
1569
|
]);
|
|
1567
1570
|
O(b, u, Q, c, I(this, h).write.view);
|
|
1568
1571
|
}
|
|
1569
|
-
I(this, h).swap(),
|
|
1572
|
+
I(this, h).swap(), LI(
|
|
1570
1573
|
S,
|
|
1571
1574
|
I(this, cg),
|
|
1572
1575
|
Z,
|
|
@@ -1597,10 +1600,10 @@ yg = new WeakMap(), j = new WeakMap(), uI = new WeakMap(), Vg = new WeakMap(), O
|
|
|
1597
1600
|
const g = I(this, j), C = I(this, Sg), { advection: i, divergence: s, pressure: l, gradientSubtract: t, splat: S, curl: u, vorticity: c, display: p } = I(this, Vg);
|
|
1598
1601
|
I(this, w).x += (I(this, w).targetX - I(this, w).x) * 0.15, I(this, w).y += (I(this, w).targetY - I(this, w).y) * 0.15;
|
|
1599
1602
|
const a = I(this, P), A = I(this, _), m = I(this, Og);
|
|
1600
|
-
g.viewport(0, 0, a, A), i.bind(), g.uniform2f(i.uniforms.texelSize, 1 / a, 1 / A), g.uniform1f(i.uniforms.dt,
|
|
1603
|
+
g.viewport(0, 0, a, A), i.bind(), g.uniform2f(i.uniforms.texelSize, 1 / a, 1 / A), g.uniform1f(i.uniforms.dt, AI), g.uniform1i(i.uniforms.uObstacle, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, z)), g.uniform1f(i.uniforms.dissipation, C.velocityDissipation), g.uniform1i(i.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(i.uniforms.uSource, 1), m(I(this, H).write.fbo), I(this, H).swap(), g.uniform1f(i.uniforms.dissipation, C.densityDissipation), g.uniform1i(i.uniforms.uSource, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, k).read.tex), m(I(this, k).write.fbo), I(this, k).swap(), u.bind(), g.uniform2f(u.uniforms.texelSize, 1 / a, 1 / A), g.uniform1i(u.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), m(I(this, ig).fbo), c.bind(), g.uniform2f(c.uniforms.texelSize, 1 / a, 1 / A), g.uniform1f(c.uniforms.curl, C.curl), g.uniform1f(c.uniforms.dt, AI), g.uniform1i(c.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(c.uniforms.uCurl, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, ig).tex), m(I(this, H).write.fbo), I(this, H).swap(), I(this, w).moved && (S.bind(), g.uniform1f(S.uniforms.aspectRatio, I(this, V) / I(this, X)), g.uniform2f(S.uniforms.point, I(this, w).x * I(this, F) / I(this, V), 1 - I(this, w).y * I(this, F) / I(this, X)), g.uniform1f(S.uniforms.radius, C.splatRadius), g.uniform1i(S.uniforms.uTarget, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform3f(S.uniforms.color, I(this, w).dx * C.splatForce, -I(this, w).dy * C.splatForce, 0), m(I(this, H).write.fbo), I(this, H).swap(), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, k).read.tex), g.uniform3f(S.uniforms.color, 1, 1, 1), m(I(this, k).write.fbo), I(this, k).swap(), I(this, w).moved = !1), s.bind(), g.uniform2f(s.uniforms.texelSize, 1 / a, 1 / A), g.uniform1i(s.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(s.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, z)), m(I(this, Ig).fbo), l.bind(), g.uniform2f(l.uniforms.texelSize, 1 / a, 1 / A), g.uniform1i(l.uniforms.uDivergence, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Ig).tex), g.uniform1i(l.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, z));
|
|
1601
1604
|
for (let Z = 0; Z < C.pressureIterations; Z++)
|
|
1602
1605
|
g.uniform1i(l.uniforms.uPressure, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, Cg).read.tex), m(I(this, Cg).write.fbo), I(this, Cg).swap();
|
|
1603
|
-
t.bind(), g.uniform2f(t.uniforms.texelSize, 1 / a, 1 / A), g.uniform1i(t.uniforms.uPressure, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Cg).read.tex), g.uniform1i(t.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(t.uniforms.uObstacle, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, z)), m(I(this, H).write.fbo), I(this, H).swap(), g.viewport(0, 0, I(this, V), I(this, X)), g.bindFramebuffer(g.FRAMEBUFFER, null), g.clear(g.COLOR_BUFFER_BIT), p.bind(), g.uniform2f(p.uniforms.texelSize, 1 / I(this, V), 1 / I(this, X)), g.uniform3fv(p.uniforms.uWaterColor,
|
|
1606
|
+
t.bind(), g.uniform2f(t.uniforms.texelSize, 1 / a, 1 / A), g.uniform1i(t.uniforms.uPressure, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Cg).read.tex), g.uniform1i(t.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(t.uniforms.uObstacle, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, z)), m(I(this, H).write.fbo), I(this, H).swap(), g.viewport(0, 0, I(this, V), I(this, X)), g.bindFramebuffer(g.FRAMEBUFFER, null), g.clear(g.COLOR_BUFFER_BIT), p.bind(), g.uniform2f(p.uniforms.texelSize, 1 / I(this, V), 1 / I(this, X)), g.uniform3fv(p.uniforms.uWaterColor, bI(C.waterColor)), g.uniform3fv(p.uniforms.uGlowColor, bI(C.glowColor)), g.uniform1f(p.uniforms.uRefraction, C.refraction), g.uniform1f(p.uniforms.uSpecularExp, C.specularExp), g.uniform1f(p.uniforms.uShine, C.shine), g.uniform1f(p.uniforms.uWarpStrength, C.warpStrength ?? 0.015), g.uniform1i(p.uniforms.uAlgorithm, _I[C.algorithm] ?? 0), g.uniform1i(p.uniforms.uEnableAlpha, I(this, fg) ? 1 : 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, k).read.tex), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, z)), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, og)), g.activeTexture(g.TEXTURE3), g.bindTexture(g.TEXTURE_2D, I(this, eg)), g.activeTexture(g.TEXTURE4), g.bindTexture(g.TEXTURE_2D, I(this, H).read.tex), g.uniform1i(p.uniforms.uTexture, 0), g.uniform1i(p.uniforms.uObstacle, 1), g.uniform1i(p.uniforms.uBackground, 2), g.uniform1i(p.uniforms.uCoverage, 3), g.uniform1i(p.uniforms.uVelocity, 4), m(null);
|
|
1604
1607
|
};
|
|
1605
1608
|
let yI = NI;
|
|
1606
1609
|
const cC = "dmFyIFR0ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5Owp2YXIgeXQgPSAoaSwgZSwgcikgPT4gZSBpbiBpID8gVHQoaSwgZSwgeyBlbnVtZXJhYmxlOiAhMCwgY29uZmlndXJhYmxlOiAhMCwgd3JpdGFibGU6ICEwLCB2YWx1ZTogciB9KSA6IGlbZV0gPSByOwp2YXIga2UgPSAoaSwgZSwgcikgPT4gKHl0KGksIHR5cGVvZiBlICE9ICJzeW1ib2wiID8gZSArICIiIDogZSwgciksIHIpLCBldCA9IChpLCBlLCByKSA9PiB7CiAgaWYgKCFlLmhhcyhpKSkKICAgIHRocm93IFR5cGVFcnJvcigiQ2Fubm90ICIgKyByKTsKfTsKdmFyIHQgPSAoaSwgZSwgcikgPT4gKGV0KGksIGUsICJyZWFkIGZyb20gcHJpdmF0ZSBmaWVsZCIpLCByID8gci5jYWxsKGkpIDogZS5nZXQoaSkpLCBmID0gKGksIGUsIHIpID0+IHsKICBpZiAoZS5oYXMoaSkpCiAgICB0aHJvdyBUeXBlRXJyb3IoIkNhbm5vdCBhZGQgdGhlIHNhbWUgcHJpdmF0ZSBtZW1iZXIgbW9yZSB0aGFuIG9uY2UiKTsKICBlIGluc3RhbmNlb2YgV2Vha1NldCA/IGUuYWRkKGkpIDogZS5zZXQoaSwgcik7Cn0sIGwgPSAoaSwgZSwgciwgcykgPT4gKGV0KGksIGUsICJ3cml0ZSB0byBwcml2YXRlIGZpZWxkIiksIHMgPyBzLmNhbGwoaSwgcikgOiBlLnNldChpLCByKSwgcik7CnZhciBTID0gKGksIGUsIHIpID0+IChldChpLCBlLCAiYWNjZXNzIHByaXZhdGUgbWV0aG9kIiksIHIpOwpjb25zdCB2dCA9IHsKICBkZW5zaXR5RGlzc2lwYXRpb246IDAuODMsCiAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC45MSwKICBwcmVzc3VyZUl0ZXJhdGlvbnM6IDEsCiAgY3VybDogMCwKICBzcGxhdFJhZGl1czogMC4xLAogIHNwbGF0Rm9yY2U6IDAuMDgsCiAgcmVmcmFjdGlvbjogMSwKICBzcGVjdWxhckV4cDogMCwKICBzaGluZTogMCwKICB3YXRlckNvbG9yOiAiIzAwMDAwMCIsCiAgZ2xvd0NvbG9yOiAiI2IzZDlmZiIsCiAgYWxnb3JpdGhtOiAiYXVyb3JhIiwKICB3YXJwU3RyZW5ndGg6IDAuMDQKfTsKKHsKICAuLi52dAp9KTsKY29uc3QgU3QgPSB7CiAgY2FsbTogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk4LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC44MSwKICAgIGN1cmw6IDFlLTQsCiAgICBzcGxhdFJhZGl1czogMC4wNSwKICAgIHNwbGF0Rm9yY2U6IDAuMDgsCiAgICByZWZyYWN0aW9uOiAwLjE1LAogICAgc2hpbmU6IDAuMDMsCiAgICBnbG93Q29sb3I6ICIjOTlkOWZmIiwKICAgIHdhdGVyQ29sb3I6ICIjMDAwNTBkIgogIH0sCiAgc2FuZDogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk1LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC44MSwKICAgIGN1cmw6IDEsCiAgICBzcGxhdFJhZGl1czogMC4yMywKICAgIHNwbGF0Rm9yY2U6IDAuMTYsCiAgICByZWZyYWN0aW9uOiAwLjgsCiAgICBzcGVjdWxhckV4cDogMCwKICAgIHNoaW5lOiAwLjMzLAogICAgZ2xvd0NvbG9yOiAiIzA3MDcwNyIsCiAgICB3YXRlckNvbG9yOiAiIzczNTQyMCIKICB9LAogIHdhdmU6IHsKICAgIGRlbnNpdHlEaXNzaXBhdGlvbjogMC45LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC4yLAogICAgY3VybDogMC4yLAogICAgc3BsYXRSYWRpdXM6IDAuMSwKICAgIHNwbGF0Rm9yY2U6IDAuMjIsCiAgICByZWZyYWN0aW9uOiAwLjM1LAogICAgc2hpbmU6IDAuMiwKICAgIGdsb3dDb2xvcjogIiM4MGNjZmYiLAogICAgd2F0ZXJDb2xvcjogIiMwMDAzMDgiCiAgfSwKICBuZW9uOiB7CiAgICBkZW5zaXR5RGlzc2lwYXRpb246IDAuNzUsCiAgICB2ZWxvY2l0eURpc3NpcGF0aW9uOiAwLjMsCiAgICBjdXJsOiAwLjA1LAogICAgc3BsYXRSYWRpdXM6IDAuMTgsCiAgICBzcGxhdEZvcmNlOiAwLjI5LAogICAgcmVmcmFjdGlvbjogMC4yNSwKICAgIHNwZWN1bGFyRXhwOiAwLjA0LAogICAgc2hpbmU6IDAuOTMsCiAgICBnbG93Q29sb3I6ICIjZmYzM2NjIiwKICAgIHdhdGVyQ29sb3I6ICIjMGQwMDE0IgogIH0sCiAgc21va2U6IHsKICAgIGRlbnNpdHlEaXNzaXBhdGlvbjogMC45MywKICAgIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuNzEsCiAgICBjdXJsOiAwLjA0LAogICAgc3BsYXRSYWRpdXM6IDAuMjEsCiAgICBzcGxhdEZvcmNlOiAwLjE0LAogICAgcmVmcmFjdGlvbjogMC4wOCwKICAgIHNoaW5lOiAwLAogICAgZ2xvd0NvbG9yOiAiIzgwODA4MCIsCiAgICB3YXRlckNvbG9yOiAiIzBmMGYwZiIKICB9Cn07CmZ1bmN0aW9uIFdlKGkpIHsKICBpZiAoQXJyYXkuaXNBcnJheShpKSkKICAgIHJldHVybiBpOwogIGNvbnN0IGUgPSBpLnNsaWNlKDEsIDcpOwogIHJldHVybiBlLmxlbmd0aCA9PT0gMyA/IFsKICAgIHBhcnNlSW50KGVbMF0gKyBlWzBdLCAxNikgLyAyNTUsCiAgICBwYXJzZUludChlWzFdICsgZVsxXSwgMTYpIC8gMjU1LAogICAgcGFyc2VJbnQoZVsyXSArIGVbMl0sIDE2KSAvIDI1NQogIF0gOiBbCiAgICBwYXJzZUludChlLnNsaWNlKDAsIDIpLCAxNikgLyAyNTUsCiAgICBwYXJzZUludChlLnNsaWNlKDIsIDQpLCAxNikgLyAyNTUsCiAgICBwYXJzZUludChlLnNsaWNlKDQsIDYpLCAxNikgLyAyNTUKICBdOwp9CmZ1bmN0aW9uIHd0KGkgPSB7fSwgZSwgciA9IHZ0KSB7CiAgcmV0dXJuIHsgLi4uZSA/IHsgLi4uciwgLi4uU3RbZV0gfSA6IHIsIC4uLmkgfTsKfQpjb25zdCByZSA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICBhdHRyaWJ1dGUgdmVjMiBhUG9zaXRpb247CiAgdmFyeWluZyB2ZWMyIHZVdjsKICB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSB2ZWMyIHRleGVsU2l6ZTsKICB2b2lkIG1haW4gKCkgewogICAgdlV2ID0gYVBvc2l0aW9uICogMC41ICsgMC41OwogICAgdkwgPSB2VXYgLSB2ZWMyKHRleGVsU2l6ZS54LCAwLjApOwogICAgdlIgPSB2VXYgKyB2ZWMyKHRleGVsU2l6ZS54LCAwLjApOwogICAgdlQgPSB2VXYgKyB2ZWMyKDAuMCwgdGV4ZWxTaXplLnkpOwogICAgdkIgPSB2VXYgLSB2ZWMyKDAuMCwgdGV4ZWxTaXplLnkpOwogICAgZ2xfUG9zaXRpb24gPSB2ZWM0KGFQb3NpdGlvbiwgMC4wLCAxLjApOwogIH0KYAopLCBSdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1U291cmNlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB1bmlmb3JtIHZlYzIgdGV4ZWxTaXplOwogIHVuaWZvcm0gZmxvYXQgZHQ7CiAgdW5pZm9ybSBmbG9hdCBkaXNzaXBhdGlvbjsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgb2JzICA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZVdikucjsKICAgIHZlYzIgY29vcmQgPSB2VXYgLSBkdCAqIHRleHR1cmUyRCh1VmVsb2NpdHksIHZVdikueHkgKiB0ZXhlbFNpemU7CiAgICAvLyBTbW9vdGggZGFtcGluZzogb2JzPTAgb3V0c2lkZSAoZnVsbCBmbG93KSwgb2JzPTEgaW5zaWRlIChmdWxsIHN0b3ApLCBibHVycmVkCiAgICAvLyBib3VuZGFyeSBpbiBiZXR3ZWVuLiAgTm8gYnJhbmNoaW5nIOKAlCBtdWx0aXBseWluZyBieSAoMS1vYnMpIGlzIGVxdWl2YWxlbnQgdG8gdGhlCiAgICAvLyBoYXJkIHplcm8taW5zaWRlIGNoZWNrIGJ1dCB3aXRoIGEgY29udGludW91cyBncmFkaWVudCB0aGF0IGF2b2lkcyBncmlkIGFydGVmYWN0cy4KICAgIGdsX0ZyYWdDb2xvciA9IGRpc3NpcGF0aW9uICogdGV4dHVyZTJEKHVTb3VyY2UsIGNvb3JkKSAqICgxLjAgLSBvYnMpOwogIH0KYAopLCBFdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZMKS54ICogKDEuMCAtIHRleHR1cmUyRCh1T2JzdGFjbGUsIHZMKS5yKTsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodVZlbG9jaXR5LCB2UikueCAqICgxLjAgLSB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2Uikucik7CiAgICBmbG9hdCBUID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlQpLnkgKiAoMS4wIC0gdGV4dHVyZTJEKHVPYnN0YWNsZSwgdlQpLnIpOwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZCKS55ICogKDEuMCAtIHRleHR1cmUyRCh1T2JzdGFjbGUsIHZCKS5yKTsKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoMC41ICogKFIgLSBMICsgVCAtIEIpLCAwLjAsIDAuMCwgMS4wKTsKICB9CmAKKSwgVXQgPSAoCiAgLyogZ2xzbCAqLwogIGAKICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgdmFyeWluZyB2ZWMyIHZVdjsgdmFyeWluZyB2ZWMyIHZMOyB2YXJ5aW5nIHZlYzIgdlI7IHZhcnlpbmcgdmVjMiB2VDsgdmFyeWluZyB2ZWMyIHZCOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVQcmVzc3VyZTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1RGl2ZXJnZW5jZTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1T2JzdGFjbGU7CiAgdm9pZCBtYWluICgpIHsKICAgIGZsb2F0IEMgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2VXYpLng7CiAgICBmbG9hdCBMID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZMKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2TCkucik7CiAgICBmbG9hdCBSID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZSKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2Uikucik7CiAgICBmbG9hdCBUID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZUKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2VCkucik7CiAgICBmbG9hdCBCID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZCKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2Qikucik7CiAgICBmbG9hdCBkaXYgPSB0ZXh0dXJlMkQodURpdmVyZ2VuY2UsIHZVdikueDsKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoKEwgKyBSICsgQiArIFQgLSBkaXYpICogMC4yNSwgMC4wLCAwLjAsIDEuMCk7CiAgfQpgCiksIER0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7IHZhcnlpbmcgdmVjMiB2TDsgdmFyeWluZyB2ZWMyIHZSOyB2YXJ5aW5nIHZlYzIgdlQ7IHZhcnlpbmcgdmVjMiB2QjsKICB1bmlmb3JtIHNhbXBsZXIyRCB1UHJlc3N1cmU7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgb2JzID0gdGV4dHVyZTJEKHVPYnN0YWNsZSwgdlV2KS5yOwogICAgZmxvYXQgQyAgID0gdGV4dHVyZTJEKHVQcmVzc3VyZSwgdlV2KS54OwogICAgZmxvYXQgTCAgID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZMKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2TCkucik7CiAgICBmbG9hdCBSICAgPSBtaXgodGV4dHVyZTJEKHVQcmVzc3VyZSwgdlIpLngsIEMsIHRleHR1cmUyRCh1T2JzdGFjbGUsIHZSKS5yKTsKICAgIGZsb2F0IFQgICA9IG1peCh0ZXh0dXJlMkQodVByZXNzdXJlLCB2VCkueCwgQywgdGV4dHVyZTJEKHVPYnN0YWNsZSwgdlQpLnIpOwogICAgZmxvYXQgQiAgID0gbWl4KHRleHR1cmUyRCh1UHJlc3N1cmUsIHZCKS54LCBDLCB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2Qikucik7CiAgICB2ZWMyIHZlbCAgPSAodGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eSAtIHZlYzIoUiAtIEwsIFQgLSBCKSkgKiAoMS4wIC0gb2JzKTsKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQodmVsLCAwLjAsIDEuMCk7CiAgfQpgCiksIF90ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVRhcmdldDsKICB1bmlmb3JtIGZsb2F0IGFzcGVjdFJhdGlvOwogIHVuaWZvcm0gdmVjMyBjb2xvcjsKICB1bmlmb3JtIHZlYzIgcG9pbnQ7CiAgdW5pZm9ybSBmbG9hdCByYWRpdXM7CiAgdm9pZCBtYWluICgpIHsKICAgIHZlYzIgcCA9IHZVdiAtIHBvaW50Lnh5OwogICAgcC54ICo9IGFzcGVjdFJhdGlvOwogICAgdmVjMyBzcGxhdCA9IGV4cCgtZG90KHAsIHApIC8gcmFkaXVzKSAqIGNvbG9yOwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCh0ZXh0dXJlMkQodVRhcmdldCwgdlV2KS54eXogKyBzcGxhdCwgMS4wKTsKICB9CmAKKSwgQ3QgPSAoCiAgLyogZ2xzbCAqLwogIGAKICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgdmFyeWluZyB2ZWMyIHZMOyB2YXJ5aW5nIHZlYzIgdlI7IHZhcnlpbmcgdmVjMiB2VDsgdmFyeWluZyB2ZWMyIHZCOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZMKS55OwogICAgZmxvYXQgUiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZSKS55OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZUKS54OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZCKS54OwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCgwLjUgKiAoUiAtIEwgLSBUICsgQiksIDAuMCwgMC4wLCAxLjApOwogIH0KYAopLCBCdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OyB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVDdXJsOwogIHVuaWZvcm0gZmxvYXQgY3VybDsKICB1bmlmb3JtIGZsb2F0IGR0OwogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBMID0gdGV4dHVyZTJEKHVDdXJsLCB2TCkueDsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodUN1cmwsIHZSKS54OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1Q3VybCwgdlQpLng7CiAgICBmbG9hdCBCID0gdGV4dHVyZTJEKHVDdXJsLCB2QikueDsKICAgIGZsb2F0IEMgPSB0ZXh0dXJlMkQodUN1cmwsIHZVdikueDsKICAgIHZlYzIgZm9yY2UgPSAwLjUgKiB2ZWMyKGFicyhUKSAtIGFicyhCKSwgYWJzKFIpIC0gYWJzKEwpKTsKICAgIGZvcmNlIC89IGxlbmd0aChmb3JjZSkgKyAwLjAwMDE7CiAgICBmb3JjZSAqPSBjdXJsICogMzAuMCAqIEM7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KHRleHR1cmUyRCh1VmVsb2NpdHksIHZVdikueHkgKyBmb3JjZSAqIGR0LCAwLjAsIDEuMCk7CiAgfQpgCiksIE90ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CgogIHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1QmFja2dyb3VuZDsKICB1bmlmb3JtIHNhbXBsZXIyRCB1Q292ZXJhZ2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwoKICB1bmlmb3JtIHZlYzIgIHRleGVsU2l6ZTsKICB1bmlmb3JtIHZlYzMgIHVXYXRlckNvbG9yOwogIHVuaWZvcm0gdmVjMyAgdUdsb3dDb2xvcjsKICB1bmlmb3JtIGZsb2F0IHVSZWZyYWN0aW9uOwogIHVuaWZvcm0gZmxvYXQgdVNwZWN1bGFyRXhwOwogIHVuaWZvcm0gZmxvYXQgdVNoaW5lOwogIHVuaWZvcm0gZmxvYXQgdVdhcnBTdHJlbmd0aDsKICB1bmlmb3JtIGludCAgIHVBbGdvcml0aG07CiAgdW5pZm9ybSBpbnQgICB1RW5hYmxlQWxwaGE7CgogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBvYnMgICAgICA9IHRleHR1cmUyRCh1T2JzdGFjbGUsICB2VXYpLnI7CiAgICAvLyBTbW9vdGggZmFkZTogZGVuc2l0eSBmYWxscyBvZmYgb3ZlciB0aGUgYmx1cnJlZCBvYnN0YWNsZSBib3VuZGFyeSB6b25lCiAgICAvLyByYXRoZXIgdGhhbiBjdXR0aW5nIG9mZiBhdCBhIGhhcmQgc3RlcCwgZWxpbWluYXRpbmcgdGhlIGphZ2dlZCBmcmluZ2UuCiAgICBmbG9hdCBkZW5zaXR5ICA9IG1heCh0ZXh0dXJlMkQodVRleHR1cmUsIHZVdikuciwgMC4wKSAqICgxLjAgLSBvYnMpOwogICAgZmxvYXQgY292ZXJhZ2UgPSB0ZXh0dXJlMkQodUNvdmVyYWdlLCAgdlV2KS5yOwoKICAgIC8vIDgtdGFwIFNvYmVsIG5vcm1hbCDigJQgY29tcHV0ZXMgZ3JhZGllbnQgdmlhIDPDlzMga2VybmVsIChubyBjZW50cmUgc2FtcGxlIG5lZWRlZCkuCiAgICAvLyB0ZXhlbFNpemUgPSAxL2Rpc3BsYXlSZXM7IGRlbnNpdHkgRkJPIGlzIGF0IHNpbVNjYWxlICgwLjXDlyksIHNvIHM9NiBkaXNwbGF5IHB4CiAgICAvLyDiiYggMyBzaW0gdGV4ZWxzIHBlciBheGlzLiAgVGhlIFNvYmVsIGtlcm5lbCBwcm9wZXJseSBhdmVyYWdlcyB0aGUgZ3JhZGllbnQgaW4KICAgIC8vIGV2ZXJ5IGRpcmVjdGlvbiDigJQgbm8gNC10YXAgY3Jvc3MgYmlhcyB0aGF0IGNyZWF0ZXMgNDXCsCBjaXJjdWl0LWJvYXJkIGFydGVmYWN0cy4KICAgIGZsb2F0IHN4ID0gdGV4ZWxTaXplLnggKiA2LjAsIHN5ID0gdGV4ZWxTaXplLnkgKiA2LjA7CiAgICBmbG9hdCBkMDAgPSBtYXgodGV4dHVyZTJEKHVUZXh0dXJlLCB2VXYgKyB2ZWMyKC1zeCwgLXN5KSkuciwgMC4wKTsKICAgIGZsb2F0IGQxMCA9IG1heCh0ZXh0dXJlMkQodVRleHR1cmUsIHZVdiArIHZlYzIoMC4wLCAtc3kpKS5yLCAwLjApOwogICAgZmxvYXQgZDIwID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMiggc3gsIC1zeSkpLnIsIDAuMCk7CiAgICBmbG9hdCBkMDEgPSBtYXgodGV4dHVyZTJEKHVUZXh0dXJlLCB2VXYgKyB2ZWMyKC1zeCwgMC4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGQyMSA9IG1heCh0ZXh0dXJlMkQodVRleHR1cmUsIHZVdiArIHZlYzIoIHN4LCAwLjApKS5yLCAwLjApOwogICAgZmxvYXQgZDAyID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMigtc3gsICBzeSkpLnIsIDAuMCk7CiAgICBmbG9hdCBkMTIgPSBtYXgodGV4dHVyZTJEKHVUZXh0dXJlLCB2VXYgKyB2ZWMyKDAuMCwgIHN5KSkuciwgMC4wKTsKICAgIGZsb2F0IGQyMiA9IG1heCh0ZXh0dXJlMkQodVRleHR1cmUsIHZVdiArIHZlYzIoIHN4LCAgc3kpKS5yLCAwLjApOwogICAgZmxvYXQgZ3ggID0gKGQyMCArIDIuMCpkMjEgKyBkMjIpIC0gKGQwMCArIDIuMCpkMDEgKyBkMDIpOwogICAgZmxvYXQgZ3kgID0gKGQwMiArIDIuMCpkMTIgKyBkMjIpIC0gKGQwMCArIDIuMCpkMTAgKyBkMjApOwoKICAgIHZlYzMgIG5vcm1hbCAgID0gbm9ybWFsaXplKHZlYzMoZ3gsIGd5LCAxLjIpKTsKICAgIHZlYzMgIGxpZ2h0RGlyID0gbm9ybWFsaXplKHZlYzMoMC41LCAxLjAsIDAuNSkpOwogICAgdmVjMyAgaGFsZlYgICAgPSBub3JtYWxpemUobGlnaHREaXIgKyB2ZWMzKDAuMCwgMC4wLCAxLjApKTsKICAgIC8vIFN1cHByZXNzIHNwZWN1bGFyIGF0IGxvdyAvIGZhZGluZyBkZW5zaXR5IOKAlCBwcmV2ZW50cyBoaWdobGlnaHQgcmluZ3MgZnJvbQogICAgLy8gYXBwZWFyaW5nIGF0IHRoZSBkaXNzaXBhdGluZyBlZGdlIG9mIGEgc3Ryb2tlIGFzIGl0cyBkZW5zaXR5IGFwcHJvYWNoZXMgemVyby4KICAgIGZsb2F0IHNwZWNEZW4gID0gZGVuc2l0eSAqIG1pbihkZW5zaXR5ICogNS4wLCAxLjApOwogICAgZmxvYXQgc3BlYyAgICAgPSBwb3cobWF4KGRvdChub3JtYWwsIGhhbGZWKSwgMC4wKSwgdVNwZWN1bGFyRXhwKSAqIHVTaGluZSAqIHNwZWNEZW47CgogICAgLy8gSW4gdHJhbnNwYXJlbnQgKG5vbi1jb3ZlcmFnZSkgYXJlYXMgdGhlIGJhY2tncm91bmQgdGV4dHVyZSBpcyBlbXB0eSBibGFjayBjYW52YXMuCiAgICAvLyBSZXBsYWNlIGl0IHdpdGggdVdhdGVyQ29sb3Igc28gZmx1aWQgY29sb3VyIGlzIG5vdCBjb250YW1pbmF0ZWQgYnkgdGhhdCBibGFjaywKICAgIC8vIGFsbG93aW5nIHRoZSBDU1MgYmFja2dyb3VuZENvbG9yIHRvIHNob3cgdGhyb3VnaCBjb3JyZWN0bHkgdmlhIHByZW11bHRpcGxpZWQgYWxwaGEuCiAgICB2ZWMzIGJnUmF3ID0gdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCB2VXYpLnJnYjsKICAgIHZlYzMgYmcgICAgPSBtaXgodVdhdGVyQ29sb3IsIGJnUmF3LCBjb3ZlcmFnZSk7CiAgICB2ZWMzIGNvbG9yID0gYmc7CgogICAgaWYgKHVBbGdvcml0aG0gPT0gMSkgewogICAgICAvLyDilIDilIAgZ2xhc3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFN0cm9uZyBVViBkaXN0b3J0aW9uIG9ubHkuIEltYWdlIGJlbmRzIGJ1dCBubyBjb2xvdXIgb3ZlcmxheS4KICAgICAgdmVjMiByZWZyVXYgPSBjbGFtcCh2VXYgKyBub3JtYWwueHkgKiB1UmVmcmFjdGlvbiAqIGRlbnNpdHkgKiAzLjAsIDAuMCwgMS4wKTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgPSByZWZyQmcgKyBzcGVjICogdUdsb3dDb2xvciAqIDIuNTsKICAgICAgY29sb3IgPSBtaXgoY29sb3IsIGJnICogMC42LCBvYnMgKiAwLjMpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAyKSB7CiAgICAgIC8vIOKUgOKUgCBpbmsg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIERlbnNlIG9wYXF1ZSBwaWdtZW50IHRoYXQgc3RhaW5zLiBTdWJ0bGUgcmVmcmFjdGlvbiB1bmRlcm5lYXRoLgogICAgICBmbG9hdCBpbmtEICA9IG1pbihkZW5zaXR5ICogNC4wLCAxLjApOwogICAgICB2ZWMyIHJlZnJVdiA9IGNsYW1wKHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eSAqIDAuNCwgMC4wLCAxLjApOwogICAgICB2ZWMzIHJlZnJCZyA9IG1peCh1V2F0ZXJDb2xvciwgdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCBtaXgodlV2LCByZWZyVXYsIDEuMCAtIG9icykpLnJnYiwgY292ZXJhZ2UpOwogICAgICBjb2xvciA9IG1peChyZWZyQmcsIHVXYXRlckNvbG9yICsgc3BlYyAqIHVHbG93Q29sb3IsIGlua0QpOwogICAgICBjb2xvciA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMTUpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAzKSB7CiAgICAgIC8vIOKUgOKUgCBhdXJvcmEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFZlbG9jaXR5IGZpZWxkIHdhcnBzIGJhY2tncm91bmQgVVZzIOKAlCBsaXF1aWQgbWV0YWwgLyBsYXZhLWxhbXAgZmVlbC4KICAgICAgdmVjMiAgdmVsICAgID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eTsKICAgICAgZmxvYXQgdmVsTWFnID0gY2xhbXAobGVuZ3RoKHZlbCkgKiAyMC4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzIgIHdhcnBVdiA9IGNsYW1wKHZVdiArIHZlbCAqIHVXYXJwU3RyZW5ndGgsIDAuMCwgMS4wKTsKICAgICAgdmVjMyAgd2FycEJnID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIHdhcnBVdikucmdiLCBjb3ZlcmFnZSk7CiAgICAgIGNvbG9yICA9IG1peChiZywgd2FycEJnLCB2ZWxNYWcgKiAoMS4wIC0gb2JzKSk7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogdmVsTWFnICogMS41OwogICAgICBjb2xvciArPSB1V2F0ZXJDb2xvciAqIGRlbnNpdHkgKiAwLjM7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CgogICAgfSBlbHNlIGlmICh1QWxnb3JpdGhtID09IDQpIHsKICAgICAgLy8g4pSA4pSAIHJpcHBsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgLy8gRXhhZ2dlcmF0ZWQgbm9ybWFsIHBlcnR1cmJhdGlvbiArIEZyZXNuZWwgcmltIOKAlCBjYWxtIHdhdGVyIHN1cmZhY2UuCiAgICAgIHZlYzIgIHJpcHBsZVV2ID0gY2xhbXAodlV2ICsgbm9ybWFsLnh5ICogdVJlZnJhY3Rpb24gKiBkZW5zaXR5ICogNi4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzMgIHJlZnJCZyAgID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIG1peCh2VXYsIHJpcHBsZVV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgZmxvYXQgZnJlc25lbCAgPSBwb3coY2xhbXAoMS4wIC0gZG90KG5vcm1hbCwgdmVjMygwLjAsIDAuMCwgMS4wKSksIDAuMCwgMS4wKSwgMy4wKSAqIGRlbnNpdHk7CiAgICAgIGNvbG9yICA9IHJlZnJCZzsKICAgICAgY29sb3IgKz0gZnJlc25lbCAqIHVHbG93Q29sb3IgKiAyLjA7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogZGVuc2l0eSAqIDIuMDsKICAgICAgY29sb3IgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKCiAgICB9IGVsc2UgewogICAgICAvLyDilIDilIAgc3RhbmRhcmQgKDApIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgICAvLyBPcmlnaW5hbDogY29sb3VyIG92ZXJsYXkgYmxlbmRlZCBvdmVyIHJlZnJhY3RlZCBiYWNrZ3JvdW5kLgogICAgICB2ZWMyIHJlZnJVdiA9IHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgID0gbWl4KHJlZnJCZywgdVdhdGVyQ29sb3IsIG1pbihkZW5zaXR5ICogMS41LCAwLjgpKTsKICAgICAgY29sb3IgKz0gc3BlYyAqIHVHbG93Q29sb3I7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CiAgICB9CgogICAgLy8gT3V0cHV0OiBwcmVtdWx0aXBsaWVkIGFscGhhIHdoZW4gdHJhbnNwYXJlbmN5IGlzIGVuYWJsZWQgKGxldHMgQ1NTIGJhY2tncm91bmRDb2xvcgogICAgLy8gc2hvdyB0aHJvdWdoKSwgb3Igc3RyYWlnaHQgb3BhcXVlIGNvbG91ciB3aGVuIGVuYWJsZUFscGhhIGlzIG9mZiAocGVyZiBtb2RlKS4KICAgIGZsb2F0IGFscGhhID0gY2xhbXAobWF4KGRlbnNpdHkgKiAxLjUsIGNvdmVyYWdlKSwgMC4wLCAxLjApOwogICAgaWYgKHVFbmFibGVBbHBoYSA9PSAxKSB7CiAgICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoY29sb3IgKiBhbHBoYSwgYWxwaGEpOwogICAgfSBlbHNlIHsKICAgICAgZ2xfRnJhZ0NvbG9yID0gdmVjNChjb2xvciwgMS4wKTsKICAgIH0KICB9CmAKKTsKZnVuY3Rpb24gVnQoaSwgZSA9ICEwKSB7CiAgY29uc3QgciA9IHsgYWxwaGE6IGUsIGRlcHRoOiAhMSwgc3RlbmNpbDogITEsIGFudGlhbGlhczogITAsIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogITEgfTsKICBsZXQgcyA9IGkuZ2V0Q29udGV4dCgid2ViZ2wyIiwgcik7CiAgY29uc3QgbyA9ICEhczsKICBvIHx8IChzID0gaS5nZXRDb250ZXh0KCJ3ZWJnbCIsIHIpLCBzLmdldEV4dGVuc2lvbigiRVhUX2NvbG9yX2J1ZmZlcl9oYWxmX2Zsb2F0IikpOwogIGNvbnN0IGEgPSBvID8gbnVsbCA6IHMuZ2V0RXh0ZW5zaW9uKCJPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0IiksIHUgPSBvID8gcy5IQUxGX0ZMT0FUIDogYS5IQUxGX0ZMT0FUX09FUzsKICByZXR1cm4gcy5nZXRFeHRlbnNpb24oIkVYVF9jb2xvcl9idWZmZXJfZmxvYXQiKSwgcy5nZXRFeHRlbnNpb24oIk9FU190ZXh0dXJlX2hhbGZfZmxvYXRfbGluZWFyIiksIHsKICAgIHR5cGU6IG8gPyAid2ViZ2wyIiA6ICJ3ZWJnbDEiLAogICAgZ2w6IHMsCiAgICBpc1dlYkdMMjogbywKICAgIGV4dDogewogICAgICBpbnRlcm5hbEZvcm1hdDogbyA/IHMuUkdCQTE2RiA6IHMuUkdCQSwKICAgICAgZm9ybWF0OiBzLlJHQkEsCiAgICAgIHR5cGU6IHUKICAgIH0KICB9Owp9CmFzeW5jIGZ1bmN0aW9uIFB0KGksIGUgPSAhMCkgewogIGlmICh0eXBlb2YgbmF2aWdhdG9yID4gInUiIHx8ICFuYXZpZ2F0b3IuZ3B1KQogICAgcmV0dXJuIG51bGw7CiAgdHJ5IHsKICAgIGNvbnN0IHIgPSBhd2FpdCBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKCk7CiAgICBpZiAoIXIpCiAgICAgIHJldHVybiBudWxsOwogICAgY29uc3QgcyA9IGF3YWl0IHIucmVxdWVzdERldmljZSgpLCBvID0gaS5nZXRDb250ZXh0KCJ3ZWJncHUiKTsKICAgIGlmICghbykKICAgICAgcmV0dXJuIG51bGw7CiAgICBjb25zdCBhID0gbmF2aWdhdG9yLmdwdS5nZXRQcmVmZXJyZWRDYW52YXNGb3JtYXQoKTsKICAgIHJldHVybiBvLmNvbmZpZ3VyZSh7IGRldmljZTogcywgZm9ybWF0OiBhLCBhbHBoYU1vZGU6IGUgPyAicHJlbXVsdGlwbGllZCIgOiAib3BhcXVlIiB9KSwgeyB0eXBlOiAid2ViZ3B1IiwgYWRhcHRlcjogciwgZGV2aWNlOiBzLCBjb250ZXh0OiBvLCBmb3JtYXQ6IGEgfTsKICB9IGNhdGNoIHsKICAgIHJldHVybiBudWxsOwogIH0KfQpjbGFzcyBpZSB7CiAgY29uc3RydWN0b3IoZSwgciwgcykgewogICAga2UodGhpcywgInByb2dyYW0iKTsKICAgIGtlKHRoaXMsICJ1bmlmb3JtcyIsIHt9KTsKICAgIGtlKHRoaXMsICJfZ2wiKTsKICAgIHRoaXMuX2dsID0gZSwgdGhpcy5wcm9ncmFtID0gZS5jcmVhdGVQcm9ncmFtKCksIGUuYXR0YWNoU2hhZGVyKHRoaXMucHJvZ3JhbSwgdGhpcy5fY29tcGlsZShlLlZFUlRFWF9TSEFERVIsIHIpKSwgZS5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCB0aGlzLl9jb21waWxlKGUuRlJBR01FTlRfU0hBREVSLCBzKSksIGUubGlua1Byb2dyYW0odGhpcy5wcm9ncmFtKTsKICAgIGNvbnN0IG8gPSBlLmdldFByb2dyYW1QYXJhbWV0ZXIodGhpcy5wcm9ncmFtLCBlLkFDVElWRV9VTklGT1JNUyk7CiAgICBmb3IgKGxldCBhID0gMDsgYSA8IG87IGErKykgewogICAgICBjb25zdCB1ID0gZS5nZXRBY3RpdmVVbmlmb3JtKHRoaXMucHJvZ3JhbSwgYSkubmFtZTsKICAgICAgdGhpcy51bmlmb3Jtc1t1XSA9IGUuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgdSk7CiAgICB9CiAgfQogIF9jb21waWxlKGUsIHIpIHsKICAgIGNvbnN0IHMgPSB0aGlzLl9nbCwgbyA9IHMuY3JlYXRlU2hhZGVyKGUpOwogICAgcmV0dXJuIHMuc2hhZGVyU291cmNlKG8sIHIpLCBzLmNvbXBpbGVTaGFkZXIobyksIG87CiAgfQogIGJpbmQoKSB7CiAgICB0aGlzLl9nbC51c2VQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQogIGRpc3Bvc2UoKSB7CiAgICB0aGlzLl9nbC5kZWxldGVQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQp9CmZ1bmN0aW9uIEZ0KGkpIHsKICByZXR1cm4gewogICAgYWR2ZWN0aW9uOiBuZXcgaWUoaSwgcmUsIFJ0KSwKICAgIGRpdmVyZ2VuY2U6IG5ldyBpZShpLCByZSwgRXQpLAogICAgcHJlc3N1cmU6IG5ldyBpZShpLCByZSwgVXQpLAogICAgZ3JhZGllbnRTdWJ0cmFjdDogbmV3IGllKGksIHJlLCBEdCksCiAgICBzcGxhdDogbmV3IGllKGksIHJlLCBfdCksCiAgICBjdXJsOiBuZXcgaWUoaSwgcmUsIEN0KSwKICAgIHZvcnRpY2l0eTogbmV3IGllKGksIHJlLCBCdCksCiAgICBkaXNwbGF5OiBuZXcgaWUoaSwgcmUsIE90KQogIH07Cn0KZnVuY3Rpb24gcWUoaSwgZSwgciwgcykgewogIGkuYWN0aXZlVGV4dHVyZShpLlRFWFRVUkUwKTsKICBjb25zdCBvID0gaS5jcmVhdGVUZXh0dXJlKCk7CiAgaS5iaW5kVGV4dHVyZShpLlRFWFRVUkVfMkQsIG8pLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUlOX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUFHX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9TLCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9ULCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleEltYWdlMkQoaS5URVhUVVJFXzJELCAwLCBlLmludGVybmFsRm9ybWF0LCByLCBzLCAwLCBlLmZvcm1hdCwgZS50eXBlLCBudWxsKTsKICBjb25zdCBhID0gaS5jcmVhdGVGcmFtZWJ1ZmZlcigpOwogIHJldHVybiBpLmJpbmRGcmFtZWJ1ZmZlcihpLkZSQU1FQlVGRkVSLCBhKSwgaS5mcmFtZWJ1ZmZlclRleHR1cmUyRChpLkZSQU1FQlVGRkVSLCBpLkNPTE9SX0FUVEFDSE1FTlQwLCBpLlRFWFRVUkVfMkQsIG8sIDApLCB7IHRleDogbywgZmJvOiBhLCB3aWR0aDogciwgaGVpZ2h0OiBzIH07Cn0KZnVuY3Rpb24gdHQoaSwgZSwgciwgcykgewogIGxldCBvID0gcWUoaSwgZSwgciwgcyksIGEgPSBxZShpLCBlLCByLCBzKTsKICByZXR1cm4gewogICAgZ2V0IHJlYWQoKSB7CiAgICAgIHJldHVybiBvOwogICAgfSwKICAgIGdldCB3cml0ZSgpIHsKICAgICAgcmV0dXJuIGE7CiAgICB9LAogICAgc3dhcCgpIHsKICAgICAgW28sIGFdID0gW2EsIG9dOwogICAgfSwKICAgIGRpc3Bvc2UoKSB7CiAgICAgIGkuZGVsZXRlVGV4dHVyZShvLnRleCksIGkuZGVsZXRlRnJhbWVidWZmZXIoby5mYm8pLCBpLmRlbGV0ZVRleHR1cmUoYS50ZXgpLCBpLmRlbGV0ZUZyYW1lYnVmZmVyKGEuZmJvKTsKICAgIH0KICB9Owp9CmZ1bmN0aW9uIEx0KGkpIHsKICBjb25zdCBlID0gaS5jcmVhdGVCdWZmZXIoKTsKICByZXR1cm4gaS5iaW5kQnVmZmVyKGkuQVJSQVlfQlVGRkVSLCBlKSwgaS5idWZmZXJEYXRhKGkuQVJSQVlfQlVGRkVSLCBuZXcgRmxvYXQzMkFycmF5KFstMSwgLTEsIC0xLCAxLCAxLCAxLCAxLCAtMV0pLCBpLlNUQVRJQ19EUkFXKSwgaS52ZXJ0ZXhBdHRyaWJQb2ludGVyKDAsIDIsIGkuRkxPQVQsICExLCAwLCAwKSwgaS5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSgwKSwgZnVuY3Rpb24ocykgewogICAgaS5iaW5kRnJhbWVidWZmZXIoaS5GUkFNRUJVRkZFUiwgcyksIGkuZHJhd0FycmF5cyhpLlRSSUFOR0xFX0ZBTiwgMCwgNCk7CiAgfTsKfQpjb25zdCBsZSA9ICgKICAvKiB3Z3NsICovCiAgYApzdHJ1Y3QgVlNPdXQgewogIEBidWlsdGluKHBvc2l0aW9uKSBwb3MgOiB2ZWM0ZiwKICBAbG9jYXRpb24oMCkgICAgICAgdXYgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDEpICAgICAgIHZMICA6IHZlYzJmLAogIEBsb2NhdGlvbigyKSAgICAgICB2UiAgOiB2ZWMyZiwKICBAbG9jYXRpb24oMykgICAgICAgdlQgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDQpICAgICAgIHZCICA6IHZlYzJmLAp9YAopLCBBdCA9ICgKICAvKiB3Z3NsICovCiAgYAoke2xlfQoKc3RydWN0IFUgewogIHRleGVsU2l6ZSAgOiB2ZWMyZiwKICBkdCAgICAgICAgIDogZjMyLAogIGRpc3NpcGF0aW9uOiBmMzIsCn0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVTcmMgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNCkgdmFyICAgICAgICAgIHVPYnMgIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgb2JzICAgPSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudXYpLnI7CiAgbGV0IHZlbCAgID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnV2KS54eTsKICBsZXQgY29vcmQgPSBpLnV2IC0gdS5kdCAqIHZlbCAqIHUudGV4ZWxTaXplOwogIGxldCBzcmMgICA9IHRleHR1cmVTYW1wbGUodVNyYywgc2FtcCwgY29vcmQpOwogIHJldHVybiB1LmRpc3NpcGF0aW9uICogc3JjICogKDEuMCAtIG9icyk7Cn0KYAopLCB6dCA9ICgKICAvKiB3Z3NsICovCiAgYAoke2xlfQoKc3RydWN0IFUgeyB0ZXhlbFNpemU6IHZlYzJmLCBfcGFkOiB2ZWMyZiB9CkBncm91cCgwKSBAYmluZGluZygwKSB2YXI8dW5pZm9ybT4gdSAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCA6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgICAgICAgICAgdVZlbCA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDMpIHZhciAgICAgICAgICB1T2JzIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgTCA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52TCkueCAqICgxLjAgLSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIpOwogIGxldCBSID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZSKS54ICogKDEuMCAtIHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS52Uikucik7CiAgbGV0IFQgPSB0ZXh0dXJlU2FtcGxlKHVWZWwsIHNhbXAsIGkudlQpLnkgKiAoMS4wIC0gdGV4dHVyZVNhbXBsZSh1T2JzLCBzYW1wLCBpLnZUKS5yKTsKICBsZXQgQiA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52QikueSAqICgxLjAgLSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIpOwogIHJldHVybiB2ZWM0ZigwLjUgKiAoUiAtIEwgKyBUIC0gQiksIDAuMCwgMC4wLCAxLjApOwp9CmAKKSwgWHQgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsgdGV4ZWxTaXplOiB2ZWMyZiwgX3BhZDogdmVjMmYgfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVQcmVzOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdURpdiA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDQpIHZhciAgICAgICAgICB1T2JzIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgQyAgPSB0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnV2KS54OwogIGxldCBMICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZMKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIpOwogIGxldCBSICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZSKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIpOwogIGxldCBUICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZUKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlQpLnIpOwogIGxldCBCICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZCKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIpOwogIGxldCBkdiA9IHRleHR1cmVTYW1wbGUodURpdiwgc2FtcCwgaS51dikueDsKICByZXR1cm4gdmVjNGYoKEwgKyBSICsgQiArIFQgLSBkdikgKiAwLjI1LCAwLjAsIDAuMCwgMS4wKTsKfQpgCiksIEd0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1UHJlczogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg0KSB2YXIgICAgICAgICAgdU9icyA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgbGV0IG9icyA9IHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS51dikucjsKICBsZXQgQyAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS51dikueDsKICBsZXQgTCAgID0gbWl4KHRleHR1cmVTYW1wbGUodVByZXMsIHNhbXAsIGkudkwpLngsIEMsIHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS52TCkucik7CiAgbGV0IFIgICA9IG1peCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZSKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIpOwogIGxldCBUICAgPSBtaXgodGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52VCkueCwgQywgdGV4dHVyZVNhbXBsZSh1T2JzLCBzYW1wLCBpLnZUKS5yKTsKICBsZXQgQiAgID0gbWl4KHRleHR1cmVTYW1wbGUodVByZXMsIHNhbXAsIGkudkIpLngsIEMsIHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS52Qikucik7CiAgbGV0IHZlbCA9ICh0ZXh0dXJlU2FtcGxlKHVWZWwsIHNhbXAsIGkudXYpLnh5IC0gdmVjMmYoUiAtIEwsIFQgLSBCKSkgKiAoMS4wIC0gb2JzKTsKICByZXR1cm4gdmVjNGYodmVsLCAwLjAsIDEuMCk7Cn0KYAopLCBNdCA9ICgKICAvKiB3Z3NsICovCiAgYAoke2xlfQoKLy8gdGV4ZWxTaXplIG9jY3VwaWVzIGJ5dGVzIDAtNyBmb3IgdGhlIHNoYXJlZCB2ZXJ0ZXggc3RhZ2U7IGFzcGVjdFJhdGlvL3JhZGl1cyBmaWxsIHRoZSByZXN0LgpzdHJ1Y3QgVSB7CiAgdGV4ZWxTaXplICA6IHZlYzJmLAogIGFzcGVjdFJhdGlvOiBmMzIsCiAgcmFkaXVzICAgICA6IGYzMiwKICBjb2xvciAgICAgIDogdmVjNGYsICAvLyB4eXogPSBjb2xvdXIsIHcgdW51c2VkCiAgcG9pbnQgICAgICA6IHZlYzJmLAogIF9wYWQgICAgICAgOiB2ZWMyZiwKfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVUZ3QgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIHZhciBwICA9IGkudXYgLSB1LnBvaW50OwogIHAueCAgICo9IHUuYXNwZWN0UmF0aW87CiAgbGV0IHNwID0gZXhwKC1kb3QocCwgcCkgLyB1LnJhZGl1cykgKiB1LmNvbG9yLnh5ejsKICByZXR1cm4gdmVjNGYodGV4dHVyZVNhbXBsZSh1VGd0LCBzYW1wLCBpLnV2KS54eXogKyBzcCwgMS4wKTsKfQpgCiksIEl0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1VmVsIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgTCA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52TCkueTsKICBsZXQgUiA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52UikueTsKICBsZXQgVCA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52VCkueDsKICBsZXQgQiA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52QikueDsKICByZXR1cm4gdmVjNGYoMC41ICogKFIgLSBMIC0gVCArIEIpLCAwLjAsIDAuMCwgMS4wKTsKfQpgCiksIGt0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7CiAgdGV4ZWxTaXplOiB2ZWMyZiwKICBjdXJsICAgICA6IGYzMiwKICBkdCAgICAgICA6IGYzMiwKfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdUNybCA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgbGV0IEwgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnZMKS54OwogIGxldCBSICAgICA9IHRleHR1cmVTYW1wbGUodUNybCwgc2FtcCwgaS52UikueDsKICBsZXQgVCAgICAgPSB0ZXh0dXJlU2FtcGxlKHVDcmwsIHNhbXAsIGkudlQpLng7CiAgbGV0IEIgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnZCKS54OwogIGxldCBDICAgICA9IHRleHR1cmVTYW1wbGUodUNybCwgc2FtcCwgaS51dikueDsKICB2YXIgZm9yY2UgPSAwLjUgKiB2ZWMyZihhYnMoVCkgLSBhYnMoQiksIGFicyhSKSAtIGFicyhMKSk7CiAgZm9yY2UgICAgLz0gbGVuZ3RoKGZvcmNlKSArIDAuMDAwMTsKICBmb3JjZSAgICAqPSB1LmN1cmwgKiAzMC4wICogQzsKICBsZXQgdmVsICAgPSB0ZXh0dXJlU2FtcGxlKHVWZWwsIHNhbXAsIGkudXYpLnh5ICsgZm9yY2UgKiB1LmR0OwogIHJldHVybiB2ZWM0Zih2ZWwsIDAuMCwgMS4wKTsKfQpgCiksIFd0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7CiAgdGV4ZWxTaXplICAgOiB2ZWMyZiwKICByZWZyYWN0aW9uICA6IGYzMiwKICBzcGVjdWxhckV4cCA6IGYzMiwKICB3YXRlckNvbG9yICA6IHZlYzRmLAogIGdsb3dDb2xvciAgIDogdmVjNGYsCiAgc2hpbmUgICAgICAgOiBmMzIsCiAgd2FycFN0cmVuZ3RoOiBmMzIsCiAgYWxnb3JpdGhtICAgOiBpMzIsCiAgZW5hYmxlQWxwaGEgOiBpMzIsCn0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1VGV4IDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVPYnMgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg0KSB2YXIgICAgICAgICAgdUJnICA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDUpIHZhciAgICAgICAgICB1Q292IDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNikgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIGxldCBvYnMgICAgID0gdGV4dHVyZVNhbXBsZSh1T2JzLCBzYW1wLCBpLnV2KS5yOwogIGxldCBkZW5zaXR5ID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51dikuciwgMC4wKSAqICgxLjAgLSBvYnMpOwogIGxldCBjb3YgICAgID0gdGV4dHVyZVNhbXBsZSh1Q292LCBzYW1wLCBpLnV2KS5yOwoKICBsZXQgc3ggID0gdS50ZXhlbFNpemUueCAqIDYuMDsKICBsZXQgc3kgID0gdS50ZXhlbFNpemUueSAqIDYuMDsKICBsZXQgZDAwID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKC1zeCwgLXN5KSkuciwgMC4wKTsKICBsZXQgZDEwID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKDAuMCwgLXN5KSkuciwgMC4wKTsKICBsZXQgZDIwID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKCBzeCwgLXN5KSkuciwgMC4wKTsKICBsZXQgZDAxID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKC1zeCwgMC4wKSkuciwgMC4wKTsKICBsZXQgZDIxID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKCBzeCwgMC4wKSkuciwgMC4wKTsKICBsZXQgZDAyID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKC1zeCwgIHN5KSkuciwgMC4wKTsKICBsZXQgZDEyID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKDAuMCwgIHN5KSkuciwgMC4wKTsKICBsZXQgZDIyID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKCBzeCwgIHN5KSkuciwgMC4wKTsKICBsZXQgZ3ggID0gKGQyMCArIDIuMCpkMjEgKyBkMjIpIC0gKGQwMCArIDIuMCpkMDEgKyBkMDIpOwogIGxldCBneSAgPSAoZDAyICsgMi4wKmQxMiArIGQyMikgLSAoZDAwICsgMi4wKmQxMCArIGQyMCk7CgogIGxldCBub3JtICAgID0gbm9ybWFsaXplKHZlYzNmKGd4LCBneSwgMS4yKSk7CiAgbGV0IGxkaXIgICAgPSBub3JtYWxpemUodmVjM2YoMC41LCAxLjAsIDAuNSkpOwogIGxldCBoYWxmViAgID0gbm9ybWFsaXplKGxkaXIgKyB2ZWMzZigwLjAsIDAuMCwgMS4wKSk7CiAgbGV0IHNwZWNEZW4gPSBkZW5zaXR5ICogbWluKGRlbnNpdHkgKiA1LjAsIDEuMCk7CiAgbGV0IHNwZWMgICAgPSBwb3cobWF4KGRvdChub3JtLCBoYWxmViksIDAuMCksIHUuc3BlY3VsYXJFeHApICogdS5zaGluZSAqIHNwZWNEZW47CgogIGxldCBiZ1JhdyA9IHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCBpLnV2KS5yZ2I7CiAgbGV0IHdjICAgID0gdS53YXRlckNvbG9yLnJnYjsKICBsZXQgZ2MgICAgPSB1Lmdsb3dDb2xvci5yZ2I7CiAgbGV0IGJnICAgID0gbWl4KHdjLCBiZ1JhdywgY292KTsKICB2YXIgY29sb3IgPSBiZzsKCiAgaWYgKHUuYWxnb3JpdGhtID09IDEpIHsKICAgIGxldCBydXYgPSBjbGFtcChpLnV2ICsgbm9ybS54eSAqIHUucmVmcmFjdGlvbiAqIGRlbnNpdHkgKiAzLjAsIHZlYzJmKDAuMCksIHZlYzJmKDEuMCkpOwogICAgbGV0IHJiZyA9IG1peCh3YywgdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIG1peChpLnV2LCBydXYsIDEuMCAtIG9icykpLnJnYiwgY292KTsKICAgIGNvbG9yICAgPSByYmcgKyBzcGVjICogZ2MgKiAyLjU7CiAgICBjb2xvciAgID0gbWl4KGNvbG9yLCBiZyAqIDAuNiwgb2JzICogMC4zKTsKICB9IGVsc2UgaWYgKHUuYWxnb3JpdGhtID09IDIpIHsKICAgIGxldCBpbmtEID0gbWluKGRlbnNpdHkgKiA0LjAsIDEuMCk7CiAgICBsZXQgcnV2ICA9IGNsYW1wKGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eSAqIDAuNCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgcmJnICA9IG1peCh3YywgdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIG1peChpLnV2LCBydXYsIDEuMCAtIG9icykpLnJnYiwgY292KTsKICAgIGNvbG9yICAgID0gbWl4KHJiZywgd2MgKyBzcGVjICogZ2MsIGlua0QpOwogICAgY29sb3IgICAgPSBtaXgoY29sb3IsIGJnICogMC41LCBvYnMgKiAwLjE1KTsKICB9IGVsc2UgaWYgKHUuYWxnb3JpdGhtID09IDMpIHsKICAgIGxldCB2ZWwgICAgPSB0ZXh0dXJlU2FtcGxlKHVWZWwsIHNhbXAsIGkudXYpLnh5OwogICAgbGV0IHZlbE1hZyA9IGNsYW1wKGxlbmd0aCh2ZWwpICogMjAuMCwgMC4wLCAxLjApOwogICAgbGV0IHd1diAgICA9IGNsYW1wKGkudXYgKyB2ZWwgKiB1LndhcnBTdHJlbmd0aCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgd2JnICAgID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgd3V2KS5yZ2IsIGNvdik7CiAgICBjb2xvciAgICAgID0gbWl4KGJnLCB3YmcsIHZlbE1hZyAqICgxLjAgLSBvYnMpKTsKICAgIGNvbG9yICAgICArPSBzcGVjICogZ2MgKiB2ZWxNYWcgKiAxLjU7CiAgICBjb2xvciAgICAgKz0gd2MgKiBkZW5zaXR5ICogMC4zOwogICAgY29sb3IgICAgICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CiAgfSBlbHNlIGlmICh1LmFsZ29yaXRobSA9PSA0KSB7CiAgICBsZXQgcnV2ICAgPSBjbGFtcChpLnV2ICsgbm9ybS54eSAqIHUucmVmcmFjdGlvbiAqIGRlbnNpdHkgKiA2LjAsIHZlYzJmKDAuMCksIHZlYzJmKDEuMCkpOwogICAgbGV0IHJiZyAgID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgbWl4KGkudXYsIHJ1diwgMS4wIC0gb2JzKSkucmdiLCBjb3YpOwogICAgbGV0IGZyZXMgID0gcG93KGNsYW1wKDEuMCAtIGRvdChub3JtLCB2ZWMzZigwLjAsIDAuMCwgMS4wKSksIDAuMCwgMS4wKSwgMy4wKSAqIGRlbnNpdHk7CiAgICBjb2xvciAgICAgPSByYmc7CiAgICBjb2xvciAgICArPSBmcmVzICogZ2MgKiAyLjA7CiAgICBjb2xvciAgICArPSBzcGVjICogZ2MgKiBkZW5zaXR5ICogMi4wOwogICAgY29sb3IgICAgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKICB9IGVsc2UgewogICAgbGV0IHJ1diA9IGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eTsKICAgIGxldCByYmcgPSBtaXgod2MsIHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCBtaXgoaS51diwgcnV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdik7CiAgICBjb2xvciAgID0gbWl4KHJiZywgd2MsIG1pbihkZW5zaXR5ICogMS41LCAwLjgpKTsKICAgIGNvbG9yICArPSBzcGVjICogZ2M7CiAgICBjb2xvciAgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKICB9CgogIGxldCBhbHBoYSA9IGNsYW1wKG1heChkZW5zaXR5ICogMS41LCBjb3YpLCAwLjAsIDEuMCk7CiAgaWYgKHUuZW5hYmxlQWxwaGEgPT0gMSkgewogICAgcmV0dXJuIHZlYzRmKGNvbG9yICogYWxwaGEsIGFscGhhKTsKICB9CiAgcmV0dXJuIHZlYzRmKGNvbG9yLCAxLjApOwp9CmAKKSwgTnQgPSB7CiAgYXJyYXlTdHJpZGU6IDgsCiAgYXR0cmlidXRlczogW3sgc2hhZGVyTG9jYXRpb246IDAsIG9mZnNldDogMCwgZm9ybWF0OiAiZmxvYXQzMngyIiB9XQp9LCBudCA9IG5ldyBGbG9hdDMyQXJyYXkoWwogIC0xLAogIC0xLAogIC0xLAogIDEsCiAgMSwKICAtMSwKICAxLAogIC0xLAogIC0xLAogIDEsCiAgMSwKICAxCl0pOwpmdW5jdGlvbiAkdChpKSB7CiAgY29uc3QgZSA9IGkuY3JlYXRlQnVmZmVyKHsgc2l6ZTogbnQuYnl0ZUxlbmd0aCwgdXNhZ2U6IEdQVUJ1ZmZlclVzYWdlLlZFUlRFWCB8IEdQVUJ1ZmZlclVzYWdlLkNPUFlfRFNUIH0pOwogIHJldHVybiBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIG50KSwgZTsKfQpmdW5jdGlvbiBIZShpLCBlLCByLCBzKSB7CiAgY29uc3QgbyA9IGkuY3JlYXRlVGV4dHVyZSh7CiAgICBzaXplOiBbciwgc10sCiAgICBmb3JtYXQ6IGUsCiAgICB1c2FnZTogR1BVVGV4dHVyZVVzYWdlLlRFWFRVUkVfQklORElORyB8IEdQVVRleHR1cmVVc2FnZS5SRU5ERVJfQVRUQUNITUVOVCB8IEdQVVRleHR1cmVVc2FnZS5DT1BZX1NSQwogIH0pOwogIHJldHVybiB7IHRleDogbywgdmlldzogby5jcmVhdGVWaWV3KCksIHdpZHRoOiByLCBoZWlnaHQ6IHMgfTsKfQpmdW5jdGlvbiBydChpLCBlLCByLCBzKSB7CiAgbGV0IG8gPSBIZShpLCBlLCByLCBzKSwgYSA9IEhlKGksIGUsIHIsIHMpOwogIHJldHVybiB7CiAgICBnZXQgcmVhZCgpIHsKICAgICAgcmV0dXJuIG87CiAgICB9LAogICAgZ2V0IHdyaXRlKCkgewogICAgICByZXR1cm4gYTsKICAgIH0sCiAgICBzd2FwKCkgewogICAgICBbbywgYV0gPSBbYSwgb107CiAgICB9LAogICAgZGlzcG9zZSgpIHsKICAgICAgby50ZXguZGVzdHJveSgpLCBhLnRleC5kZXN0cm95KCk7CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBzZShpLCBlLCByLCBzKSB7CiAgY29uc3QgbyA9IGkuY3JlYXRlU2hhZGVyTW9kdWxlKHsgY29kZTogZSB9KTsKICByZXR1cm4gaS5jcmVhdGVSZW5kZXJQaXBlbGluZSh7CiAgICBsYXlvdXQ6ICJhdXRvIiwKICAgIHZlcnRleDogeyBtb2R1bGU6IG8sIGVudHJ5UG9pbnQ6ICJ2cyIsIGJ1ZmZlcnM6IFtOdF0gfSwKICAgIGZyYWdtZW50OiB7IG1vZHVsZTogbywgZW50cnlQb2ludDogImZzIiwgdGFyZ2V0czogW3sgZm9ybWF0OiByLCAuLi5zID8geyBibGVuZDogcyB9IDoge30gfV0gfSwKICAgIHByaW1pdGl2ZTogeyB0b3BvbG9neTogInRyaWFuZ2xlLWxpc3QiIH0KICB9KTsKfQpjb25zdCBxdCA9IHsKICBjb2xvcjogeyBvcGVyYXRpb246ICJhZGQiLCBzcmNGYWN0b3I6ICJvbmUiLCBkc3RGYWN0b3I6ICJ6ZXJvIiB9LAogIGFscGhhOiB7IG9wZXJhdGlvbjogImFkZCIsIHNyY0ZhY3RvcjogIm9uZSIsIGRzdEZhY3RvcjogInplcm8iIH0KfTsKZnVuY3Rpb24gSHQoaSwgZSwgciA9ICEwKSB7CiAgY29uc3QgcyA9ICJyZ2JhMTZmbG9hdCI7CiAgcmV0dXJuIHsKICAgIGFkdmVjdGlvbjogc2UoaSwgQXQsIHMpLAogICAgZGl2ZXJnZW5jZTogc2UoaSwgenQsIHMpLAogICAgcHJlc3N1cmU6IHNlKGksIFh0LCBzKSwKICAgIGdyYWRpZW50U3VidHJhY3Q6IHNlKGksIEd0LCBzKSwKICAgIHNwbGF0OiBzZShpLCBNdCwgcyksCiAgICBjdXJsOiBzZShpLCBJdCwgcyksCiAgICB2b3J0aWNpdHk6IHNlKGksIGt0LCBzKSwKICAgIGRpc3BsYXk6IHNlKGksIFd0LCBlLCByID8gdm9pZCAwIDogcXQpCiAgfTsKfQpmdW5jdGlvbiBZdChpKSB7CiAgcmV0dXJuIGkuY3JlYXRlU2FtcGxlcih7IG1hZ0ZpbHRlcjogImxpbmVhciIsIG1pbkZpbHRlcjogImxpbmVhciIsIGFkZHJlc3NNb2RlVTogImNsYW1wLXRvLWVkZ2UiLCBhZGRyZXNzTW9kZVY6ICJjbGFtcC10by1lZGdlIiB9KTsKfQpmdW5jdGlvbiBXKGksIGUpIHsKICByZXR1cm4gaS5jcmVhdGVCdWZmZXIoeyBzaXplOiBlLCB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuVU5JRk9STSB8IEdQVUJ1ZmZlclVzYWdlLkNPUFlfRFNUIH0pOwp9CmZ1bmN0aW9uIGx0KGksIGUsIHIsIHMsIG8sIGEpIHsKICBjb25zdCB1ID0gbmV3IEZsb2F0MzJBcnJheShbciwgcywgbywgYV0pOwogIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgdSk7Cn0KZnVuY3Rpb24gTmUoaSwgZSwgciwgcykgewogIGNvbnN0IG8gPSBuZXcgRmxvYXQzMkFycmF5KFtyLCBzLCAwLCAwXSk7CiAgaS5xdWV1ZS53cml0ZUJ1ZmZlcihlLCAwLCBvKTsKfQpmdW5jdGlvbiBRdChpLCBlLCByLCBzLCBvLCBhKSB7CiAgY29uc3QgdSA9IG5ldyBGbG9hdDMyQXJyYXkoW3IsIHMsIG8sIGFdKTsKICBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIHUpOwp9CmZ1bmN0aW9uICRlKGksIGUsIHIsIHMsIG8sIGEsIHUsIHYsIG0sIGMsIHApIHsKICBjb25zdCB4ID0gbmV3IEZsb2F0MzJBcnJheSgxMik7CiAgeFswXSA9IHIsIHhbMV0gPSBzLCB4WzJdID0gbywgeFszXSA9IGEsIHhbNF0gPSB1LCB4WzVdID0gdiwgeFs2XSA9IG0sIHhbN10gPSAwLCB4WzhdID0gYywgeFs5XSA9IHAsIHhbMTBdID0gMCwgeFsxMV0gPSAwLCBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIHgpOwp9CmZ1bmN0aW9uIGp0KGksIGUsIHIsIHMsIG8sIGEsIHUsIHYsIG0sIGMsIHAsIHgpIHsKICBjb25zdCBuID0gbmV3IEZsb2F0MzJBcnJheSgxNiksIGQgPSBuZXcgSW50MzJBcnJheShuLmJ1ZmZlcik7CiAgblswXSA9IHIsIG5bMV0gPSBzLCBuWzJdID0gbywgblszXSA9IGEsIG5bNF0gPSB1WzBdLCBuWzVdID0gdVsxXSwgbls2XSA9IHVbMl0sIG5bN10gPSAwLCBuWzhdID0gdlswXSwgbls5XSA9IHZbMV0sIG5bMTBdID0gdlsyXSwgblsxMV0gPSAwLCBuWzEyXSA9IG0sIG5bMTNdID0gYywgZFsxNF0gPSBwLCBkWzE1XSA9IHggPyAxIDogMCwgaS5xdWV1ZS53cml0ZUJ1ZmZlcihlLCAwLCBuKTsKfQpmdW5jdGlvbiBYKGksIGUsIHIsIHMsIG8pIHsKICBjb25zdCBhID0gaS5iZWdpblJlbmRlclBhc3MoewogICAgY29sb3JBdHRhY2htZW50czogW3sKICAgICAgdmlldzogbywKICAgICAgY2xlYXJWYWx1ZTogWzAsIDAsIDAsIDBdLAogICAgICBsb2FkT3A6ICJjbGVhciIsCiAgICAgIHN0b3JlT3A6ICJzdG9yZSIKICAgIH1dCiAgfSk7CiAgYS5zZXRQaXBlbGluZShlKSwgYS5zZXRCaW5kR3JvdXAoMCwgciksIGEuc2V0VmVydGV4QnVmZmVyKDAsIHMpLCBhLmRyYXcoNiksIGEuZW5kKCk7Cn0KZnVuY3Rpb24gS3QoaSwgZSwgciwgcywgbykgewogIGNvbnN0IGEgPSBpLmJlZ2luUmVuZGVyUGFzcyh7CiAgICBjb2xvckF0dGFjaG1lbnRzOiBbewogICAgICB2aWV3OiBvLAogICAgICBjbGVhclZhbHVlOiBbMCwgMCwgMCwgMF0sCiAgICAgIGxvYWRPcDogImNsZWFyIiwKICAgICAgc3RvcmVPcDogInN0b3JlIgogICAgfV0KICB9KTsKICBhLnNldFBpcGVsaW5lKGUpLCBhLnNldEJpbmRHcm91cCgwLCByKSwgYS5zZXRWZXJ0ZXhCdWZmZXIoMCwgcyksIGEuZHJhdyg2KSwgYS5lbmQoKTsKfQpmdW5jdGlvbiBCZShpLCBlLCByLCBzLCBvID0gImNvdmVyIikgewogIGxldCBhOwogIG8gPT09ICJjb3ZlciIgPyBhID0gTWF0aC5tYXgociAvIGksIHMgLyBlKSA6IG8gPT09ICJjb250YWluIiA/IGEgPSBNYXRoLm1pbihyIC8gaSwgcyAvIGUpIDogdHlwZW9mIG8gPT0gInN0cmluZyIgJiYgby5lbmRzV2l0aCgiJSIpID8gYSA9IE1hdGgubWluKHIgLyBpLCBzIC8gZSkgKiAocGFyc2VGbG9hdChvKSAvIDEwMCkgOiB0eXBlb2YgbyA9PSAic3RyaW5nIiAmJiBvLmVuZHNXaXRoKCJweCIpID8gYSA9IHBhcnNlRmxvYXQobykgLyBNYXRoLm1heChpLCBlKSA6IHR5cGVvZiBvID09ICJudW1iZXIiID8gYSA9IG8gOiBhID0gTWF0aC5tYXgociAvIGksIHMgLyBlKTsKICBjb25zdCB1ID0gaSAqIGEsIHYgPSBlICogYTsKICByZXR1cm4geyB4OiAociAtIHUpIC8gMiwgeTogKHMgLSB2KSAvIDIsIGRyYXdXOiB1LCBkcmF3SDogdiB9Owp9CmZ1bmN0aW9uIEp0KGksIGUsIHIsIHMsIG8gPSBudWxsLCBhID0gImNvdmVyIikgewogIGNvbnN0IHsgdGV4dDogdSwgZm9udFNpemU6IHYsIGNvbG9yOiBtLCBmb250RmFtaWx5OiBjID0gInNhbnMtc2VyaWYiLCBmb250V2VpZ2h0OiBwID0gOTAwIH0gPSBzLCB4ID0gbmV3IE9mZnNjcmVlbkNhbnZhcyhlLCByKSwgbiA9IHguZ2V0Q29udGV4dCgiMmQiKTsKICAoKEQpID0+IHsKICAgIGlmIChvKSB7CiAgICAgIG4uY2xlYXJSZWN0KDAsIDAsIGUsIHIpLCBuLmZpbGxTdHlsZSA9ICJibGFjayIsIG4uZmlsbFJlY3QoMCwgMCwgZSwgcik7CiAgICAgIGNvbnN0IHsgeDogZywgeTogXywgZHJhd1c6IEYsIGRyYXdIOiBrIH0gPSBCZSgKICAgICAgICBvLndpZHRoLAogICAgICAgIG8uaGVpZ2h0LAogICAgICAgIGUsCiAgICAgICAgciwKICAgICAgICBhCiAgICAgICk7CiAgICAgIG4uZHJhd0ltYWdlKG8sIGcsIF8sIEYsIGspOwogICAgfSBlbHNlCiAgICAgIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKTsKICAgIG4uZmlsbFN0eWxlID0gRCwgbi5mb250ID0gYCR7cH0gJHt2fXB4ICR7Y31gLCBuLnRleHRBbGlnbiA9ICJjZW50ZXIiLCBuLnRleHRCYXNlbGluZSA9ICJtaWRkbGUiLCBuLmZpbGxUZXh0KHUsIGUgLyAyLCByIC8gMik7CiAgfSkobSk7CiAgY29uc3QgYiA9IExlKGksIHgpOwogIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKSwgbi5maWxsU3R5bGUgPSAid2hpdGUiLCBuLmZvbnQgPSBgJHtwfSAke3Z9cHggJHtjfWAsIG4udGV4dEFsaWduID0gImNlbnRlciIsIG4udGV4dEJhc2VsaW5lID0gIm1pZGRsZSIsIG4uZmlsbFRleHQodSwgZSAvIDIsIHIgLyAyKTsKICBjb25zdCB5ID0gTGUoaSwgeCk7CiAgcmV0dXJuIHsgYmFja2dyb3VuZFRleDogYiwgb2JzdGFjbGVUZXg6IHksIGNvdmVyYWdlVGV4OiB5IH07Cn0KZnVuY3Rpb24gWnQoaSwgZSwgciwgcywgbyA9IDAsIGEgPSAiY292ZXIiLCB1ID0gbnVsbCwgdiA9ICJjb3ZlciIpIHsKICBjb25zdCBtID0gbmV3IE9mZnNjcmVlbkNhbnZhcyhyLCBzKSwgYyA9IG0uZ2V0Q29udGV4dCgiMmQiKSwgeyB4OiBwLCB5OiB4LCBkcmF3VzogbiwgZHJhd0g6IGQgfSA9IEJlKGUud2lkdGgsIGUuaGVpZ2h0LCByLCBzLCBhKTsKICBpZiAoYy5jbGVhclJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gImJsYWNrIiwgYy5maWxsUmVjdCgwLCAwLCByLCBzKSwgdSkgewogICAgY29uc3QgewogICAgICB4OiBnLAogICAgICB5OiBfLAogICAgICBkcmF3VzogRiwKICAgICAgZHJhd0g6IGsKICAgIH0gPSBCZSh1LndpZHRoLCB1LmhlaWdodCwgciwgcywgdik7CiAgICBjLmZpbHRlciA9IGBicmlnaHRuZXNzKCR7b30pIGJsdXIoOHB4KWAsIGMuZHJhd0ltYWdlKHUsIGcsIF8sIEYsIGspLCBjLmZpbHRlciA9ICJub25lIjsKICB9CiAgYy5kcmF3SW1hZ2UoZSwgcCwgeCwgbiwgZCk7CiAgY29uc3QgYiA9IExlKGksIG0pOwogIGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIGMuZmlsdGVyID0gYGJyaWdodG5lc3MoJHtvfSkgYmx1cig4cHgpYCwgYy5kcmF3SW1hZ2UoZSwgcCwgeCwgbiwgZCksIGMuZmlsdGVyID0gIm5vbmUiOwogIGNvbnN0IHkgPSBMZShpLCBtKTsKICBjLmNsZWFyUmVjdCgwLCAwLCByLCBzKSwgYy5maWxsU3R5bGUgPSAiYmxhY2siLCBjLmZpbGxSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJ3aGl0ZSIsIGMuZmlsbFJlY3QoCiAgICBNYXRoLm1heCgwLCBwKSwKICAgIE1hdGgubWF4KDAsIHgpLAogICAgTWF0aC5taW4obiwgciAtIE1hdGgubWF4KDAsIHApKSwKICAgIE1hdGgubWluKGQsIHMgLSBNYXRoLm1heCgwLCB4KSkKICApOwogIGNvbnN0IEQgPSBMZShpLCBtKTsKICByZXR1cm4geyBiYWNrZ3JvdW5kVGV4OiBiLCBvYnN0YWNsZVRleDogeSwgY292ZXJhZ2VUZXg6IEQgfTsKfQpmdW5jdGlvbiBMZShpLCBlKSB7CiAgY29uc3QgciA9IGkuY3JlYXRlVGV4dHVyZSgpOwogIHJldHVybiBpLmJpbmRUZXh0dXJlKGkuVEVYVFVSRV8yRCwgciksIGkucGl4ZWxTdG9yZWkoaS5VTlBBQ0tfRkxJUF9ZX1dFQkdMLCAhMCksIGkudGV4SW1hZ2UyRChpLlRFWFRVUkVfMkQsIDAsIGkuUkdCQSwgaS5SR0JBLCBpLlVOU0lHTkVEX0JZVEUsIGUpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUlOX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUFHX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9TLCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9ULCBpLkNMQU1QX1RPX0VER0UpLCByOwp9CmZ1bmN0aW9uIGVyKGksIGUsIHIsIHMsIG8gPSBudWxsLCBhID0gImNvdmVyIikgewogIGNvbnN0IHsgdGV4dDogdSwgZm9udFNpemU6IHYsIGNvbG9yOiBtLCBmb250RmFtaWx5OiBjID0gInNhbnMtc2VyaWYiLCBmb250V2VpZ2h0OiBwID0gOTAwIH0gPSBzLCB4ID0gbmV3IE9mZnNjcmVlbkNhbnZhcyhlLCByKSwgbiA9IHguZ2V0Q29udGV4dCgiMmQiKTsKICAoKEQpID0+IHsKICAgIGlmIChvKSB7CiAgICAgIG4uY2xlYXJSZWN0KDAsIDAsIGUsIHIpLCBuLmZpbGxTdHlsZSA9ICJibGFjayIsIG4uZmlsbFJlY3QoMCwgMCwgZSwgcik7CiAgICAgIGNvbnN0IHsgeDogZywgeTogXywgZHJhd1c6IEYsIGRyYXdIOiBrIH0gPSBCZSgKICAgICAgICBvLndpZHRoLAogICAgICAgIG8uaGVpZ2h0LAogICAgICAgIGUsCiAgICAgICAgciwKICAgICAgICBhCiAgICAgICk7CiAgICAgIG4uZHJhd0ltYWdlKG8sIGcsIF8sIEYsIGspOwogICAgfSBlbHNlCiAgICAgIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKTsKICAgIG4uZmlsbFN0eWxlID0gRCwgbi5mb250ID0gYCR7cH0gJHt2fXB4ICR7Y31gLCBuLnRleHRBbGlnbiA9ICJjZW50ZXIiLCBuLnRleHRCYXNlbGluZSA9ICJtaWRkbGUiLCBuLmZpbGxUZXh0KHUsIGUgLyAyLCByIC8gMik7CiAgfSkobSk7CiAgY29uc3QgYiA9IEFlKGksIHgsIGUsIHIpOwogIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKSwgbi5maWxsU3R5bGUgPSAid2hpdGUiLCBuLmZvbnQgPSBgJHtwfSAke3Z9cHggJHtjfWAsIG4udGV4dEFsaWduID0gImNlbnRlciIsIG4udGV4dEJhc2VsaW5lID0gIm1pZGRsZSIsIG4uZmlsbFRleHQodSwgZSAvIDIsIHIgLyAyKTsKICBjb25zdCB5ID0gQWUoaSwgeCwgZSwgcik7CiAgcmV0dXJuIHsKICAgIGJhY2tncm91bmRUZXg6IGIsCiAgICBiYWNrZ3JvdW5kVmlldzogYi5jcmVhdGVWaWV3KCksCiAgICBvYnN0YWNsZVRleDogeSwKICAgIG9ic3RhY2xlVmlldzogeS5jcmVhdGVWaWV3KCksCiAgICBjb3ZlcmFnZVRleDogeSwKICAgIGNvdmVyYWdlVmlldzogeS5jcmVhdGVWaWV3KCksCiAgICBzaGFyZWRDb3ZlcmFnZTogITAKICB9Owp9CmZ1bmN0aW9uIHRyKGksIGUsIHIsIHMsIG8gPSAwLCBhID0gImNvdmVyIiwgdSA9IG51bGwsIHYgPSAiY292ZXIiKSB7CiAgY29uc3QgbSA9IG5ldyBPZmZzY3JlZW5DYW52YXMociwgcyksIGMgPSBtLmdldENvbnRleHQoIjJkIiksIHsgeDogcCwgeTogeCwgZHJhd1c6IG4sIGRyYXdIOiBkIH0gPSBCZShlLndpZHRoLCBlLmhlaWdodCwgciwgcywgYSk7CiAgaWYgKGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIHUpIHsKICAgIGNvbnN0IHsgeDogZywgeTogXywgZHJhd1c6IEYsIGRyYXdIOiBrIH0gPSBCZSgKICAgICAgdS53aWR0aCwKICAgICAgdS5oZWlnaHQsCiAgICAgIHIsCiAgICAgIHMsCiAgICAgIHYKICAgICk7CiAgICBjLmZpbHRlciA9IGBicmlnaHRuZXNzKCR7b30pIGJsdXIoOHB4KWAsIGMuZHJhd0ltYWdlKHUsIGcsIF8sIEYsIGspLCBjLmZpbHRlciA9ICJub25lIjsKICB9CiAgYy5kcmF3SW1hZ2UoZSwgcCwgeCwgbiwgZCk7CiAgY29uc3QgYiA9IEFlKGksIG0sIHIsIHMpOwogIGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIGMuZmlsdGVyID0gYGJyaWdodG5lc3MoJHtvfSkgYmx1cig4cHgpYCwgYy5kcmF3SW1hZ2UoZSwgcCwgeCwgbiwgZCksIGMuZmlsdGVyID0gIm5vbmUiOwogIGNvbnN0IHkgPSBBZShpLCBtLCByLCBzKTsKICBjLmNsZWFyUmVjdCgwLCAwLCByLCBzKSwgYy5maWxsU3R5bGUgPSAiYmxhY2siLCBjLmZpbGxSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJ3aGl0ZSIsIGMuZmlsbFJlY3QoTWF0aC5tYXgoMCwgcCksIE1hdGgubWF4KDAsIHgpLCBNYXRoLm1pbihuLCByIC0gTWF0aC5tYXgoMCwgcCkpLCBNYXRoLm1pbihkLCBzIC0gTWF0aC5tYXgoMCwgeCkpKTsKICBjb25zdCBEID0gQWUoaSwgbSwgciwgcyk7CiAgcmV0dXJuIHsKICAgIGJhY2tncm91bmRUZXg6IGIsCiAgICBiYWNrZ3JvdW5kVmlldzogYi5jcmVhdGVWaWV3KCksCiAgICBvYnN0YWNsZVRleDogeSwKICAgIG9ic3RhY2xlVmlldzogeS5jcmVhdGVWaWV3KCksCiAgICBjb3ZlcmFnZVRleDogRCwKICAgIGNvdmVyYWdlVmlldzogRC5jcmVhdGVWaWV3KCksCiAgICBzaGFyZWRDb3ZlcmFnZTogITEKICB9Owp9CmZ1bmN0aW9uIEFlKGksIGUsIHIsIHMpIHsKICBjb25zdCBvID0gaS5jcmVhdGVUZXh0dXJlKHsKICAgIHNpemU6IFtyLCBzXSwKICAgIGZvcm1hdDogInJnYmE4dW5vcm0iLAogICAgdXNhZ2U6IEdQVVRleHR1cmVVc2FnZS5URVhUVVJFX0JJTkRJTkcgfCBHUFVUZXh0dXJlVXNhZ2UuQ09QWV9EU1QgfCBHUFVUZXh0dXJlVXNhZ2UuUkVOREVSX0FUVEFDSE1FTlQKICB9KTsKICByZXR1cm4gaS5xdWV1ZS5jb3B5RXh0ZXJuYWxJbWFnZVRvVGV4dHVyZSgKICAgIHsgc291cmNlOiBlIH0sCiAgICB7IHRleHR1cmU6IG8gfSwKICAgIFtyLCBzXQogICksIG87Cn0KYXN5bmMgZnVuY3Rpb24gcnIoaSkgewogIGNvbnN0IGUgPSBhd2FpdCBmZXRjaChpKTsKICBpZiAoIWUub2spCiAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBmZXRjaCBpbWFnZTogJHtpfSAoJHtlLnN0YXR1c30pYCk7CiAgY29uc3QgciA9IGF3YWl0IGUuYmxvYigpOwogIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChyKTsKfQpjb25zdCBjdCA9IHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPCAidSIgPyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUuYmluZChnbG9iYWxUaGlzKSA6IChpKSA9PiBzZXRUaW1lb3V0KGksIDFlMyAvIDYwKSwgaXIgPSB0eXBlb2YgY2FuY2VsQW5pbWF0aW9uRnJhbWUgPCAidSIgPyBjYW5jZWxBbmltYXRpb25GcmFtZS5iaW5kKGdsb2JhbFRoaXMpIDogY2xlYXJUaW1lb3V0LCBWZSA9IDAuMDE2LCBmdCA9IHsgc3RhbmRhcmQ6IDAsIGdsYXNzOiAxLCBpbms6IDIsIGF1cm9yYTogMywgcmlwcGxlOiA0IH07CnZhciBjZSwgRywgemUsIGZlLCBVZSwgQiwgUiwgJCwgcSwgSCwgSywgTCwgWSwgViwgRGUsIHZlLCBfZSwgTywgVCwgb2UsIFEsIGFlLCB6LCB4ZSwgcGUsIG1lLCBkZSwgaGUsIEosIFosIGdlLCBiZSwgVGUsIHcsIFUsIE0sIEksIFAsIENlLCBlZSwgQSwgdWUsIHRlLCBoLCBDLCBqLCB5ZSwgWGUsIFNlLCBZZSwgeHQsIHdlLCBQZSwgR2UsIHN0LCBuZSwgRWUsIFJlLCBGZSwgTWUsIG90LCBJZSwgYXQsIFFlLCBwdCwgamUsIG10LCBLZSwgZHQsIEplLCBodCwgWmUsIGd0Owpjb25zdCB1dCA9IGNsYXNzIHV0IHsKICAvLyDilIDilIAgQ29uc3RydWN0b3Ig4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgY29uc3RydWN0b3IoZSwgciA9IHt9LCBzID0ge30sIG8sIGEgPSAhMCkgewogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBHUFUgaW5pdGlhbGlzYXRpb24KICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBZZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIHNoYXJlZCBoZWxwZXJzCiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGYodGhpcywgd2UpOwogICAgZih0aGlzLCBHZSk7CiAgICBmKHRoaXMsIG5lKTsKICAgIGYodGhpcywgUmUpOwogICAgZih0aGlzLCBNZSk7CiAgICBmKHRoaXMsIEllKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgZnJhbWUgZGlzcGF0Y2gKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBRZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIFdlYkdQVSBzaW11bGF0aW9uIHN0ZXAKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBqZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIFdlYkdQVSBkaXJlY3Qgc3BsYXQKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBLZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIFdlYkdMIHNwbGF0CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGYodGhpcywgSmUpOwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBXZWJHTCBzaW11bGF0aW9uIHN0ZXAgKHVuY2hhbmdlZCBmcm9tIG9yaWdpbmFsKQogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIFplKTsKICAgIGYodGhpcywgY2UsIHZvaWQgMCk7CiAgICAvLyDilIDilIAgV2ViR0wgcGF0aCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgIGYodGhpcywgRywgbnVsbCk7CiAgICBmKHRoaXMsIHplLCBudWxsKTsKICAgIGYodGhpcywgZmUsIG51bGwpOwogICAgZih0aGlzLCBVZSwgbnVsbCk7CiAgICBmKHRoaXMsIEIsIG51bGwpOwogICAgZih0aGlzLCBSLCBudWxsKTsKICAgIGYodGhpcywgJCwgbnVsbCk7CiAgICBmKHRoaXMsIHEsIG51bGwpOwogICAgZih0aGlzLCBILCBudWxsKTsKICAgIGYodGhpcywgSywgbnVsbCk7CiAgICBmKHRoaXMsIEwsIG51bGwpOwogICAgZih0aGlzLCBZLCBudWxsKTsKICAgIC8vIOKUgOKUgCBXZWJHUFUgcGF0aCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgIGYodGhpcywgViwgbnVsbCk7CiAgICBmKHRoaXMsIERlLCBudWxsKTsKICAgIGYodGhpcywgdmUsIG51bGwpOwogICAgZih0aGlzLCBfZSwgbnVsbCk7CiAgICBmKHRoaXMsIE8sIG51bGwpOwogICAgZih0aGlzLCBULCBudWxsKTsKICAgIGYodGhpcywgb2UsIG51bGwpOwogICAgZih0aGlzLCBRLCBudWxsKTsKICAgIGYodGhpcywgYWUsIG51bGwpOwogICAgZih0aGlzLCB6LCBudWxsKTsKICAgIC8vIFByZS1hbGxvY2F0ZWQgdW5pZm9ybSBidWZmZXJzIChzaXplczogc2VlIGdwdS11dGlscyB3cml0ZVh4eCBkb2NzKQogICAgLy8gVmVsb2NpdHkvZGVuc2l0eSBhZHZlY3Rpb24gdXNlIHNlcGFyYXRlIGJ1ZmZlcnMg4oCUIHdyaXRlQnVmZmVyIGlzIGEgcXVldWUgb3A7CiAgICAvLyBhIHNlY29uZCB3cml0ZSB0byB0aGUgc2FtZSBidWZmZXIgYmVmb3JlIHF1ZXVlLnN1Ym1pdCgpIGFsaWFzZXMgYm90aCBwYXNzZXMuCiAgICBmKHRoaXMsIHhlLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzIOKAlCB2ZWxvY2l0eSBhZHZlY3Rpb24KICAgIGYodGhpcywgcGUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMg4oCUIGRlbnNpdHkgYWR2ZWN0aW9uCiAgICBmKHRoaXMsIG1lLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzCiAgICBmKHRoaXMsIGRlLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzCiAgICBmKHRoaXMsIGhlLCBudWxsKTsKICAgIC8vIDE2IGJ5dGVzCiAgICBmKHRoaXMsIEosIG51bGwpOwogICAgLy8gNDggYnl0ZXMg4oCUIHZlbG9jaXR5IHNwbGF0CiAgICBmKHRoaXMsIFosIG51bGwpOwogICAgLy8gNDggYnl0ZXMg4oCUIGRlbnNpdHkgc3BsYXQKICAgIGYodGhpcywgZ2UsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgYmUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgVGUsIG51bGwpOwogICAgLy8gNjQgYnl0ZXMKICAgIC8vIOKUgOKUgCBTaGFyZWQgc3RhdGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICBmKHRoaXMsIHcsIDApOwogICAgZih0aGlzLCBVLCAwKTsKICAgIGYodGhpcywgTSwgMCk7CiAgICBmKHRoaXMsIEksIDApOwogICAgZih0aGlzLCBQLCAxKTsKICAgIGYodGhpcywgQ2UsIDEpOwogICAgZih0aGlzLCBlZSwgMC41KTsKICAgIGYodGhpcywgQSwgbnVsbCk7CiAgICBmKHRoaXMsIHVlLCAiY292ZXIiKTsKICAgIGYodGhpcywgdGUsIHZvaWQgMCk7CiAgICBmKHRoaXMsIGgsIHsgeDogMCwgeTogMCwgZHg6IDAsIGR5OiAwLCB0YXJnZXRYOiAwLCB0YXJnZXRZOiAwLCBtb3ZlZDogITEgfSk7CiAgICBmKHRoaXMsIEMsIG51bGwpOwogICAgZih0aGlzLCBqLCBudWxsKTsKICAgIGYodGhpcywgeWUsICExKTsKICAgIGYodGhpcywgWGUsICExKTsKICAgIGYodGhpcywgU2UsICEwKTsKICAgIGlmIChsKHRoaXMsIGNlLCBlKSwgbCh0aGlzLCBDZSwgTWF0aC5tYXgoMC4xLCBNYXRoLm1pbigxLCBzLmRwciA/PyAxKSkpLCBsKHRoaXMsIGVlLCBNYXRoLm1heCgwLjEsIE1hdGgubWluKDEsIHMuc2ltID8/IDAuNSkpKSwgbCh0aGlzLCB0ZSwgd3QocikpLCBsKHRoaXMsIFNlLCBhKSwgbykKICAgICAgbCh0aGlzLCBWLCBvKSwgUyh0aGlzLCBZZSwgeHQpLmNhbGwodGhpcywgbyk7CiAgICBlbHNlIHsKICAgICAgY29uc3QgeyBnbDogdSwgZXh0OiB2IH0gPSBWdChlLCBhKTsKICAgICAgbCh0aGlzLCBHLCB1KSwgbCh0aGlzLCB6ZSwgdiksIGwodGhpcywgZmUsIEZ0KHUpKSwgbCh0aGlzLCBVZSwgTHQodSkpLCB1LmNsZWFyQ29sb3IoMCwgMCwgMCwgYSA/IDAgOiAxKTsKICAgIH0KICB9CiAgLyoqCiAgICogV2ViR1BVLWZpcnN0IGZhY3RvcnkuIFRyaWVzIFdlYkdQVSwgZmFsbHMgYmFjayB0byBXZWJHTDIg4oaSIFdlYkdMMS4KICAgKiBUaGlzIGlzIHRoZSByZWNvbW1lbmRlZCBlbnRyeSBwb2ludCB3aGVuIFdlYkdQVSBzdXBwb3J0IGlzIGRlc2lyZWQuCiAgICovCiAgc3RhdGljIGFzeW5jIGNyZWF0ZShlLCByID0ge30sIHMgPSB7fSwgbyA9ICEwLCBhID0gITApIHsKICAgIGNvbnN0IHUgPSBvID8gYXdhaXQgUHQoZSwgYSkgOiBudWxsOwogICAgcmV0dXJuIG5ldyB1dChlLCByLCBzLCB1ID8/IHZvaWQgMCwgYSk7CiAgfQogIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFB1YmxpYyBBUEkKICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICBzZXRUZXh0U291cmNlKGUpIHsKICAgIGwodGhpcywgQywgeyB0eXBlOiAidGV4dCIsIG9wdHM6IGUgfSksIFModGhpcywgd2UsIFBlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIG5lLCBFZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBSZSwgRmUpLmNhbGwodGhpcyk7CiAgfQogIGFzeW5jIHNldEltYWdlU291cmNlKGUsIHIgPSAwLCBzID0gImNvdmVyIikgewogICAgY29uc3QgbyA9IGF3YWl0IHJyKGUpOwogICAgaWYgKHQodGhpcywgWGUpKSB7CiAgICAgIG8uY2xvc2UoKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgbCh0aGlzLCBDLCB7IHR5cGU6ICJpbWFnZSIsIGJpdG1hcDogbywgZWZmZWN0OiByLCBzaXplOiBzIH0pLCBTKHRoaXMsIHdlLCBQZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBuZSwgRWUpLmNhbGwodGhpcyksIFModGhpcywgUmUsIEZlKS5jYWxsKHRoaXMpOwogIH0KICBzZXRJbWFnZUJpdG1hcChlLCByID0gMCwgcyA9ICJjb3ZlciIpIHsKICAgIGwodGhpcywgQywgeyB0eXBlOiAiaW1hZ2UiLCBiaXRtYXA6IGUsIGVmZmVjdDogciwgc2l6ZTogcyB9KSwgUyh0aGlzLCB3ZSwgUGUpLmNhbGwodGhpcyksIFModGhpcywgbmUsIEVlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIFJlLCBGZSkuY2FsbCh0aGlzKTsKICB9CiAgc2V0QmFja2dyb3VuZChlLCByID0gImNvdmVyIikgewogICAgdCh0aGlzLCBBKSAmJiB0KHRoaXMsIEEpICE9PSBlICYmIHQodGhpcywgQSkuY2xvc2UoKSwgbCh0aGlzLCBBLCBlKSwgbCh0aGlzLCB1ZSwgciA/PyAiY292ZXIiKSwgdCh0aGlzLCBDKSAmJiB0KHRoaXMsIHcpID4gMCAmJiB0KHRoaXMsIFUpID4gMCAmJiBTKHRoaXMsIG5lLCBFZSkuY2FsbCh0aGlzKTsKICB9CiAgaGFuZGxlTW92ZShlLCByLCBzID0gMSkgewogICAgdCh0aGlzLCBoKS5tb3ZlZCA9ICEwLCB0KHRoaXMsIGgpLmR4ID0gKGUgLSB0KHRoaXMsIGgpLnRhcmdldFgpICogcywgdCh0aGlzLCBoKS5keSA9IChyIC0gdCh0aGlzLCBoKS50YXJnZXRZKSAqIHMsIHQodGhpcywgaCkudGFyZ2V0WCA9IGUsIHQodGhpcywgaCkudGFyZ2V0WSA9IHI7CiAgfQogIC8qKgogICAqIEltbWVkaWF0ZWx5IGFwcGxpZXMgb25lIGZsdWlkIHNwbGF0IGF0ICh4LCB5KSB3aXRoIGV4cGxpY2l0IHZlbG9jaXR5ICh2eCwgdnkpLgogICAqIFNhZmUgdG8gY2FsbCBtdWx0aXBsZSB0aW1lcyBwZXIgZnJhbWUg4oCUIGVhY2ggY2FsbCB3cml0ZXMgZGlyZWN0bHkgdG8gdGhlIEZCT3MuCiAgICogRGVzaWduZWQgZm9yIHByb2dyYW1tYXRpYyB1c2UgY2FzZXMgKGUuZy4gcGFydGljbGUgc3lzdGVtcywgYXR0cmFjdG9yIHBhdGhzKQogICAqIHdoZXJlIHlvdSB3YW50IE4gaW5kZXBlbmRlbnQgaW5qZWN0aW9uIHBvaW50cyBwZXIgZnJhbWUgd2l0aG91dCBmbG9vZGluZyB0aGUKICAgKiBtb3VzZS1zdGF0ZSBtYWNoaW5lIG9yIHRoZSB3b3JrZXIgbWVzc2FnZSBxdWV1ZS4KICAgKi8KICBzcGxhdChlLCByLCBzLCBvLCBhID0gMSkgewogICAgIXQodGhpcywgeWUpIHx8IHQodGhpcywgdykgPT09IDAgfHwgKHQodGhpcywgVikgPyBTKHRoaXMsIEtlLCBkdCkuY2FsbCh0aGlzLCBlLCByLCBzLCBvLCBhKSA6IFModGhpcywgSmUsIGh0KS5jYWxsKHRoaXMsIGUsIHIsIHMsIG8sIGEpKTsKICB9CiAgdXBkYXRlUXVhbGl0eShlKSB7CiAgICBlLmRwciAhPT0gdm9pZCAwICYmIGwodGhpcywgQ2UsIE1hdGgubWF4KDAuMSwgTWF0aC5taW4oMSwgZS5kcHIpKSksIGUuc2ltICE9PSB2b2lkIDAgJiYgbCh0aGlzLCBlZSwgTWF0aC5tYXgoMC4xLCBNYXRoLm1pbigxLCBlLnNpbSkpKTsKICB9CiAgcmVzaXplKGUsIHIsIHMpIHsKICAgIGlmIChzICE9PSB2b2lkIDAgPyBsKHRoaXMsIFAsIHMpIDogdHlwZW9mIHdpbmRvdyA8ICJ1IiAmJiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyAmJiBsKHRoaXMsIFAsIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKSwgZSAhPT0gdm9pZCAwICYmIGUgPiAwKSB7CiAgICAgIGlmIChyID09PSB2b2lkIDAgfHwgciA8PSAwKQogICAgICAgIHJldHVybjsKICAgICAgbCh0aGlzLCB3LCB0KHRoaXMsIGNlKS53aWR0aCA9IGUpLCBsKHRoaXMsIFUsIHQodGhpcywgY2UpLmhlaWdodCA9IHIpLCBsKHRoaXMsIE0sIE1hdGgubWF4KDEsIE1hdGgucm91bmQoZSAqIHQodGhpcywgZWUpKSkpLCBsKHRoaXMsIEksIE1hdGgubWF4KDEsIE1hdGgucm91bmQociAqIHQodGhpcywgZWUpKSkpLCBTKHRoaXMsIEdlLCBzdCkuY2FsbCh0aGlzKTsKICAgIH0gZWxzZQogICAgICBTKHRoaXMsIHdlLCBQZSkuY2FsbCh0aGlzKTsKICAgIHQodGhpcywgQykgJiYgUyh0aGlzLCBuZSwgRWUpLmNhbGwodGhpcyksIFModGhpcywgUmUsIEZlKS5jYWxsKHRoaXMpOwogIH0KICB1cGRhdGVDb25maWcoZSkgewogICAgT2JqZWN0LmFzc2lnbih0KHRoaXMsIHRlKSwgZSk7CiAgfQogIGRlc3Ryb3koKSB7CiAgICB2YXIgZSwgciwgcywgbywgYSwgdSwgdiwgbSwgYywgcCwgeDsKICAgIGlmIChsKHRoaXMsIFhlLCAhMCksIHRoaXMuc3RvcCgpLCBTKHRoaXMsIE1lLCBvdCkuY2FsbCh0aGlzKSwgUyh0aGlzLCBJZSwgYXQpLmNhbGwodGhpcyksIHQodGhpcywgQSkgJiYgKHQodGhpcywgQSkuY2xvc2UoKSwgbCh0aGlzLCBBLCBudWxsKSksIHQodGhpcywgVikpCiAgICAgIChlID0gdCh0aGlzLCB4ZSkpID09IG51bGwgfHwgZS5kZXN0cm95KCksIChyID0gdCh0aGlzLCBwZSkpID09IG51bGwgfHwgci5kZXN0cm95KCksIChzID0gdCh0aGlzLCBtZSkpID09IG51bGwgfHwgcy5kZXN0cm95KCksIChvID0gdCh0aGlzLCBkZSkpID09IG51bGwgfHwgby5kZXN0cm95KCksIChhID0gdCh0aGlzLCBoZSkpID09IG51bGwgfHwgYS5kZXN0cm95KCksICh1ID0gdCh0aGlzLCBKKSkgPT0gbnVsbCB8fCB1LmRlc3Ryb3koKSwgKHYgPSB0KHRoaXMsIFopKSA9PSBudWxsIHx8IHYuZGVzdHJveSgpLCAobSA9IHQodGhpcywgZ2UpKSA9PSBudWxsIHx8IG0uZGVzdHJveSgpLCAoYyA9IHQodGhpcywgYmUpKSA9PSBudWxsIHx8IGMuZGVzdHJveSgpLCAocCA9IHQodGhpcywgVGUpKSA9PSBudWxsIHx8IHAuZGVzdHJveSgpLCAoeCA9IHQodGhpcywgdmUpKSA9PSBudWxsIHx8IHguZGVzdHJveSgpLCB0KHRoaXMsIFYpLmRldmljZS5kZXN0cm95KCk7CiAgICBlbHNlIHsKICAgICAgY29uc3QgbiA9IHQodGhpcywgRyk7CiAgICAgIGZvciAoY29uc3QgYiBvZiBPYmplY3QudmFsdWVzKHQodGhpcywgZmUpKSkKICAgICAgICBiLmRpc3Bvc2UoKTsKICAgICAgY29uc3QgZCA9IG4uZ2V0RXh0ZW5zaW9uKCJXRUJHTF9sb3NlX2NvbnRleHQiKTsKICAgICAgZCA9PSBudWxsIHx8IGQubG9zZUNvbnRleHQoKTsKICAgIH0KICB9CiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gTG9vcCBjb250cm9sCiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgc3RhcnQoKSB7CiAgICBpZiAodCh0aGlzLCBqKSAhPT0gbnVsbCkKICAgICAgcmV0dXJuOwogICAgY29uc3QgZSA9ICgpID0+IHsKICAgICAgUyh0aGlzLCBRZSwgcHQpLmNhbGwodGhpcyksIGwodGhpcywgaiwgY3QoZSkpOwogICAgfTsKICAgIGwodGhpcywgaiwgY3QoZSkpOwogIH0KICBzdG9wKCkgewogICAgdCh0aGlzLCBqKSAhPT0gbnVsbCAmJiAoaXIodCh0aGlzLCBqKSksIGwodGhpcywgaiwgbnVsbCkpOwogIH0KICBnZXQgaXNSdW5uaW5nKCkgewogICAgcmV0dXJuIHQodGhpcywgaikgIT09IG51bGw7CiAgfQp9OwpjZSA9IG5ldyBXZWFrTWFwKCksIEcgPSBuZXcgV2Vha01hcCgpLCB6ZSA9IG5ldyBXZWFrTWFwKCksIGZlID0gbmV3IFdlYWtNYXAoKSwgVWUgPSBuZXcgV2Vha01hcCgpLCBCID0gbmV3IFdlYWtNYXAoKSwgUiA9IG5ldyBXZWFrTWFwKCksICQgPSBuZXcgV2Vha01hcCgpLCBxID0gbmV3IFdlYWtNYXAoKSwgSCA9IG5ldyBXZWFrTWFwKCksIEsgPSBuZXcgV2Vha01hcCgpLCBMID0gbmV3IFdlYWtNYXAoKSwgWSA9IG5ldyBXZWFrTWFwKCksIFYgPSBuZXcgV2Vha01hcCgpLCBEZSA9IG5ldyBXZWFrTWFwKCksIHZlID0gbmV3IFdlYWtNYXAoKSwgX2UgPSBuZXcgV2Vha01hcCgpLCBPID0gbmV3IFdlYWtNYXAoKSwgVCA9IG5ldyBXZWFrTWFwKCksIG9lID0gbmV3IFdlYWtNYXAoKSwgUSA9IG5ldyBXZWFrTWFwKCksIGFlID0gbmV3IFdlYWtNYXAoKSwgeiA9IG5ldyBXZWFrTWFwKCksIHhlID0gbmV3IFdlYWtNYXAoKSwgcGUgPSBuZXcgV2Vha01hcCgpLCBtZSA9IG5ldyBXZWFrTWFwKCksIGRlID0gbmV3IFdlYWtNYXAoKSwgaGUgPSBuZXcgV2Vha01hcCgpLCBKID0gbmV3IFdlYWtNYXAoKSwgWiA9IG5ldyBXZWFrTWFwKCksIGdlID0gbmV3IFdlYWtNYXAoKSwgYmUgPSBuZXcgV2Vha01hcCgpLCBUZSA9IG5ldyBXZWFrTWFwKCksIHcgPSBuZXcgV2Vha01hcCgpLCBVID0gbmV3IFdlYWtNYXAoKSwgTSA9IG5ldyBXZWFrTWFwKCksIEkgPSBuZXcgV2Vha01hcCgpLCBQID0gbmV3IFdlYWtNYXAoKSwgQ2UgPSBuZXcgV2Vha01hcCgpLCBlZSA9IG5ldyBXZWFrTWFwKCksIEEgPSBuZXcgV2Vha01hcCgpLCB1ZSA9IG5ldyBXZWFrTWFwKCksIHRlID0gbmV3IFdlYWtNYXAoKSwgaCA9IG5ldyBXZWFrTWFwKCksIEMgPSBuZXcgV2Vha01hcCgpLCBqID0gbmV3IFdlYWtNYXAoKSwgeWUgPSBuZXcgV2Vha01hcCgpLCBYZSA9IG5ldyBXZWFrTWFwKCksIFNlID0gbmV3IFdlYWtNYXAoKSwgWWUgPSBuZXcgV2Vha1NldCgpLCB4dCA9IGZ1bmN0aW9uKGUpIHsKICBjb25zdCB7IGRldmljZTogciwgZm9ybWF0OiBzIH0gPSBlOwogIGwodGhpcywgRGUsIEh0KHIsIHMsIHQodGhpcywgU2UpKSksIGwodGhpcywgdmUsICR0KHIpKSwgbCh0aGlzLCBfZSwgWXQocikpLCBsKHRoaXMsIHhlLCBXKHIsIDE2KSksIGwodGhpcywgcGUsIFcociwgMTYpKSwgbCh0aGlzLCBtZSwgVyhyLCAxNikpLCBsKHRoaXMsIGRlLCBXKHIsIDE2KSksIGwodGhpcywgaGUsIFcociwgMTYpKSwgbCh0aGlzLCBKLCBXKHIsIDQ4KSksIGwodGhpcywgWiwgVyhyLCA0OCkpLCBsKHRoaXMsIGdlLCBXKHIsIDE2KSksIGwodGhpcywgYmUsIFcociwgMTYpKSwgbCh0aGlzLCBUZSwgVyhyLCA2NCkpOwp9LCB3ZSA9IG5ldyBXZWFrU2V0KCksIFBlID0gZnVuY3Rpb24oKSB7CiAgY29uc3QgZSA9IHQodGhpcywgY2UpOwogICJjbGllbnRXaWR0aCIgaW4gZSAmJiBlLmNsaWVudFdpZHRoID4gMCA/IChsKHRoaXMsIFAsICh0eXBlb2Ygd2luZG93IDwgInUiICYmIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDEpICogdCh0aGlzLCBDZSkpLCBsKHRoaXMsIHcsIGUud2lkdGggPSBNYXRoLnJvdW5kKGUuY2xpZW50V2lkdGggKiB0KHRoaXMsIFApKSksIGwodGhpcywgVSwgZS5oZWlnaHQgPSBNYXRoLnJvdW5kKGUuY2xpZW50SGVpZ2h0ICogdCh0aGlzLCBQKSkpKSA6IChsKHRoaXMsIHcsIGUud2lkdGgpLCBsKHRoaXMsIFUsIGUuaGVpZ2h0KSksICEodCh0aGlzLCB3KSA9PT0gMCB8fCB0KHRoaXMsIFUpID09PSAwKSAmJiAobCh0aGlzLCBNLCBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKHQodGhpcywgdykgKiB0KHRoaXMsIGVlKSkpKSwgbCh0aGlzLCBJLCBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKHQodGhpcywgVSkgKiB0KHRoaXMsIGVlKSkpKSwgUyh0aGlzLCBHZSwgc3QpLmNhbGwodGhpcykpOwp9LCBHZSA9IG5ldyBXZWFrU2V0KCksIHN0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKFModGhpcywgTWUsIG90KS5jYWxsKHRoaXMpLCB0KHRoaXMsIFYpKSB7CiAgICBjb25zdCB7IGRldmljZTogZSB9ID0gdCh0aGlzLCBWKSwgciA9ICJyZ2JhMTZmbG9hdCIsIHMgPSB0KHRoaXMsIE0pLCBvID0gdCh0aGlzLCBJKTsKICAgIGwodGhpcywgTywgcnQoZSwgciwgcywgbykpLCBsKHRoaXMsIFQsIHJ0KGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBRLCBydChlLCByLCBzLCBvKSksIGwodGhpcywgb2UsIEhlKGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBhZSwgSGUoZSwgciwgcywgbykpOwogIH0gZWxzZSB7CiAgICBjb25zdCBlID0gdCh0aGlzLCBHKSwgciA9IHQodGhpcywgemUpLCBzID0gdCh0aGlzLCBNKSwgbyA9IHQodGhpcywgSSk7CiAgICBsKHRoaXMsIEIsIHR0KGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBSLCB0dChlLCByLCBzLCBvKSksIGwodGhpcywgcSwgdHQoZSwgciwgcywgbykpLCBsKHRoaXMsICQsIHFlKGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBILCBxZShlLCByLCBzLCBvKSk7CiAgfQp9LCBuZSA9IG5ldyBXZWFrU2V0KCksIEVlID0gZnVuY3Rpb24oKSB7CiAgaWYgKCEoIXQodGhpcywgQykgfHwgdCh0aGlzLCB3KSA9PT0gMCB8fCB0KHRoaXMsIFUpID09PSAwKSkgewogICAgaWYgKFModGhpcywgSWUsIGF0KS5jYWxsKHRoaXMpLCB0KHRoaXMsIFYpKSB7CiAgICAgIGNvbnN0IHsgZGV2aWNlOiBlIH0gPSB0KHRoaXMsIFYpOwogICAgICB0KHRoaXMsIEMpLnR5cGUgPT09ICJ0ZXh0IiA/IGwodGhpcywgeiwgZXIoCiAgICAgICAgZSwKICAgICAgICB0KHRoaXMsIHcpLAogICAgICAgIHQodGhpcywgVSksCiAgICAgICAgdCh0aGlzLCBDKS5vcHRzLAogICAgICAgIHQodGhpcywgQSksCiAgICAgICAgdCh0aGlzLCB1ZSkKICAgICAgKSkgOiBsKHRoaXMsIHosIHRyKAogICAgICAgIGUsCiAgICAgICAgdCh0aGlzLCBDKS5iaXRtYXAsCiAgICAgICAgdCh0aGlzLCB3KSwKICAgICAgICB0KHRoaXMsIFUpLAogICAgICAgIHQodGhpcywgQykuZWZmZWN0LAogICAgICAgIHQodGhpcywgQykuc2l6ZSwKICAgICAgICB0KHRoaXMsIEEpLAogICAgICAgIHQodGhpcywgdWUpCiAgICAgICkpOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgZSA9IHQodGhpcywgRyk7CiAgICAgIGlmICh0KHRoaXMsIEMpLnR5cGUgPT09ICJ0ZXh0IikgewogICAgICAgIGNvbnN0IHsgYmFja2dyb3VuZFRleDogciwgb2JzdGFjbGVUZXg6IHMsIGNvdmVyYWdlVGV4OiBvIH0gPSBKdCgKICAgICAgICAgIGUsCiAgICAgICAgICB0KHRoaXMsIHcpLAogICAgICAgICAgdCh0aGlzLCBVKSwKICAgICAgICAgIHQodGhpcywgQykub3B0cywKICAgICAgICAgIHQodGhpcywgQSksCiAgICAgICAgICB0KHRoaXMsIHVlKQogICAgICAgICk7CiAgICAgICAgbCh0aGlzLCBLLCByKSwgbCh0aGlzLCBMLCBzKSwgbCh0aGlzLCBZLCBvKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCB7IGJhY2tncm91bmRUZXg6IHIsIG9ic3RhY2xlVGV4OiBzLCBjb3ZlcmFnZVRleDogbyB9ID0gWnQoCiAgICAgICAgICBlLAogICAgICAgICAgdCh0aGlzLCBDKS5iaXRtYXAsCiAgICAgICAgICB0KHRoaXMsIHcpLAogICAgICAgICAgdCh0aGlzLCBVKSwKICAgICAgICAgIHQodGhpcywgQykuZWZmZWN0LAogICAgICAgICAgdCh0aGlzLCBDKS5zaXplLAogICAgICAgICAgdCh0aGlzLCBBKSwKICAgICAgICAgIHQodGhpcywgdWUpCiAgICAgICAgKTsKICAgICAgICBsKHRoaXMsIEssIHIpLCBsKHRoaXMsIEwsIHMpLCBsKHRoaXMsIFksIG8pOwogICAgICB9CiAgICB9CiAgICBsKHRoaXMsIHllLCAhMCk7CiAgfQp9LCBSZSA9IG5ldyBXZWFrU2V0KCksIEZlID0gZnVuY3Rpb24oKSB7CiAgdCh0aGlzLCB5ZSkgJiYgIXRoaXMuaXNSdW5uaW5nICYmIHRoaXMuc3RhcnQoKTsKfSwgTWUgPSBuZXcgV2Vha1NldCgpLCBvdCA9IGZ1bmN0aW9uKCkgewogIHZhciBlLCByLCBzLCBvLCBhLCB1LCB2LCBtOwogIGlmICh0KHRoaXMsIFYpKQogICAgKGUgPSB0KHRoaXMsIE8pKSA9PSBudWxsIHx8IGUuZGlzcG9zZSgpLCAociA9IHQodGhpcywgVCkpID09IG51bGwgfHwgci5kaXNwb3NlKCksIChzID0gdCh0aGlzLCBRKSkgPT0gbnVsbCB8fCBzLmRpc3Bvc2UoKSwgKG8gPSB0KHRoaXMsIG9lKSkgPT0gbnVsbCB8fCBvLnRleC5kZXN0cm95KCksIChhID0gdCh0aGlzLCBhZSkpID09IG51bGwgfHwgYS50ZXguZGVzdHJveSgpLCBsKHRoaXMsIE8sIGwodGhpcywgVCwgbCh0aGlzLCBRLCBudWxsKSkpLCBsKHRoaXMsIG9lLCBsKHRoaXMsIGFlLCBudWxsKSk7CiAgZWxzZSB7CiAgICBjb25zdCBjID0gdCh0aGlzLCBHKTsKICAgICh1ID0gdCh0aGlzLCBCKSkgPT0gbnVsbCB8fCB1LmRpc3Bvc2UoKSwgKHYgPSB0KHRoaXMsIFIpKSA9PSBudWxsIHx8IHYuZGlzcG9zZSgpLCAobSA9IHQodGhpcywgcSkpID09IG51bGwgfHwgbS5kaXNwb3NlKCksIHQodGhpcywgJCkgJiYgKGMuZGVsZXRlVGV4dHVyZSh0KHRoaXMsICQpLnRleCksIGMuZGVsZXRlRnJhbWVidWZmZXIodCh0aGlzLCAkKS5mYm8pKSwgdCh0aGlzLCBIKSAmJiAoYy5kZWxldGVUZXh0dXJlKHQodGhpcywgSCkudGV4KSwgYy5kZWxldGVGcmFtZWJ1ZmZlcih0KHRoaXMsIEgpLmZibykpLCBsKHRoaXMsIEIsIGwodGhpcywgUiwgbCh0aGlzLCBxLCBsKHRoaXMsICQsIGwodGhpcywgSCwgbnVsbCkpKSkpOwogIH0KfSwgSWUgPSBuZXcgV2Vha1NldCgpLCBhdCA9IGZ1bmN0aW9uKCkgewogIGlmICh0KHRoaXMsIFYpKQogICAgdCh0aGlzLCB6KSAmJiAodCh0aGlzLCB6KS5iYWNrZ3JvdW5kVGV4LmRlc3Ryb3koKSwgdCh0aGlzLCB6KS5vYnN0YWNsZVRleC5kZXN0cm95KCksIHQodGhpcywgeikuc2hhcmVkQ292ZXJhZ2UgfHwgdCh0aGlzLCB6KS5jb3ZlcmFnZVRleC5kZXN0cm95KCksIGwodGhpcywgeiwgbnVsbCkpOwogIGVsc2UgewogICAgY29uc3QgZSA9IHQodGhpcywgRyk7CiAgICB0KHRoaXMsIEspICYmIGUuZGVsZXRlVGV4dHVyZSh0KHRoaXMsIEspKSwgdCh0aGlzLCBMKSAmJiBlLmRlbGV0ZVRleHR1cmUodCh0aGlzLCBMKSksIHQodGhpcywgWSkgJiYgdCh0aGlzLCBZKSAhPT0gdCh0aGlzLCBMKSAmJiBlLmRlbGV0ZVRleHR1cmUodCh0aGlzLCBZKSksIGwodGhpcywgSywgbCh0aGlzLCBMLCBsKHRoaXMsIFksIG51bGwpKSk7CiAgfQp9LCBRZSA9IG5ldyBXZWFrU2V0KCksIHB0ID0gZnVuY3Rpb24oKSB7CiAgIXQodGhpcywgeWUpIHx8IHQodGhpcywgdykgPT09IDAgfHwgKHQodGhpcywgVikgPyBTKHRoaXMsIGplLCBtdCkuY2FsbCh0aGlzKSA6IFModGhpcywgWmUsIGd0KS5jYWxsKHRoaXMpKTsKfSwgamUgPSBuZXcgV2Vha1NldCgpLCBtdCA9IGZ1bmN0aW9uKCkgewogIGNvbnN0IGUgPSB0KHRoaXMsIFYpLCByID0gZS5kZXZpY2UsIHMgPSB0KHRoaXMsIERlKSwgbyA9IHQodGhpcywgdmUpLCBhID0gdCh0aGlzLCBfZSksIHUgPSB0KHRoaXMsIHRlKSwgdiA9IHQodGhpcywgeik7CiAgaWYgKCF0KHRoaXMsIE8pIHx8ICF0KHRoaXMsIFQpKQogICAgcmV0dXJuOwogIHQodGhpcywgaCkueCArPSAodCh0aGlzLCBoKS50YXJnZXRYIC0gdCh0aGlzLCBoKS54KSAqIDAuMTUsIHQodGhpcywgaCkueSArPSAodCh0aGlzLCBoKS50YXJnZXRZIC0gdCh0aGlzLCBoKS55KSAqIDAuMTU7CiAgY29uc3QgbSA9IHQodGhpcywgTSksIGMgPSB0KHRoaXMsIEkpLCBwID0gdCh0aGlzLCB3KSwgeCA9IHQodGhpcywgVSksIG4gPSAxIC8gbSwgZCA9IDEgLyBjOwogIGx0KHIsIHQodGhpcywgeGUpLCBuLCBkLCBWZSwgdS52ZWxvY2l0eURpc3NpcGF0aW9uKSwgTmUociwgdCh0aGlzLCBtZSksIG4sIGQpLCBOZShyLCB0KHRoaXMsIGRlKSwgbiwgZCksIE5lKHIsIHQodGhpcywgaGUpLCBuLCBkKSwgTmUociwgdCh0aGlzLCBnZSksIG4sIGQpLCBRdChyLCB0KHRoaXMsIGJlKSwgbiwgZCwgdS5jdXJsLCBWZSksIGp0KAogICAgciwKICAgIHQodGhpcywgVGUpLAogICAgMSAvIHAsCiAgICAxIC8geCwKICAgIHUucmVmcmFjdGlvbiwKICAgIHUuc3BlY3VsYXJFeHAsCiAgICBXZSh1LndhdGVyQ29sb3IpLAogICAgV2UodS5nbG93Q29sb3IpLAogICAgdS5zaGluZSwKICAgIHUud2FycFN0cmVuZ3RoID8/IDAuMDE1LAogICAgZnRbdS5hbGdvcml0aG1dID8/IDAsCiAgICB0KHRoaXMsIFNlKQogICk7CiAgY29uc3QgYiA9IHIuY3JlYXRlQ29tbWFuZEVuY29kZXIoKSwgeSA9IChnLCBfKSA9PiByLmNyZWF0ZUJpbmRHcm91cCh7IGxheW91dDogZy5nZXRCaW5kR3JvdXBMYXlvdXQoMCksIGVudHJpZXM6IF8gfSksIEQgPSB7IGJpbmRpbmc6IDEsIHJlc291cmNlOiBhIH07CiAgewogICAgY29uc3QgZyA9IHkocy5hZHZlY3Rpb24sIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgeGUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA0LCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuYWR2ZWN0aW9uLCBnLCBvLCB0KHRoaXMsIFQpLndyaXRlLnZpZXcpOwogIH0KICB0KHRoaXMsIFQpLnN3YXAoKTsKICB7CiAgICBsdChyLCB0KHRoaXMsIHBlKSwgbiwgZCwgVmUsIHUuZGVuc2l0eURpc3NpcGF0aW9uKTsKICAgIGNvbnN0IGcgPSB5KHMuYWR2ZWN0aW9uLCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIHBlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHQodGhpcywgTykucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogNCwgcmVzb3VyY2U6IHYub2JzdGFjbGVWaWV3IH0KICAgIF0pOwogICAgWChiLCBzLmFkdmVjdGlvbiwgZywgbywgdCh0aGlzLCBPKS53cml0ZS52aWV3KTsKICB9CiAgdCh0aGlzLCBPKS5zd2FwKCk7CiAgewogICAgY29uc3QgZyA9IHkocy5jdXJsLCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIGdlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0KICAgIF0pOwogICAgWChiLCBzLmN1cmwsIGcsIG8sIHQodGhpcywgYWUpLnZpZXcpOwogIH0KICB7CiAgICBjb25zdCBnID0geShzLnZvcnRpY2l0eSwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBiZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB0KHRoaXMsIGFlKS52aWV3IH0KICAgIF0pOwogICAgWChiLCBzLnZvcnRpY2l0eSwgZywgbywgdCh0aGlzLCBUKS53cml0ZS52aWV3KTsKICB9CiAgaWYgKHQodGhpcywgVCkuc3dhcCgpLCB0KHRoaXMsIGgpLm1vdmVkKSB7CiAgICBjb25zdCBnID0gdCh0aGlzLCBoKS54ICogdCh0aGlzLCBQKSAvIHAsIF8gPSB0KHRoaXMsIGgpLnkgKiB0KHRoaXMsIFApIC8geDsKICAgICRlKAogICAgICByLAogICAgICB0KHRoaXMsIEopLAogICAgICBuLAogICAgICBkLAogICAgICBwIC8geCwKICAgICAgdS5zcGxhdFJhZGl1cywKICAgICAgdCh0aGlzLCBoKS5keCAqIHUuc3BsYXRGb3JjZSwKICAgICAgdCh0aGlzLCBoKS5keSAqIHUuc3BsYXRGb3JjZSwKICAgICAgMCwKICAgICAgZywKICAgICAgXwogICAgKTsKICAgIHsKICAgICAgY29uc3QgRiA9IHkocy5zcGxhdCwgWwogICAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIEopIH0gfSwKICAgICAgICBELAogICAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0KICAgICAgXSk7CiAgICAgIFgoYiwgcy5zcGxhdCwgRiwgbywgdCh0aGlzLCBUKS53cml0ZS52aWV3KTsKICAgIH0KICAgIHQodGhpcywgVCkuc3dhcCgpLCAkZSgKICAgICAgciwKICAgICAgdCh0aGlzLCBaKSwKICAgICAgbiwKICAgICAgZCwKICAgICAgcCAvIHgsCiAgICAgIHUuc3BsYXRSYWRpdXMsCiAgICAgIDEsCiAgICAgIDEsCiAgICAgIDEsCiAgICAgIGcsCiAgICAgIF8KICAgICk7CiAgICB7CiAgICAgIGNvbnN0IEYgPSB5KHMuc3BsYXQsIFsKICAgICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBaKSB9IH0sCiAgICAgICAgRCwKICAgICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIE8pLnJlYWQudmlldyB9CiAgICAgIF0pOwogICAgICBYKGIsIHMuc3BsYXQsIEYsIG8sIHQodGhpcywgTykud3JpdGUudmlldyk7CiAgICB9CiAgICB0KHRoaXMsIE8pLnN3YXAoKSwgdCh0aGlzLCBoKS5tb3ZlZCA9ICExOwogIH0KICB7CiAgICBjb25zdCBnID0geShzLmRpdmVyZ2VuY2UsIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgbWUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuZGl2ZXJnZW5jZSwgZywgbywgdCh0aGlzLCBvZSkudmlldyk7CiAgfQogIGZvciAobGV0IGcgPSAwOyBnIDwgdS5wcmVzc3VyZUl0ZXJhdGlvbnM7IGcrKykgewogICAgY29uc3QgXyA9IHkocy5wcmVzc3VyZSwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBkZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFEpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB0KHRoaXMsIG9lKS52aWV3IH0sCiAgICAgIHsgYmluZGluZzogNCwgcmVzb3VyY2U6IHYub2JzdGFjbGVWaWV3IH0KICAgIF0pOwogICAgWChiLCBzLnByZXNzdXJlLCBfLCBvLCB0KHRoaXMsIFEpLndyaXRlLnZpZXcpLCB0KHRoaXMsIFEpLnN3YXAoKTsKICB9CiAgewogICAgY29uc3QgZyA9IHkocy5ncmFkaWVudFN1YnRyYWN0LCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIGhlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgUSkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogNCwgcmVzb3VyY2U6IHYub2JzdGFjbGVWaWV3IH0KICAgIF0pOwogICAgWChiLCBzLmdyYWRpZW50U3VidHJhY3QsIGcsIG8sIHQodGhpcywgVCkud3JpdGUudmlldyk7CiAgfQogIHQodGhpcywgVCkuc3dhcCgpOwogIHsKICAgIGNvbnN0IGcgPSBlLmNvbnRleHQuZ2V0Q3VycmVudFRleHR1cmUoKS5jcmVhdGVWaWV3KCksIF8gPSB5KHMuZGlzcGxheSwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBUZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIE8pLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB2Lm9ic3RhY2xlVmlldyB9LAogICAgICB7IGJpbmRpbmc6IDQsIHJlc291cmNlOiB2LmJhY2tncm91bmRWaWV3IH0sCiAgICAgIHsgYmluZGluZzogNSwgcmVzb3VyY2U6IHYuY292ZXJhZ2VWaWV3IH0sCiAgICAgIHsgYmluZGluZzogNiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0KICAgIF0pOwogICAgS3QoYiwgcy5kaXNwbGF5LCBfLCBvLCBnKTsKICB9CiAgci5xdWV1ZS5zdWJtaXQoW2IuZmluaXNoKCldKTsKfSwgS2UgPSBuZXcgV2Vha1NldCgpLCBkdCA9IGZ1bmN0aW9uKGUsIHIsIHMsIG8sIGEpIHsKICBjb25zdCB2ID0gdCh0aGlzLCBWKS5kZXZpY2UsIG0gPSB0KHRoaXMsIERlKS5zcGxhdCwgYyA9IHQodGhpcywgdmUpLCBwID0gdCh0aGlzLCBfZSksIHggPSB0KHRoaXMsIHRlKSwgbiA9IHQodGhpcywgTSksIGQgPSB0KHRoaXMsIEkpLCBiID0gMSAvIG4sIHkgPSAxIC8gZCwgRCA9IHYuY3JlYXRlQ29tbWFuZEVuY29kZXIoKSwgZyA9IHsgYmluZGluZzogMSwgcmVzb3VyY2U6IHAgfSwgXyA9IChPZSkgPT4gdi5jcmVhdGVCaW5kR3JvdXAoeyBsYXlvdXQ6IG0uZ2V0QmluZEdyb3VwTGF5b3V0KDApLCBlbnRyaWVzOiBPZSB9KSwgRiA9IGUgKiB0KHRoaXMsIFApIC8gdCh0aGlzLCB3KSwgayA9IHIgKiB0KHRoaXMsIFApIC8gdCh0aGlzLCBVKTsKICAkZSgKICAgIHYsCiAgICB0KHRoaXMsIEopLAogICAgYiwKICAgIHksCiAgICB0KHRoaXMsIHcpIC8gdCh0aGlzLCBVKSwKICAgIHguc3BsYXRSYWRpdXMsCiAgICBzICogeC5zcGxhdEZvcmNlICogYSwKICAgIG8gKiB4LnNwbGF0Rm9yY2UgKiBhLAogICAgMCwKICAgIEYsCiAgICBrCiAgKTsKICB7CiAgICBjb25zdCBPZSA9IF8oWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBKKSB9IH0sCiAgICAgIGcsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0KICAgIF0pOwogICAgWChELCBtLCBPZSwgYywgdCh0aGlzLCBUKS53cml0ZS52aWV3KTsKICB9CiAgdCh0aGlzLCBUKS5zd2FwKCksICRlKAogICAgdiwKICAgIHQodGhpcywgWiksCiAgICBiLAogICAgeSwKICAgIHQodGhpcywgdykgLyB0KHRoaXMsIFUpLAogICAgeC5zcGxhdFJhZGl1cywKICAgIGEsCiAgICBhLAogICAgYSwKICAgIEYsCiAgICBrCiAgKTsKICB7CiAgICBjb25zdCBPZSA9IF8oWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBaKSB9IH0sCiAgICAgIGcsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgTykucmVhZC52aWV3IH0KICAgIF0pOwogICAgWChELCBtLCBPZSwgYywgdCh0aGlzLCBPKS53cml0ZS52aWV3KTsKICB9CiAgdCh0aGlzLCBPKS5zd2FwKCksIHYucXVldWUuc3VibWl0KFtELmZpbmlzaCgpXSk7Cn0sIEplID0gbmV3IFdlYWtTZXQoKSwgaHQgPSBmdW5jdGlvbihlLCByLCBzLCBvLCBhKSB7CiAgY29uc3QgdSA9IHQodGhpcywgRyksIHYgPSB0KHRoaXMsIHRlKSwgbSA9IHQodGhpcywgZmUpLnNwbGF0LCBjID0gdCh0aGlzLCBVZSk7CiAgdS52aWV3cG9ydCgwLCAwLCB0KHRoaXMsIE0pLCB0KHRoaXMsIEkpKSwgbS5iaW5kKCksIHUudW5pZm9ybTFmKG0udW5pZm9ybXMuYXNwZWN0UmF0aW8sIHQodGhpcywgdykgLyB0KHRoaXMsIFUpKSwgdS51bmlmb3JtMmYobS51bmlmb3Jtcy5wb2ludCwgZSAqIHQodGhpcywgUCkgLyB0KHRoaXMsIHcpLCAxIC0gciAqIHQodGhpcywgUCkgLyB0KHRoaXMsIFUpKSwgdS51bmlmb3JtMWYobS51bmlmb3Jtcy5yYWRpdXMsIHYuc3BsYXRSYWRpdXMpLCB1LnVuaWZvcm0xaShtLnVuaWZvcm1zLnVUYXJnZXQsIDApLCB1LmFjdGl2ZVRleHR1cmUodS5URVhUVVJFMCksIHUuYmluZFRleHR1cmUodS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgdS51bmlmb3JtM2YobS51bmlmb3Jtcy5jb2xvciwgcyAqIHYuc3BsYXRGb3JjZSAqIGEsIC1vICogdi5zcGxhdEZvcmNlICogYSwgMCksIGModCh0aGlzLCBSKS53cml0ZS5mYm8pLCB0KHRoaXMsIFIpLnN3YXAoKSwgdS5hY3RpdmVUZXh0dXJlKHUuVEVYVFVSRTApLCB1LmJpbmRUZXh0dXJlKHUuVEVYVFVSRV8yRCwgdCh0aGlzLCBCKS5yZWFkLnRleCksIHUudW5pZm9ybTNmKG0udW5pZm9ybXMuY29sb3IsIGEsIGEsIGEpLCBjKHQodGhpcywgQikud3JpdGUuZmJvKSwgdCh0aGlzLCBCKS5zd2FwKCk7Cn0sIFplID0gbmV3IFdlYWtTZXQoKSwgZ3QgPSBmdW5jdGlvbigpIHsKICBpZiAoIXQodGhpcywgQikgfHwgIXQodGhpcywgUikpCiAgICByZXR1cm47CiAgY29uc3QgZSA9IHQodGhpcywgRyksIHIgPSB0KHRoaXMsIHRlKSwgeyBhZHZlY3Rpb246IHMsIGRpdmVyZ2VuY2U6IG8sIHByZXNzdXJlOiBhLCBncmFkaWVudFN1YnRyYWN0OiB1LCBzcGxhdDogdiwgY3VybDogbSwgdm9ydGljaXR5OiBjLCBkaXNwbGF5OiBwIH0gPSB0KHRoaXMsIGZlKTsKICB0KHRoaXMsIGgpLnggKz0gKHQodGhpcywgaCkudGFyZ2V0WCAtIHQodGhpcywgaCkueCkgKiAwLjE1LCB0KHRoaXMsIGgpLnkgKz0gKHQodGhpcywgaCkudGFyZ2V0WSAtIHQodGhpcywgaCkueSkgKiAwLjE1OwogIGNvbnN0IHggPSB0KHRoaXMsIE0pLCBuID0gdCh0aGlzLCBJKSwgZCA9IHQodGhpcywgVWUpOwogIGUudmlld3BvcnQoMCwgMCwgeCwgbiksIHMuYmluZCgpLCBlLnVuaWZvcm0yZihzLnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHgsIDEgLyBuKSwgZS51bmlmb3JtMWYocy51bmlmb3Jtcy5kdCwgVmUpLCBlLnVuaWZvcm0xaShzLnVuaWZvcm1zLnVPYnN0YWNsZSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgTCkpLCBlLnVuaWZvcm0xZihzLnVuaWZvcm1zLmRpc3NpcGF0aW9uLCByLnZlbG9jaXR5RGlzc2lwYXRpb24pLCBlLnVuaWZvcm0xaShzLnVuaWZvcm1zLnVWZWxvY2l0eSwgMSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUxKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBlLnVuaWZvcm0xaShzLnVuaWZvcm1zLnVTb3VyY2UsIDEpLCBkKHQodGhpcywgUikud3JpdGUuZmJvKSwgdCh0aGlzLCBSKS5zd2FwKCksIGUudW5pZm9ybTFmKHMudW5pZm9ybXMuZGlzc2lwYXRpb24sIHIuZGVuc2l0eURpc3NpcGF0aW9uKSwgZS51bmlmb3JtMWkocy51bmlmb3Jtcy51U291cmNlLCAyKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTIpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBCKS5yZWFkLnRleCksIGQodCh0aGlzLCBCKS53cml0ZS5mYm8pLCB0KHRoaXMsIEIpLnN3YXAoKSwgbS5iaW5kKCksIGUudW5pZm9ybTJmKG0udW5pZm9ybXMudGV4ZWxTaXplLCAxIC8geCwgMSAvIG4pLCBlLnVuaWZvcm0xaShtLnVuaWZvcm1zLnVWZWxvY2l0eSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBkKHQodGhpcywgSCkuZmJvKSwgYy5iaW5kKCksIGUudW5pZm9ybTJmKGMudW5pZm9ybXMudGV4ZWxTaXplLCAxIC8geCwgMSAvIG4pLCBlLnVuaWZvcm0xZihjLnVuaWZvcm1zLmN1cmwsIHIuY3VybCksIGUudW5pZm9ybTFmKGMudW5pZm9ybXMuZHQsIFZlKSwgZS51bmlmb3JtMWkoYy51bmlmb3Jtcy51VmVsb2NpdHksIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkoYy51bmlmb3Jtcy51Q3VybCwgMSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUxKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgSCkudGV4KSwgZCh0KHRoaXMsIFIpLndyaXRlLmZibyksIHQodGhpcywgUikuc3dhcCgpLCB0KHRoaXMsIGgpLm1vdmVkICYmICh2LmJpbmQoKSwgZS51bmlmb3JtMWYodi51bmlmb3Jtcy5hc3BlY3RSYXRpbywgdCh0aGlzLCB3KSAvIHQodGhpcywgVSkpLCBlLnVuaWZvcm0yZih2LnVuaWZvcm1zLnBvaW50LCB0KHRoaXMsIGgpLnggKiB0KHRoaXMsIFApIC8gdCh0aGlzLCB3KSwgMSAtIHQodGhpcywgaCkueSAqIHQodGhpcywgUCkgLyB0KHRoaXMsIFUpKSwgZS51bmlmb3JtMWYodi51bmlmb3Jtcy5yYWRpdXMsIHIuc3BsYXRSYWRpdXMpLCBlLnVuaWZvcm0xaSh2LnVuaWZvcm1zLnVUYXJnZXQsIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtM2Yodi51bmlmb3Jtcy5jb2xvciwgdCh0aGlzLCBoKS5keCAqIHIuc3BsYXRGb3JjZSwgLXQodGhpcywgaCkuZHkgKiByLnNwbGF0Rm9yY2UsIDApLCBkKHQodGhpcywgUikud3JpdGUuZmJvKSwgdCh0aGlzLCBSKS5zd2FwKCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgQikucmVhZC50ZXgpLCBlLnVuaWZvcm0zZih2LnVuaWZvcm1zLmNvbG9yLCAxLCAxLCAxKSwgZCh0KHRoaXMsIEIpLndyaXRlLmZibyksIHQodGhpcywgQikuc3dhcCgpLCB0KHRoaXMsIGgpLm1vdmVkID0gITEpLCBvLmJpbmQoKSwgZS51bmlmb3JtMmYoby51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyB4LCAxIC8gbiksIGUudW5pZm9ybTFpKG8udW5pZm9ybXMudVZlbG9jaXR5LCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKG8udW5pZm9ybXMudU9ic3RhY2xlLCAxKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSksIGQodCh0aGlzLCAkKS5mYm8pLCBhLmJpbmQoKSwgZS51bmlmb3JtMmYoYS51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyB4LCAxIC8gbiksIGUudW5pZm9ybTFpKGEudW5pZm9ybXMudURpdmVyZ2VuY2UsIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsICQpLnRleCksIGUudW5pZm9ybTFpKGEudW5pZm9ybXMudU9ic3RhY2xlLCAxKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSk7CiAgZm9yIChsZXQgYiA9IDA7IGIgPCByLnByZXNzdXJlSXRlcmF0aW9uczsgYisrKQogICAgZS51bmlmb3JtMWkoYS51bmlmb3Jtcy51UHJlc3N1cmUsIDIpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMiksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIHEpLnJlYWQudGV4KSwgZCh0KHRoaXMsIHEpLndyaXRlLmZibyksIHQodGhpcywgcSkuc3dhcCgpOwogIHUuYmluZCgpLCBlLnVuaWZvcm0yZih1LnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHgsIDEgLyBuKSwgZS51bmlmb3JtMWkodS51bmlmb3Jtcy51UHJlc3N1cmUsIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIHEpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkodS51bmlmb3Jtcy51VmVsb2NpdHksIDEpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkodS51bmlmb3Jtcy51T2JzdGFjbGUsIDIpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMiksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEwpKSwgZCh0KHRoaXMsIFIpLndyaXRlLmZibyksIHQodGhpcywgUikuc3dhcCgpLCBlLnZpZXdwb3J0KDAsIDAsIHQodGhpcywgdyksIHQodGhpcywgVSkpLCBlLmJpbmRGcmFtZWJ1ZmZlcihlLkZSQU1FQlVGRkVSLCBudWxsKSwgZS5jbGVhcihlLkNPTE9SX0JVRkZFUl9CSVQpLCBwLmJpbmQoKSwgZS51bmlmb3JtMmYocC51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyB0KHRoaXMsIHcpLCAxIC8gdCh0aGlzLCBVKSksIGUudW5pZm9ybTNmdihwLnVuaWZvcm1zLnVXYXRlckNvbG9yLCBXZShyLndhdGVyQ29sb3IpKSwgZS51bmlmb3JtM2Z2KHAudW5pZm9ybXMudUdsb3dDb2xvciwgV2Uoci5nbG93Q29sb3IpKSwgZS51bmlmb3JtMWYocC51bmlmb3Jtcy51UmVmcmFjdGlvbiwgci5yZWZyYWN0aW9uKSwgZS51bmlmb3JtMWYocC51bmlmb3Jtcy51U3BlY3VsYXJFeHAsIHIuc3BlY3VsYXJFeHApLCBlLnVuaWZvcm0xZihwLnVuaWZvcm1zLnVTaGluZSwgci5zaGluZSksIGUudW5pZm9ybTFmKHAudW5pZm9ybXMudVdhcnBTdHJlbmd0aCwgci53YXJwU3RyZW5ndGggPz8gMC4wMTUpLCBlLnVuaWZvcm0xaShwLnVuaWZvcm1zLnVBbGdvcml0aG0sIGZ0W3IuYWxnb3JpdGhtXSA/PyAwKSwgZS51bmlmb3JtMWkocC51bmlmb3Jtcy51RW5hYmxlQWxwaGEsIHQodGhpcywgU2UpID8gMSA6IDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEIpLnJlYWQudGV4KSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUyKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgSykpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMyksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFkpKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTQpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudVRleHR1cmUsIDApLCBlLnVuaWZvcm0xaShwLnVuaWZvcm1zLnVPYnN0YWNsZSwgMSksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudUJhY2tncm91bmQsIDIpLCBlLnVuaWZvcm0xaShwLnVuaWZvcm1zLnVDb3ZlcmFnZSwgMyksIGUudW5pZm9ybTFpKHAudW5pZm9ybXMudVZlbG9jaXR5LCA0KSwgZChudWxsKTsKfTsKbGV0IGl0ID0gdXQsIEUgPSBudWxsLCBidDsKY29uc3QgTiA9IG5ldyBQcm9taXNlKChpKSA9PiB7CiAgYnQgPSBpOwp9KTsKc2VsZi5vbm1lc3NhZ2UgPSBhc3luYyAoaSkgPT4gewogIGNvbnN0IHsgdHlwZTogZSwgLi4uciB9ID0gaS5kYXRhOwogIHRyeSB7CiAgICBzd2l0Y2ggKGUpIHsKICAgICAgY2FzZSAiaW5pdCI6IHsKICAgICAgICBjb25zdCB7IGNhbnZhczogcywgd2lkdGg6IG8sIGhlaWdodDogYSwgY29uZmlnOiB1LCBkcHI6IHYsIHF1YWxpdHk6IG0sIHVzZVdlYkdQVTogYywgZW5hYmxlQWxwaGE6IHAgfSA9IHI7CiAgICAgICAgcy53aWR0aCA9IG8sIHMuaGVpZ2h0ID0gYSwgRSA9IGF3YWl0IGl0LmNyZWF0ZShzLCB1LCBtID8/IHt9LCBjID8/ICEwLCBwID8/ICEwKSwgRS5yZXNpemUobywgYSwgdiB8fCAxKSwgYnQoKSwgc2VsZi5wb3N0TWVzc2FnZSh7IHR5cGU6ICJyZWFkeSIgfSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAic2V0VGV4dFNvdXJjZSI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS5zZXRUZXh0U291cmNlKHIub3B0cyk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAic2V0SW1hZ2VTb3VyY2UiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIGF3YWl0IEUuc2V0SW1hZ2VTb3VyY2UoCiAgICAgICAgICByLnNyYywKICAgICAgICAgIHIuZWZmZWN0LAogICAgICAgICAgci5zaXplCiAgICAgICAgKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzZXRJbWFnZUJpdG1hcCI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS5zZXRJbWFnZUJpdG1hcCgKICAgICAgICAgIHIuYml0bWFwLAogICAgICAgICAgci5lZmZlY3QsCiAgICAgICAgICByLnNpemUKICAgICAgICApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInNldEJhY2tncm91bmQiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUuc2V0QmFja2dyb3VuZChyLmJpdG1hcCwgci5zaXplKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzcGxhdCI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS5zcGxhdCgKICAgICAgICAgIHIueCwKICAgICAgICAgIHIueSwKICAgICAgICAgIHIudngsCiAgICAgICAgICByLnZ5LAogICAgICAgICAgci5zdHJlbmd0aCA/PyAxCiAgICAgICAgKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJtb3ZlIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLmhhbmRsZU1vdmUoci54LCByLnksIHIuc3RyZW5ndGggPz8gMSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAicmVzaXplIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnJlc2l6ZShyLndpZHRoLCByLmhlaWdodCwgci5kcHIpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInVwZGF0ZVF1YWxpdHkiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUudXBkYXRlUXVhbGl0eShyLnF1YWxpdHkpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInVwZGF0ZUNvbmZpZyI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS51cGRhdGVDb25maWcoci5jb25maWcpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgImRlc3Ryb3kiOiB7CiAgICAgICAgYXdhaXQgTiwgRSA9PSBudWxsIHx8IEUuZGVzdHJveSgpLCBFID0gbnVsbDsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBkZWZhdWx0OgogICAgICAgIGNvbnNvbGUud2FybigiW2ZsdWlkaXR5LWpzIHdvcmtlcl0gVW5rbm93biBtZXNzYWdlIHR5cGU6IiwgZSk7CiAgICB9CiAgfSBjYXRjaCAocykgewogICAgc2VsZi5wb3N0TWVzc2FnZSh7IHR5cGU6ICJlcnJvciIsIG1lc3NhZ2U6IChzID09IG51bGwgPyB2b2lkIDAgOiBzLm1lc3NhZ2UpID8/IFN0cmluZyhzKSB9KTsKICB9Cn07Cg==", qI = typeof window < "u" && window.Blob && new Blob([atob(cC)], { type: "text/javascript;charset=utf-8" });
|
|
@@ -1617,7 +1620,7 @@ function PC() {
|
|
|
1617
1620
|
}
|
|
1618
1621
|
}
|
|
1619
1622
|
const _C = typeof Worker < "u" && typeof OffscreenCanvas < "u";
|
|
1620
|
-
var v, f, qg, $g, Jg, q, ag, Lg, hg,
|
|
1623
|
+
var v, f, qg, $g, Jg, q, ag, Lg, hg, rI, TI, YI, dC;
|
|
1621
1624
|
class qC {
|
|
1622
1625
|
constructor(g, {
|
|
1623
1626
|
workerEnabled: C = !0,
|
|
@@ -1639,7 +1642,7 @@ class qC {
|
|
|
1639
1642
|
* this is the common path in jsdom/test environments and keeps the
|
|
1640
1643
|
* constructor behaviour synchronous where possible.
|
|
1641
1644
|
*/
|
|
1642
|
-
d(this,
|
|
1645
|
+
d(this, rI);
|
|
1643
1646
|
d(this, YI);
|
|
1644
1647
|
d(this, v, null);
|
|
1645
1648
|
d(this, f, null);
|
|
@@ -1651,7 +1654,7 @@ class qC {
|
|
|
1651
1654
|
// Pending source calls queued while WebGPU async init is in progress (main-thread only)
|
|
1652
1655
|
d(this, Lg, null);
|
|
1653
1656
|
d(this, hg, null);
|
|
1654
|
-
o(this, q, Math.max(0.1, Math.min(1, l.dpr ?? 1))), o(this, ag, Math.max(0.1, Math.min(1, l.sim ?? 0.5))), o(this, $g, i), o(this, Jg, s), o(this, qg, C && _C), I(this, qg) ? L(this, YI, dC).call(this, g, t) : L(this,
|
|
1657
|
+
o(this, q, Math.max(0.1, Math.min(1, l.dpr ?? 1))), o(this, ag, Math.max(0.1, Math.min(1, l.sim ?? 0.5))), o(this, $g, i), o(this, Jg, s), o(this, qg, C && _C), I(this, qg) ? L(this, YI, dC).call(this, g, t) : L(this, rI, TI).call(this, g, t);
|
|
1655
1658
|
}
|
|
1656
1659
|
// ---------------------------------------------------------------------------
|
|
1657
1660
|
// Source setters
|
|
@@ -1709,7 +1712,7 @@ class qC {
|
|
|
1709
1712
|
(g = I(this, f)) == null || g.destroy(), o(this, f, null);
|
|
1710
1713
|
}
|
|
1711
1714
|
}
|
|
1712
|
-
v = new WeakMap(), f = new WeakMap(), qg = new WeakMap(), $g = new WeakMap(), Jg = new WeakMap(), q = new WeakMap(), ag = new WeakMap(), Lg = new WeakMap(), hg = new WeakMap(),
|
|
1715
|
+
v = new WeakMap(), f = new WeakMap(), qg = new WeakMap(), $g = new WeakMap(), Jg = new WeakMap(), q = new WeakMap(), ag = new WeakMap(), Lg = new WeakMap(), hg = new WeakMap(), rI = new WeakSet(), TI = function(g, C) {
|
|
1713
1716
|
const i = { dpr: I(this, q), sim: I(this, ag) };
|
|
1714
1717
|
I(this, $g) && typeof navigator < "u" && !!navigator.gpu ? yI.create(g, C, i, !0, I(this, Jg)).then((l) => {
|
|
1715
1718
|
if (o(this, f, l), I(this, Lg))
|
|
@@ -1730,7 +1733,7 @@ v = new WeakMap(), f = new WeakMap(), qg = new WeakMap(), $g = new WeakMap(), Jg
|
|
|
1730
1733
|
} catch {
|
|
1731
1734
|
console.warn(
|
|
1732
1735
|
"[fluidity-js] OffscreenCanvas transfer failed — falling back to main-thread mode. This is expected in React StrictMode development."
|
|
1733
|
-
), o(this, qg, !1), L(this,
|
|
1736
|
+
), o(this, qg, !1), L(this, rI, TI).call(this, g, C);
|
|
1734
1737
|
return;
|
|
1735
1738
|
}
|
|
1736
1739
|
const S = o(this, v, new PC());
|
|
@@ -1751,7 +1754,7 @@ function SC(e, {
|
|
|
1751
1754
|
simResolution: l,
|
|
1752
1755
|
config: t = {}
|
|
1753
1756
|
} = {}) {
|
|
1754
|
-
const S = { dpr: s, sim: l }, u = Qg(null), c = Qg({ workerEnabled: g, quality: S, config: t }), p = Qg(Math.max(0.1, Math.min(1, s ?? 1))), a = Qg({
|
|
1757
|
+
const S = { dpr: s, sim: l }, u = Qg(null), c = Qg({ workerEnabled: g, quality: S, config: t }), p = Qg(Math.max(0.1, Math.min(1, s ?? gI.dpr ?? 1))), a = Qg({
|
|
1755
1758
|
pixelRatio: s,
|
|
1756
1759
|
simResolution: l
|
|
1757
1760
|
});
|
|
@@ -1773,17 +1776,17 @@ function SC(e, {
|
|
|
1773
1776
|
config: b
|
|
1774
1777
|
});
|
|
1775
1778
|
u.current = Q;
|
|
1776
|
-
const Tg = new ResizeObserver((
|
|
1777
|
-
for (const
|
|
1778
|
-
const zg = (window.devicePixelRatio || 1) * p.current, { inlineSize:
|
|
1779
|
-
Q.resize(Math.round(
|
|
1779
|
+
const Tg = new ResizeObserver((CI) => {
|
|
1780
|
+
for (const iI of CI) {
|
|
1781
|
+
const zg = (window.devicePixelRatio || 1) * p.current, { inlineSize: eI, blockSize: sI } = iI.contentBoxSize[0];
|
|
1782
|
+
Q.resize(Math.round(eI * zg), Math.round(sI * zg));
|
|
1780
1783
|
}
|
|
1781
1784
|
});
|
|
1782
1785
|
return Tg.observe(A), () => {
|
|
1783
1786
|
Tg.disconnect(), Q.destroy(), m.remove(), u.current = null;
|
|
1784
1787
|
};
|
|
1785
1788
|
}, [C, i]), tg(() => {
|
|
1786
|
-
p.current = Math.max(0.1, Math.min(1, s ?? 1));
|
|
1789
|
+
p.current = Math.max(0.1, Math.min(1, s ?? gI.dpr ?? 1));
|
|
1787
1790
|
const A = a.current;
|
|
1788
1791
|
a.current = { pixelRatio: s, simResolution: l };
|
|
1789
1792
|
const m = u.current, Z = e.current;
|
|
@@ -1811,34 +1814,34 @@ const Ci = gC(function({
|
|
|
1811
1814
|
workerEnabled: Z = mg.workerEnabled,
|
|
1812
1815
|
webGPUEnabled: r = !0,
|
|
1813
1816
|
alphaEnabled: b = !0,
|
|
1814
|
-
pixelRatio: B =
|
|
1815
|
-
simResolution: K =
|
|
1817
|
+
pixelRatio: B = gI.dpr,
|
|
1818
|
+
simResolution: K = gI.sim,
|
|
1816
1819
|
// FluidConfig flat props
|
|
1817
1820
|
densityDissipation: W,
|
|
1818
1821
|
velocityDissipation: x,
|
|
1819
1822
|
pressureIterations: Q,
|
|
1820
1823
|
curl: Tg,
|
|
1821
|
-
splatRadius:
|
|
1822
|
-
splatForce:
|
|
1824
|
+
splatRadius: CI,
|
|
1825
|
+
splatForce: iI,
|
|
1823
1826
|
refraction: zg,
|
|
1824
|
-
specularExp:
|
|
1825
|
-
shine:
|
|
1827
|
+
specularExp: eI,
|
|
1828
|
+
shine: sI,
|
|
1826
1829
|
waterColor: UI,
|
|
1827
1830
|
glowColor: xI,
|
|
1828
|
-
warpStrength:
|
|
1829
|
-
},
|
|
1830
|
-
const J = Qg(null),
|
|
1831
|
-
Object.entries({ densityDissipation: W, velocityDissipation: x, pressureIterations: Q, curl: Tg, splatRadius:
|
|
1831
|
+
warpStrength: lI
|
|
1832
|
+
}, tI) {
|
|
1833
|
+
const J = Qg(null), oI = Object.fromEntries(
|
|
1834
|
+
Object.entries({ densityDissipation: W, velocityDissipation: x, pressureIterations: Q, curl: Tg, splatRadius: CI, splatForce: iI, refraction: zg, specularExp: eI, shine: sI, waterColor: UI, glowColor: xI, algorithm: c, warpStrength: lI }).filter(([, G]) => G !== void 0)
|
|
1832
1835
|
), n = SC(J, {
|
|
1833
1836
|
workerEnabled: Z,
|
|
1834
1837
|
webGPUEnabled: r,
|
|
1835
1838
|
alphaEnabled: b,
|
|
1836
1839
|
pixelRatio: B,
|
|
1837
1840
|
simResolution: K,
|
|
1838
|
-
config: Eg(
|
|
1841
|
+
config: Eg(uI(oI, u, EI))
|
|
1839
1842
|
});
|
|
1840
1843
|
IC(
|
|
1841
|
-
|
|
1844
|
+
tI,
|
|
1842
1845
|
() => ({
|
|
1843
1846
|
reset() {
|
|
1844
1847
|
var G;
|
|
@@ -1862,11 +1865,11 @@ const Ci = gC(function({
|
|
|
1862
1865
|
var G;
|
|
1863
1866
|
(G = n.current) == null || G.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: l });
|
|
1864
1867
|
}, [g, C, i, s, l, r, b]);
|
|
1865
|
-
const T = JSON.stringify(
|
|
1868
|
+
const T = JSON.stringify(oI);
|
|
1866
1869
|
return tg(() => {
|
|
1867
1870
|
var G;
|
|
1868
1871
|
(G = n.current) == null || G.updateConfig(
|
|
1869
|
-
Eg(
|
|
1872
|
+
Eg(uI(oI, u, EI))
|
|
1870
1873
|
);
|
|
1871
1874
|
}, [u, T, r, b]), tg(() => {
|
|
1872
1875
|
var y;
|
|
@@ -1934,8 +1937,8 @@ const Ci = gC(function({
|
|
|
1934
1937
|
workerEnabled: A = Gg.workerEnabled,
|
|
1935
1938
|
webGPUEnabled: m = !0,
|
|
1936
1939
|
alphaEnabled: Z = !0,
|
|
1937
|
-
pixelRatio: r =
|
|
1938
|
-
simResolution: b =
|
|
1940
|
+
pixelRatio: r = gI.dpr,
|
|
1941
|
+
simResolution: b = gI.sim,
|
|
1939
1942
|
// FluidConfig flat props
|
|
1940
1943
|
densityDissipation: B,
|
|
1941
1944
|
velocityDissipation: K,
|
|
@@ -1943,22 +1946,22 @@ const Ci = gC(function({
|
|
|
1943
1946
|
curl: x,
|
|
1944
1947
|
splatRadius: Q,
|
|
1945
1948
|
splatForce: Tg,
|
|
1946
|
-
refraction:
|
|
1947
|
-
specularExp:
|
|
1949
|
+
refraction: CI,
|
|
1950
|
+
specularExp: iI,
|
|
1948
1951
|
shine: zg,
|
|
1949
|
-
waterColor:
|
|
1950
|
-
glowColor:
|
|
1952
|
+
waterColor: eI,
|
|
1953
|
+
glowColor: sI,
|
|
1951
1954
|
warpStrength: UI
|
|
1952
1955
|
}, xI) {
|
|
1953
|
-
const
|
|
1954
|
-
Object.entries({ densityDissipation: B, velocityDissipation: K, pressureIterations: W, curl: x, splatRadius: Q, splatForce: Tg, refraction:
|
|
1955
|
-
), J = SC(
|
|
1956
|
+
const lI = Qg(null), tI = Object.fromEntries(
|
|
1957
|
+
Object.entries({ densityDissipation: B, velocityDissipation: K, pressureIterations: W, curl: x, splatRadius: Q, splatForce: Tg, refraction: CI, specularExp: iI, shine: zg, waterColor: eI, glowColor: sI, algorithm: S, warpStrength: UI }).filter(([, n]) => n !== void 0)
|
|
1958
|
+
), J = SC(lI, {
|
|
1956
1959
|
workerEnabled: A,
|
|
1957
1960
|
webGPUEnabled: m,
|
|
1958
1961
|
alphaEnabled: Z,
|
|
1959
1962
|
pixelRatio: r,
|
|
1960
1963
|
simResolution: b,
|
|
1961
|
-
config: Eg(
|
|
1964
|
+
config: Eg(uI(tI, t))
|
|
1962
1965
|
});
|
|
1963
1966
|
IC(
|
|
1964
1967
|
xI,
|
|
@@ -1985,13 +1988,13 @@ const Ci = gC(function({
|
|
|
1985
1988
|
var n;
|
|
1986
1989
|
g && ((n = J.current) == null || n.setImageSource(g, C, i));
|
|
1987
1990
|
}, [g, C, i, m, Z]);
|
|
1988
|
-
const
|
|
1991
|
+
const oI = JSON.stringify(tI);
|
|
1989
1992
|
return tg(() => {
|
|
1990
1993
|
var n;
|
|
1991
1994
|
(n = J.current) == null || n.updateConfig(
|
|
1992
|
-
Eg(
|
|
1995
|
+
Eg(uI(tI, t))
|
|
1993
1996
|
);
|
|
1994
|
-
}, [t,
|
|
1997
|
+
}, [t, oI, m, Z]), tg(() => {
|
|
1995
1998
|
var T;
|
|
1996
1999
|
if (!c) {
|
|
1997
2000
|
(T = J.current) == null || T.setBackground(null);
|
|
@@ -2011,7 +2014,7 @@ const Ci = gC(function({
|
|
|
2011
2014
|
}, [c, p, m, Z]), tg(() => {
|
|
2012
2015
|
if (!a)
|
|
2013
2016
|
return;
|
|
2014
|
-
const n =
|
|
2017
|
+
const n = lI.current;
|
|
2015
2018
|
if (!n)
|
|
2016
2019
|
return;
|
|
2017
2020
|
const T = (y) => {
|
|
@@ -2030,7 +2033,7 @@ const Ci = gC(function({
|
|
|
2030
2033
|
}, [a]), /* @__PURE__ */ $I(
|
|
2031
2034
|
"div",
|
|
2032
2035
|
{
|
|
2033
|
-
ref:
|
|
2036
|
+
ref: lI,
|
|
2034
2037
|
className: s,
|
|
2035
2038
|
style: {
|
|
2036
2039
|
position: "relative",
|
|
@@ -2056,8 +2059,8 @@ export {
|
|
|
2056
2059
|
pC as PRESETS,
|
|
2057
2060
|
mC as PROP_RANGES,
|
|
2058
2061
|
zI as loadImageBitmap,
|
|
2059
|
-
|
|
2062
|
+
uI as mergeConfig,
|
|
2060
2063
|
Eg as normalizeConfig,
|
|
2061
|
-
|
|
2064
|
+
bI as parseColor,
|
|
2062
2065
|
SC as useFluid
|
|
2063
2066
|
};
|