@jayf0x/fluidity-js 0.2.3 → 0.2.5

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/dist/index.js CHANGED
@@ -1,119 +1,136 @@
1
- var qI = Object.defineProperty;
2
- var $I = (e, g, C) => g in e ? qI(e, g, { enumerable: !0, configurable: !0, writable: !0, value: C }) : e[g] = C;
3
- var oI = (e, g, C) => ($I(e, typeof g != "symbol" ? g + "" : g, C), C), LI = (e, g, C) => {
1
+ var aC = Object.defineProperty;
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 rI = (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
  };
7
- var I = (e, g, C) => (LI(e, g, "read from private field"), C ? C.call(e) : g.get(e)), d = (e, g, C) => {
7
+ var I = (e, g, C) => (kI(e, g, "read from private field"), C ? C.call(e) : g.get(e)), d = (e, g, C) => {
8
8
  if (g.has(e))
9
9
  throw TypeError("Cannot add the same private member more than once");
10
10
  g instanceof WeakSet ? g.add(e) : g.set(e, C);
11
- }, o = (e, g, C, i) => (LI(e, g, "write to private field"), i ? i.call(e, C) : g.set(e, C), C);
12
- var h = (e, g, C) => (LI(e, g, "access private method"), C);
13
- import { jsx as xI } from "react/jsx-runtime";
14
- import { useRef as Tg, useEffect as sg, forwardRef as FI, useImperativeHandle as DI } from "react";
15
- const TI = {
16
- densityDissipation: 0.992,
17
- velocityDissipation: 0.93,
11
+ }, o = (e, g, C, i) => (kI(e, g, "write to private field"), i ? i.call(e, C) : g.set(e, C), C);
12
+ var L = (e, g, C) => (kI(e, g, "access private method"), C);
13
+ import { jsx as $I } from "react/jsx-runtime";
14
+ import { useRef as Qg, useEffect as tg, forwardRef as gC, useImperativeHandle as IC } from "react";
15
+ const mC = {
16
+ densityDissipation: [0.94, 1],
17
+ velocityDissipation: [0.9, 0.999],
18
+ splatRadius: [1e-3, 0.04],
19
+ splatForce: [0.1, 5],
20
+ specularExp: [0.1, 10],
21
+ shine: [0, 0.15],
22
+ warpStrength: [1e-3, 0.1]
23
+ };
24
+ function Eg(e) {
25
+ const g = { ...e };
26
+ for (const [C, [i, s]] of Object.entries(mC)) {
27
+ const l = e[C];
28
+ l !== void 0 && l >= 0 && l <= 1 && (g[C] = i + (s - i) * l);
29
+ }
30
+ return g;
31
+ }
32
+ const CC = {
33
+ densityDissipation: 0.83,
34
+ velocityDissipation: 0.91,
18
35
  pressureIterations: 1,
19
- curl: 1e-4,
20
- splatRadius: 4e-3,
21
- splatForce: 0.91,
22
- refraction: 0.25,
23
- specularExp: 1.01,
24
- shine: 0.01,
36
+ curl: 0,
37
+ splatRadius: 0.1,
38
+ splatForce: 0.08,
39
+ refraction: 1,
40
+ specularExp: 0,
41
+ shine: 0,
25
42
  waterColor: "#000000",
26
43
  glowColor: "#b3d9ff",
27
- algorithm: "standard",
28
- warpStrength: 0.015
29
- }, UI = {
30
- ...TI,
31
- densityDissipation: 0.99,
32
- velocityDissipation: 0.98,
44
+ algorithm: "aurora",
45
+ warpStrength: 0.04
46
+ }, EI = {
47
+ ...CC,
48
+ densityDissipation: 0.9,
49
+ velocityDissipation: 0.9,
33
50
  pressureIterations: 3,
34
- curl: 0.15,
35
- splatRadius: 0.01,
36
- splatForce: 3,
37
- refraction: 0.25,
38
- specularExp: 1,
39
- shine: 0.1,
40
- glowColor: "#0080ff"
41
- }, gC = { dpr: 1, sim: 0.5 }, wI = {
51
+ curl: 0.2,
52
+ splatRadius: 0.2,
53
+ splatForce: 0.5,
54
+ refraction: 0.2,
55
+ specularExp: 0.01,
56
+ shine: 0.5,
57
+ waterColor: "#090017",
58
+ glowColor: "#b04721"
59
+ }, LI = { dpr: 1, sim: 0.5 }, iC = {
42
60
  backgroundColor: "#0a0a0a",
43
61
  backgroundSize: "cover",
44
- isMouseEnabled: !0,
45
- isWorkerEnabled: !0,
46
- quality: gC
47
- }, ng = {
48
- ...wI,
62
+ mouseEnabled: !0,
63
+ workerEnabled: !0
64
+ }, Gg = {
65
+ ...iC,
49
66
  effect: 0,
50
67
  imageSize: "cover"
51
- }, ag = {
52
- ...wI,
68
+ }, mg = {
69
+ ...iC,
53
70
  fontSize: 100,
54
71
  color: "#ffffff",
55
72
  fontFamily: "sans-serif",
56
73
  fontWeight: 900
57
- }, IC = {
74
+ }, pC = {
58
75
  calm: {
59
- densityDissipation: 0.999,
60
- velocityDissipation: 0.98,
76
+ densityDissipation: 0.98,
77
+ velocityDissipation: 0.81,
61
78
  curl: 1e-4,
62
- splatRadius: 3e-3,
63
- splatForce: 0.5,
79
+ splatRadius: 0.05,
80
+ splatForce: 0.08,
64
81
  refraction: 0.15,
65
- shine: 5e-3,
82
+ shine: 0.03,
66
83
  glowColor: "#99d9ff",
67
84
  waterColor: "#00050d"
68
85
  },
69
86
  sand: {
70
- densityDissipation: 0.997,
71
- velocityDissipation: 0.98,
87
+ densityDissipation: 0.95,
88
+ velocityDissipation: 0.81,
72
89
  curl: 1,
73
- splatRadius: 0.01,
74
- splatForce: 0.9,
90
+ splatRadius: 0.23,
91
+ splatForce: 0.16,
75
92
  refraction: 0.8,
76
- specularExp: 0.1,
77
- shine: 0.05,
93
+ specularExp: 0,
94
+ shine: 0.33,
78
95
  glowColor: "#070707",
79
96
  waterColor: "#735420"
80
97
  },
81
98
  wave: {
82
- densityDissipation: 0.994,
83
- velocityDissipation: 0.92,
99
+ densityDissipation: 0.9,
100
+ velocityDissipation: 0.2,
84
101
  curl: 0.2,
85
- splatRadius: 5e-3,
86
- splatForce: 1.2,
102
+ splatRadius: 0.1,
103
+ splatForce: 0.22,
87
104
  refraction: 0.35,
88
- shine: 0.03,
105
+ shine: 0.2,
89
106
  glowColor: "#80ccff",
90
107
  waterColor: "#000308"
91
108
  },
92
109
  neon: {
93
- densityDissipation: 0.985,
94
- velocityDissipation: 0.93,
110
+ densityDissipation: 0.75,
111
+ velocityDissipation: 0.3,
95
112
  curl: 0.05,
96
- splatRadius: 8e-3,
97
- splatForce: 1.5,
113
+ splatRadius: 0.18,
114
+ splatForce: 0.29,
98
115
  refraction: 0.25,
99
- specularExp: 0.5,
100
- shine: 0.14,
116
+ specularExp: 0.04,
117
+ shine: 0.93,
101
118
  glowColor: "#ff33cc",
102
119
  waterColor: "#0d0014"
103
120
  },
104
121
  smoke: {
105
- densityDissipation: 0.996,
106
- velocityDissipation: 0.97,
122
+ densityDissipation: 0.93,
123
+ velocityDissipation: 0.71,
107
124
  curl: 0.04,
108
- splatRadius: 9e-3,
109
- splatForce: 0.8,
125
+ splatRadius: 0.21,
126
+ splatForce: 0.14,
110
127
  refraction: 0.08,
111
128
  shine: 0,
112
129
  glowColor: "#808080",
113
130
  waterColor: "#0f0f0f"
114
131
  }
115
132
  };
116
- function AI(e) {
133
+ function nI(e) {
117
134
  if (Array.isArray(e))
118
135
  return e;
119
136
  const g = e.slice(1, 7);
@@ -127,88 +144,88 @@ function AI(e) {
127
144
  parseInt(g.slice(4, 6), 16) / 255
128
145
  ];
129
146
  }
130
- function II(e = {}, g, C = TI) {
131
- return { ...g ? { ...C, ...IC[g] } : C, ...e };
147
+ function aI(e = {}, g, C = CC) {
148
+ return { ...g ? { ...C, ...pC[g] } : C, ...e };
132
149
  }
133
- function jg(e, g, C, i, s = "cover") {
150
+ function gI(e, g, C, i, s = "cover") {
134
151
  let l;
135
152
  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);
136
- const t = e * l, a = g * l;
137
- return { x: (C - t) / 2, y: (i - a) / 2, drawW: t, drawH: a };
153
+ const t = e * l, S = g * l;
154
+ return { x: (C - t) / 2, y: (i - S) / 2, drawW: t, drawH: S };
138
155
  }
139
- function CC(e, g, C, i, s = null, l = "cover") {
140
- const { text: t, fontSize: a, color: u, fontFamily: c = "sans-serif", fontWeight: Z = 900 } = i, S = new OffscreenCanvas(g, C), A = S.getContext("2d");
141
- ((L) => {
156
+ function ZC(e, g, C, i, s = null, l = "cover") {
157
+ const { text: t, fontSize: S, color: u, fontFamily: c = "sans-serif", fontWeight: p = 900 } = i, a = new OffscreenCanvas(g, C), A = a.getContext("2d");
158
+ ((b) => {
142
159
  if (s) {
143
160
  A.clearRect(0, 0, g, C), A.fillStyle = "black", A.fillRect(0, 0, g, C);
144
- const { x: G, y: K, drawW: b, drawH: Y } = jg(
161
+ const { x: B, y: K, drawW: W, drawH: x } = gI(
145
162
  s.width,
146
163
  s.height,
147
164
  g,
148
165
  C,
149
166
  l
150
167
  );
151
- A.drawImage(s, G, K, b, Y);
168
+ A.drawImage(s, B, K, W, x);
152
169
  } else
153
170
  A.fillStyle = "black", A.fillRect(0, 0, g, C);
154
- A.fillStyle = L, A.font = `${Z} ${a}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
171
+ A.fillStyle = b, A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
155
172
  })(u);
156
- const m = $g(e, S);
157
- A.fillStyle = "black", A.fillRect(0, 0, g, C), A.fillStyle = "white", A.font = `${Z} ${a}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
158
- const r = $g(e, S);
159
- return { backgroundTex: m, obstacleTex: r, coverageTex: r };
173
+ const Z = dI(e, a);
174
+ 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 = dI(e, a);
176
+ return { backgroundTex: Z, obstacleTex: r, coverageTex: r };
160
177
  }
161
- function iC(e, g, C, i, s = 0, l = "cover", t = null, a = "cover") {
162
- const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: Z, y: S, drawW: A, drawH: B } = jg(g.width, g.height, C, i, l);
178
+ 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 } = gI(g.width, g.height, C, i, l);
163
180
  if (c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), t) {
164
181
  const {
165
- x: G,
182
+ x: B,
166
183
  y: K,
167
- drawW: b,
168
- drawH: Y
169
- } = jg(t.width, t.height, C, i, a);
170
- c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, G, K, b, Y), c.filter = "none";
184
+ drawW: W,
185
+ drawH: x
186
+ } = gI(t.width, t.height, C, i, S);
187
+ c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, B, K, W, x), c.filter = "none";
171
188
  }
172
- c.drawImage(g, Z, S, A, B);
173
- const m = $g(e, u);
174
- c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.filter = `brightness(${s}) blur(8px)`, c.drawImage(g, Z, S, A, B), c.filter = "none";
175
- const r = $g(e, u);
189
+ c.drawImage(g, p, a, A, m);
190
+ const Z = dI(e, u);
191
+ 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 = dI(e, u);
176
193
  c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.fillStyle = "white", c.fillRect(
177
- Math.max(0, Z),
178
- Math.max(0, S),
179
- Math.min(A, C - Math.max(0, Z)),
180
- Math.min(B, i - Math.max(0, S))
194
+ Math.max(0, p),
195
+ Math.max(0, a),
196
+ Math.min(A, C - Math.max(0, p)),
197
+ Math.min(m, i - Math.max(0, a))
181
198
  );
182
- const L = $g(e, u);
183
- return { backgroundTex: m, obstacleTex: r, coverageTex: L };
199
+ const b = dI(e, u);
200
+ return { backgroundTex: Z, obstacleTex: r, coverageTex: b };
184
201
  }
185
- function $g(e, g) {
202
+ function dI(e, g) {
186
203
  const C = e.createTexture();
187
204
  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;
188
205
  }
189
- function eC(e, g, C, i, s = null, l = "cover") {
190
- const { text: t, fontSize: a, color: u, fontFamily: c = "sans-serif", fontWeight: Z = 900 } = i, S = new OffscreenCanvas(g, C), A = S.getContext("2d");
191
- ((L) => {
206
+ function GC(e, g, C, i, s = null, l = "cover") {
207
+ const { text: t, fontSize: S, color: u, fontFamily: c = "sans-serif", fontWeight: p = 900 } = i, a = new OffscreenCanvas(g, C), A = a.getContext("2d");
208
+ ((b) => {
192
209
  if (s) {
193
210
  A.clearRect(0, 0, g, C), A.fillStyle = "black", A.fillRect(0, 0, g, C);
194
- const { x: G, y: K, drawW: b, drawH: Y } = jg(
211
+ const { x: B, y: K, drawW: W, drawH: x } = gI(
195
212
  s.width,
196
213
  s.height,
197
214
  g,
198
215
  C,
199
216
  l
200
217
  );
201
- A.drawImage(s, G, K, b, Y);
218
+ A.drawImage(s, B, K, W, x);
202
219
  } else
203
220
  A.fillStyle = "black", A.fillRect(0, 0, g, C);
204
- A.fillStyle = L, A.font = `${Z} ${a}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
221
+ A.fillStyle = b, A.font = `${p} ${S}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
205
222
  })(u);
206
- const m = gI(e, S, g, C);
207
- A.fillStyle = "black", A.fillRect(0, 0, g, C), A.fillStyle = "white", A.font = `${Z} ${a}px ${c}`, A.textAlign = "center", A.textBaseline = "middle", A.fillText(t, g / 2, C / 2);
208
- const r = gI(e, S, g, C);
223
+ const Z = SI(e, a, g, C);
224
+ 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 = SI(e, a, g, C);
209
226
  return {
210
- backgroundTex: m,
211
- backgroundView: m.createView(),
227
+ backgroundTex: Z,
228
+ backgroundView: Z.createView(),
212
229
  obstacleTex: r,
213
230
  obstacleView: r.createView(),
214
231
  coverageTex: r,
@@ -216,35 +233,35 @@ function eC(e, g, C, i, s = null, l = "cover") {
216
233
  sharedCoverage: !0
217
234
  };
218
235
  }
219
- function sC(e, g, C, i, s = 0, l = "cover", t = null, a = "cover") {
220
- const u = new OffscreenCanvas(C, i), c = u.getContext("2d"), { x: Z, y: S, drawW: A, drawH: B } = jg(g.width, g.height, C, i, l);
236
+ 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 } = gI(g.width, g.height, C, i, l);
221
238
  if (c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), t) {
222
- const { x: G, y: K, drawW: b, drawH: Y } = jg(
239
+ const { x: B, y: K, drawW: W, drawH: x } = gI(
223
240
  t.width,
224
241
  t.height,
225
242
  C,
226
243
  i,
227
- a
244
+ S
228
245
  );
229
- c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, G, K, b, Y), c.filter = "none";
246
+ c.filter = `brightness(${s}) blur(8px)`, c.drawImage(t, B, K, W, x), c.filter = "none";
230
247
  }
231
- c.drawImage(g, Z, S, A, B);
232
- const m = gI(e, u, C, i);
233
- c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.filter = `brightness(${s}) blur(8px)`, c.drawImage(g, Z, S, A, B), c.filter = "none";
234
- const r = gI(e, u, C, i);
235
- c.clearRect(0, 0, C, i), c.fillStyle = "black", c.fillRect(0, 0, C, i), c.fillStyle = "white", c.fillRect(Math.max(0, Z), Math.max(0, S), Math.min(A, C - Math.max(0, Z)), Math.min(B, i - Math.max(0, S)));
236
- const L = gI(e, u, C, i);
248
+ c.drawImage(g, p, a, A, m);
249
+ const Z = SI(e, u, C, i);
250
+ 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 = SI(e, u, C, i);
252
+ 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 = SI(e, u, C, i);
237
254
  return {
238
- backgroundTex: m,
239
- backgroundView: m.createView(),
255
+ backgroundTex: Z,
256
+ backgroundView: Z.createView(),
240
257
  obstacleTex: r,
241
258
  obstacleView: r.createView(),
242
- coverageTex: L,
243
- coverageView: L.createView(),
259
+ coverageTex: b,
260
+ coverageView: b.createView(),
244
261
  sharedCoverage: !1
245
262
  };
246
263
  }
247
- function gI(e, g, C, i) {
264
+ function SI(e, g, C, i) {
248
265
  const s = e.createTexture({
249
266
  size: [C, i],
250
267
  format: "rgba8unorm",
@@ -256,14 +273,14 @@ function gI(e, g, C, i) {
256
273
  [C, i]
257
274
  ), s;
258
275
  }
259
- async function XI(e) {
276
+ async function zI(e) {
260
277
  const g = await fetch(e);
261
278
  if (!g.ok)
262
279
  throw new Error(`Failed to fetch image: ${e} (${g.status})`);
263
280
  const C = await g.blob();
264
281
  return createImageBitmap(C);
265
282
  }
266
- const Zg = (
283
+ const pg = (
267
284
  /* glsl */
268
285
  `
269
286
  precision highp float;
@@ -280,7 +297,7 @@ const Zg = (
280
297
  gl_Position = vec4(aPosition, 0.0, 1.0);
281
298
  }
282
299
  `
283
- ), lC = (
300
+ ), nC = (
284
301
  /* glsl */
285
302
  `
286
303
  precision highp float;
@@ -292,12 +309,15 @@ const Zg = (
292
309
  uniform float dt;
293
310
  uniform float dissipation;
294
311
  void main () {
295
- if (texture2D(uObstacle, vUv).r > 0.5) { gl_FragColor = vec4(0.0); return; }
312
+ float obs = texture2D(uObstacle, vUv).r;
296
313
  vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
297
- gl_FragColor = dissipation * texture2D(uSource, coord);
314
+ // Smooth damping: obs=0 outside (full flow), obs=1 inside (full stop), blurred
315
+ // boundary in between. No branching — multiplying by (1-obs) is equivalent to the
316
+ // hard zero-inside check but with a continuous gradient that avoids grid artefacts.
317
+ gl_FragColor = dissipation * texture2D(uSource, coord) * (1.0 - obs);
298
318
  }
299
319
  `
300
- ), tC = (
320
+ ), bC = (
301
321
  /* glsl */
302
322
  `
303
323
  precision highp float;
@@ -305,14 +325,14 @@ const Zg = (
305
325
  uniform sampler2D uVelocity;
306
326
  uniform sampler2D uObstacle;
307
327
  void main () {
308
- float L = texture2D(uObstacle, vL).r > 0.5 ? 0.0 : texture2D(uVelocity, vL).x;
309
- float R = texture2D(uObstacle, vR).r > 0.5 ? 0.0 : texture2D(uVelocity, vR).x;
310
- float T = texture2D(uObstacle, vT).r > 0.5 ? 0.0 : texture2D(uVelocity, vT).y;
311
- float B = texture2D(uObstacle, vB).r > 0.5 ? 0.0 : texture2D(uVelocity, vB).y;
328
+ float L = texture2D(uVelocity, vL).x * (1.0 - texture2D(uObstacle, vL).r);
329
+ float R = texture2D(uVelocity, vR).x * (1.0 - texture2D(uObstacle, vR).r);
330
+ float T = texture2D(uVelocity, vT).y * (1.0 - texture2D(uObstacle, vT).r);
331
+ float B = texture2D(uVelocity, vB).y * (1.0 - texture2D(uObstacle, vB).r);
312
332
  gl_FragColor = vec4(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
313
333
  }
314
334
  `
315
- ), oC = (
335
+ ), wC = (
316
336
  /* glsl */
317
337
  `
318
338
  precision highp float;
@@ -322,15 +342,15 @@ const Zg = (
322
342
  uniform sampler2D uObstacle;
323
343
  void main () {
324
344
  float C = texture2D(uPressure, vUv).x;
325
- float L = texture2D(uObstacle, vL).r > 0.5 ? C : texture2D(uPressure, vL).x;
326
- float R = texture2D(uObstacle, vR).r > 0.5 ? C : texture2D(uPressure, vR).x;
327
- float T = texture2D(uObstacle, vT).r > 0.5 ? C : texture2D(uPressure, vT).x;
328
- float B = texture2D(uObstacle, vB).r > 0.5 ? C : texture2D(uPressure, vB).x;
345
+ float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);
346
+ float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);
347
+ float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);
348
+ float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);
329
349
  float div = texture2D(uDivergence, vUv).x;
330
350
  gl_FragColor = vec4((L + R + B + T - div) * 0.25, 0.0, 0.0, 1.0);
331
351
  }
332
352
  `
333
- ), AC = (
353
+ ), LC = (
334
354
  /* glsl */
335
355
  `
336
356
  precision highp float;
@@ -339,16 +359,17 @@ const Zg = (
339
359
  uniform sampler2D uVelocity;
340
360
  uniform sampler2D uObstacle;
341
361
  void main () {
342
- if (texture2D(uObstacle, vUv).r > 0.5) { gl_FragColor = vec4(0.0); return; }
343
- float L = texture2D(uPressure, vL).x;
344
- float R = texture2D(uPressure, vR).x;
345
- float T = texture2D(uPressure, vT).x;
346
- float B = texture2D(uPressure, vB).x;
347
- vec2 vel = texture2D(uVelocity, vUv).xy - vec2(R - L, T - B);
362
+ float obs = texture2D(uObstacle, vUv).r;
363
+ float C = texture2D(uPressure, vUv).x;
364
+ float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);
365
+ float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);
366
+ float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);
367
+ float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);
368
+ vec2 vel = (texture2D(uVelocity, vUv).xy - vec2(R - L, T - B)) * (1.0 - obs);
348
369
  gl_FragColor = vec4(vel, 0.0, 1.0);
349
370
  }
350
371
  `
351
- ), cC = (
372
+ ), hC = (
352
373
  /* glsl */
353
374
  `
354
375
  precision highp float;
@@ -365,7 +386,7 @@ const Zg = (
365
386
  gl_FragColor = vec4(texture2D(uTarget, vUv).xyz + splat, 1.0);
366
387
  }
367
388
  `
368
- ), dC = (
389
+ ), KC = (
369
390
  /* glsl */
370
391
  `
371
392
  precision highp float;
@@ -379,7 +400,7 @@ const Zg = (
379
400
  gl_FragColor = vec4(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
380
401
  }
381
402
  `
382
- ), SC = (
403
+ ), yC = (
383
404
  /* glsl */
384
405
  `
385
406
  precision highp float;
@@ -400,7 +421,7 @@ const Zg = (
400
421
  gl_FragColor = vec4(texture2D(uVelocity, vUv).xy + force * dt, 0.0, 1.0);
401
422
  }
402
423
  `
403
- ), aC = (
424
+ ), VC = (
404
425
  /* glsl */
405
426
  `
406
427
  precision highp float;
@@ -424,19 +445,34 @@ const Zg = (
424
445
 
425
446
  void main () {
426
447
  float obs = texture2D(uObstacle, vUv).r;
427
- // Mask density inside obstacles so splats don't flicker the text/image content.
428
- float density = max(texture2D(uTexture, vUv).r, 0.0) * (1.0 - step(0.5, obs));
448
+ // Smooth fade: density falls off over the blurred obstacle boundary zone
449
+ // rather than cutting off at a hard step, eliminating the jagged fringe.
450
+ float density = max(texture2D(uTexture, vUv).r, 0.0) * (1.0 - obs);
429
451
  float coverage = texture2D(uCoverage, vUv).r;
430
452
 
431
- float dL = max(texture2D(uTexture, vUv - vec2(texelSize.x * 2.0, 0.0)).r, 0.0);
432
- float dR = max(texture2D(uTexture, vUv + vec2(texelSize.x * 2.0, 0.0)).r, 0.0);
433
- float dT = max(texture2D(uTexture, vUv + vec2(0.0, texelSize.y * 2.0)).r, 0.0);
434
- float dB = max(texture2D(uTexture, vUv - vec2(0.0, texelSize.y * 2.0)).r, 0.0);
453
+ // 8-tap Sobel normal computes gradient via 3×3 kernel (no centre sample needed).
454
+ // texelSize = 1/displayRes; density FBO is at simScale (0.), so s=6 display px
455
+ // 3 sim texels per axis. The Sobel kernel properly averages the gradient in
456
+ // every direction no 4-tap cross bias that creates 45° circuit-board artefacts.
457
+ float sx = texelSize.x * 6.0, sy = texelSize.y * 6.0;
458
+ float d00 = max(texture2D(uTexture, vUv + vec2(-sx, -sy)).r, 0.0);
459
+ float d10 = max(texture2D(uTexture, vUv + vec2(0.0, -sy)).r, 0.0);
460
+ float d20 = max(texture2D(uTexture, vUv + vec2( sx, -sy)).r, 0.0);
461
+ float d01 = max(texture2D(uTexture, vUv + vec2(-sx, 0.0)).r, 0.0);
462
+ float d21 = max(texture2D(uTexture, vUv + vec2( sx, 0.0)).r, 0.0);
463
+ float d02 = max(texture2D(uTexture, vUv + vec2(-sx, sy)).r, 0.0);
464
+ float d12 = max(texture2D(uTexture, vUv + vec2(0.0, sy)).r, 0.0);
465
+ float d22 = max(texture2D(uTexture, vUv + vec2( sx, sy)).r, 0.0);
466
+ float gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);
467
+ float gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);
435
468
 
436
- vec3 normal = normalize(vec3(dL - dR, dB - dT, 0.2));
469
+ vec3 normal = normalize(vec3(gx, gy, 1.2));
437
470
  vec3 lightDir = normalize(vec3(0.5, 1.0, 0.5));
438
471
  vec3 halfV = normalize(lightDir + vec3(0.0, 0.0, 1.0));
439
- float spec = pow(max(dot(normal, halfV), 0.0), uSpecularExp) * uShine * density;
472
+ // Suppress specular at low / fading density prevents highlight rings from
473
+ // appearing at the dissipating edge of a stroke as its density approaches zero.
474
+ float specDen = density * min(density * 5.0, 1.0);
475
+ float spec = pow(max(dot(normal, halfV), 0.0), uSpecularExp) * uShine * specDen;
440
476
 
441
477
  // In transparent (non-coverage) areas the background texture is empty black canvas.
442
478
  // Replace it with uWaterColor so fluid colour is not contaminated by that black,
@@ -506,7 +542,7 @@ const Zg = (
506
542
  }
507
543
  `
508
544
  );
509
- function ZC(e, g = !0) {
545
+ function HC(e, g = !0) {
510
546
  const C = { alpha: g, depth: !1, stencil: !1, antialias: !0, preserveDrawingBuffer: !1 };
511
547
  let i = e.getContext("webgl2", C);
512
548
  const s = !!i;
@@ -523,7 +559,7 @@ function ZC(e, g = !0) {
523
559
  }
524
560
  };
525
561
  }
526
- async function uC(e, g = !0) {
562
+ async function XC(e, g = !0) {
527
563
  if (typeof navigator > "u" || !navigator.gpu)
528
564
  return null;
529
565
  try {
@@ -539,11 +575,11 @@ async function uC(e, g = !0) {
539
575
  return null;
540
576
  }
541
577
  }
542
- class ug {
578
+ class Zg {
543
579
  constructor(g, C, i) {
544
- oI(this, "program");
545
- oI(this, "uniforms", {});
546
- oI(this, "_gl");
580
+ rI(this, "program");
581
+ rI(this, "uniforms", {});
582
+ rI(this, "_gl");
547
583
  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);
548
584
  const s = g.getProgramParameter(this.program, g.ACTIVE_UNIFORMS);
549
585
  for (let l = 0; l < s; l++) {
@@ -562,27 +598,27 @@ class ug {
562
598
  this._gl.deleteProgram(this.program);
563
599
  }
564
600
  }
565
- function BC(e) {
601
+ function vC(e) {
566
602
  return {
567
- advection: new ug(e, Zg, lC),
568
- divergence: new ug(e, Zg, tC),
569
- pressure: new ug(e, Zg, oC),
570
- gradientSubtract: new ug(e, Zg, AC),
571
- splat: new ug(e, Zg, cC),
572
- curl: new ug(e, Zg, dC),
573
- vorticity: new ug(e, Zg, SC),
574
- display: new ug(e, Zg, aC)
603
+ advection: new Zg(e, pg, nC),
604
+ divergence: new Zg(e, pg, bC),
605
+ pressure: new Zg(e, pg, wC),
606
+ gradientSubtract: new Zg(e, pg, LC),
607
+ splat: new Zg(e, pg, hC),
608
+ curl: new Zg(e, pg, KC),
609
+ vorticity: new Zg(e, pg, yC),
610
+ display: new Zg(e, pg, VC)
575
611
  };
576
612
  }
577
- function SI(e, g, C, i) {
613
+ function hI(e, g, C, i) {
578
614
  e.activeTexture(e.TEXTURE0);
579
615
  const s = e.createTexture();
580
616
  e.bindTexture(e.TEXTURE_2D, s), 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), e.texImage2D(e.TEXTURE_2D, 0, g.internalFormat, C, i, 0, g.format, g.type, null);
581
617
  const l = e.createFramebuffer();
582
618
  return e.bindFramebuffer(e.FRAMEBUFFER, l), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, s, 0), { tex: s, fbo: l, width: C, height: i };
583
619
  }
584
- function bI(e, g, C, i) {
585
- let s = SI(e, g, C, i), l = SI(e, g, C, i);
620
+ function MI(e, g, C, i) {
621
+ let s = hI(e, g, C, i), l = hI(e, g, C, i);
586
622
  return {
587
623
  get read() {
588
624
  return s;
@@ -598,13 +634,13 @@ function bI(e, g, C, i) {
598
634
  }
599
635
  };
600
636
  }
601
- function nC(e) {
637
+ function RC(e) {
602
638
  const g = e.createBuffer();
603
639
  return e.bindBuffer(e.ARRAY_BUFFER, g), e.bufferData(e.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), e.STATIC_DRAW), e.vertexAttribPointer(0, 2, e.FLOAT, !1, 0, 0), e.enableVertexAttribArray(0), function(i) {
604
640
  e.bindFramebuffer(e.FRAMEBUFFER, i), e.drawArrays(e.TRIANGLE_FAN, 0, 4);
605
641
  };
606
642
  }
607
- const bg = (
643
+ const Kg = (
608
644
  /* wgsl */
609
645
  `
610
646
  struct VSOut {
@@ -615,10 +651,10 @@ struct VSOut {
615
651
  @location(3) vT : vec2f,
616
652
  @location(4) vB : vec2f,
617
653
  }`
618
- ), mC = (
654
+ ), WC = (
619
655
  /* wgsl */
620
656
  `
621
- ${bg}
657
+ ${Kg}
622
658
 
623
659
  struct U {
624
660
  texelSize : vec2f,
@@ -643,19 +679,17 @@ struct U {
643
679
  }
644
680
 
645
681
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
646
- // Sample all textures before branching — textureSample requires uniform control flow
647
682
  let obs = textureSample(uObs, samp, i.uv).r;
648
683
  let vel = textureSample(uVel, samp, i.uv).xy;
649
684
  let coord = i.uv - u.dt * vel * u.texelSize;
650
685
  let src = textureSample(uSrc, samp, coord);
651
- if (obs > 0.5) { return vec4f(0.0); }
652
- return u.dissipation * src;
686
+ return u.dissipation * src * (1.0 - obs);
653
687
  }
654
688
  `
655
- ), GC = (
689
+ ), YC = (
656
690
  /* wgsl */
657
691
  `
658
- ${bg}
692
+ ${Kg}
659
693
 
660
694
  struct U { texelSize: vec2f, _pad: vec2f }
661
695
  @group(0) @binding(0) var<uniform> u : U;
@@ -675,17 +709,17 @@ struct U { texelSize: vec2f, _pad: vec2f }
675
709
  }
676
710
 
677
711
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
678
- let L = select(textureSample(uVel, samp, i.vL).x, 0.0, textureSample(uObs, samp, i.vL).r > 0.5);
679
- let R = select(textureSample(uVel, samp, i.vR).x, 0.0, textureSample(uObs, samp, i.vR).r > 0.5);
680
- let T = select(textureSample(uVel, samp, i.vT).y, 0.0, textureSample(uObs, samp, i.vT).r > 0.5);
681
- let B = select(textureSample(uVel, samp, i.vB).y, 0.0, textureSample(uObs, samp, i.vB).r > 0.5);
712
+ let L = textureSample(uVel, samp, i.vL).x * (1.0 - textureSample(uObs, samp, i.vL).r);
713
+ let R = textureSample(uVel, samp, i.vR).x * (1.0 - textureSample(uObs, samp, i.vR).r);
714
+ let T = textureSample(uVel, samp, i.vT).y * (1.0 - textureSample(uObs, samp, i.vT).r);
715
+ let B = textureSample(uVel, samp, i.vB).y * (1.0 - textureSample(uObs, samp, i.vB).r);
682
716
  return vec4f(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
683
717
  }
684
718
  `
685
- ), pC = (
719
+ ), UC = (
686
720
  /* wgsl */
687
721
  `
688
- ${bg}
722
+ ${Kg}
689
723
 
690
724
  struct U { texelSize: vec2f, _pad: vec2f }
691
725
  @group(0) @binding(0) var<uniform> u : U;
@@ -707,18 +741,18 @@ struct U { texelSize: vec2f, _pad: vec2f }
707
741
 
708
742
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
709
743
  let C = textureSample(uPres, samp, i.uv).x;
710
- let L = select(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r > 0.5);
711
- let R = select(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r > 0.5);
712
- let T = select(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r > 0.5);
713
- let B = select(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r > 0.5);
744
+ let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);
745
+ let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);
746
+ let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);
747
+ let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);
714
748
  let dv = textureSample(uDiv, samp, i.uv).x;
715
749
  return vec4f((L + R + B + T - dv) * 0.25, 0.0, 0.0, 1.0);
716
750
  }
717
751
  `
718
- ), rC = (
752
+ ), xC = (
719
753
  /* wgsl */
720
754
  `
721
- ${bg}
755
+ ${Kg}
722
756
 
723
757
  struct U { texelSize: vec2f, _pad: vec2f }
724
758
  @group(0) @binding(0) var<uniform> u : U;
@@ -739,21 +773,20 @@ struct U { texelSize: vec2f, _pad: vec2f }
739
773
  }
740
774
 
741
775
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
742
- // Sample all textures before branching — textureSample requires uniform control flow
743
776
  let obs = textureSample(uObs, samp, i.uv).r;
744
- let L = textureSample(uPres, samp, i.vL).x;
745
- let R = textureSample(uPres, samp, i.vR).x;
746
- let T = textureSample(uPres, samp, i.vT).x;
747
- let B = textureSample(uPres, samp, i.vB).x;
748
- let vel = textureSample(uVel, samp, i.uv).xy - vec2f(R - L, T - B);
749
- if (obs > 0.5) { return vec4f(0.0); }
777
+ let C = textureSample(uPres, samp, i.uv).x;
778
+ let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);
779
+ let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);
780
+ let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);
781
+ let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);
782
+ let vel = (textureSample(uVel, samp, i.uv).xy - vec2f(R - L, T - B)) * (1.0 - obs);
750
783
  return vec4f(vel, 0.0, 1.0);
751
784
  }
752
785
  `
753
- ), wC = (
786
+ ), kC = (
754
787
  /* wgsl */
755
788
  `
756
- ${bg}
789
+ ${Kg}
757
790
 
758
791
  // texelSize occupies bytes 0-7 for the shared vertex stage; aspectRatio/radius fill the rest.
759
792
  struct U {
@@ -786,10 +819,10 @@ struct U {
786
819
  return vec4f(textureSample(uTgt, samp, i.uv).xyz + sp, 1.0);
787
820
  }
788
821
  `
789
- ), LC = (
822
+ ), MC = (
790
823
  /* wgsl */
791
824
  `
792
- ${bg}
825
+ ${Kg}
793
826
 
794
827
  struct U { texelSize: vec2f, _pad: vec2f }
795
828
  @group(0) @binding(0) var<uniform> u : U;
@@ -815,10 +848,10 @@ struct U { texelSize: vec2f, _pad: vec2f }
815
848
  return vec4f(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
816
849
  }
817
850
  `
818
- ), bC = (
851
+ ), fC = (
819
852
  /* wgsl */
820
853
  `
821
- ${bg}
854
+ ${Kg}
822
855
 
823
856
  struct U {
824
857
  texelSize: vec2f,
@@ -854,10 +887,10 @@ struct U {
854
887
  return vec4f(vel, 0.0, 1.0);
855
888
  }
856
889
  `
857
- ), hC = (
890
+ ), DC = (
858
891
  /* wgsl */
859
892
  `
860
- ${bg}
893
+ ${Kg}
861
894
 
862
895
  struct U {
863
896
  texelSize : vec2f,
@@ -891,19 +924,27 @@ struct U {
891
924
 
892
925
  @fragment fn fs(i: VSOut) -> @location(0) vec4f {
893
926
  let obs = textureSample(uObs, samp, i.uv).r;
894
- let density = max(textureSample(uTex, samp, i.uv).r, 0.0) * (1.0 - step(0.5, obs));
927
+ let density = max(textureSample(uTex, samp, i.uv).r, 0.0) * (1.0 - obs);
895
928
  let cov = textureSample(uCov, samp, i.uv).r;
896
929
 
897
- let ts2 = u.texelSize * 2.0;
898
- let dL = max(textureSample(uTex, samp, i.uv - vec2f(ts2.x, 0.0)).r, 0.0);
899
- let dR = max(textureSample(uTex, samp, i.uv + vec2f(ts2.x, 0.0)).r, 0.0);
900
- let dT = max(textureSample(uTex, samp, i.uv + vec2f(0.0, ts2.y)).r, 0.0);
901
- let dB = max(textureSample(uTex, samp, i.uv - vec2f(0.0, ts2.y)).r, 0.0);
930
+ let sx = u.texelSize.x * 6.0;
931
+ let sy = u.texelSize.y * 6.0;
932
+ let d00 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, -sy)).r, 0.0);
933
+ let d10 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, -sy)).r, 0.0);
934
+ let d20 = max(textureSample(uTex, samp, i.uv + vec2f( sx, -sy)).r, 0.0);
935
+ let d01 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, 0.0)).r, 0.0);
936
+ let d21 = max(textureSample(uTex, samp, i.uv + vec2f( sx, 0.0)).r, 0.0);
937
+ let d02 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, sy)).r, 0.0);
938
+ let d12 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, sy)).r, 0.0);
939
+ let d22 = max(textureSample(uTex, samp, i.uv + vec2f( sx, sy)).r, 0.0);
940
+ let gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);
941
+ let gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);
902
942
 
903
- let norm = normalize(vec3f(dL - dR, dB - dT, 0.2));
904
- let ldir = normalize(vec3f(0.5, 1.0, 0.5));
905
- let halfV = normalize(ldir + vec3f(0.0, 0.0, 1.0));
906
- let spec = pow(max(dot(norm, halfV), 0.0), u.specularExp) * u.shine * density;
943
+ let norm = normalize(vec3f(gx, gy, 1.2));
944
+ let ldir = normalize(vec3f(0.5, 1.0, 0.5));
945
+ let halfV = normalize(ldir + vec3f(0.0, 0.0, 1.0));
946
+ let specDen = density * min(density * 5.0, 1.0);
947
+ let spec = pow(max(dot(norm, halfV), 0.0), u.specularExp) * u.shine * specDen;
907
948
 
908
949
  let bgRaw = textureSample(uBg, samp, i.uv).rgb;
909
950
  let wc = u.waterColor.rgb;
@@ -954,10 +995,10 @@ struct U {
954
995
  return vec4f(color, 1.0);
955
996
  }
956
997
  `
957
- ), KC = {
998
+ ), FC = {
958
999
  arrayStride: 8,
959
1000
  attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }]
960
- }, WI = new Float32Array([
1001
+ }, OI = new Float32Array([
961
1002
  -1,
962
1003
  -1,
963
1004
  -1,
@@ -971,11 +1012,11 @@ struct U {
971
1012
  1,
972
1013
  1
973
1014
  ]);
974
- function VC(e) {
975
- const g = e.createBuffer({ size: WI.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });
976
- return e.queue.writeBuffer(g, 0, WI), g;
1015
+ function JC(e) {
1016
+ const g = e.createBuffer({ size: OI.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });
1017
+ return e.queue.writeBuffer(g, 0, OI), g;
977
1018
  }
978
- function aI(e, g, C, i) {
1019
+ function KI(e, g, C, i) {
979
1020
  const s = e.createTexture({
980
1021
  size: [C, i],
981
1022
  format: g,
@@ -983,8 +1024,8 @@ function aI(e, g, C, i) {
983
1024
  });
984
1025
  return { tex: s, view: s.createView(), width: C, height: i };
985
1026
  }
986
- function hI(e, g, C, i) {
987
- let s = aI(e, g, C, i), l = aI(e, g, C, i);
1027
+ function fI(e, g, C, i) {
1028
+ let s = KI(e, g, C, i), l = KI(e, g, C, i);
988
1029
  return {
989
1030
  get read() {
990
1031
  return s;
@@ -1004,55 +1045,55 @@ function Bg(e, g, C, i) {
1004
1045
  const s = e.createShaderModule({ code: g });
1005
1046
  return e.createRenderPipeline({
1006
1047
  layout: "auto",
1007
- vertex: { module: s, entryPoint: "vs", buffers: [KC] },
1048
+ vertex: { module: s, entryPoint: "vs", buffers: [FC] },
1008
1049
  fragment: { module: s, entryPoint: "fs", targets: [{ format: C, ...i ? { blend: i } : {} }] },
1009
1050
  primitive: { topology: "triangle-list" }
1010
1051
  });
1011
1052
  }
1012
- const yC = {
1053
+ const TC = {
1013
1054
  color: { operation: "add", srcFactor: "one", dstFactor: "zero" },
1014
1055
  alpha: { operation: "add", srcFactor: "one", dstFactor: "zero" }
1015
1056
  };
1016
- function HC(e, g, C = !0) {
1057
+ function zC(e, g, C = !0) {
1017
1058
  const i = "rgba16float";
1018
1059
  return {
1019
- advection: Bg(e, mC, i),
1020
- divergence: Bg(e, GC, i),
1021
- pressure: Bg(e, pC, i),
1022
- gradientSubtract: Bg(e, rC, i),
1023
- splat: Bg(e, wC, i),
1024
- curl: Bg(e, LC, i),
1025
- vorticity: Bg(e, bC, i),
1026
- display: Bg(e, hC, g, C ? void 0 : yC)
1060
+ advection: Bg(e, WC, i),
1061
+ divergence: Bg(e, YC, i),
1062
+ pressure: Bg(e, UC, i),
1063
+ gradientSubtract: Bg(e, xC, i),
1064
+ splat: Bg(e, kC, i),
1065
+ curl: Bg(e, MC, i),
1066
+ vorticity: Bg(e, fC, i),
1067
+ display: Bg(e, DC, g, C ? void 0 : TC)
1027
1068
  };
1028
1069
  }
1029
- function XC(e) {
1070
+ function NC(e) {
1030
1071
  return e.createSampler({ magFilter: "linear", minFilter: "linear", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge" });
1031
1072
  }
1032
- function q(e, g) {
1073
+ function gg(e, g) {
1033
1074
  return e.createBuffer({ size: g, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
1034
1075
  }
1035
- function YI(e, g, C, i, s, l) {
1076
+ function jI(e, g, C, i, s, l) {
1036
1077
  const t = new Float32Array([C, i, s, l]);
1037
1078
  e.queue.writeBuffer(g, 0, t);
1038
1079
  }
1039
- function cI(e, g, C, i) {
1080
+ function bI(e, g, C, i) {
1040
1081
  const s = new Float32Array([C, i, 0, 0]);
1041
1082
  e.queue.writeBuffer(g, 0, s);
1042
1083
  }
1043
- function vC(e, g, C, i, s, l) {
1084
+ function QC(e, g, C, i, s, l) {
1044
1085
  const t = new Float32Array([C, i, s, l]);
1045
1086
  e.queue.writeBuffer(g, 0, t);
1046
1087
  }
1047
- function dI(e, g, C, i, s, l, t, a, u, c, Z) {
1048
- const S = new Float32Array(12);
1049
- S[0] = C, S[1] = i, S[2] = s, S[3] = l, S[4] = t, S[5] = a, S[6] = u, S[7] = 0, S[8] = c, S[9] = Z, S[10] = 0, S[11] = 0, e.queue.writeBuffer(g, 0, S);
1088
+ function wI(e, g, C, i, s, l, t, S, u, c, p) {
1089
+ const a = new Float32Array(12);
1090
+ 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);
1050
1091
  }
1051
- function RC(e, g, C, i, s, l, t, a, u, c, Z, S) {
1052
- const A = new Float32Array(16), B = new Int32Array(A.buffer);
1053
- A[0] = C, A[1] = i, A[2] = s, A[3] = l, A[4] = t[0], A[5] = t[1], A[6] = t[2], A[7] = 0, A[8] = a[0], A[9] = a[1], A[10] = a[2], A[11] = 0, A[12] = u, A[13] = c, B[14] = Z, B[15] = S ? 1 : 0, e.queue.writeBuffer(g, 0, A);
1092
+ function EC(e, g, C, i, s, l, t, S, u, c, p, a) {
1093
+ const A = new Float32Array(16), m = new Int32Array(A.buffer);
1094
+ A[0] = C, A[1] = i, A[2] = s, A[3] = l, A[4] = t[0], A[5] = t[1], A[6] = t[2], A[7] = 0, A[8] = S[0], A[9] = S[1], A[10] = S[2], A[11] = 0, A[12] = u, A[13] = c, m[14] = p, m[15] = a ? 1 : 0, e.queue.writeBuffer(g, 0, A);
1054
1095
  }
1055
- function Q(e, g, C, i, s) {
1096
+ function O(e, g, C, i, s) {
1056
1097
  const l = e.beginRenderPass({
1057
1098
  colorAttachments: [{
1058
1099
  view: s,
@@ -1063,7 +1104,7 @@ function Q(e, g, C, i, s) {
1063
1104
  });
1064
1105
  l.setPipeline(g), l.setBindGroup(0, C), l.setVertexBuffer(0, i), l.draw(6), l.end();
1065
1106
  }
1066
- function UC(e, g, C, i, s) {
1107
+ function OC(e, g, C, i, s) {
1067
1108
  const l = e.beginRenderPass({
1068
1109
  colorAttachments: [{
1069
1110
  view: s,
@@ -1074,114 +1115,114 @@ function UC(e, g, C, i, s) {
1074
1115
  });
1075
1116
  l.setPipeline(g), l.setBindGroup(0, C), l.setVertexBuffer(0, i), l.draw(6), l.end();
1076
1117
  }
1077
- const kI = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), WC = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, Pg = 0.016, MI = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };
1078
- var hg, O, CI, Kg, Jg, M, X, $, gg, Ig, lg, J, Cg, D, zg, Vg, Ng, f, y, mg, ig, Gg, N, yg, Hg, Xg, vg, Rg, tg, og, Ug, Wg, Yg, H, v, E, j, T, Qg, Ag, z, pg, cg, w, k, eg, kg, iI, Mg, uI, JI, fg, _g, eI, KI, rg, Dg, xg, qg, sI, VI, lI, yI, BI, zI, nI, NI, mI, QI, GI, OI, pI, EI;
1079
- const vI = class vI {
1118
+ const PI = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), jC = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, oI = 0.016, _I = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };
1119
+ var yg, j, uI, 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, mI, fg, VI, eC, Dg, AI, pI, DI, wg, Ng, Fg, cI, ZI, FI, BI, JI, HI, sC, XI, lC, vI, tC, RI, oC, WI, AC;
1120
+ const NI = class NI {
1080
1121
  // ── Constructor ─────────────────────────────────────────────────────────────
1081
1122
  constructor(g, C = {}, i = {}, s, l = !0) {
1082
1123
  // ---------------------------------------------------------------------------
1083
1124
  // Private — GPU initialisation
1084
1125
  // ---------------------------------------------------------------------------
1085
- d(this, uI);
1126
+ d(this, VI);
1086
1127
  // ---------------------------------------------------------------------------
1087
1128
  // Private — shared helpers
1088
1129
  // ---------------------------------------------------------------------------
1089
- d(this, fg);
1090
- d(this, eI);
1091
- d(this, rg);
1092
- d(this, xg);
1093
- d(this, sI);
1094
- d(this, lI);
1130
+ d(this, Dg);
1131
+ d(this, pI);
1132
+ d(this, wg);
1133
+ d(this, Fg);
1134
+ d(this, ZI);
1135
+ d(this, BI);
1095
1136
  // ---------------------------------------------------------------------------
1096
1137
  // Private — frame dispatch
1097
1138
  // ---------------------------------------------------------------------------
1098
- d(this, BI);
1139
+ d(this, HI);
1099
1140
  // ---------------------------------------------------------------------------
1100
1141
  // Private — WebGPU simulation step
1101
1142
  // ---------------------------------------------------------------------------
1102
- d(this, nI);
1143
+ d(this, XI);
1103
1144
  // ---------------------------------------------------------------------------
1104
1145
  // Private — WebGPU direct splat
1105
1146
  // ---------------------------------------------------------------------------
1106
- d(this, mI);
1147
+ d(this, vI);
1107
1148
  // ---------------------------------------------------------------------------
1108
1149
  // Private — WebGL splat
1109
1150
  // ---------------------------------------------------------------------------
1110
- d(this, GI);
1151
+ d(this, RI);
1111
1152
  // ---------------------------------------------------------------------------
1112
1153
  // Private — WebGL simulation step (unchanged from original)
1113
1154
  // ---------------------------------------------------------------------------
1114
- d(this, pI);
1115
- d(this, hg, void 0);
1155
+ d(this, WI);
1156
+ d(this, yg, void 0);
1116
1157
  // ── WebGL path ──────────────────────────────────────────────────────────────
1117
- d(this, O, null);
1118
- d(this, CI, null);
1119
- d(this, Kg, null);
1120
- d(this, Jg, null);
1121
- d(this, M, null);
1122
- d(this, X, null);
1123
- d(this, $, null);
1124
- d(this, gg, null);
1158
+ d(this, j, null);
1159
+ d(this, uI, null);
1160
+ d(this, Vg, null);
1161
+ d(this, Og, null);
1162
+ d(this, k, null);
1163
+ d(this, H, null);
1125
1164
  d(this, Ig, null);
1126
- d(this, lg, null);
1127
- d(this, J, null);
1128
1165
  d(this, Cg, null);
1166
+ d(this, ig, null);
1167
+ d(this, og, null);
1168
+ d(this, z, null);
1169
+ d(this, eg, null);
1129
1170
  // ── WebGPU path ─────────────────────────────────────────────────────────────
1130
1171
  d(this, D, null);
1131
- d(this, zg, null);
1132
- d(this, Vg, null);
1133
- d(this, Ng, null);
1134
- d(this, f, null);
1135
- d(this, y, null);
1136
- d(this, mg, null);
1137
- d(this, ig, null);
1138
- d(this, Gg, null);
1139
- d(this, N, null);
1172
+ d(this, jg, null);
1173
+ d(this, Hg, null);
1174
+ d(this, Pg, null);
1175
+ d(this, M, null);
1176
+ d(this, h, null);
1177
+ d(this, rg, null);
1178
+ d(this, sg, null);
1179
+ d(this, ng, null);
1180
+ d(this, E, null);
1140
1181
  // Pre-allocated uniform buffers (sizes: see gpu-utils writeXxx docs)
1141
1182
  // Velocity/density advection use separate buffers — writeBuffer is a queue op;
1142
1183
  // a second write to the same buffer before queue.submit() aliases both passes.
1143
- d(this, yg, null);
1184
+ d(this, Xg, null);
1144
1185
  // 16 bytes — velocity advection
1145
- d(this, Hg, null);
1186
+ d(this, vg, null);
1146
1187
  // 16 bytes — density advection
1147
- d(this, Xg, null);
1188
+ d(this, Rg, null);
1148
1189
  // 16 bytes
1149
- d(this, vg, null);
1190
+ d(this, Wg, null);
1150
1191
  // 16 bytes
1151
- d(this, Rg, null);
1192
+ d(this, Yg, null);
1152
1193
  // 16 bytes
1153
- d(this, tg, null);
1194
+ d(this, Ag, null);
1154
1195
  // 48 bytes — velocity splat
1155
- d(this, og, null);
1196
+ d(this, cg, null);
1156
1197
  // 48 bytes — density splat
1157
1198
  d(this, Ug, null);
1158
1199
  // 16 bytes
1159
- d(this, Wg, null);
1200
+ d(this, xg, null);
1160
1201
  // 16 bytes
1161
- d(this, Yg, null);
1202
+ d(this, kg, null);
1162
1203
  // 64 bytes
1163
1204
  // ── Shared state ────────────────────────────────────────────────────────────
1164
- d(this, H, 0);
1165
- d(this, v, 0);
1166
- d(this, E, 0);
1167
- d(this, j, 0);
1168
- d(this, T, 1);
1169
- d(this, Qg, 1);
1170
- d(this, Ag, 0.5);
1171
- d(this, z, null);
1172
- d(this, pg, "cover");
1173
- d(this, cg, void 0);
1205
+ d(this, V, 0);
1206
+ d(this, X, 0);
1207
+ d(this, P, 0);
1208
+ d(this, _, 0);
1209
+ d(this, F, 1);
1210
+ d(this, _g, 1);
1211
+ d(this, dg, 0.5);
1212
+ d(this, N, null);
1213
+ d(this, bg, "cover");
1214
+ d(this, Sg, void 0);
1174
1215
  d(this, w, { x: 0, y: 0, dx: 0, dy: 0, targetX: 0, targetY: 0, moved: !1 });
1175
- d(this, k, null);
1176
- d(this, eg, null);
1177
- d(this, kg, !1);
1178
- d(this, iI, !1);
1179
- d(this, Mg, !0);
1180
- if (o(this, hg, g), o(this, Qg, Math.max(0.1, Math.min(1, i.dpr ?? 1))), o(this, Ag, Math.max(0.1, Math.min(1, i.sim ?? 0.5))), o(this, cg, II(C)), o(this, Mg, l), s)
1181
- o(this, D, s), h(this, uI, JI).call(this, s);
1216
+ d(this, U, null);
1217
+ d(this, lg, null);
1218
+ d(this, Mg, !1);
1219
+ d(this, mI, !1);
1220
+ 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, aI(C)), o(this, fg, l), s)
1222
+ o(this, D, s), L(this, VI, eC).call(this, s);
1182
1223
  else {
1183
- const { gl: t, ext: a } = ZC(g, l);
1184
- o(this, O, t), o(this, CI, a), o(this, Kg, BC(t)), o(this, Jg, nC(t)), t.clearColor(0, 0, 0, l ? 0 : 1);
1224
+ const { gl: t, ext: S } = HC(g, l);
1225
+ o(this, j, t), o(this, uI, S), o(this, Vg, vC(t)), o(this, Og, RC(t)), t.clearColor(0, 0, 0, l ? 0 : 1);
1185
1226
  }
1186
1227
  }
1187
1228
  /**
@@ -1189,28 +1230,28 @@ const vI = class vI {
1189
1230
  * This is the recommended entry point when WebGPU support is desired.
1190
1231
  */
1191
1232
  static async create(g, C = {}, i = {}, s = !0, l = !0) {
1192
- const t = s ? await uC(g, l) : null;
1193
- return new vI(g, C, i, t ?? void 0, l);
1233
+ const t = s ? await XC(g, l) : null;
1234
+ return new NI(g, C, i, t ?? void 0, l);
1194
1235
  }
1195
1236
  // ---------------------------------------------------------------------------
1196
1237
  // Public API
1197
1238
  // ---------------------------------------------------------------------------
1198
1239
  setTextSource(g) {
1199
- o(this, k, { type: "text", opts: g }), h(this, fg, _g).call(this), h(this, rg, Dg).call(this), h(this, xg, qg).call(this);
1240
+ o(this, U, { type: "text", opts: g }), L(this, Dg, AI).call(this), L(this, wg, Ng).call(this), L(this, Fg, cI).call(this);
1200
1241
  }
1201
1242
  async setImageSource(g, C = 0, i = "cover") {
1202
- const s = await XI(g);
1203
- if (I(this, iI)) {
1243
+ const s = await zI(g);
1244
+ if (I(this, mI)) {
1204
1245
  s.close();
1205
1246
  return;
1206
1247
  }
1207
- o(this, k, { type: "image", bitmap: s, effect: C, size: i }), h(this, fg, _g).call(this), h(this, rg, Dg).call(this), h(this, xg, qg).call(this);
1248
+ o(this, U, { type: "image", bitmap: s, effect: C, size: i }), L(this, Dg, AI).call(this), L(this, wg, Ng).call(this), L(this, Fg, cI).call(this);
1208
1249
  }
1209
1250
  setImageBitmap(g, C = 0, i = "cover") {
1210
- o(this, k, { type: "image", bitmap: g, effect: C, size: i }), h(this, fg, _g).call(this), h(this, rg, Dg).call(this), h(this, xg, qg).call(this);
1251
+ o(this, U, { type: "image", bitmap: g, effect: C, size: i }), L(this, Dg, AI).call(this), L(this, wg, Ng).call(this), L(this, Fg, cI).call(this);
1211
1252
  }
1212
1253
  setBackground(g, C = "cover") {
1213
- I(this, z) && I(this, z) !== g && I(this, z).close(), o(this, z, g), o(this, pg, C ?? "cover"), I(this, k) && I(this, H) > 0 && I(this, v) > 0 && h(this, rg, Dg).call(this);
1254
+ 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);
1214
1255
  }
1215
1256
  handleMove(g, C, i = 1) {
1216
1257
  I(this, w).moved = !0, I(this, w).dx = (g - I(this, w).targetX) * i, I(this, w).dy = (C - I(this, w).targetY) * i, I(this, w).targetX = g, I(this, w).targetY = C;
@@ -1223,365 +1264,365 @@ const vI = class vI {
1223
1264
  * mouse-state machine or the worker message queue.
1224
1265
  */
1225
1266
  splat(g, C, i, s, l = 1) {
1226
- !I(this, kg) || I(this, H) === 0 || (I(this, D) ? h(this, mI, QI).call(this, g, C, i, s, l) : h(this, GI, OI).call(this, g, C, i, s, l));
1267
+ !I(this, Mg) || I(this, V) === 0 || (I(this, D) ? L(this, vI, tC).call(this, g, C, i, s, l) : L(this, RI, oC).call(this, g, C, i, s, l));
1227
1268
  }
1228
1269
  updateQuality(g) {
1229
- g.dpr !== void 0 && o(this, Qg, Math.max(0.1, Math.min(1, g.dpr))), g.sim !== void 0 && o(this, Ag, Math.max(0.1, Math.min(1, g.sim)));
1270
+ g.dpr !== void 0 && o(this, _g, Math.max(0.1, Math.min(1, g.dpr))), g.sim !== void 0 && o(this, dg, Math.max(0.1, Math.min(1, g.sim)));
1230
1271
  }
1231
1272
  resize(g, C, i) {
1232
- if (i !== void 0 ? o(this, T, i) : typeof window < "u" && window.devicePixelRatio && o(this, T, window.devicePixelRatio), g !== void 0 && g > 0) {
1273
+ if (i !== void 0 ? o(this, F, i) : typeof window < "u" && window.devicePixelRatio && o(this, F, window.devicePixelRatio), g !== void 0 && g > 0) {
1233
1274
  if (C === void 0 || C <= 0)
1234
1275
  return;
1235
- o(this, H, I(this, hg).width = g), o(this, v, I(this, hg).height = C), o(this, E, Math.max(1, Math.round(g * I(this, Ag)))), o(this, j, Math.max(1, Math.round(C * I(this, Ag)))), h(this, eI, KI).call(this);
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, pI, DI).call(this);
1236
1277
  } else
1237
- h(this, fg, _g).call(this);
1238
- I(this, k) && h(this, rg, Dg).call(this), h(this, xg, qg).call(this);
1278
+ L(this, Dg, AI).call(this);
1279
+ I(this, U) && L(this, wg, Ng).call(this), L(this, Fg, cI).call(this);
1239
1280
  }
1240
1281
  updateConfig(g) {
1241
- Object.assign(I(this, cg), g);
1282
+ Object.assign(I(this, Sg), g);
1242
1283
  }
1243
1284
  destroy() {
1244
- var g, C, i, s, l, t, a, u, c, Z, S;
1245
- if (o(this, iI, !0), this.stop(), h(this, sI, VI).call(this), h(this, lI, yI).call(this), I(this, z) && (I(this, z).close(), o(this, z, null)), I(this, D))
1246
- (g = I(this, yg)) == null || g.destroy(), (C = I(this, Hg)) == null || C.destroy(), (i = I(this, Xg)) == null || i.destroy(), (s = I(this, vg)) == null || s.destroy(), (l = I(this, Rg)) == null || l.destroy(), (t = I(this, tg)) == null || t.destroy(), (a = I(this, og)) == null || a.destroy(), (u = I(this, Ug)) == null || u.destroy(), (c = I(this, Wg)) == null || c.destroy(), (Z = I(this, Yg)) == null || Z.destroy(), (S = I(this, Vg)) == null || S.destroy(), I(this, D).device.destroy();
1285
+ var g, C, i, s, l, t, S, u, c, p, a;
1286
+ if (o(this, mI, !0), this.stop(), L(this, ZI, FI).call(this), L(this, BI, JI).call(this), I(this, N) && (I(this, N).close(), o(this, N, null)), I(this, D))
1287
+ (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();
1247
1288
  else {
1248
- const A = I(this, O);
1249
- for (const m of Object.values(I(this, Kg)))
1250
- m.dispose();
1251
- const B = A.getExtension("WEBGL_lose_context");
1252
- B == null || B.loseContext();
1289
+ const A = I(this, j);
1290
+ for (const Z of Object.values(I(this, Vg)))
1291
+ Z.dispose();
1292
+ const m = A.getExtension("WEBGL_lose_context");
1293
+ m == null || m.loseContext();
1253
1294
  }
1254
1295
  }
1255
1296
  // ---------------------------------------------------------------------------
1256
1297
  // Loop control
1257
1298
  // ---------------------------------------------------------------------------
1258
1299
  start() {
1259
- if (I(this, eg) !== null)
1300
+ if (I(this, lg) !== null)
1260
1301
  return;
1261
1302
  const g = () => {
1262
- h(this, BI, zI).call(this), o(this, eg, kI(g));
1303
+ L(this, HI, sC).call(this), o(this, lg, PI(g));
1263
1304
  };
1264
- o(this, eg, kI(g));
1305
+ o(this, lg, PI(g));
1265
1306
  }
1266
1307
  stop() {
1267
- I(this, eg) !== null && (WC(I(this, eg)), o(this, eg, null));
1308
+ I(this, lg) !== null && (jC(I(this, lg)), o(this, lg, null));
1268
1309
  }
1269
1310
  get isRunning() {
1270
- return I(this, eg) !== null;
1311
+ return I(this, lg) !== null;
1271
1312
  }
1272
1313
  };
1273
- hg = new WeakMap(), O = new WeakMap(), CI = new WeakMap(), Kg = new WeakMap(), Jg = new WeakMap(), M = new WeakMap(), X = new WeakMap(), $ = new WeakMap(), gg = new WeakMap(), Ig = new WeakMap(), lg = new WeakMap(), J = new WeakMap(), Cg = new WeakMap(), D = new WeakMap(), zg = new WeakMap(), Vg = new WeakMap(), Ng = new WeakMap(), f = new WeakMap(), y = new WeakMap(), mg = new WeakMap(), ig = new WeakMap(), Gg = new WeakMap(), N = new WeakMap(), yg = new WeakMap(), Hg = new WeakMap(), Xg = new WeakMap(), vg = new WeakMap(), Rg = new WeakMap(), tg = new WeakMap(), og = new WeakMap(), Ug = new WeakMap(), Wg = new WeakMap(), Yg = new WeakMap(), H = new WeakMap(), v = new WeakMap(), E = new WeakMap(), j = new WeakMap(), T = new WeakMap(), Qg = new WeakMap(), Ag = new WeakMap(), z = new WeakMap(), pg = new WeakMap(), cg = new WeakMap(), w = new WeakMap(), k = new WeakMap(), eg = new WeakMap(), kg = new WeakMap(), iI = new WeakMap(), Mg = new WeakMap(), uI = new WeakSet(), JI = function(g) {
1314
+ yg = new WeakMap(), j = new WeakMap(), uI = 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(), mI = new WeakMap(), fg = new WeakMap(), VI = new WeakSet(), eC = function(g) {
1274
1315
  const { device: C, format: i } = g;
1275
- o(this, zg, HC(C, i, I(this, Mg))), o(this, Vg, VC(C)), o(this, Ng, XC(C)), o(this, yg, q(C, 16)), o(this, Hg, q(C, 16)), o(this, Xg, q(C, 16)), o(this, vg, q(C, 16)), o(this, Rg, q(C, 16)), o(this, tg, q(C, 48)), o(this, og, q(C, 48)), o(this, Ug, q(C, 16)), o(this, Wg, q(C, 16)), o(this, Yg, q(C, 64));
1276
- }, fg = new WeakSet(), _g = function() {
1277
- const g = I(this, hg);
1278
- "clientWidth" in g && g.clientWidth > 0 ? (o(this, T, (typeof window < "u" && window.devicePixelRatio || 1) * I(this, Qg)), o(this, H, g.width = Math.round(g.clientWidth * I(this, T))), o(this, v, g.height = Math.round(g.clientHeight * I(this, T)))) : (o(this, H, g.width), o(this, v, g.height)), !(I(this, H) === 0 || I(this, v) === 0) && (o(this, E, Math.max(1, Math.round(I(this, H) * I(this, Ag)))), o(this, j, Math.max(1, Math.round(I(this, v) * I(this, Ag)))), h(this, eI, KI).call(this));
1279
- }, eI = new WeakSet(), KI = function() {
1280
- if (h(this, sI, VI).call(this), I(this, D)) {
1281
- const { device: g } = I(this, D), C = "rgba16float", i = I(this, E), s = I(this, j);
1282
- o(this, f, hI(g, C, i, s)), o(this, y, hI(g, C, i, s)), o(this, ig, hI(g, C, i, s)), o(this, mg, aI(g, C, i, s)), o(this, Gg, aI(g, C, i, s));
1316
+ 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(), AI = function() {
1318
+ 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, pI, DI).call(this));
1320
+ }, pI = new WeakSet(), DI = function() {
1321
+ if (L(this, ZI, FI).call(this), I(this, D)) {
1322
+ const { device: g } = I(this, D), C = "rgba16float", i = I(this, P), s = I(this, _);
1323
+ 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));
1283
1324
  } else {
1284
- const g = I(this, O), C = I(this, CI), i = I(this, E), s = I(this, j);
1285
- o(this, M, bI(g, C, i, s)), o(this, X, bI(g, C, i, s)), o(this, gg, bI(g, C, i, s)), o(this, $, SI(g, C, i, s)), o(this, Ig, SI(g, C, i, s));
1325
+ const g = I(this, j), C = I(this, uI), i = I(this, P), s = I(this, _);
1326
+ 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));
1286
1327
  }
1287
- }, rg = new WeakSet(), Dg = function() {
1288
- if (!(!I(this, k) || I(this, H) === 0 || I(this, v) === 0)) {
1289
- if (h(this, lI, yI).call(this), I(this, D)) {
1328
+ }, wg = new WeakSet(), Ng = function() {
1329
+ if (!(!I(this, U) || I(this, V) === 0 || I(this, X) === 0)) {
1330
+ if (L(this, BI, JI).call(this), I(this, D)) {
1290
1331
  const { device: g } = I(this, D);
1291
- I(this, k).type === "text" ? o(this, N, eC(
1332
+ I(this, U).type === "text" ? o(this, E, GC(
1292
1333
  g,
1293
- I(this, H),
1294
- I(this, v),
1295
- I(this, k).opts,
1296
- I(this, z),
1297
- I(this, pg)
1298
- )) : o(this, N, sC(
1334
+ I(this, V),
1335
+ I(this, X),
1336
+ I(this, U).opts,
1337
+ I(this, N),
1338
+ I(this, bg)
1339
+ )) : o(this, E, rC(
1299
1340
  g,
1300
- I(this, k).bitmap,
1301
- I(this, H),
1302
- I(this, v),
1303
- I(this, k).effect,
1304
- I(this, k).size,
1305
- I(this, z),
1306
- I(this, pg)
1341
+ I(this, U).bitmap,
1342
+ I(this, V),
1343
+ I(this, X),
1344
+ I(this, U).effect,
1345
+ I(this, U).size,
1346
+ I(this, N),
1347
+ I(this, bg)
1307
1348
  ));
1308
1349
  } else {
1309
- const g = I(this, O);
1310
- if (I(this, k).type === "text") {
1311
- const { backgroundTex: C, obstacleTex: i, coverageTex: s } = CC(
1350
+ const g = I(this, j);
1351
+ if (I(this, U).type === "text") {
1352
+ const { backgroundTex: C, obstacleTex: i, coverageTex: s } = ZC(
1312
1353
  g,
1313
- I(this, H),
1314
- I(this, v),
1315
- I(this, k).opts,
1316
- I(this, z),
1317
- I(this, pg)
1354
+ I(this, V),
1355
+ I(this, X),
1356
+ I(this, U).opts,
1357
+ I(this, N),
1358
+ I(this, bg)
1318
1359
  );
1319
- o(this, lg, C), o(this, J, i), o(this, Cg, s);
1360
+ o(this, og, C), o(this, z, i), o(this, eg, s);
1320
1361
  } else {
1321
- const { backgroundTex: C, obstacleTex: i, coverageTex: s } = iC(
1362
+ const { backgroundTex: C, obstacleTex: i, coverageTex: s } = BC(
1322
1363
  g,
1323
- I(this, k).bitmap,
1324
- I(this, H),
1325
- I(this, v),
1326
- I(this, k).effect,
1327
- I(this, k).size,
1328
- I(this, z),
1329
- I(this, pg)
1364
+ I(this, U).bitmap,
1365
+ I(this, V),
1366
+ I(this, X),
1367
+ I(this, U).effect,
1368
+ I(this, U).size,
1369
+ I(this, N),
1370
+ I(this, bg)
1330
1371
  );
1331
- o(this, lg, C), o(this, J, i), o(this, Cg, s);
1372
+ o(this, og, C), o(this, z, i), o(this, eg, s);
1332
1373
  }
1333
1374
  }
1334
- o(this, kg, !0);
1375
+ o(this, Mg, !0);
1335
1376
  }
1336
- }, xg = new WeakSet(), qg = function() {
1337
- I(this, kg) && !this.isRunning && this.start();
1338
- }, sI = new WeakSet(), VI = function() {
1339
- var g, C, i, s, l, t, a, u;
1377
+ }, Fg = new WeakSet(), cI = function() {
1378
+ I(this, Mg) && !this.isRunning && this.start();
1379
+ }, ZI = new WeakSet(), FI = function() {
1380
+ var g, C, i, s, l, t, S, u;
1340
1381
  if (I(this, D))
1341
- (g = I(this, f)) == null || g.dispose(), (C = I(this, y)) == null || C.dispose(), (i = I(this, ig)) == null || i.dispose(), (s = I(this, mg)) == null || s.tex.destroy(), (l = I(this, Gg)) == null || l.tex.destroy(), o(this, f, o(this, y, o(this, ig, null))), o(this, mg, o(this, Gg, null));
1382
+ (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));
1342
1383
  else {
1343
- const c = I(this, O);
1344
- (t = I(this, M)) == null || t.dispose(), (a = I(this, X)) == null || a.dispose(), (u = I(this, gg)) == null || u.dispose(), I(this, $) && (c.deleteTexture(I(this, $).tex), c.deleteFramebuffer(I(this, $).fbo)), I(this, Ig) && (c.deleteTexture(I(this, Ig).tex), c.deleteFramebuffer(I(this, Ig).fbo)), o(this, M, o(this, X, o(this, gg, o(this, $, o(this, Ig, null)))));
1384
+ const c = I(this, j);
1385
+ (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)))));
1345
1386
  }
1346
- }, lI = new WeakSet(), yI = function() {
1387
+ }, BI = new WeakSet(), JI = function() {
1347
1388
  if (I(this, D))
1348
- I(this, N) && (I(this, N).backgroundTex.destroy(), I(this, N).obstacleTex.destroy(), I(this, N).sharedCoverage || I(this, N).coverageTex.destroy(), o(this, N, null));
1389
+ 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));
1349
1390
  else {
1350
- const g = I(this, O);
1351
- I(this, lg) && g.deleteTexture(I(this, lg)), I(this, J) && g.deleteTexture(I(this, J)), I(this, Cg) && I(this, Cg) !== I(this, J) && g.deleteTexture(I(this, Cg)), o(this, lg, o(this, J, o(this, Cg, null)));
1391
+ const g = I(this, j);
1392
+ I(this, og) && g.deleteTexture(I(this, og)), I(this, z) && g.deleteTexture(I(this, z)), I(this, eg) && I(this, eg) !== I(this, z) && g.deleteTexture(I(this, eg)), o(this, og, o(this, z, o(this, eg, null)));
1352
1393
  }
1353
- }, BI = new WeakSet(), zI = function() {
1354
- !I(this, kg) || I(this, H) === 0 || (I(this, D) ? h(this, nI, NI).call(this) : h(this, pI, EI).call(this));
1355
- }, nI = new WeakSet(), NI = function() {
1356
- const g = I(this, D), C = g.device, i = I(this, zg), s = I(this, Vg), l = I(this, Ng), t = I(this, cg), a = I(this, N);
1357
- if (!I(this, f) || !I(this, y))
1394
+ }, HI = new WeakSet(), sC = function() {
1395
+ !I(this, Mg) || I(this, V) === 0 || (I(this, D) ? L(this, XI, lC).call(this) : L(this, WI, AC).call(this));
1396
+ }, XI = new WeakSet(), lC = function() {
1397
+ const g = I(this, D), C = g.device, i = I(this, jg), s = I(this, Hg), l = I(this, Pg), t = I(this, Sg), S = I(this, E);
1398
+ if (!I(this, M) || !I(this, h))
1358
1399
  return;
1359
1400
  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;
1360
- const u = I(this, E), c = I(this, j), Z = I(this, H), S = I(this, v), A = 1 / u, B = 1 / c;
1361
- YI(C, I(this, yg), A, B, Pg, t.velocityDissipation), cI(C, I(this, Xg), A, B), cI(C, I(this, vg), A, B), cI(C, I(this, Rg), A, B), cI(C, I(this, Ug), A, B), vC(C, I(this, Wg), A, B, t.curl, Pg), RC(
1401
+ 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, oI, t.velocityDissipation), bI(C, I(this, Rg), A, m), bI(C, I(this, Wg), A, m), bI(C, I(this, Yg), A, m), bI(C, I(this, Ug), A, m), QC(C, I(this, xg), A, m, t.curl, oI), EC(
1362
1403
  C,
1363
- I(this, Yg),
1364
- 1 / Z,
1365
- 1 / S,
1404
+ I(this, kg),
1405
+ 1 / p,
1406
+ 1 / a,
1366
1407
  t.refraction,
1367
1408
  t.specularExp,
1368
- AI(t.waterColor),
1369
- AI(t.glowColor),
1409
+ nI(t.waterColor),
1410
+ nI(t.glowColor),
1370
1411
  t.shine,
1371
1412
  t.warpStrength ?? 0.015,
1372
- MI[t.algorithm] ?? 0,
1373
- I(this, Mg)
1413
+ _I[t.algorithm] ?? 0,
1414
+ I(this, fg)
1374
1415
  );
1375
- const m = C.createCommandEncoder(), r = (G, K) => C.createBindGroup({ layout: G.getBindGroupLayout(0), entries: K }), L = { binding: 1, resource: l };
1416
+ const Z = C.createCommandEncoder(), r = (B, K) => C.createBindGroup({ layout: B.getBindGroupLayout(0), entries: K }), b = { binding: 1, resource: l };
1376
1417
  {
1377
- const G = r(i.advection, [
1378
- { binding: 0, resource: { buffer: I(this, yg) } },
1379
- L,
1380
- { binding: 2, resource: I(this, y).read.view },
1381
- { binding: 3, resource: I(this, y).read.view },
1382
- { binding: 4, resource: a.obstacleView }
1418
+ const B = r(i.advection, [
1419
+ { binding: 0, resource: { buffer: I(this, Xg) } },
1420
+ b,
1421
+ { binding: 2, resource: I(this, h).read.view },
1422
+ { binding: 3, resource: I(this, h).read.view },
1423
+ { binding: 4, resource: S.obstacleView }
1383
1424
  ]);
1384
- Q(m, i.advection, G, s, I(this, y).write.view);
1425
+ O(Z, i.advection, B, s, I(this, h).write.view);
1385
1426
  }
1386
- I(this, y).swap();
1427
+ I(this, h).swap();
1387
1428
  {
1388
- YI(C, I(this, Hg), A, B, Pg, t.densityDissipation);
1389
- const G = r(i.advection, [
1390
- { binding: 0, resource: { buffer: I(this, Hg) } },
1391
- L,
1392
- { binding: 2, resource: I(this, y).read.view },
1393
- { binding: 3, resource: I(this, f).read.view },
1394
- { binding: 4, resource: a.obstacleView }
1429
+ jI(C, I(this, vg), A, m, oI, t.densityDissipation);
1430
+ const B = r(i.advection, [
1431
+ { binding: 0, resource: { buffer: I(this, vg) } },
1432
+ b,
1433
+ { binding: 2, resource: I(this, h).read.view },
1434
+ { binding: 3, resource: I(this, M).read.view },
1435
+ { binding: 4, resource: S.obstacleView }
1395
1436
  ]);
1396
- Q(m, i.advection, G, s, I(this, f).write.view);
1437
+ O(Z, i.advection, B, s, I(this, M).write.view);
1397
1438
  }
1398
- I(this, f).swap();
1439
+ I(this, M).swap();
1399
1440
  {
1400
- const G = r(i.curl, [
1441
+ const B = r(i.curl, [
1401
1442
  { binding: 0, resource: { buffer: I(this, Ug) } },
1402
- L,
1403
- { binding: 2, resource: I(this, y).read.view }
1443
+ b,
1444
+ { binding: 2, resource: I(this, h).read.view }
1404
1445
  ]);
1405
- Q(m, i.curl, G, s, I(this, Gg).view);
1446
+ O(Z, i.curl, B, s, I(this, ng).view);
1406
1447
  }
1407
1448
  {
1408
- const G = r(i.vorticity, [
1409
- { binding: 0, resource: { buffer: I(this, Wg) } },
1410
- L,
1411
- { binding: 2, resource: I(this, y).read.view },
1412
- { binding: 3, resource: I(this, Gg).view }
1449
+ const B = r(i.vorticity, [
1450
+ { binding: 0, resource: { buffer: I(this, xg) } },
1451
+ b,
1452
+ { binding: 2, resource: I(this, h).read.view },
1453
+ { binding: 3, resource: I(this, ng).view }
1413
1454
  ]);
1414
- Q(m, i.vorticity, G, s, I(this, y).write.view);
1455
+ O(Z, i.vorticity, B, s, I(this, h).write.view);
1415
1456
  }
1416
- if (I(this, y).swap(), I(this, w).moved) {
1417
- const G = I(this, w).x * I(this, T) / Z, K = I(this, w).y * I(this, T) / S;
1418
- dI(
1457
+ if (I(this, h).swap(), I(this, w).moved) {
1458
+ const B = I(this, w).x * I(this, F) / p, K = I(this, w).y * I(this, F) / a;
1459
+ wI(
1419
1460
  C,
1420
- I(this, tg),
1461
+ I(this, Ag),
1421
1462
  A,
1422
- B,
1423
- Z / S,
1463
+ m,
1464
+ p / a,
1424
1465
  t.splatRadius,
1425
1466
  I(this, w).dx * t.splatForce,
1426
1467
  I(this, w).dy * t.splatForce,
1427
1468
  0,
1428
- G,
1469
+ B,
1429
1470
  K
1430
1471
  );
1431
1472
  {
1432
- const b = r(i.splat, [
1433
- { binding: 0, resource: { buffer: I(this, tg) } },
1434
- L,
1435
- { binding: 2, resource: I(this, y).read.view }
1473
+ const W = r(i.splat, [
1474
+ { binding: 0, resource: { buffer: I(this, Ag) } },
1475
+ b,
1476
+ { binding: 2, resource: I(this, h).read.view }
1436
1477
  ]);
1437
- Q(m, i.splat, b, s, I(this, y).write.view);
1478
+ O(Z, i.splat, W, s, I(this, h).write.view);
1438
1479
  }
1439
- I(this, y).swap(), dI(
1480
+ I(this, h).swap(), wI(
1440
1481
  C,
1441
- I(this, og),
1482
+ I(this, cg),
1442
1483
  A,
1443
- B,
1444
- Z / S,
1484
+ m,
1485
+ p / a,
1445
1486
  t.splatRadius,
1446
1487
  1,
1447
1488
  1,
1448
1489
  1,
1449
- G,
1490
+ B,
1450
1491
  K
1451
1492
  );
1452
1493
  {
1453
- const b = r(i.splat, [
1454
- { binding: 0, resource: { buffer: I(this, og) } },
1455
- L,
1456
- { binding: 2, resource: I(this, f).read.view }
1494
+ const W = r(i.splat, [
1495
+ { binding: 0, resource: { buffer: I(this, cg) } },
1496
+ b,
1497
+ { binding: 2, resource: I(this, M).read.view }
1457
1498
  ]);
1458
- Q(m, i.splat, b, s, I(this, f).write.view);
1499
+ O(Z, i.splat, W, s, I(this, M).write.view);
1459
1500
  }
1460
- I(this, f).swap(), I(this, w).moved = !1;
1501
+ I(this, M).swap(), I(this, w).moved = !1;
1461
1502
  }
1462
1503
  {
1463
- const G = r(i.divergence, [
1464
- { binding: 0, resource: { buffer: I(this, Xg) } },
1465
- L,
1466
- { binding: 2, resource: I(this, y).read.view },
1467
- { binding: 3, resource: a.obstacleView }
1504
+ const B = r(i.divergence, [
1505
+ { binding: 0, resource: { buffer: I(this, Rg) } },
1506
+ b,
1507
+ { binding: 2, resource: I(this, h).read.view },
1508
+ { binding: 3, resource: S.obstacleView }
1468
1509
  ]);
1469
- Q(m, i.divergence, G, s, I(this, mg).view);
1510
+ O(Z, i.divergence, B, s, I(this, rg).view);
1470
1511
  }
1471
- for (let G = 0; G < t.pressureIterations; G++) {
1512
+ for (let B = 0; B < t.pressureIterations; B++) {
1472
1513
  const K = r(i.pressure, [
1473
- { binding: 0, resource: { buffer: I(this, vg) } },
1474
- L,
1475
- { binding: 2, resource: I(this, ig).read.view },
1476
- { binding: 3, resource: I(this, mg).view },
1477
- { binding: 4, resource: a.obstacleView }
1514
+ { binding: 0, resource: { buffer: I(this, Wg) } },
1515
+ b,
1516
+ { binding: 2, resource: I(this, sg).read.view },
1517
+ { binding: 3, resource: I(this, rg).view },
1518
+ { binding: 4, resource: S.obstacleView }
1478
1519
  ]);
1479
- Q(m, i.pressure, K, s, I(this, ig).write.view), I(this, ig).swap();
1520
+ O(Z, i.pressure, K, s, I(this, sg).write.view), I(this, sg).swap();
1480
1521
  }
1481
1522
  {
1482
- const G = r(i.gradientSubtract, [
1483
- { binding: 0, resource: { buffer: I(this, Rg) } },
1484
- L,
1485
- { binding: 2, resource: I(this, ig).read.view },
1486
- { binding: 3, resource: I(this, y).read.view },
1487
- { binding: 4, resource: a.obstacleView }
1523
+ const B = r(i.gradientSubtract, [
1524
+ { binding: 0, resource: { buffer: I(this, Yg) } },
1525
+ b,
1526
+ { binding: 2, resource: I(this, sg).read.view },
1527
+ { binding: 3, resource: I(this, h).read.view },
1528
+ { binding: 4, resource: S.obstacleView }
1488
1529
  ]);
1489
- Q(m, i.gradientSubtract, G, s, I(this, y).write.view);
1530
+ O(Z, i.gradientSubtract, B, s, I(this, h).write.view);
1490
1531
  }
1491
- I(this, y).swap();
1532
+ I(this, h).swap();
1492
1533
  {
1493
- const G = g.context.getCurrentTexture().createView(), K = r(i.display, [
1494
- { binding: 0, resource: { buffer: I(this, Yg) } },
1495
- L,
1496
- { binding: 2, resource: I(this, f).read.view },
1497
- { binding: 3, resource: a.obstacleView },
1498
- { binding: 4, resource: a.backgroundView },
1499
- { binding: 5, resource: a.coverageView },
1500
- { binding: 6, resource: I(this, y).read.view }
1534
+ const B = g.context.getCurrentTexture().createView(), K = r(i.display, [
1535
+ { binding: 0, resource: { buffer: I(this, kg) } },
1536
+ b,
1537
+ { binding: 2, resource: I(this, M).read.view },
1538
+ { binding: 3, resource: S.obstacleView },
1539
+ { binding: 4, resource: S.backgroundView },
1540
+ { binding: 5, resource: S.coverageView },
1541
+ { binding: 6, resource: I(this, h).read.view }
1501
1542
  ]);
1502
- UC(m, i.display, K, s, G);
1543
+ OC(Z, i.display, K, s, B);
1503
1544
  }
1504
- C.queue.submit([m.finish()]);
1505
- }, mI = new WeakSet(), QI = function(g, C, i, s, l) {
1506
- const a = I(this, D).device, u = I(this, zg).splat, c = I(this, Vg), Z = I(this, Ng), S = I(this, cg), A = I(this, E), B = I(this, j), m = 1 / A, r = 1 / B, L = a.createCommandEncoder(), G = { binding: 1, resource: Z }, K = (n) => a.createBindGroup({ layout: u.getBindGroupLayout(0), entries: n }), b = g * I(this, T) / I(this, H), Y = C * I(this, T) / I(this, v);
1507
- dI(
1508
- a,
1509
- I(this, tg),
1510
- m,
1545
+ C.queue.submit([Z.finish()]);
1546
+ }, vI = new WeakSet(), tC = function(g, C, i, s, l) {
1547
+ 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
+ wI(
1549
+ S,
1550
+ I(this, Ag),
1551
+ Z,
1511
1552
  r,
1512
- I(this, H) / I(this, v),
1513
- S.splatRadius,
1514
- i * S.splatForce * l,
1515
- s * S.splatForce * l,
1553
+ I(this, V) / I(this, X),
1554
+ a.splatRadius,
1555
+ i * a.splatForce * l,
1556
+ s * a.splatForce * l,
1516
1557
  0,
1517
- b,
1518
- Y
1558
+ W,
1559
+ x
1519
1560
  );
1520
1561
  {
1521
- const n = K([
1522
- { binding: 0, resource: { buffer: I(this, tg) } },
1523
- G,
1524
- { binding: 2, resource: I(this, y).read.view }
1562
+ const Q = K([
1563
+ { binding: 0, resource: { buffer: I(this, Ag) } },
1564
+ B,
1565
+ { binding: 2, resource: I(this, h).read.view }
1525
1566
  ]);
1526
- Q(L, u, n, c, I(this, y).write.view);
1567
+ O(b, u, Q, c, I(this, h).write.view);
1527
1568
  }
1528
- I(this, y).swap(), dI(
1529
- a,
1530
- I(this, og),
1531
- m,
1569
+ I(this, h).swap(), wI(
1570
+ S,
1571
+ I(this, cg),
1572
+ Z,
1532
1573
  r,
1533
- I(this, H) / I(this, v),
1534
- S.splatRadius,
1574
+ I(this, V) / I(this, X),
1575
+ a.splatRadius,
1535
1576
  l,
1536
1577
  l,
1537
1578
  l,
1538
- b,
1539
- Y
1579
+ W,
1580
+ x
1540
1581
  );
1541
1582
  {
1542
- const n = K([
1543
- { binding: 0, resource: { buffer: I(this, og) } },
1544
- G,
1545
- { binding: 2, resource: I(this, f).read.view }
1583
+ const Q = K([
1584
+ { binding: 0, resource: { buffer: I(this, cg) } },
1585
+ B,
1586
+ { binding: 2, resource: I(this, M).read.view }
1546
1587
  ]);
1547
- Q(L, u, n, c, I(this, f).write.view);
1588
+ O(b, u, Q, c, I(this, M).write.view);
1548
1589
  }
1549
- I(this, f).swap(), a.queue.submit([L.finish()]);
1550
- }, GI = new WeakSet(), OI = function(g, C, i, s, l) {
1551
- const t = I(this, O), a = I(this, cg), u = I(this, Kg).splat, c = I(this, Jg);
1552
- t.viewport(0, 0, I(this, E), I(this, j)), u.bind(), t.uniform1f(u.uniforms.aspectRatio, I(this, H) / I(this, v)), t.uniform2f(u.uniforms.point, g * I(this, T) / I(this, H), 1 - C * I(this, T) / I(this, v)), t.uniform1f(u.uniforms.radius, a.splatRadius), t.uniform1i(u.uniforms.uTarget, 0), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, I(this, X).read.tex), t.uniform3f(u.uniforms.color, i * a.splatForce * l, -s * a.splatForce * l, 0), c(I(this, X).write.fbo), I(this, X).swap(), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, I(this, M).read.tex), t.uniform3f(u.uniforms.color, l, l, l), c(I(this, M).write.fbo), I(this, M).swap();
1553
- }, pI = new WeakSet(), EI = function() {
1554
- if (!I(this, M) || !I(this, X))
1590
+ I(this, M).swap(), S.queue.submit([b.finish()]);
1591
+ }, RI = new WeakSet(), oC = function(g, C, i, s, l) {
1592
+ const t = I(this, j), S = I(this, Sg), u = I(this, Vg).splat, c = I(this, Og);
1593
+ t.viewport(0, 0, I(this, P), I(this, _)), u.bind(), t.uniform1f(u.uniforms.aspectRatio, I(this, V) / I(this, X)), t.uniform2f(u.uniforms.point, g * I(this, F) / I(this, V), 1 - C * I(this, F) / I(this, X)), t.uniform1f(u.uniforms.radius, S.splatRadius), t.uniform1i(u.uniforms.uTarget, 0), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, I(this, H).read.tex), t.uniform3f(u.uniforms.color, i * S.splatForce * l, -s * S.splatForce * l, 0), c(I(this, H).write.fbo), I(this, H).swap(), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, I(this, k).read.tex), t.uniform3f(u.uniforms.color, l, l, l), c(I(this, k).write.fbo), I(this, k).swap();
1594
+ }, WI = new WeakSet(), AC = function() {
1595
+ if (!I(this, k) || !I(this, H))
1555
1596
  return;
1556
- const g = I(this, O), C = I(this, cg), { advection: i, divergence: s, pressure: l, gradientSubtract: t, splat: a, curl: u, vorticity: c, display: Z } = I(this, Kg);
1597
+ 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);
1557
1598
  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;
1558
- const S = I(this, E), A = I(this, j), B = I(this, Jg);
1559
- g.viewport(0, 0, S, A), i.bind(), g.uniform2f(i.uniforms.texelSize, 1 / S, 1 / A), g.uniform1f(i.uniforms.dt, Pg), g.uniform1i(i.uniforms.uObstacle, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, J)), g.uniform1f(i.uniforms.dissipation, C.velocityDissipation), g.uniform1i(i.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(i.uniforms.uSource, 1), B(I(this, X).write.fbo), I(this, X).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, M).read.tex), B(I(this, M).write.fbo), I(this, M).swap(), u.bind(), g.uniform2f(u.uniforms.texelSize, 1 / S, 1 / A), g.uniform1i(u.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), B(I(this, Ig).fbo), c.bind(), g.uniform2f(c.uniforms.texelSize, 1 / S, 1 / A), g.uniform1f(c.uniforms.curl, C.curl), g.uniform1f(c.uniforms.dt, Pg), g.uniform1i(c.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(c.uniforms.uCurl, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, Ig).tex), B(I(this, X).write.fbo), I(this, X).swap(), I(this, w).moved && (a.bind(), g.uniform1f(a.uniforms.aspectRatio, I(this, H) / I(this, v)), g.uniform2f(a.uniforms.point, I(this, w).x * I(this, T) / I(this, H), 1 - I(this, w).y * I(this, T) / I(this, v)), g.uniform1f(a.uniforms.radius, C.splatRadius), g.uniform1i(a.uniforms.uTarget, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform3f(a.uniforms.color, I(this, w).dx * C.splatForce, -I(this, w).dy * C.splatForce, 0), B(I(this, X).write.fbo), I(this, X).swap(), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, M).read.tex), g.uniform3f(a.uniforms.color, 1, 1, 1), B(I(this, M).write.fbo), I(this, M).swap(), I(this, w).moved = !1), s.bind(), g.uniform2f(s.uniforms.texelSize, 1 / S, 1 / A), g.uniform1i(s.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(s.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, J)), B(I(this, $).fbo), l.bind(), g.uniform2f(l.uniforms.texelSize, 1 / S, 1 / A), g.uniform1i(l.uniforms.uDivergence, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, $).tex), g.uniform1i(l.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, J));
1560
- for (let m = 0; m < C.pressureIterations; m++)
1561
- g.uniform1i(l.uniforms.uPressure, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, gg).read.tex), B(I(this, gg).write.fbo), I(this, gg).swap();
1562
- t.bind(), g.uniform2f(t.uniforms.texelSize, 1 / S, 1 / A), g.uniform1i(t.uniforms.uPressure, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, gg).read.tex), g.uniform1i(t.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(t.uniforms.uObstacle, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, J)), B(I(this, X).write.fbo), I(this, X).swap(), g.viewport(0, 0, I(this, H), I(this, v)), g.bindFramebuffer(g.FRAMEBUFFER, null), g.clear(g.COLOR_BUFFER_BIT), Z.bind(), g.uniform2f(Z.uniforms.texelSize, 1 / I(this, H), 1 / I(this, v)), g.uniform3fv(Z.uniforms.uWaterColor, AI(C.waterColor)), g.uniform3fv(Z.uniforms.uGlowColor, AI(C.glowColor)), g.uniform1f(Z.uniforms.uRefraction, C.refraction), g.uniform1f(Z.uniforms.uSpecularExp, C.specularExp), g.uniform1f(Z.uniforms.uShine, C.shine), g.uniform1f(Z.uniforms.uWarpStrength, C.warpStrength ?? 0.015), g.uniform1i(Z.uniforms.uAlgorithm, MI[C.algorithm] ?? 0), g.uniform1i(Z.uniforms.uEnableAlpha, I(this, Mg) ? 1 : 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, M).read.tex), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, J)), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, lg)), g.activeTexture(g.TEXTURE3), g.bindTexture(g.TEXTURE_2D, I(this, Cg)), g.activeTexture(g.TEXTURE4), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(Z.uniforms.uTexture, 0), g.uniform1i(Z.uniforms.uObstacle, 1), g.uniform1i(Z.uniforms.uBackground, 2), g.uniform1i(Z.uniforms.uCoverage, 3), g.uniform1i(Z.uniforms.uVelocity, 4), B(null);
1599
+ 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, oI), 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, oI), 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
+ for (let Z = 0; Z < C.pressureIterations; Z++)
1602
+ 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, nI(C.waterColor)), g.uniform3fv(p.uniforms.uGlowColor, nI(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);
1563
1604
  };
1564
- let ZI = vI;
1565
- const jI = "dmFyIFR0ID0gT2JqZWN0LmRlZmluZVByb3BlcnR5Owp2YXIgeXQgPSAoaSwgZSwgcikgPT4gZSBpbiBpID8gVHQoaSwgZSwgeyBlbnVtZXJhYmxlOiAhMCwgY29uZmlndXJhYmxlOiAhMCwgd3JpdGFibGU6ICEwLCB2YWx1ZTogciB9KSA6IGlbZV0gPSByOwp2YXIga2UgPSAoaSwgZSwgcikgPT4gKHl0KGksIHR5cGVvZiBlICE9ICJzeW1ib2wiID8gZSArICIiIDogZSwgciksIHIpLCBldCA9IChpLCBlLCByKSA9PiB7CiAgaWYgKCFlLmhhcyhpKSkKICAgIHRocm93IFR5cGVFcnJvcigiQ2Fubm90ICIgKyByKTsKfTsKdmFyIHQgPSAoaSwgZSwgcikgPT4gKGV0KGksIGUsICJyZWFkIGZyb20gcHJpdmF0ZSBmaWVsZCIpLCByID8gci5jYWxsKGkpIDogZS5nZXQoaSkpLCBmID0gKGksIGUsIHIpID0+IHsKICBpZiAoZS5oYXMoaSkpCiAgICB0aHJvdyBUeXBlRXJyb3IoIkNhbm5vdCBhZGQgdGhlIHNhbWUgcHJpdmF0ZSBtZW1iZXIgbW9yZSB0aGFuIG9uY2UiKTsKICBlIGluc3RhbmNlb2YgV2Vha1NldCA/IGUuYWRkKGkpIDogZS5zZXQoaSwgcik7Cn0sIGwgPSAoaSwgZSwgciwgcykgPT4gKGV0KGksIGUsICJ3cml0ZSB0byBwcml2YXRlIGZpZWxkIiksIHMgPyBzLmNhbGwoaSwgcikgOiBlLnNldChpLCByKSwgcik7CnZhciBTID0gKGksIGUsIHIpID0+IChldChpLCBlLCAiYWNjZXNzIHByaXZhdGUgbWV0aG9kIiksIHIpOwpjb25zdCB2dCA9IHsKICBkZW5zaXR5RGlzc2lwYXRpb246IDAuOTkyLAogIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuOTMsCiAgcHJlc3N1cmVJdGVyYXRpb25zOiAxLAogIGN1cmw6IDFlLTQsCiAgc3BsYXRSYWRpdXM6IDRlLTMsCiAgc3BsYXRGb3JjZTogMC45MSwKICByZWZyYWN0aW9uOiAwLjI1LAogIHNwZWN1bGFyRXhwOiAxLjAxLAogIHNoaW5lOiAwLjAxLAogIHdhdGVyQ29sb3I6ICIjMDAwMDAwIiwKICBnbG93Q29sb3I6ICIjYjNkOWZmIiwKICBhbGdvcml0aG06ICJzdGFuZGFyZCIsCiAgd2FycFN0cmVuZ3RoOiAwLjAxNQp9OwooewogIC4uLnZ0Cn0pOwpjb25zdCBTdCA9IHsKICBjYWxtOiB7CiAgICBkZW5zaXR5RGlzc2lwYXRpb246IDAuOTk5LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC45OCwKICAgIGN1cmw6IDFlLTQsCiAgICBzcGxhdFJhZGl1czogM2UtMywKICAgIHNwbGF0Rm9yY2U6IDAuNSwKICAgIHJlZnJhY3Rpb246IDAuMTUsCiAgICBzaGluZTogNWUtMywKICAgIGdsb3dDb2xvcjogIiM5OWQ5ZmYiLAogICAgd2F0ZXJDb2xvcjogIiMwMDA1MGQiCiAgfSwKICBzYW5kOiB7CiAgICBkZW5zaXR5RGlzc2lwYXRpb246IDAuOTk3LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC45OCwKICAgIGN1cmw6IDEsCiAgICBzcGxhdFJhZGl1czogMC4wMSwKICAgIHNwbGF0Rm9yY2U6IDAuOSwKICAgIHJlZnJhY3Rpb246IDAuOCwKICAgIHNwZWN1bGFyRXhwOiAwLjEsCiAgICBzaGluZTogMC4wNSwKICAgIGdsb3dDb2xvcjogIiMwNzA3MDciLAogICAgd2F0ZXJDb2xvcjogIiM3MzU0MjAiCiAgfSwKICB3YXZlOiB7CiAgICBkZW5zaXR5RGlzc2lwYXRpb246IDAuOTk0LAogICAgdmVsb2NpdHlEaXNzaXBhdGlvbjogMC45MiwKICAgIGN1cmw6IDAuMiwKICAgIHNwbGF0UmFkaXVzOiA1ZS0zLAogICAgc3BsYXRGb3JjZTogMS4yLAogICAgcmVmcmFjdGlvbjogMC4zNSwKICAgIHNoaW5lOiAwLjAzLAogICAgZ2xvd0NvbG9yOiAiIzgwY2NmZiIsCiAgICB3YXRlckNvbG9yOiAiIzAwMDMwOCIKICB9LAogIG5lb246IHsKICAgIGRlbnNpdHlEaXNzaXBhdGlvbjogMC45ODUsCiAgICB2ZWxvY2l0eURpc3NpcGF0aW9uOiAwLjkzLAogICAgY3VybDogMC4wNSwKICAgIHNwbGF0UmFkaXVzOiA4ZS0zLAogICAgc3BsYXRGb3JjZTogMS41LAogICAgcmVmcmFjdGlvbjogMC4yNSwKICAgIHNwZWN1bGFyRXhwOiAwLjUsCiAgICBzaGluZTogMC4xNCwKICAgIGdsb3dDb2xvcjogIiNmZjMzY2MiLAogICAgd2F0ZXJDb2xvcjogIiMwZDAwMTQiCiAgfSwKICBzbW9rZTogewogICAgZGVuc2l0eURpc3NpcGF0aW9uOiAwLjk5NiwKICAgIHZlbG9jaXR5RGlzc2lwYXRpb246IDAuOTcsCiAgICBjdXJsOiAwLjA0LAogICAgc3BsYXRSYWRpdXM6IDllLTMsCiAgICBzcGxhdEZvcmNlOiAwLjgsCiAgICByZWZyYWN0aW9uOiAwLjA4LAogICAgc2hpbmU6IDAsCiAgICBnbG93Q29sb3I6ICIjODA4MDgwIiwKICAgIHdhdGVyQ29sb3I6ICIjMGYwZjBmIgogIH0KfTsKZnVuY3Rpb24gV2UoaSkgewogIGlmIChBcnJheS5pc0FycmF5KGkpKQogICAgcmV0dXJuIGk7CiAgY29uc3QgZSA9IGkuc2xpY2UoMSwgNyk7CiAgcmV0dXJuIGUubGVuZ3RoID09PSAzID8gWwogICAgcGFyc2VJbnQoZVswXSArIGVbMF0sIDE2KSAvIDI1NSwKICAgIHBhcnNlSW50KGVbMV0gKyBlWzFdLCAxNikgLyAyNTUsCiAgICBwYXJzZUludChlWzJdICsgZVsyXSwgMTYpIC8gMjU1CiAgXSA6IFsKICAgIHBhcnNlSW50KGUuc2xpY2UoMCwgMiksIDE2KSAvIDI1NSwKICAgIHBhcnNlSW50KGUuc2xpY2UoMiwgNCksIDE2KSAvIDI1NSwKICAgIHBhcnNlSW50KGUuc2xpY2UoNCwgNiksIDE2KSAvIDI1NQogIF07Cn0KZnVuY3Rpb24gd3QoaSA9IHt9LCBlLCByID0gdnQpIHsKICByZXR1cm4geyAuLi5lID8geyAuLi5yLCAuLi5TdFtlXSB9IDogciwgLi4uaSB9Owp9CmNvbnN0IHJlID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIGF0dHJpYnV0ZSB2ZWMyIGFQb3NpdGlvbjsKICB2YXJ5aW5nIHZlYzIgdlV2OwogIHZhcnlpbmcgdmVjMiB2TDsgdmFyeWluZyB2ZWMyIHZSOyB2YXJ5aW5nIHZlYzIgdlQ7IHZhcnlpbmcgdmVjMiB2QjsKICB1bmlmb3JtIHZlYzIgdGV4ZWxTaXplOwogIHZvaWQgbWFpbiAoKSB7CiAgICB2VXYgPSBhUG9zaXRpb24gKiAwLjUgKyAwLjU7CiAgICB2TCA9IHZVdiAtIHZlYzIodGV4ZWxTaXplLngsIDAuMCk7CiAgICB2UiA9IHZVdiArIHZlYzIodGV4ZWxTaXplLngsIDAuMCk7CiAgICB2VCA9IHZVdiArIHZlYzIoMC4wLCB0ZXhlbFNpemUueSk7CiAgICB2QiA9IHZVdiAtIHZlYzIoMC4wLCB0ZXhlbFNpemUueSk7CiAgICBnbF9Qb3NpdGlvbiA9IHZlYzQoYVBvc2l0aW9uLCAwLjAsIDEuMCk7CiAgfQpgCiksIFJ0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVTb3VyY2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdU9ic3RhY2xlOwogIHVuaWZvcm0gdmVjMiB0ZXhlbFNpemU7CiAgdW5pZm9ybSBmbG9hdCBkdDsKICB1bmlmb3JtIGZsb2F0IGRpc3NpcGF0aW9uOwogIHZvaWQgbWFpbiAoKSB7CiAgICBpZiAodGV4dHVyZTJEKHVPYnN0YWNsZSwgdlV2KS5yID4gMC41KSB7IGdsX0ZyYWdDb2xvciA9IHZlYzQoMC4wKTsgcmV0dXJuOyB9CiAgICB2ZWMyIGNvb3JkID0gdlV2IC0gZHQgKiB0ZXh0dXJlMkQodVZlbG9jaXR5LCB2VXYpLnh5ICogdGV4ZWxTaXplOwogICAgZ2xfRnJhZ0NvbG9yID0gZGlzc2lwYXRpb24gKiB0ZXh0dXJlMkQodVNvdXJjZSwgY29vcmQpOwogIH0KYAopLCBFdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZMKS5yID4gMC41ID8gMC4wIDogdGV4dHVyZTJEKHVWZWxvY2l0eSwgdkwpLng7CiAgICBmbG9hdCBSID0gdGV4dHVyZTJEKHVPYnN0YWNsZSwgdlIpLnIgPiAwLjUgPyAwLjAgOiB0ZXh0dXJlMkQodVZlbG9jaXR5LCB2UikueDsKICAgIGZsb2F0IFQgPSB0ZXh0dXJlMkQodU9ic3RhY2xlLCB2VCkuciA+IDAuNSA/IDAuMCA6IHRleHR1cmUyRCh1VmVsb2NpdHksIHZUKS55OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZCKS5yID4gMC41ID8gMC4wIDogdGV4dHVyZTJEKHVWZWxvY2l0eSwgdkIpLnk7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KDAuNSAqIChSIC0gTCArIFQgLSBCKSwgMC4wLCAwLjAsIDEuMCk7CiAgfQpgCiksIFV0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7IHZhcnlpbmcgdmVjMiB2TDsgdmFyeWluZyB2ZWMyIHZSOyB2YXJ5aW5nIHZlYzIgdlQ7IHZhcnlpbmcgdmVjMiB2QjsKICB1bmlmb3JtIHNhbXBsZXIyRCB1UHJlc3N1cmU7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdURpdmVyZ2VuY2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdU9ic3RhY2xlOwogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBDID0gdGV4dHVyZTJEKHVQcmVzc3VyZSwgdlV2KS54OwogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZMKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZMKS54OwogICAgZmxvYXQgUiA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZSKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZSKS54OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZUKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZUKS54OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1T2JzdGFjbGUsIHZCKS5yID4gMC41ID8gQyA6IHRleHR1cmUyRCh1UHJlc3N1cmUsIHZCKS54OwogICAgZmxvYXQgZGl2ID0gdGV4dHVyZTJEKHVEaXZlcmdlbmNlLCB2VXYpLng7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KChMICsgUiArIEIgKyBUIC0gZGl2KSAqIDAuMjUsIDAuMCwgMC4wLCAxLjApOwogIH0KYAopLCBEdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OyB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVByZXNzdXJlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1T2JzdGFjbGU7CiAgdm9pZCBtYWluICgpIHsKICAgIGlmICh0ZXh0dXJlMkQodU9ic3RhY2xlLCB2VXYpLnIgPiAwLjUpIHsgZ2xfRnJhZ0NvbG9yID0gdmVjNCgwLjApOyByZXR1cm47IH0KICAgIGZsb2F0IEwgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2TCkueDsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2UikueDsKICAgIGZsb2F0IFQgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2VCkueDsKICAgIGZsb2F0IEIgPSB0ZXh0dXJlMkQodVByZXNzdXJlLCB2QikueDsKICAgIHZlYzIgdmVsID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eSAtIHZlYzIoUiAtIEwsIFQgLSBCKTsKICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQodmVsLCAwLjAsIDEuMCk7CiAgfQpgCiksIF90ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVRhcmdldDsKICB1bmlmb3JtIGZsb2F0IGFzcGVjdFJhdGlvOwogIHVuaWZvcm0gdmVjMyBjb2xvcjsKICB1bmlmb3JtIHZlYzIgcG9pbnQ7CiAgdW5pZm9ybSBmbG9hdCByYWRpdXM7CiAgdm9pZCBtYWluICgpIHsKICAgIHZlYzIgcCA9IHZVdiAtIHBvaW50Lnh5OwogICAgcC54ICo9IGFzcGVjdFJhdGlvOwogICAgdmVjMyBzcGxhdCA9IGV4cCgtZG90KHAsIHApIC8gcmFkaXVzKSAqIGNvbG9yOwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCh0ZXh0dXJlMkQodVRhcmdldCwgdlV2KS54eXogKyBzcGxhdCwgMS4wKTsKICB9CmAKKSwgQ3QgPSAoCiAgLyogZ2xzbCAqLwogIGAKICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7CiAgdmFyeWluZyB2ZWMyIHZMOyB2YXJ5aW5nIHZlYzIgdlI7IHZhcnlpbmcgdmVjMiB2VDsgdmFyeWluZyB2ZWMyIHZCOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVWZWxvY2l0eTsKICB2b2lkIG1haW4gKCkgewogICAgZmxvYXQgTCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZMKS55OwogICAgZmxvYXQgUiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZSKS55OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZUKS54OwogICAgZmxvYXQgQiA9IHRleHR1cmUyRCh1VmVsb2NpdHksIHZCKS54OwogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNCgwLjUgKiAoUiAtIEwgLSBUICsgQiksIDAuMCwgMC4wLCAxLjApOwogIH0KYAopLCBCdCA9ICgKICAvKiBnbHNsICovCiAgYAogIHByZWNpc2lvbiBoaWdocCBmbG9hdDsKICB2YXJ5aW5nIHZlYzIgdlV2OyB2YXJ5aW5nIHZlYzIgdkw7IHZhcnlpbmcgdmVjMiB2UjsgdmFyeWluZyB2ZWMyIHZUOyB2YXJ5aW5nIHZlYzIgdkI7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwogIHVuaWZvcm0gc2FtcGxlcjJEIHVDdXJsOwogIHVuaWZvcm0gZmxvYXQgY3VybDsKICB1bmlmb3JtIGZsb2F0IGR0OwogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBMID0gdGV4dHVyZTJEKHVDdXJsLCB2TCkueDsKICAgIGZsb2F0IFIgPSB0ZXh0dXJlMkQodUN1cmwsIHZSKS54OwogICAgZmxvYXQgVCA9IHRleHR1cmUyRCh1Q3VybCwgdlQpLng7CiAgICBmbG9hdCBCID0gdGV4dHVyZTJEKHVDdXJsLCB2QikueDsKICAgIGZsb2F0IEMgPSB0ZXh0dXJlMkQodUN1cmwsIHZVdikueDsKICAgIHZlYzIgZm9yY2UgPSAwLjUgKiB2ZWMyKGFicyhUKSAtIGFicyhCKSwgYWJzKFIpIC0gYWJzKEwpKTsKICAgIGZvcmNlIC89IGxlbmd0aChmb3JjZSkgKyAwLjAwMDE7CiAgICBmb3JjZSAqPSBjdXJsICogMzAuMCAqIEM7CiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KHRleHR1cmUyRCh1VmVsb2NpdHksIHZVdikueHkgKyBmb3JjZSAqIGR0LCAwLjAsIDEuMCk7CiAgfQpgCiksIFZ0ID0gKAogIC8qIGdsc2wgKi8KICBgCiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0OwogIHZhcnlpbmcgdmVjMiB2VXY7CgogIHVuaWZvcm0gc2FtcGxlcjJEIHVUZXh0dXJlOwogIHVuaWZvcm0gc2FtcGxlcjJEIHVPYnN0YWNsZTsKICB1bmlmb3JtIHNhbXBsZXIyRCB1QmFja2dyb3VuZDsKICB1bmlmb3JtIHNhbXBsZXIyRCB1Q292ZXJhZ2U7CiAgdW5pZm9ybSBzYW1wbGVyMkQgdVZlbG9jaXR5OwoKICB1bmlmb3JtIHZlYzIgIHRleGVsU2l6ZTsKICB1bmlmb3JtIHZlYzMgIHVXYXRlckNvbG9yOwogIHVuaWZvcm0gdmVjMyAgdUdsb3dDb2xvcjsKICB1bmlmb3JtIGZsb2F0IHVSZWZyYWN0aW9uOwogIHVuaWZvcm0gZmxvYXQgdVNwZWN1bGFyRXhwOwogIHVuaWZvcm0gZmxvYXQgdVNoaW5lOwogIHVuaWZvcm0gZmxvYXQgdVdhcnBTdHJlbmd0aDsKICB1bmlmb3JtIGludCAgIHVBbGdvcml0aG07CiAgdW5pZm9ybSBpbnQgICB1RW5hYmxlQWxwaGE7CgogIHZvaWQgbWFpbiAoKSB7CiAgICBmbG9hdCBvYnMgICAgICA9IHRleHR1cmUyRCh1T2JzdGFjbGUsICB2VXYpLnI7CiAgICAvLyBNYXNrIGRlbnNpdHkgaW5zaWRlIG9ic3RhY2xlcyBzbyBzcGxhdHMgZG9uJ3QgZmxpY2tlciB0aGUgdGV4dC9pbWFnZSBjb250ZW50LgogICAgZmxvYXQgZGVuc2l0eSAgPSBtYXgodGV4dHVyZTJEKHVUZXh0dXJlLCB2VXYpLnIsIDAuMCkgKiAoMS4wIC0gc3RlcCgwLjUsIG9icykpOwogICAgZmxvYXQgY292ZXJhZ2UgPSB0ZXh0dXJlMkQodUNvdmVyYWdlLCAgdlV2KS5yOwoKICAgIGZsb2F0IGRMID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2IC0gdmVjMih0ZXhlbFNpemUueCAqIDIuMCwgMC4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGRSID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMih0ZXhlbFNpemUueCAqIDIuMCwgMC4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGRUID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2ICsgdmVjMigwLjAsIHRleGVsU2l6ZS55ICogMi4wKSkuciwgMC4wKTsKICAgIGZsb2F0IGRCID0gbWF4KHRleHR1cmUyRCh1VGV4dHVyZSwgdlV2IC0gdmVjMigwLjAsIHRleGVsU2l6ZS55ICogMi4wKSkuciwgMC4wKTsKCiAgICB2ZWMzICBub3JtYWwgICA9IG5vcm1hbGl6ZSh2ZWMzKGRMIC0gZFIsIGRCIC0gZFQsIDAuMikpOwogICAgdmVjMyAgbGlnaHREaXIgPSBub3JtYWxpemUodmVjMygwLjUsIDEuMCwgMC41KSk7CiAgICB2ZWMzICBoYWxmViAgICA9IG5vcm1hbGl6ZShsaWdodERpciArIHZlYzMoMC4wLCAwLjAsIDEuMCkpOwogICAgZmxvYXQgc3BlYyAgICAgPSBwb3cobWF4KGRvdChub3JtYWwsIGhhbGZWKSwgMC4wKSwgdVNwZWN1bGFyRXhwKSAqIHVTaGluZSAqIGRlbnNpdHk7CgogICAgLy8gSW4gdHJhbnNwYXJlbnQgKG5vbi1jb3ZlcmFnZSkgYXJlYXMgdGhlIGJhY2tncm91bmQgdGV4dHVyZSBpcyBlbXB0eSBibGFjayBjYW52YXMuCiAgICAvLyBSZXBsYWNlIGl0IHdpdGggdVdhdGVyQ29sb3Igc28gZmx1aWQgY29sb3VyIGlzIG5vdCBjb250YW1pbmF0ZWQgYnkgdGhhdCBibGFjaywKICAgIC8vIGFsbG93aW5nIHRoZSBDU1MgYmFja2dyb3VuZENvbG9yIHRvIHNob3cgdGhyb3VnaCBjb3JyZWN0bHkgdmlhIHByZW11bHRpcGxpZWQgYWxwaGEuCiAgICB2ZWMzIGJnUmF3ID0gdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCB2VXYpLnJnYjsKICAgIHZlYzMgYmcgICAgPSBtaXgodVdhdGVyQ29sb3IsIGJnUmF3LCBjb3ZlcmFnZSk7CiAgICB2ZWMzIGNvbG9yID0gYmc7CgogICAgaWYgKHVBbGdvcml0aG0gPT0gMSkgewogICAgICAvLyDilIDilIAgZ2xhc3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFN0cm9uZyBVViBkaXN0b3J0aW9uIG9ubHkuIEltYWdlIGJlbmRzIGJ1dCBubyBjb2xvdXIgb3ZlcmxheS4KICAgICAgdmVjMiByZWZyVXYgPSBjbGFtcCh2VXYgKyBub3JtYWwueHkgKiB1UmVmcmFjdGlvbiAqIGRlbnNpdHkgKiAzLjAsIDAuMCwgMS4wKTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgPSByZWZyQmcgKyBzcGVjICogdUdsb3dDb2xvciAqIDIuNTsKICAgICAgY29sb3IgPSBtaXgoY29sb3IsIGJnICogMC42LCBvYnMgKiAwLjMpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAyKSB7CiAgICAgIC8vIOKUgOKUgCBpbmsg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIERlbnNlIG9wYXF1ZSBwaWdtZW50IHRoYXQgc3RhaW5zLiBTdWJ0bGUgcmVmcmFjdGlvbiB1bmRlcm5lYXRoLgogICAgICBmbG9hdCBpbmtEICA9IG1pbihkZW5zaXR5ICogNC4wLCAxLjApOwogICAgICB2ZWMyIHJlZnJVdiA9IGNsYW1wKHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eSAqIDAuNCwgMC4wLCAxLjApOwogICAgICB2ZWMzIHJlZnJCZyA9IG1peCh1V2F0ZXJDb2xvciwgdGV4dHVyZTJEKHVCYWNrZ3JvdW5kLCBtaXgodlV2LCByZWZyVXYsIDEuMCAtIG9icykpLnJnYiwgY292ZXJhZ2UpOwogICAgICBjb2xvciA9IG1peChyZWZyQmcsIHVXYXRlckNvbG9yICsgc3BlYyAqIHVHbG93Q29sb3IsIGlua0QpOwogICAgICBjb2xvciA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMTUpOwoKICAgIH0gZWxzZSBpZiAodUFsZ29yaXRobSA9PSAzKSB7CiAgICAgIC8vIOKUgOKUgCBhdXJvcmEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiAgICAgIC8vIFZlbG9jaXR5IGZpZWxkIHdhcnBzIGJhY2tncm91bmQgVVZzIOKAlCBsaXF1aWQgbWV0YWwgLyBsYXZhLWxhbXAgZmVlbC4KICAgICAgdmVjMiAgdmVsICAgID0gdGV4dHVyZTJEKHVWZWxvY2l0eSwgdlV2KS54eTsKICAgICAgZmxvYXQgdmVsTWFnID0gY2xhbXAobGVuZ3RoKHZlbCkgKiAyMC4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzIgIHdhcnBVdiA9IGNsYW1wKHZVdiArIHZlbCAqIHVXYXJwU3RyZW5ndGgsIDAuMCwgMS4wKTsKICAgICAgdmVjMyAgd2FycEJnID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIHdhcnBVdikucmdiLCBjb3ZlcmFnZSk7CiAgICAgIGNvbG9yICA9IG1peChiZywgd2FycEJnLCB2ZWxNYWcgKiAoMS4wIC0gb2JzKSk7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogdmVsTWFnICogMS41OwogICAgICBjb2xvciArPSB1V2F0ZXJDb2xvciAqIGRlbnNpdHkgKiAwLjM7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CgogICAgfSBlbHNlIGlmICh1QWxnb3JpdGhtID09IDQpIHsKICAgICAgLy8g4pSA4pSAIHJpcHBsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgLy8gRXhhZ2dlcmF0ZWQgbm9ybWFsIHBlcnR1cmJhdGlvbiArIEZyZXNuZWwgcmltIOKAlCBjYWxtIHdhdGVyIHN1cmZhY2UuCiAgICAgIHZlYzIgIHJpcHBsZVV2ID0gY2xhbXAodlV2ICsgbm9ybWFsLnh5ICogdVJlZnJhY3Rpb24gKiBkZW5zaXR5ICogNi4wLCAwLjAsIDEuMCk7CiAgICAgIHZlYzMgIHJlZnJCZyAgID0gbWl4KHVXYXRlckNvbG9yLCB0ZXh0dXJlMkQodUJhY2tncm91bmQsIG1peCh2VXYsIHJpcHBsZVV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgZmxvYXQgZnJlc25lbCAgPSBwb3coY2xhbXAoMS4wIC0gZG90KG5vcm1hbCwgdmVjMygwLjAsIDAuMCwgMS4wKSksIDAuMCwgMS4wKSwgMy4wKSAqIGRlbnNpdHk7CiAgICAgIGNvbG9yICA9IHJlZnJCZzsKICAgICAgY29sb3IgKz0gZnJlc25lbCAqIHVHbG93Q29sb3IgKiAyLjA7CiAgICAgIGNvbG9yICs9IHNwZWMgKiB1R2xvd0NvbG9yICogZGVuc2l0eSAqIDIuMDsKICAgICAgY29sb3IgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKCiAgICB9IGVsc2UgewogICAgICAvLyDilIDilIAgc3RhbmRhcmQgKDApIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgICAvLyBPcmlnaW5hbDogY29sb3VyIG92ZXJsYXkgYmxlbmRlZCBvdmVyIHJlZnJhY3RlZCBiYWNrZ3JvdW5kLgogICAgICB2ZWMyIHJlZnJVdiA9IHZVdiArIG5vcm1hbC54eSAqIHVSZWZyYWN0aW9uICogZGVuc2l0eTsKICAgICAgdmVjMyByZWZyQmcgPSBtaXgodVdhdGVyQ29sb3IsIHRleHR1cmUyRCh1QmFja2dyb3VuZCwgbWl4KHZVdiwgcmVmclV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdmVyYWdlKTsKICAgICAgY29sb3IgID0gbWl4KHJlZnJCZywgdVdhdGVyQ29sb3IsIG1pbihkZW5zaXR5ICogMS41LCAwLjgpKTsKICAgICAgY29sb3IgKz0gc3BlYyAqIHVHbG93Q29sb3I7CiAgICAgIGNvbG9yICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMik7CiAgICB9CgogICAgLy8gT3V0cHV0OiBwcmVtdWx0aXBsaWVkIGFscGhhIHdoZW4gdHJhbnNwYXJlbmN5IGlzIGVuYWJsZWQgKGxldHMgQ1NTIGJhY2tncm91bmRDb2xvcgogICAgLy8gc2hvdyB0aHJvdWdoKSwgb3Igc3RyYWlnaHQgb3BhcXVlIGNvbG91ciB3aGVuIGVuYWJsZUFscGhhIGlzIG9mZiAocGVyZiBtb2RlKS4KICAgIGZsb2F0IGFscGhhID0gY2xhbXAobWF4KGRlbnNpdHkgKiAxLjUsIGNvdmVyYWdlKSwgMC4wLCAxLjApOwogICAgaWYgKHVFbmFibGVBbHBoYSA9PSAxKSB7CiAgICAgIGdsX0ZyYWdDb2xvciA9IHZlYzQoY29sb3IgKiBhbHBoYSwgYWxwaGEpOwogICAgfSBlbHNlIHsKICAgICAgZ2xfRnJhZ0NvbG9yID0gdmVjNChjb2xvciwgMS4wKTsKICAgIH0KICB9CmAKKTsKZnVuY3Rpb24gT3QoaSwgZSA9ICEwKSB7CiAgY29uc3QgciA9IHsgYWxwaGE6IGUsIGRlcHRoOiAhMSwgc3RlbmNpbDogITEsIGFudGlhbGlhczogITAsIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogITEgfTsKICBsZXQgcyA9IGkuZ2V0Q29udGV4dCgid2ViZ2wyIiwgcik7CiAgY29uc3QgbyA9ICEhczsKICBvIHx8IChzID0gaS5nZXRDb250ZXh0KCJ3ZWJnbCIsIHIpLCBzLmdldEV4dGVuc2lvbigiRVhUX2NvbG9yX2J1ZmZlcl9oYWxmX2Zsb2F0IikpOwogIGNvbnN0IGEgPSBvID8gbnVsbCA6IHMuZ2V0RXh0ZW5zaW9uKCJPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0IiksIHUgPSBvID8gcy5IQUxGX0ZMT0FUIDogYS5IQUxGX0ZMT0FUX09FUzsKICByZXR1cm4gcy5nZXRFeHRlbnNpb24oIkVYVF9jb2xvcl9idWZmZXJfZmxvYXQiKSwgcy5nZXRFeHRlbnNpb24oIk9FU190ZXh0dXJlX2hhbGZfZmxvYXRfbGluZWFyIiksIHsKICAgIHR5cGU6IG8gPyAid2ViZ2wyIiA6ICJ3ZWJnbDEiLAogICAgZ2w6IHMsCiAgICBpc1dlYkdMMjogbywKICAgIGV4dDogewogICAgICBpbnRlcm5hbEZvcm1hdDogbyA/IHMuUkdCQTE2RiA6IHMuUkdCQSwKICAgICAgZm9ybWF0OiBzLlJHQkEsCiAgICAgIHR5cGU6IHUKICAgIH0KICB9Owp9CmFzeW5jIGZ1bmN0aW9uIEZ0KGksIGUgPSAhMCkgewogIGlmICh0eXBlb2YgbmF2aWdhdG9yID4gInUiIHx8ICFuYXZpZ2F0b3IuZ3B1KQogICAgcmV0dXJuIG51bGw7CiAgdHJ5IHsKICAgIGNvbnN0IHIgPSBhd2FpdCBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKCk7CiAgICBpZiAoIXIpCiAgICAgIHJldHVybiBudWxsOwogICAgY29uc3QgcyA9IGF3YWl0IHIucmVxdWVzdERldmljZSgpLCBvID0gaS5nZXRDb250ZXh0KCJ3ZWJncHUiKTsKICAgIGlmICghbykKICAgICAgcmV0dXJuIG51bGw7CiAgICBjb25zdCBhID0gbmF2aWdhdG9yLmdwdS5nZXRQcmVmZXJyZWRDYW52YXNGb3JtYXQoKTsKICAgIHJldHVybiBvLmNvbmZpZ3VyZSh7IGRldmljZTogcywgZm9ybWF0OiBhLCBhbHBoYU1vZGU6IGUgPyAicHJlbXVsdGlwbGllZCIgOiAib3BhcXVlIiB9KSwgeyB0eXBlOiAid2ViZ3B1IiwgYWRhcHRlcjogciwgZGV2aWNlOiBzLCBjb250ZXh0OiBvLCBmb3JtYXQ6IGEgfTsKICB9IGNhdGNoIHsKICAgIHJldHVybiBudWxsOwogIH0KfQpjbGFzcyBpZSB7CiAgY29uc3RydWN0b3IoZSwgciwgcykgewogICAga2UodGhpcywgInByb2dyYW0iKTsKICAgIGtlKHRoaXMsICJ1bmlmb3JtcyIsIHt9KTsKICAgIGtlKHRoaXMsICJfZ2wiKTsKICAgIHRoaXMuX2dsID0gZSwgdGhpcy5wcm9ncmFtID0gZS5jcmVhdGVQcm9ncmFtKCksIGUuYXR0YWNoU2hhZGVyKHRoaXMucHJvZ3JhbSwgdGhpcy5fY29tcGlsZShlLlZFUlRFWF9TSEFERVIsIHIpKSwgZS5hdHRhY2hTaGFkZXIodGhpcy5wcm9ncmFtLCB0aGlzLl9jb21waWxlKGUuRlJBR01FTlRfU0hBREVSLCBzKSksIGUubGlua1Byb2dyYW0odGhpcy5wcm9ncmFtKTsKICAgIGNvbnN0IG8gPSBlLmdldFByb2dyYW1QYXJhbWV0ZXIodGhpcy5wcm9ncmFtLCBlLkFDVElWRV9VTklGT1JNUyk7CiAgICBmb3IgKGxldCBhID0gMDsgYSA8IG87IGErKykgewogICAgICBjb25zdCB1ID0gZS5nZXRBY3RpdmVVbmlmb3JtKHRoaXMucHJvZ3JhbSwgYSkubmFtZTsKICAgICAgdGhpcy51bmlmb3Jtc1t1XSA9IGUuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgdSk7CiAgICB9CiAgfQogIF9jb21waWxlKGUsIHIpIHsKICAgIGNvbnN0IHMgPSB0aGlzLl9nbCwgbyA9IHMuY3JlYXRlU2hhZGVyKGUpOwogICAgcmV0dXJuIHMuc2hhZGVyU291cmNlKG8sIHIpLCBzLmNvbXBpbGVTaGFkZXIobyksIG87CiAgfQogIGJpbmQoKSB7CiAgICB0aGlzLl9nbC51c2VQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQogIGRpc3Bvc2UoKSB7CiAgICB0aGlzLl9nbC5kZWxldGVQcm9ncmFtKHRoaXMucHJvZ3JhbSk7CiAgfQp9CmZ1bmN0aW9uIFB0KGkpIHsKICByZXR1cm4gewogICAgYWR2ZWN0aW9uOiBuZXcgaWUoaSwgcmUsIFJ0KSwKICAgIGRpdmVyZ2VuY2U6IG5ldyBpZShpLCByZSwgRXQpLAogICAgcHJlc3N1cmU6IG5ldyBpZShpLCByZSwgVXQpLAogICAgZ3JhZGllbnRTdWJ0cmFjdDogbmV3IGllKGksIHJlLCBEdCksCiAgICBzcGxhdDogbmV3IGllKGksIHJlLCBfdCksCiAgICBjdXJsOiBuZXcgaWUoaSwgcmUsIEN0KSwKICAgIHZvcnRpY2l0eTogbmV3IGllKGksIHJlLCBCdCksCiAgICBkaXNwbGF5OiBuZXcgaWUoaSwgcmUsIFZ0KQogIH07Cn0KZnVuY3Rpb24gcWUoaSwgZSwgciwgcykgewogIGkuYWN0aXZlVGV4dHVyZShpLlRFWFRVUkUwKTsKICBjb25zdCBvID0gaS5jcmVhdGVUZXh0dXJlKCk7CiAgaS5iaW5kVGV4dHVyZShpLlRFWFRVUkVfMkQsIG8pLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUlOX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfTUFHX0ZJTFRFUiwgaS5MSU5FQVIpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9TLCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleFBhcmFtZXRlcmkoaS5URVhUVVJFXzJELCBpLlRFWFRVUkVfV1JBUF9ULCBpLkNMQU1QX1RPX0VER0UpLCBpLnRleEltYWdlMkQoaS5URVhUVVJFXzJELCAwLCBlLmludGVybmFsRm9ybWF0LCByLCBzLCAwLCBlLmZvcm1hdCwgZS50eXBlLCBudWxsKTsKICBjb25zdCBhID0gaS5jcmVhdGVGcmFtZWJ1ZmZlcigpOwogIHJldHVybiBpLmJpbmRGcmFtZWJ1ZmZlcihpLkZSQU1FQlVGRkVSLCBhKSwgaS5mcmFtZWJ1ZmZlclRleHR1cmUyRChpLkZSQU1FQlVGRkVSLCBpLkNPTE9SX0FUVEFDSE1FTlQwLCBpLlRFWFRVUkVfMkQsIG8sIDApLCB7IHRleDogbywgZmJvOiBhLCB3aWR0aDogciwgaGVpZ2h0OiBzIH07Cn0KZnVuY3Rpb24gdHQoaSwgZSwgciwgcykgewogIGxldCBvID0gcWUoaSwgZSwgciwgcyksIGEgPSBxZShpLCBlLCByLCBzKTsKICByZXR1cm4gewogICAgZ2V0IHJlYWQoKSB7CiAgICAgIHJldHVybiBvOwogICAgfSwKICAgIGdldCB3cml0ZSgpIHsKICAgICAgcmV0dXJuIGE7CiAgICB9LAogICAgc3dhcCgpIHsKICAgICAgW28sIGFdID0gW2EsIG9dOwogICAgfSwKICAgIGRpc3Bvc2UoKSB7CiAgICAgIGkuZGVsZXRlVGV4dHVyZShvLnRleCksIGkuZGVsZXRlRnJhbWVidWZmZXIoby5mYm8pLCBpLmRlbGV0ZVRleHR1cmUoYS50ZXgpLCBpLmRlbGV0ZUZyYW1lYnVmZmVyKGEuZmJvKTsKICAgIH0KICB9Owp9CmZ1bmN0aW9uIEx0KGkpIHsKICBjb25zdCBlID0gaS5jcmVhdGVCdWZmZXIoKTsKICByZXR1cm4gaS5iaW5kQnVmZmVyKGkuQVJSQVlfQlVGRkVSLCBlKSwgaS5idWZmZXJEYXRhKGkuQVJSQVlfQlVGRkVSLCBuZXcgRmxvYXQzMkFycmF5KFstMSwgLTEsIC0xLCAxLCAxLCAxLCAxLCAtMV0pLCBpLlNUQVRJQ19EUkFXKSwgaS52ZXJ0ZXhBdHRyaWJQb2ludGVyKDAsIDIsIGkuRkxPQVQsICExLCAwLCAwKSwgaS5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSgwKSwgZnVuY3Rpb24ocykgewogICAgaS5iaW5kRnJhbWVidWZmZXIoaS5GUkFNRUJVRkZFUiwgcyksIGkuZHJhd0FycmF5cyhpLlRSSUFOR0xFX0ZBTiwgMCwgNCk7CiAgfTsKfQpjb25zdCBsZSA9ICgKICAvKiB3Z3NsICovCiAgYApzdHJ1Y3QgVlNPdXQgewogIEBidWlsdGluKHBvc2l0aW9uKSBwb3MgOiB2ZWM0ZiwKICBAbG9jYXRpb24oMCkgICAgICAgdXYgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDEpICAgICAgIHZMICA6IHZlYzJmLAogIEBsb2NhdGlvbigyKSAgICAgICB2UiAgOiB2ZWMyZiwKICBAbG9jYXRpb24oMykgICAgICAgdlQgIDogdmVjMmYsCiAgQGxvY2F0aW9uKDQpICAgICAgIHZCICA6IHZlYzJmLAp9YAopLCBBdCA9ICgKICAvKiB3Z3NsICovCiAgYAoke2xlfQoKc3RydWN0IFUgewogIHRleGVsU2l6ZSAgOiB2ZWMyZiwKICBkdCAgICAgICAgIDogZjMyLAogIGRpc3NpcGF0aW9uOiBmMzIsCn0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVTcmMgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNCkgdmFyICAgICAgICAgIHVPYnMgIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICAvLyBTYW1wbGUgYWxsIHRleHR1cmVzIGJlZm9yZSBicmFuY2hpbmcg4oCUIHRleHR1cmVTYW1wbGUgcmVxdWlyZXMgdW5pZm9ybSBjb250cm9sIGZsb3cKICBsZXQgb2JzICAgPSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudXYpLnI7CiAgbGV0IHZlbCAgID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnV2KS54eTsKICBsZXQgY29vcmQgPSBpLnV2IC0gdS5kdCAqIHZlbCAqIHUudGV4ZWxTaXplOwogIGxldCBzcmMgICA9IHRleHR1cmVTYW1wbGUodVNyYywgc2FtcCwgY29vcmQpOwogIGlmIChvYnMgPiAwLjUpIHsgcmV0dXJuIHZlYzRmKDAuMCk7IH0KICByZXR1cm4gdS5kaXNzaXBhdGlvbiAqIHNyYzsKfQpgCiksIHp0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1VmVsIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVPYnMgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIGxldCBMID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52TCkueCwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIgPiAwLjUpOwogIGxldCBSID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52UikueCwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIgPiAwLjUpOwogIGxldCBUID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52VCkueSwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlQpLnIgPiAwLjUpOwogIGxldCBCID0gc2VsZWN0KHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS52QikueSwgMC4wLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIgPiAwLjUpOwogIHJldHVybiB2ZWM0ZigwLjUgKiAoUiAtIEwgKyBUIC0gQiksIDAuMCwgMC4wLCAxLjApOwp9CmAKKSwgWHQgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsgdGV4ZWxTaXplOiB2ZWMyZiwgX3BhZDogdmVjMmYgfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVQcmVzOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdURpdiA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDQpIHZhciAgICAgICAgICB1T2JzIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgQyAgPSB0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnV2KS54OwogIGxldCBMICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZMKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkwpLnIgPiAwLjUpOwogIGxldCBSICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZSKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlIpLnIgPiAwLjUpOwogIGxldCBUICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZUKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudlQpLnIgPiAwLjUpOwogIGxldCBCICA9IHNlbGVjdCh0ZXh0dXJlU2FtcGxlKHVQcmVzLCBzYW1wLCBpLnZCKS54LCBDLCB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudkIpLnIgPiAwLjUpOwogIGxldCBkdiA9IHRleHR1cmVTYW1wbGUodURpdiwgc2FtcCwgaS51dikueDsKICByZXR1cm4gdmVjNGYoKEwgKyBSICsgQiArIFQgLSBkdikgKiAwLjI1LCAwLjAsIDAuMCwgMS4wKTsKfQpgCiksIE10ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgpzdHJ1Y3QgVSB7IHRleGVsU2l6ZTogdmVjMmYsIF9wYWQ6IHZlYzJmIH0KQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhcjx1bmlmb3JtPiB1ICAgIDogVTsKQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciAgICAgICAgICBzYW1wIDogc2FtcGxlcjsKQGdyb3VwKDApIEBiaW5kaW5nKDIpIHZhciAgICAgICAgICB1UHJlczogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoMykgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg0KSB2YXIgICAgICAgICAgdU9icyA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgLy8gU2FtcGxlIGFsbCB0ZXh0dXJlcyBiZWZvcmUgYnJhbmNoaW5nIOKAlCB0ZXh0dXJlU2FtcGxlIHJlcXVpcmVzIHVuaWZvcm0gY29udHJvbCBmbG93CiAgbGV0IG9icyA9IHRleHR1cmVTYW1wbGUodU9icywgc2FtcCwgaS51dikucjsKICBsZXQgTCAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52TCkueDsKICBsZXQgUiAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52UikueDsKICBsZXQgVCAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52VCkueDsKICBsZXQgQiAgID0gdGV4dHVyZVNhbXBsZSh1UHJlcywgc2FtcCwgaS52QikueDsKICBsZXQgdmVsID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnV2KS54eSAtIHZlYzJmKFIgLSBMLCBUIC0gQik7CiAgaWYgKG9icyA+IDAuNSkgeyByZXR1cm4gdmVjNGYoMC4wKTsgfQogIHJldHVybiB2ZWM0Zih2ZWwsIDAuMCwgMS4wKTsKfQpgCiksIEd0ID0gKAogIC8qIHdnc2wgKi8KICBgCiR7bGV9CgovLyB0ZXhlbFNpemUgb2NjdXBpZXMgYnl0ZXMgMC03IGZvciB0aGUgc2hhcmVkIHZlcnRleCBzdGFnZTsgYXNwZWN0UmF0aW8vcmFkaXVzIGZpbGwgdGhlIHJlc3QuCnN0cnVjdCBVIHsKICB0ZXhlbFNpemUgIDogdmVjMmYsCiAgYXNwZWN0UmF0aW86IGYzMiwKICByYWRpdXMgICAgIDogZjMyLAogIGNvbG9yICAgICAgOiB2ZWM0ZiwgIC8vIHh5eiA9IGNvbG91ciwgdyB1bnVzZWQKICBwb2ludCAgICAgIDogdmVjMmYsCiAgX3BhZCAgICAgICA6IHZlYzJmLAp9CkBncm91cCgwKSBAYmluZGluZygwKSB2YXI8dW5pZm9ybT4gdSAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCA6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgICAgICAgICAgdVRndCA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgdmFyIHAgID0gaS51diAtIHUucG9pbnQ7CiAgcC54ICAgKj0gdS5hc3BlY3RSYXRpbzsKICBsZXQgc3AgPSBleHAoLWRvdChwLCBwKSAvIHUucmFkaXVzKSAqIHUuY29sb3IueHl6OwogIHJldHVybiB2ZWM0Zih0ZXh0dXJlU2FtcGxlKHVUZ3QsIHNhbXAsIGkudXYpLnh5eiArIHNwLCAxLjApOwp9CmAKKSwgSXQgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsgdGV4ZWxTaXplOiB2ZWMyZiwgX3BhZDogdmVjMmYgfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVWZWwgOiB0ZXh0dXJlXzJkPGYzMj47CgpAdmVydGV4IGZuIHZzKEBsb2NhdGlvbigwKSBhOiB2ZWMyZikgLT4gVlNPdXQgewogIHZhciBvOiBWU091dDsKICBvLnV2ID0gdmVjMmYoYS54ICogMC41ICsgMC41LCAwLjUgLSBhLnkgKiAwLjUpOwogIG8udkwgPSBvLnV2IC0gdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZSID0gby51diArIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52VCA9IG8udXYgKyB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8udkIgPSBvLnV2IC0gdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnBvcyA9IHZlYzRmKGEsIDAuMCwgMS4wKTsKICByZXR1cm4gbzsKfQoKQGZyYWdtZW50IGZuIGZzKGk6IFZTT3V0KSAtPiBAbG9jYXRpb24oMCkgdmVjNGYgewogIGxldCBMID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZMKS55OwogIGxldCBSID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZSKS55OwogIGxldCBUID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZUKS54OwogIGxldCBCID0gdGV4dHVyZVNhbXBsZSh1VmVsLCBzYW1wLCBpLnZCKS54OwogIHJldHVybiB2ZWM0ZigwLjUgKiAoUiAtIEwgLSBUICsgQiksIDAuMCwgMC4wLCAxLjApOwp9CmAKKSwga3QgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsKICB0ZXhlbFNpemU6IHZlYzJmLAogIGN1cmwgICAgIDogZjMyLAogIGR0ICAgICAgIDogZjMyLAp9CkBncm91cCgwKSBAYmluZGluZygwKSB2YXI8dW5pZm9ybT4gdSAgICA6IFU7CkBncm91cCgwKSBAYmluZGluZygxKSB2YXIgICAgICAgICAgc2FtcCA6IHNhbXBsZXI7CkBncm91cCgwKSBAYmluZGluZygyKSB2YXIgICAgICAgICAgdVZlbCA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDMpIHZhciAgICAgICAgICB1Q3JsIDogdGV4dHVyZV8yZDxmMzI+OwoKQHZlcnRleCBmbiB2cyhAbG9jYXRpb24oMCkgYTogdmVjMmYpIC0+IFZTT3V0IHsKICB2YXIgbzogVlNPdXQ7CiAgby51diA9IHZlYzJmKGEueCAqIDAuNSArIDAuNSwgMC41IC0gYS55ICogMC41KTsKICBvLnZMID0gby51diAtIHZlYzJmKHUudGV4ZWxTaXplLngsIDAuMCk7CiAgby52UiA9IG8udXYgKyB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlQgPSBvLnV2ICsgdmVjMmYoMC4wLCB1LnRleGVsU2l6ZS55KTsKICBvLnZCID0gby51diAtIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby5wb3MgPSB2ZWM0ZihhLCAwLjAsIDEuMCk7CiAgcmV0dXJuIG87Cn0KCkBmcmFnbWVudCBmbiBmcyhpOiBWU091dCkgLT4gQGxvY2F0aW9uKDApIHZlYzRmIHsKICBsZXQgTCAgICAgPSB0ZXh0dXJlU2FtcGxlKHVDcmwsIHNhbXAsIGkudkwpLng7CiAgbGV0IFIgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnZSKS54OwogIGxldCBUICAgICA9IHRleHR1cmVTYW1wbGUodUNybCwgc2FtcCwgaS52VCkueDsKICBsZXQgQiAgICAgPSB0ZXh0dXJlU2FtcGxlKHVDcmwsIHNhbXAsIGkudkIpLng7CiAgbGV0IEMgICAgID0gdGV4dHVyZVNhbXBsZSh1Q3JsLCBzYW1wLCBpLnV2KS54OwogIHZhciBmb3JjZSA9IDAuNSAqIHZlYzJmKGFicyhUKSAtIGFicyhCKSwgYWJzKFIpIC0gYWJzKEwpKTsKICBmb3JjZSAgICAvPSBsZW5ndGgoZm9yY2UpICsgMC4wMDAxOwogIGZvcmNlICAgICo9IHUuY3VybCAqIDMwLjAgKiBDOwogIGxldCB2ZWwgICA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS51dikueHkgKyBmb3JjZSAqIHUuZHQ7CiAgcmV0dXJuIHZlYzRmKHZlbCwgMC4wLCAxLjApOwp9CmAKKSwgV3QgPSAoCiAgLyogd2dzbCAqLwogIGAKJHtsZX0KCnN0cnVjdCBVIHsKICB0ZXhlbFNpemUgICA6IHZlYzJmLAogIHJlZnJhY3Rpb24gIDogZjMyLAogIHNwZWN1bGFyRXhwIDogZjMyLAogIHdhdGVyQ29sb3IgIDogdmVjNGYsCiAgZ2xvd0NvbG9yICAgOiB2ZWM0ZiwKICBzaGluZSAgICAgICA6IGYzMiwKICB3YXJwU3RyZW5ndGg6IGYzMiwKICBhbGdvcml0aG0gICA6IGkzMiwKICBlbmFibGVBbHBoYSA6IGkzMiwKfQpAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyPHVuaWZvcm0+IHUgICAgOiBVOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMSkgdmFyICAgICAgICAgIHNhbXAgOiBzYW1wbGVyOwpAZ3JvdXAoMCkgQGJpbmRpbmcoMikgdmFyICAgICAgICAgIHVUZXggOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZygzKSB2YXIgICAgICAgICAgdU9icyA6IHRleHR1cmVfMmQ8ZjMyPjsKQGdyb3VwKDApIEBiaW5kaW5nKDQpIHZhciAgICAgICAgICB1QmcgIDogdGV4dHVyZV8yZDxmMzI+OwpAZ3JvdXAoMCkgQGJpbmRpbmcoNSkgdmFyICAgICAgICAgIHVDb3YgOiB0ZXh0dXJlXzJkPGYzMj47CkBncm91cCgwKSBAYmluZGluZyg2KSB2YXIgICAgICAgICAgdVZlbCA6IHRleHR1cmVfMmQ8ZjMyPjsKCkB2ZXJ0ZXggZm4gdnMoQGxvY2F0aW9uKDApIGE6IHZlYzJmKSAtPiBWU091dCB7CiAgdmFyIG86IFZTT3V0OwogIG8udXYgPSB2ZWMyZihhLnggKiAwLjUgKyAwLjUsIDAuNSAtIGEueSAqIDAuNSk7CiAgby52TCA9IG8udXYgLSB2ZWMyZih1LnRleGVsU2l6ZS54LCAwLjApOwogIG8udlIgPSBvLnV2ICsgdmVjMmYodS50ZXhlbFNpemUueCwgMC4wKTsKICBvLnZUID0gby51diArIHZlYzJmKDAuMCwgdS50ZXhlbFNpemUueSk7CiAgby52QiA9IG8udXYgLSB2ZWMyZigwLjAsIHUudGV4ZWxTaXplLnkpOwogIG8ucG9zID0gdmVjNGYoYSwgMC4wLCAxLjApOwogIHJldHVybiBvOwp9CgpAZnJhZ21lbnQgZm4gZnMoaTogVlNPdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0ZiB7CiAgbGV0IG9icyAgICAgPSB0ZXh0dXJlU2FtcGxlKHVPYnMsIHNhbXAsIGkudXYpLnI7CiAgbGV0IGRlbnNpdHkgPSBtYXgodGV4dHVyZVNhbXBsZSh1VGV4LCBzYW1wLCBpLnV2KS5yLCAwLjApICogKDEuMCAtIHN0ZXAoMC41LCBvYnMpKTsKICBsZXQgY292ICAgICA9IHRleHR1cmVTYW1wbGUodUNvdiwgc2FtcCwgaS51dikucjsKCiAgbGV0IHRzMiA9IHUudGV4ZWxTaXplICogMi4wOwogIGxldCBkTCAgPSBtYXgodGV4dHVyZVNhbXBsZSh1VGV4LCBzYW1wLCBpLnV2IC0gdmVjMmYodHMyLngsIDAuMCkpLnIsIDAuMCk7CiAgbGV0IGRSICA9IG1heCh0ZXh0dXJlU2FtcGxlKHVUZXgsIHNhbXAsIGkudXYgKyB2ZWMyZih0czIueCwgMC4wKSkuciwgMC4wKTsKICBsZXQgZFQgID0gbWF4KHRleHR1cmVTYW1wbGUodVRleCwgc2FtcCwgaS51diArIHZlYzJmKDAuMCwgdHMyLnkpKS5yLCAwLjApOwogIGxldCBkQiAgPSBtYXgodGV4dHVyZVNhbXBsZSh1VGV4LCBzYW1wLCBpLnV2IC0gdmVjMmYoMC4wLCB0czIueSkpLnIsIDAuMCk7CgogIGxldCBub3JtICA9IG5vcm1hbGl6ZSh2ZWMzZihkTCAtIGRSLCBkQiAtIGRULCAwLjIpKTsKICBsZXQgbGRpciAgPSBub3JtYWxpemUodmVjM2YoMC41LCAxLjAsIDAuNSkpOwogIGxldCBoYWxmViA9IG5vcm1hbGl6ZShsZGlyICsgdmVjM2YoMC4wLCAwLjAsIDEuMCkpOwogIGxldCBzcGVjICA9IHBvdyhtYXgoZG90KG5vcm0sIGhhbGZWKSwgMC4wKSwgdS5zcGVjdWxhckV4cCkgKiB1LnNoaW5lICogZGVuc2l0eTsKCiAgbGV0IGJnUmF3ID0gdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIGkudXYpLnJnYjsKICBsZXQgd2MgICAgPSB1LndhdGVyQ29sb3IucmdiOwogIGxldCBnYyAgICA9IHUuZ2xvd0NvbG9yLnJnYjsKICBsZXQgYmcgICAgPSBtaXgod2MsIGJnUmF3LCBjb3YpOwogIHZhciBjb2xvciA9IGJnOwoKICBpZiAodS5hbGdvcml0aG0gPT0gMSkgewogICAgbGV0IHJ1diA9IGNsYW1wKGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eSAqIDMuMCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgcmJnID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgbWl4KGkudXYsIHJ1diwgMS4wIC0gb2JzKSkucmdiLCBjb3YpOwogICAgY29sb3IgICA9IHJiZyArIHNwZWMgKiBnYyAqIDIuNTsKICAgIGNvbG9yICAgPSBtaXgoY29sb3IsIGJnICogMC42LCBvYnMgKiAwLjMpOwogIH0gZWxzZSBpZiAodS5hbGdvcml0aG0gPT0gMikgewogICAgbGV0IGlua0QgPSBtaW4oZGVuc2l0eSAqIDQuMCwgMS4wKTsKICAgIGxldCBydXYgID0gY2xhbXAoaS51diArIG5vcm0ueHkgKiB1LnJlZnJhY3Rpb24gKiBkZW5zaXR5ICogMC40LCB2ZWMyZigwLjApLCB2ZWMyZigxLjApKTsKICAgIGxldCByYmcgID0gbWl4KHdjLCB0ZXh0dXJlU2FtcGxlKHVCZywgc2FtcCwgbWl4KGkudXYsIHJ1diwgMS4wIC0gb2JzKSkucmdiLCBjb3YpOwogICAgY29sb3IgICAgPSBtaXgocmJnLCB3YyArIHNwZWMgKiBnYywgaW5rRCk7CiAgICBjb2xvciAgICA9IG1peChjb2xvciwgYmcgKiAwLjUsIG9icyAqIDAuMTUpOwogIH0gZWxzZSBpZiAodS5hbGdvcml0aG0gPT0gMykgewogICAgbGV0IHZlbCAgICA9IHRleHR1cmVTYW1wbGUodVZlbCwgc2FtcCwgaS51dikueHk7CiAgICBsZXQgdmVsTWFnID0gY2xhbXAobGVuZ3RoKHZlbCkgKiAyMC4wLCAwLjAsIDEuMCk7CiAgICBsZXQgd3V2ICAgID0gY2xhbXAoaS51diArIHZlbCAqIHUud2FycFN0cmVuZ3RoLCB2ZWMyZigwLjApLCB2ZWMyZigxLjApKTsKICAgIGxldCB3YmcgICAgPSBtaXgod2MsIHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCB3dXYpLnJnYiwgY292KTsKICAgIGNvbG9yICAgICAgPSBtaXgoYmcsIHdiZywgdmVsTWFnICogKDEuMCAtIG9icykpOwogICAgY29sb3IgICAgICs9IHNwZWMgKiBnYyAqIHZlbE1hZyAqIDEuNTsKICAgIGNvbG9yICAgICArPSB3YyAqIGRlbnNpdHkgKiAwLjM7CiAgICBjb2xvciAgICAgID0gbWl4KGNvbG9yLCBiZyAqIDAuNSwgb2JzICogMC4yKTsKICB9IGVsc2UgaWYgKHUuYWxnb3JpdGhtID09IDQpIHsKICAgIGxldCBydXYgICA9IGNsYW1wKGkudXYgKyBub3JtLnh5ICogdS5yZWZyYWN0aW9uICogZGVuc2l0eSAqIDYuMCwgdmVjMmYoMC4wKSwgdmVjMmYoMS4wKSk7CiAgICBsZXQgcmJnICAgPSBtaXgod2MsIHRleHR1cmVTYW1wbGUodUJnLCBzYW1wLCBtaXgoaS51diwgcnV2LCAxLjAgLSBvYnMpKS5yZ2IsIGNvdik7CiAgICBsZXQgZnJlcyAgPSBwb3coY2xhbXAoMS4wIC0gZG90KG5vcm0sIHZlYzNmKDAuMCwgMC4wLCAxLjApKSwgMC4wLCAxLjApLCAzLjApICogZGVuc2l0eTsKICAgIGNvbG9yICAgICA9IHJiZzsKICAgIGNvbG9yICAgICs9IGZyZXMgKiBnYyAqIDIuMDsKICAgIGNvbG9yICAgICs9IHNwZWMgKiBnYyAqIGRlbnNpdHkgKiAyLjA7CiAgICBjb2xvciAgICAgPSBtaXgoY29sb3IsIGJnICogMC41LCBvYnMgKiAwLjIpOwogIH0gZWxzZSB7CiAgICBsZXQgcnV2ID0gaS51diArIG5vcm0ueHkgKiB1LnJlZnJhY3Rpb24gKiBkZW5zaXR5OwogICAgbGV0IHJiZyA9IG1peCh3YywgdGV4dHVyZVNhbXBsZSh1QmcsIHNhbXAsIG1peChpLnV2LCBydXYsIDEuMCAtIG9icykpLnJnYiwgY292KTsKICAgIGNvbG9yICAgPSBtaXgocmJnLCB3YywgbWluKGRlbnNpdHkgKiAxLjUsIDAuOCkpOwogICAgY29sb3IgICs9IHNwZWMgKiBnYzsKICAgIGNvbG9yICAgPSBtaXgoY29sb3IsIGJnICogMC41LCBvYnMgKiAwLjIpOwogIH0KCiAgbGV0IGFscGhhID0gY2xhbXAobWF4KGRlbnNpdHkgKiAxLjUsIGNvdiksIDAuMCwgMS4wKTsKICBpZiAodS5lbmFibGVBbHBoYSA9PSAxKSB7CiAgICByZXR1cm4gdmVjNGYoY29sb3IgKiBhbHBoYSwgYWxwaGEpOwogIH0KICByZXR1cm4gdmVjNGYoY29sb3IsIDEuMCk7Cn0KYAopLCBOdCA9IHsKICBhcnJheVN0cmlkZTogOCwKICBhdHRyaWJ1dGVzOiBbeyBzaGFkZXJMb2NhdGlvbjogMCwgb2Zmc2V0OiAwLCBmb3JtYXQ6ICJmbG9hdDMyeDIiIH1dCn0sIG50ID0gbmV3IEZsb2F0MzJBcnJheShbCiAgLTEsCiAgLTEsCiAgLTEsCiAgMSwKICAxLAogIC0xLAogIDEsCiAgLTEsCiAgLTEsCiAgMSwKICAxLAogIDEKXSk7CmZ1bmN0aW9uICR0KGkpIHsKICBjb25zdCBlID0gaS5jcmVhdGVCdWZmZXIoeyBzaXplOiBudC5ieXRlTGVuZ3RoLCB1c2FnZTogR1BVQnVmZmVyVXNhZ2UuVkVSVEVYIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QgfSk7CiAgcmV0dXJuIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgbnQpLCBlOwp9CmZ1bmN0aW9uIEhlKGksIGUsIHIsIHMpIHsKICBjb25zdCBvID0gaS5jcmVhdGVUZXh0dXJlKHsKICAgIHNpemU6IFtyLCBzXSwKICAgIGZvcm1hdDogZSwKICAgIHVzYWdlOiBHUFVUZXh0dXJlVXNhZ2UuVEVYVFVSRV9CSU5ESU5HIHwgR1BVVGV4dHVyZVVzYWdlLlJFTkRFUl9BVFRBQ0hNRU5UIHwgR1BVVGV4dHVyZVVzYWdlLkNPUFlfU1JDCiAgfSk7CiAgcmV0dXJuIHsgdGV4OiBvLCB2aWV3OiBvLmNyZWF0ZVZpZXcoKSwgd2lkdGg6IHIsIGhlaWdodDogcyB9Owp9CmZ1bmN0aW9uIHJ0KGksIGUsIHIsIHMpIHsKICBsZXQgbyA9IEhlKGksIGUsIHIsIHMpLCBhID0gSGUoaSwgZSwgciwgcyk7CiAgcmV0dXJuIHsKICAgIGdldCByZWFkKCkgewogICAgICByZXR1cm4gbzsKICAgIH0sCiAgICBnZXQgd3JpdGUoKSB7CiAgICAgIHJldHVybiBhOwogICAgfSwKICAgIHN3YXAoKSB7CiAgICAgIFtvLCBhXSA9IFthLCBvXTsKICAgIH0sCiAgICBkaXNwb3NlKCkgewogICAgICBvLnRleC5kZXN0cm95KCksIGEudGV4LmRlc3Ryb3koKTsKICAgIH0KICB9Owp9CmZ1bmN0aW9uIHNlKGksIGUsIHIsIHMpIHsKICBjb25zdCBvID0gaS5jcmVhdGVTaGFkZXJNb2R1bGUoeyBjb2RlOiBlIH0pOwogIHJldHVybiBpLmNyZWF0ZVJlbmRlclBpcGVsaW5lKHsKICAgIGxheW91dDogImF1dG8iLAogICAgdmVydGV4OiB7IG1vZHVsZTogbywgZW50cnlQb2ludDogInZzIiwgYnVmZmVyczogW050XSB9LAogICAgZnJhZ21lbnQ6IHsgbW9kdWxlOiBvLCBlbnRyeVBvaW50OiAiZnMiLCB0YXJnZXRzOiBbeyBmb3JtYXQ6IHIsIC4uLnMgPyB7IGJsZW5kOiBzIH0gOiB7fSB9XSB9LAogICAgcHJpbWl0aXZlOiB7IHRvcG9sb2d5OiAidHJpYW5nbGUtbGlzdCIgfQogIH0pOwp9CmNvbnN0IHF0ID0gewogIGNvbG9yOiB7IG9wZXJhdGlvbjogImFkZCIsIHNyY0ZhY3RvcjogIm9uZSIsIGRzdEZhY3RvcjogInplcm8iIH0sCiAgYWxwaGE6IHsgb3BlcmF0aW9uOiAiYWRkIiwgc3JjRmFjdG9yOiAib25lIiwgZHN0RmFjdG9yOiAiemVybyIgfQp9OwpmdW5jdGlvbiBIdChpLCBlLCByID0gITApIHsKICBjb25zdCBzID0gInJnYmExNmZsb2F0IjsKICByZXR1cm4gewogICAgYWR2ZWN0aW9uOiBzZShpLCBBdCwgcyksCiAgICBkaXZlcmdlbmNlOiBzZShpLCB6dCwgcyksCiAgICBwcmVzc3VyZTogc2UoaSwgWHQsIHMpLAogICAgZ3JhZGllbnRTdWJ0cmFjdDogc2UoaSwgTXQsIHMpLAogICAgc3BsYXQ6IHNlKGksIEd0LCBzKSwKICAgIGN1cmw6IHNlKGksIEl0LCBzKSwKICAgIHZvcnRpY2l0eTogc2UoaSwga3QsIHMpLAogICAgZGlzcGxheTogc2UoaSwgV3QsIGUsIHIgPyB2b2lkIDAgOiBxdCkKICB9Owp9CmZ1bmN0aW9uIFl0KGkpIHsKICByZXR1cm4gaS5jcmVhdGVTYW1wbGVyKHsgbWFnRmlsdGVyOiAibGluZWFyIiwgbWluRmlsdGVyOiAibGluZWFyIiwgYWRkcmVzc01vZGVVOiAiY2xhbXAtdG8tZWRnZSIsIGFkZHJlc3NNb2RlVjogImNsYW1wLXRvLWVkZ2UiIH0pOwp9CmZ1bmN0aW9uIFcoaSwgZSkgewogIHJldHVybiBpLmNyZWF0ZUJ1ZmZlcih7IHNpemU6IGUsIHVzYWdlOiBHUFVCdWZmZXJVc2FnZS5VTklGT1JNIHwgR1BVQnVmZmVyVXNhZ2UuQ09QWV9EU1QgfSk7Cn0KZnVuY3Rpb24gbHQoaSwgZSwgciwgcywgbywgYSkgewogIGNvbnN0IHUgPSBuZXcgRmxvYXQzMkFycmF5KFtyLCBzLCBvLCBhXSk7CiAgaS5xdWV1ZS53cml0ZUJ1ZmZlcihlLCAwLCB1KTsKfQpmdW5jdGlvbiBOZShpLCBlLCByLCBzKSB7CiAgY29uc3QgbyA9IG5ldyBGbG9hdDMyQXJyYXkoW3IsIHMsIDAsIDBdKTsKICBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIG8pOwp9CmZ1bmN0aW9uIFF0KGksIGUsIHIsIHMsIG8sIGEpIHsKICBjb25zdCB1ID0gbmV3IEZsb2F0MzJBcnJheShbciwgcywgbywgYV0pOwogIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgdSk7Cn0KZnVuY3Rpb24gJGUoaSwgZSwgciwgcywgbywgYSwgdSwgdiwgbSwgYywgeCkgewogIGNvbnN0IHAgPSBuZXcgRmxvYXQzMkFycmF5KDEyKTsKICBwWzBdID0gciwgcFsxXSA9IHMsIHBbMl0gPSBvLCBwWzNdID0gYSwgcFs0XSA9IHUsIHBbNV0gPSB2LCBwWzZdID0gbSwgcFs3XSA9IDAsIHBbOF0gPSBjLCBwWzldID0geCwgcFsxMF0gPSAwLCBwWzExXSA9IDAsIGkucXVldWUud3JpdGVCdWZmZXIoZSwgMCwgcCk7Cn0KZnVuY3Rpb24ganQoaSwgZSwgciwgcywgbywgYSwgdSwgdiwgbSwgYywgeCwgcCkgewogIGNvbnN0IG4gPSBuZXcgRmxvYXQzMkFycmF5KDE2KSwgZCA9IG5ldyBJbnQzMkFycmF5KG4uYnVmZmVyKTsKICBuWzBdID0gciwgblsxXSA9IHMsIG5bMl0gPSBvLCBuWzNdID0gYSwgbls0XSA9IHVbMF0sIG5bNV0gPSB1WzFdLCBuWzZdID0gdVsyXSwgbls3XSA9IDAsIG5bOF0gPSB2WzBdLCBuWzldID0gdlsxXSwgblsxMF0gPSB2WzJdLCBuWzExXSA9IDAsIG5bMTJdID0gbSwgblsxM10gPSBjLCBkWzE0XSA9IHgsIGRbMTVdID0gcCA/IDEgOiAwLCBpLnF1ZXVlLndyaXRlQnVmZmVyKGUsIDAsIG4pOwp9CmZ1bmN0aW9uIFgoaSwgZSwgciwgcywgbykgewogIGNvbnN0IGEgPSBpLmJlZ2luUmVuZGVyUGFzcyh7CiAgICBjb2xvckF0dGFjaG1lbnRzOiBbewogICAgICB2aWV3OiBvLAogICAgICBjbGVhclZhbHVlOiBbMCwgMCwgMCwgMF0sCiAgICAgIGxvYWRPcDogImNsZWFyIiwKICAgICAgc3RvcmVPcDogInN0b3JlIgogICAgfV0KICB9KTsKICBhLnNldFBpcGVsaW5lKGUpLCBhLnNldEJpbmRHcm91cCgwLCByKSwgYS5zZXRWZXJ0ZXhCdWZmZXIoMCwgcyksIGEuZHJhdyg2KSwgYS5lbmQoKTsKfQpmdW5jdGlvbiBLdChpLCBlLCByLCBzLCBvKSB7CiAgY29uc3QgYSA9IGkuYmVnaW5SZW5kZXJQYXNzKHsKICAgIGNvbG9yQXR0YWNobWVudHM6IFt7CiAgICAgIHZpZXc6IG8sCiAgICAgIGNsZWFyVmFsdWU6IFswLCAwLCAwLCAwXSwKICAgICAgbG9hZE9wOiAiY2xlYXIiLAogICAgICBzdG9yZU9wOiAic3RvcmUiCiAgICB9XQogIH0pOwogIGEuc2V0UGlwZWxpbmUoZSksIGEuc2V0QmluZEdyb3VwKDAsIHIpLCBhLnNldFZlcnRleEJ1ZmZlcigwLCBzKSwgYS5kcmF3KDYpLCBhLmVuZCgpOwp9CmZ1bmN0aW9uIEJlKGksIGUsIHIsIHMsIG8gPSAiY292ZXIiKSB7CiAgbGV0IGE7CiAgbyA9PT0gImNvdmVyIiA/IGEgPSBNYXRoLm1heChyIC8gaSwgcyAvIGUpIDogbyA9PT0gImNvbnRhaW4iID8gYSA9IE1hdGgubWluKHIgLyBpLCBzIC8gZSkgOiB0eXBlb2YgbyA9PSAic3RyaW5nIiAmJiBvLmVuZHNXaXRoKCIlIikgPyBhID0gTWF0aC5taW4ociAvIGksIHMgLyBlKSAqIChwYXJzZUZsb2F0KG8pIC8gMTAwKSA6IHR5cGVvZiBvID09ICJzdHJpbmciICYmIG8uZW5kc1dpdGgoInB4IikgPyBhID0gcGFyc2VGbG9hdChvKSAvIE1hdGgubWF4KGksIGUpIDogdHlwZW9mIG8gPT0gIm51bWJlciIgPyBhID0gbyA6IGEgPSBNYXRoLm1heChyIC8gaSwgcyAvIGUpOwogIGNvbnN0IHUgPSBpICogYSwgdiA9IGUgKiBhOwogIHJldHVybiB7IHg6IChyIC0gdSkgLyAyLCB5OiAocyAtIHYpIC8gMiwgZHJhd1c6IHUsIGRyYXdIOiB2IH07Cn0KZnVuY3Rpb24gSnQoaSwgZSwgciwgcywgbyA9IG51bGwsIGEgPSAiY292ZXIiKSB7CiAgY29uc3QgeyB0ZXh0OiB1LCBmb250U2l6ZTogdiwgY29sb3I6IG0sIGZvbnRGYW1pbHk6IGMgPSAic2Fucy1zZXJpZiIsIGZvbnRXZWlnaHQ6IHggPSA5MDAgfSA9IHMsIHAgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKGUsIHIpLCBuID0gcC5nZXRDb250ZXh0KCIyZCIpOwogICgoRCkgPT4gewogICAgaWYgKG8pIHsKICAgICAgbi5jbGVhclJlY3QoMCwgMCwgZSwgciksIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKTsKICAgICAgY29uc3QgeyB4OiBnLCB5OiBfLCBkcmF3VzogUCwgZHJhd0g6IGsgfSA9IEJlKAogICAgICAgIG8ud2lkdGgsCiAgICAgICAgby5oZWlnaHQsCiAgICAgICAgZSwKICAgICAgICByLAogICAgICAgIGEKICAgICAgKTsKICAgICAgbi5kcmF3SW1hZ2UobywgZywgXywgUCwgayk7CiAgICB9IGVsc2UKICAgICAgbi5maWxsU3R5bGUgPSAiYmxhY2siLCBuLmZpbGxSZWN0KDAsIDAsIGUsIHIpOwogICAgbi5maWxsU3R5bGUgPSBELCBuLmZvbnQgPSBgJHt4fSAke3Z9cHggJHtjfWAsIG4udGV4dEFsaWduID0gImNlbnRlciIsIG4udGV4dEJhc2VsaW5lID0gIm1pZGRsZSIsIG4uZmlsbFRleHQodSwgZSAvIDIsIHIgLyAyKTsKICB9KShtKTsKICBjb25zdCBiID0gTGUoaSwgcCk7CiAgbi5maWxsU3R5bGUgPSAiYmxhY2siLCBuLmZpbGxSZWN0KDAsIDAsIGUsIHIpLCBuLmZpbGxTdHlsZSA9ICJ3aGl0ZSIsIG4uZm9udCA9IGAke3h9ICR7dn1weCAke2N9YCwgbi50ZXh0QWxpZ24gPSAiY2VudGVyIiwgbi50ZXh0QmFzZWxpbmUgPSAibWlkZGxlIiwgbi5maWxsVGV4dCh1LCBlIC8gMiwgciAvIDIpOwogIGNvbnN0IHkgPSBMZShpLCBwKTsKICByZXR1cm4geyBiYWNrZ3JvdW5kVGV4OiBiLCBvYnN0YWNsZVRleDogeSwgY292ZXJhZ2VUZXg6IHkgfTsKfQpmdW5jdGlvbiBadChpLCBlLCByLCBzLCBvID0gMCwgYSA9ICJjb3ZlciIsIHUgPSBudWxsLCB2ID0gImNvdmVyIikgewogIGNvbnN0IG0gPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHIsIHMpLCBjID0gbS5nZXRDb250ZXh0KCIyZCIpLCB7IHgsIHk6IHAsIGRyYXdXOiBuLCBkcmF3SDogZCB9ID0gQmUoZS53aWR0aCwgZS5oZWlnaHQsIHIsIHMsIGEpOwogIGlmIChjLmNsZWFyUmVjdCgwLCAwLCByLCBzKSwgYy5maWxsU3R5bGUgPSAiYmxhY2siLCBjLmZpbGxSZWN0KDAsIDAsIHIsIHMpLCB1KSB7CiAgICBjb25zdCB7CiAgICAgIHg6IGcsCiAgICAgIHk6IF8sCiAgICAgIGRyYXdXOiBQLAogICAgICBkcmF3SDogawogICAgfSA9IEJlKHUud2lkdGgsIHUuaGVpZ2h0LCByLCBzLCB2KTsKICAgIGMuZmlsdGVyID0gYGJyaWdodG5lc3MoJHtvfSkgYmx1cig4cHgpYCwgYy5kcmF3SW1hZ2UodSwgZywgXywgUCwgayksIGMuZmlsdGVyID0gIm5vbmUiOwogIH0KICBjLmRyYXdJbWFnZShlLCB4LCBwLCBuLCBkKTsKICBjb25zdCBiID0gTGUoaSwgbSk7CiAgYy5jbGVhclJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gImJsYWNrIiwgYy5maWxsUmVjdCgwLCAwLCByLCBzKSwgYy5maWx0ZXIgPSBgYnJpZ2h0bmVzcygke299KSBibHVyKDhweClgLCBjLmRyYXdJbWFnZShlLCB4LCBwLCBuLCBkKSwgYy5maWx0ZXIgPSAibm9uZSI7CiAgY29uc3QgeSA9IExlKGksIG0pOwogIGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gIndoaXRlIiwgYy5maWxsUmVjdCgKICAgIE1hdGgubWF4KDAsIHgpLAogICAgTWF0aC5tYXgoMCwgcCksCiAgICBNYXRoLm1pbihuLCByIC0gTWF0aC5tYXgoMCwgeCkpLAogICAgTWF0aC5taW4oZCwgcyAtIE1hdGgubWF4KDAsIHApKQogICk7CiAgY29uc3QgRCA9IExlKGksIG0pOwogIHJldHVybiB7IGJhY2tncm91bmRUZXg6IGIsIG9ic3RhY2xlVGV4OiB5LCBjb3ZlcmFnZVRleDogRCB9Owp9CmZ1bmN0aW9uIExlKGksIGUpIHsKICBjb25zdCByID0gaS5jcmVhdGVUZXh0dXJlKCk7CiAgcmV0dXJuIGkuYmluZFRleHR1cmUoaS5URVhUVVJFXzJELCByKSwgaS5waXhlbFN0b3JlaShpLlVOUEFDS19GTElQX1lfV0VCR0wsICEwKSwgaS50ZXhJbWFnZTJEKGkuVEVYVFVSRV8yRCwgMCwgaS5SR0JBLCBpLlJHQkEsIGkuVU5TSUdORURfQllURSwgZSksIGkudGV4UGFyYW1ldGVyaShpLlRFWFRVUkVfMkQsIGkuVEVYVFVSRV9NSU5fRklMVEVSLCBpLkxJTkVBUiksIGkudGV4UGFyYW1ldGVyaShpLlRFWFRVUkVfMkQsIGkuVEVYVFVSRV9NQUdfRklMVEVSLCBpLkxJTkVBUiksIGkudGV4UGFyYW1ldGVyaShpLlRFWFRVUkVfMkQsIGkuVEVYVFVSRV9XUkFQX1MsIGkuQ0xBTVBfVE9fRURHRSksIGkudGV4UGFyYW1ldGVyaShpLlRFWFRVUkVfMkQsIGkuVEVYVFVSRV9XUkFQX1QsIGkuQ0xBTVBfVE9fRURHRSksIHI7Cn0KZnVuY3Rpb24gZXIoaSwgZSwgciwgcywgbyA9IG51bGwsIGEgPSAiY292ZXIiKSB7CiAgY29uc3QgeyB0ZXh0OiB1LCBmb250U2l6ZTogdiwgY29sb3I6IG0sIGZvbnRGYW1pbHk6IGMgPSAic2Fucy1zZXJpZiIsIGZvbnRXZWlnaHQ6IHggPSA5MDAgfSA9IHMsIHAgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKGUsIHIpLCBuID0gcC5nZXRDb250ZXh0KCIyZCIpOwogICgoRCkgPT4gewogICAgaWYgKG8pIHsKICAgICAgbi5jbGVhclJlY3QoMCwgMCwgZSwgciksIG4uZmlsbFN0eWxlID0gImJsYWNrIiwgbi5maWxsUmVjdCgwLCAwLCBlLCByKTsKICAgICAgY29uc3QgeyB4OiBnLCB5OiBfLCBkcmF3VzogUCwgZHJhd0g6IGsgfSA9IEJlKAogICAgICAgIG8ud2lkdGgsCiAgICAgICAgby5oZWlnaHQsCiAgICAgICAgZSwKICAgICAgICByLAogICAgICAgIGEKICAgICAgKTsKICAgICAgbi5kcmF3SW1hZ2UobywgZywgXywgUCwgayk7CiAgICB9IGVsc2UKICAgICAgbi5maWxsU3R5bGUgPSAiYmxhY2siLCBuLmZpbGxSZWN0KDAsIDAsIGUsIHIpOwogICAgbi5maWxsU3R5bGUgPSBELCBuLmZvbnQgPSBgJHt4fSAke3Z9cHggJHtjfWAsIG4udGV4dEFsaWduID0gImNlbnRlciIsIG4udGV4dEJhc2VsaW5lID0gIm1pZGRsZSIsIG4uZmlsbFRleHQodSwgZSAvIDIsIHIgLyAyKTsKICB9KShtKTsKICBjb25zdCBiID0gQWUoaSwgcCwgZSwgcik7CiAgbi5maWxsU3R5bGUgPSAiYmxhY2siLCBuLmZpbGxSZWN0KDAsIDAsIGUsIHIpLCBuLmZpbGxTdHlsZSA9ICJ3aGl0ZSIsIG4uZm9udCA9IGAke3h9ICR7dn1weCAke2N9YCwgbi50ZXh0QWxpZ24gPSAiY2VudGVyIiwgbi50ZXh0QmFzZWxpbmUgPSAibWlkZGxlIiwgbi5maWxsVGV4dCh1LCBlIC8gMiwgciAvIDIpOwogIGNvbnN0IHkgPSBBZShpLCBwLCBlLCByKTsKICByZXR1cm4gewogICAgYmFja2dyb3VuZFRleDogYiwKICAgIGJhY2tncm91bmRWaWV3OiBiLmNyZWF0ZVZpZXcoKSwKICAgIG9ic3RhY2xlVGV4OiB5LAogICAgb2JzdGFjbGVWaWV3OiB5LmNyZWF0ZVZpZXcoKSwKICAgIGNvdmVyYWdlVGV4OiB5LAogICAgY292ZXJhZ2VWaWV3OiB5LmNyZWF0ZVZpZXcoKSwKICAgIHNoYXJlZENvdmVyYWdlOiAhMAogIH07Cn0KZnVuY3Rpb24gdHIoaSwgZSwgciwgcywgbyA9IDAsIGEgPSAiY292ZXIiLCB1ID0gbnVsbCwgdiA9ICJjb3ZlciIpIHsKICBjb25zdCBtID0gbmV3IE9mZnNjcmVlbkNhbnZhcyhyLCBzKSwgYyA9IG0uZ2V0Q29udGV4dCgiMmQiKSwgeyB4LCB5OiBwLCBkcmF3VzogbiwgZHJhd0g6IGQgfSA9IEJlKGUud2lkdGgsIGUuaGVpZ2h0LCByLCBzLCBhKTsKICBpZiAoYy5jbGVhclJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gImJsYWNrIiwgYy5maWxsUmVjdCgwLCAwLCByLCBzKSwgdSkgewogICAgY29uc3QgeyB4OiBnLCB5OiBfLCBkcmF3VzogUCwgZHJhd0g6IGsgfSA9IEJlKAogICAgICB1LndpZHRoLAogICAgICB1LmhlaWdodCwKICAgICAgciwKICAgICAgcywKICAgICAgdgogICAgKTsKICAgIGMuZmlsdGVyID0gYGJyaWdodG5lc3MoJHtvfSkgYmx1cig4cHgpYCwgYy5kcmF3SW1hZ2UodSwgZywgXywgUCwgayksIGMuZmlsdGVyID0gIm5vbmUiOwogIH0KICBjLmRyYXdJbWFnZShlLCB4LCBwLCBuLCBkKTsKICBjb25zdCBiID0gQWUoaSwgbSwgciwgcyk7CiAgYy5jbGVhclJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gImJsYWNrIiwgYy5maWxsUmVjdCgwLCAwLCByLCBzKSwgYy5maWx0ZXIgPSBgYnJpZ2h0bmVzcygke299KSBibHVyKDhweClgLCBjLmRyYXdJbWFnZShlLCB4LCBwLCBuLCBkKSwgYy5maWx0ZXIgPSAibm9uZSI7CiAgY29uc3QgeSA9IEFlKGksIG0sIHIsIHMpOwogIGMuY2xlYXJSZWN0KDAsIDAsIHIsIHMpLCBjLmZpbGxTdHlsZSA9ICJibGFjayIsIGMuZmlsbFJlY3QoMCwgMCwgciwgcyksIGMuZmlsbFN0eWxlID0gIndoaXRlIiwgYy5maWxsUmVjdChNYXRoLm1heCgwLCB4KSwgTWF0aC5tYXgoMCwgcCksIE1hdGgubWluKG4sIHIgLSBNYXRoLm1heCgwLCB4KSksIE1hdGgubWluKGQsIHMgLSBNYXRoLm1heCgwLCBwKSkpOwogIGNvbnN0IEQgPSBBZShpLCBtLCByLCBzKTsKICByZXR1cm4gewogICAgYmFja2dyb3VuZFRleDogYiwKICAgIGJhY2tncm91bmRWaWV3OiBiLmNyZWF0ZVZpZXcoKSwKICAgIG9ic3RhY2xlVGV4OiB5LAogICAgb2JzdGFjbGVWaWV3OiB5LmNyZWF0ZVZpZXcoKSwKICAgIGNvdmVyYWdlVGV4OiBELAogICAgY292ZXJhZ2VWaWV3OiBELmNyZWF0ZVZpZXcoKSwKICAgIHNoYXJlZENvdmVyYWdlOiAhMQogIH07Cn0KZnVuY3Rpb24gQWUoaSwgZSwgciwgcykgewogIGNvbnN0IG8gPSBpLmNyZWF0ZVRleHR1cmUoewogICAgc2l6ZTogW3IsIHNdLAogICAgZm9ybWF0OiAicmdiYTh1bm9ybSIsCiAgICB1c2FnZTogR1BVVGV4dHVyZVVzYWdlLlRFWFRVUkVfQklORElORyB8IEdQVVRleHR1cmVVc2FnZS5DT1BZX0RTVCB8IEdQVVRleHR1cmVVc2FnZS5SRU5ERVJfQVRUQUNITUVOVAogIH0pOwogIHJldHVybiBpLnF1ZXVlLmNvcHlFeHRlcm5hbEltYWdlVG9UZXh0dXJlKAogICAgeyBzb3VyY2U6IGUgfSwKICAgIHsgdGV4dHVyZTogbyB9LAogICAgW3IsIHNdCiAgKSwgbzsKfQphc3luYyBmdW5jdGlvbiBycihpKSB7CiAgY29uc3QgZSA9IGF3YWl0IGZldGNoKGkpOwogIGlmICghZS5vaykKICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZldGNoIGltYWdlOiAke2l9ICgke2Uuc3RhdHVzfSlgKTsKICBjb25zdCByID0gYXdhaXQgZS5ibG9iKCk7CiAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKHIpOwp9CmNvbnN0IGN0ID0gdHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZSA8ICJ1IiA/IHJlcXVlc3RBbmltYXRpb25GcmFtZS5iaW5kKGdsb2JhbFRoaXMpIDogKGkpID0+IHNldFRpbWVvdXQoaSwgMWUzIC8gNjApLCBpciA9IHR5cGVvZiBjYW5jZWxBbmltYXRpb25GcmFtZSA8ICJ1IiA/IGNhbmNlbEFuaW1hdGlvbkZyYW1lLmJpbmQoZ2xvYmFsVGhpcykgOiBjbGVhclRpbWVvdXQsIE9lID0gMC4wMTYsIGZ0ID0geyBzdGFuZGFyZDogMCwgZ2xhc3M6IDEsIGluazogMiwgYXVyb3JhOiAzLCByaXBwbGU6IDQgfTsKdmFyIGNlLCBNLCB6ZSwgZmUsIFVlLCBCLCBSLCAkLCBxLCBILCBLLCBMLCBZLCBPLCBEZSwgdmUsIF9lLCBWLCBULCBvZSwgUSwgYWUsIHosIHBlLCB4ZSwgbWUsIGRlLCBoZSwgSiwgWiwgZ2UsIGJlLCBUZSwgdywgVSwgRywgSSwgRiwgQ2UsIGVlLCBBLCB1ZSwgdGUsIGgsIEMsIGosIHllLCBYZSwgU2UsIFllLCBwdCwgd2UsIEZlLCBNZSwgc3QsIG5lLCBFZSwgUmUsIFBlLCBHZSwgb3QsIEllLCBhdCwgUWUsIHh0LCBqZSwgbXQsIEtlLCBkdCwgSmUsIGh0LCBaZSwgZ3Q7CmNvbnN0IHV0ID0gY2xhc3MgdXQgewogIC8vIOKUgOKUgCBDb25zdHJ1Y3RvciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICBjb25zdHJ1Y3RvcihlLCByID0ge30sIHMgPSB7fSwgbywgYSA9ICEwKSB7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIEdQVSBpbml0aWFsaXNhdGlvbgogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIFllKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgc2hhcmVkIGhlbHBlcnMKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCB3ZSk7CiAgICBmKHRoaXMsIE1lKTsKICAgIGYodGhpcywgbmUpOwogICAgZih0aGlzLCBSZSk7CiAgICBmKHRoaXMsIEdlKTsKICAgIGYodGhpcywgSWUpOwogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIOKAlCBmcmFtZSBkaXNwYXRjaAogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIFFlKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgV2ViR1BVIHNpbXVsYXRpb24gc3RlcAogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIGplKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgV2ViR1BVIGRpcmVjdCBzcGxhdAogICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBmKHRoaXMsIEtlKTsKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSDigJQgV2ViR0wgc3BsYXQKICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgZih0aGlzLCBKZSk7CiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUg4oCUIFdlYkdMIHNpbXVsYXRpb24gc3RlcCAodW5jaGFuZ2VkIGZyb20gb3JpZ2luYWwpCiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGYodGhpcywgWmUpOwogICAgZih0aGlzLCBjZSwgdm9pZCAwKTsKICAgIC8vIOKUgOKUgCBXZWJHTCBwYXRoIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgZih0aGlzLCBNLCBudWxsKTsKICAgIGYodGhpcywgemUsIG51bGwpOwogICAgZih0aGlzLCBmZSwgbnVsbCk7CiAgICBmKHRoaXMsIFVlLCBudWxsKTsKICAgIGYodGhpcywgQiwgbnVsbCk7CiAgICBmKHRoaXMsIFIsIG51bGwpOwogICAgZih0aGlzLCAkLCBudWxsKTsKICAgIGYodGhpcywgcSwgbnVsbCk7CiAgICBmKHRoaXMsIEgsIG51bGwpOwogICAgZih0aGlzLCBLLCBudWxsKTsKICAgIGYodGhpcywgTCwgbnVsbCk7CiAgICBmKHRoaXMsIFksIG51bGwpOwogICAgLy8g4pSA4pSAIFdlYkdQVSBwYXRoIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgZih0aGlzLCBPLCBudWxsKTsKICAgIGYodGhpcywgRGUsIG51bGwpOwogICAgZih0aGlzLCB2ZSwgbnVsbCk7CiAgICBmKHRoaXMsIF9lLCBudWxsKTsKICAgIGYodGhpcywgViwgbnVsbCk7CiAgICBmKHRoaXMsIFQsIG51bGwpOwogICAgZih0aGlzLCBvZSwgbnVsbCk7CiAgICBmKHRoaXMsIFEsIG51bGwpOwogICAgZih0aGlzLCBhZSwgbnVsbCk7CiAgICBmKHRoaXMsIHosIG51bGwpOwogICAgLy8gUHJlLWFsbG9jYXRlZCB1bmlmb3JtIGJ1ZmZlcnMgKHNpemVzOiBzZWUgZ3B1LXV0aWxzIHdyaXRlWHh4IGRvY3MpCiAgICAvLyBWZWxvY2l0eS9kZW5zaXR5IGFkdmVjdGlvbiB1c2Ugc2VwYXJhdGUgYnVmZmVycyDigJQgd3JpdGVCdWZmZXIgaXMgYSBxdWV1ZSBvcDsKICAgIC8vIGEgc2Vjb25kIHdyaXRlIHRvIHRoZSBzYW1lIGJ1ZmZlciBiZWZvcmUgcXVldWUuc3VibWl0KCkgYWxpYXNlcyBib3RoIHBhc3Nlcy4KICAgIGYodGhpcywgcGUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMg4oCUIHZlbG9jaXR5IGFkdmVjdGlvbgogICAgZih0aGlzLCB4ZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcyDigJQgZGVuc2l0eSBhZHZlY3Rpb24KICAgIGYodGhpcywgbWUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgZGUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgaGUsIG51bGwpOwogICAgLy8gMTYgYnl0ZXMKICAgIGYodGhpcywgSiwgbnVsbCk7CiAgICAvLyA0OCBieXRlcyDigJQgdmVsb2NpdHkgc3BsYXQKICAgIGYodGhpcywgWiwgbnVsbCk7CiAgICAvLyA0OCBieXRlcyDigJQgZGVuc2l0eSBzcGxhdAogICAgZih0aGlzLCBnZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcwogICAgZih0aGlzLCBiZSwgbnVsbCk7CiAgICAvLyAxNiBieXRlcwogICAgZih0aGlzLCBUZSwgbnVsbCk7CiAgICAvLyA2NCBieXRlcwogICAgLy8g4pSA4pSAIFNoYXJlZCBzdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgIGYodGhpcywgdywgMCk7CiAgICBmKHRoaXMsIFUsIDApOwogICAgZih0aGlzLCBHLCAwKTsKICAgIGYodGhpcywgSSwgMCk7CiAgICBmKHRoaXMsIEYsIDEpOwogICAgZih0aGlzLCBDZSwgMSk7CiAgICBmKHRoaXMsIGVlLCAwLjUpOwogICAgZih0aGlzLCBBLCBudWxsKTsKICAgIGYodGhpcywgdWUsICJjb3ZlciIpOwogICAgZih0aGlzLCB0ZSwgdm9pZCAwKTsKICAgIGYodGhpcywgaCwgeyB4OiAwLCB5OiAwLCBkeDogMCwgZHk6IDAsIHRhcmdldFg6IDAsIHRhcmdldFk6IDAsIG1vdmVkOiAhMSB9KTsKICAgIGYodGhpcywgQywgbnVsbCk7CiAgICBmKHRoaXMsIGosIG51bGwpOwogICAgZih0aGlzLCB5ZSwgITEpOwogICAgZih0aGlzLCBYZSwgITEpOwogICAgZih0aGlzLCBTZSwgITApOwogICAgaWYgKGwodGhpcywgY2UsIGUpLCBsKHRoaXMsIENlLCBNYXRoLm1heCgwLjEsIE1hdGgubWluKDEsIHMuZHByID8/IDEpKSksIGwodGhpcywgZWUsIE1hdGgubWF4KDAuMSwgTWF0aC5taW4oMSwgcy5zaW0gPz8gMC41KSkpLCBsKHRoaXMsIHRlLCB3dChyKSksIGwodGhpcywgU2UsIGEpLCBvKQogICAgICBsKHRoaXMsIE8sIG8pLCBTKHRoaXMsIFllLCBwdCkuY2FsbCh0aGlzLCBvKTsKICAgIGVsc2UgewogICAgICBjb25zdCB7IGdsOiB1LCBleHQ6IHYgfSA9IE90KGUsIGEpOwogICAgICBsKHRoaXMsIE0sIHUpLCBsKHRoaXMsIHplLCB2KSwgbCh0aGlzLCBmZSwgUHQodSkpLCBsKHRoaXMsIFVlLCBMdCh1KSksIHUuY2xlYXJDb2xvcigwLCAwLCAwLCBhID8gMCA6IDEpOwogICAgfQogIH0KICAvKioKICAgKiBXZWJHUFUtZmlyc3QgZmFjdG9yeS4gVHJpZXMgV2ViR1BVLCBmYWxscyBiYWNrIHRvIFdlYkdMMiDihpIgV2ViR0wxLgogICAqIFRoaXMgaXMgdGhlIHJlY29tbWVuZGVkIGVudHJ5IHBvaW50IHdoZW4gV2ViR1BVIHN1cHBvcnQgaXMgZGVzaXJlZC4KICAgKi8KICBzdGF0aWMgYXN5bmMgY3JlYXRlKGUsIHIgPSB7fSwgcyA9IHt9LCBvID0gITAsIGEgPSAhMCkgewogICAgY29uc3QgdSA9IG8gPyBhd2FpdCBGdChlLCBhKSA6IG51bGw7CiAgICByZXR1cm4gbmV3IHV0KGUsIHIsIHMsIHUgPz8gdm9pZCAwLCBhKTsKICB9CiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gUHVibGljIEFQSQogIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIHNldFRleHRTb3VyY2UoZSkgewogICAgbCh0aGlzLCBDLCB7IHR5cGU6ICJ0ZXh0Iiwgb3B0czogZSB9KSwgUyh0aGlzLCB3ZSwgRmUpLmNhbGwodGhpcyksIFModGhpcywgbmUsIEVlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIFJlLCBQZSkuY2FsbCh0aGlzKTsKICB9CiAgYXN5bmMgc2V0SW1hZ2VTb3VyY2UoZSwgciA9IDAsIHMgPSAiY292ZXIiKSB7CiAgICBjb25zdCBvID0gYXdhaXQgcnIoZSk7CiAgICBpZiAodCh0aGlzLCBYZSkpIHsKICAgICAgby5jbG9zZSgpOwogICAgICByZXR1cm47CiAgICB9CiAgICBsKHRoaXMsIEMsIHsgdHlwZTogImltYWdlIiwgYml0bWFwOiBvLCBlZmZlY3Q6IHIsIHNpemU6IHMgfSksIFModGhpcywgd2UsIEZlKS5jYWxsKHRoaXMpLCBTKHRoaXMsIG5lLCBFZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBSZSwgUGUpLmNhbGwodGhpcyk7CiAgfQogIHNldEltYWdlQml0bWFwKGUsIHIgPSAwLCBzID0gImNvdmVyIikgewogICAgbCh0aGlzLCBDLCB7IHR5cGU6ICJpbWFnZSIsIGJpdG1hcDogZSwgZWZmZWN0OiByLCBzaXplOiBzIH0pLCBTKHRoaXMsIHdlLCBGZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBuZSwgRWUpLmNhbGwodGhpcyksIFModGhpcywgUmUsIFBlKS5jYWxsKHRoaXMpOwogIH0KICBzZXRCYWNrZ3JvdW5kKGUsIHIgPSAiY292ZXIiKSB7CiAgICB0KHRoaXMsIEEpICYmIHQodGhpcywgQSkgIT09IGUgJiYgdCh0aGlzLCBBKS5jbG9zZSgpLCBsKHRoaXMsIEEsIGUpLCBsKHRoaXMsIHVlLCByID8/ICJjb3ZlciIpLCB0KHRoaXMsIEMpICYmIHQodGhpcywgdykgPiAwICYmIHQodGhpcywgVSkgPiAwICYmIFModGhpcywgbmUsIEVlKS5jYWxsKHRoaXMpOwogIH0KICBoYW5kbGVNb3ZlKGUsIHIsIHMgPSAxKSB7CiAgICB0KHRoaXMsIGgpLm1vdmVkID0gITAsIHQodGhpcywgaCkuZHggPSAoZSAtIHQodGhpcywgaCkudGFyZ2V0WCkgKiBzLCB0KHRoaXMsIGgpLmR5ID0gKHIgLSB0KHRoaXMsIGgpLnRhcmdldFkpICogcywgdCh0aGlzLCBoKS50YXJnZXRYID0gZSwgdCh0aGlzLCBoKS50YXJnZXRZID0gcjsKICB9CiAgLyoqCiAgICogSW1tZWRpYXRlbHkgYXBwbGllcyBvbmUgZmx1aWQgc3BsYXQgYXQgKHgsIHkpIHdpdGggZXhwbGljaXQgdmVsb2NpdHkgKHZ4LCB2eSkuCiAgICogU2FmZSB0byBjYWxsIG11bHRpcGxlIHRpbWVzIHBlciBmcmFtZSDigJQgZWFjaCBjYWxsIHdyaXRlcyBkaXJlY3RseSB0byB0aGUgRkJPcy4KICAgKiBEZXNpZ25lZCBmb3IgcHJvZ3JhbW1hdGljIHVzZSBjYXNlcyAoZS5nLiBwYXJ0aWNsZSBzeXN0ZW1zLCBhdHRyYWN0b3IgcGF0aHMpCiAgICogd2hlcmUgeW91IHdhbnQgTiBpbmRlcGVuZGVudCBpbmplY3Rpb24gcG9pbnRzIHBlciBmcmFtZSB3aXRob3V0IGZsb29kaW5nIHRoZQogICAqIG1vdXNlLXN0YXRlIG1hY2hpbmUgb3IgdGhlIHdvcmtlciBtZXNzYWdlIHF1ZXVlLgogICAqLwogIHNwbGF0KGUsIHIsIHMsIG8sIGEgPSAxKSB7CiAgICAhdCh0aGlzLCB5ZSkgfHwgdCh0aGlzLCB3KSA9PT0gMCB8fCAodCh0aGlzLCBPKSA/IFModGhpcywgS2UsIGR0KS5jYWxsKHRoaXMsIGUsIHIsIHMsIG8sIGEpIDogUyh0aGlzLCBKZSwgaHQpLmNhbGwodGhpcywgZSwgciwgcywgbywgYSkpOwogIH0KICB1cGRhdGVRdWFsaXR5KGUpIHsKICAgIGUuZHByICE9PSB2b2lkIDAgJiYgbCh0aGlzLCBDZSwgTWF0aC5tYXgoMC4xLCBNYXRoLm1pbigxLCBlLmRwcikpKSwgZS5zaW0gIT09IHZvaWQgMCAmJiBsKHRoaXMsIGVlLCBNYXRoLm1heCgwLjEsIE1hdGgubWluKDEsIGUuc2ltKSkpOwogIH0KICByZXNpemUoZSwgciwgcykgewogICAgaWYgKHMgIT09IHZvaWQgMCA/IGwodGhpcywgRiwgcykgOiB0eXBlb2Ygd2luZG93IDwgInUiICYmIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvICYmIGwodGhpcywgRiwgd2luZG93LmRldmljZVBpeGVsUmF0aW8pLCBlICE9PSB2b2lkIDAgJiYgZSA+IDApIHsKICAgICAgaWYgKHIgPT09IHZvaWQgMCB8fCByIDw9IDApCiAgICAgICAgcmV0dXJuOwogICAgICBsKHRoaXMsIHcsIHQodGhpcywgY2UpLndpZHRoID0gZSksIGwodGhpcywgVSwgdCh0aGlzLCBjZSkuaGVpZ2h0ID0gciksIGwodGhpcywgRywgTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChlICogdCh0aGlzLCBlZSkpKSksIGwodGhpcywgSSwgTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChyICogdCh0aGlzLCBlZSkpKSksIFModGhpcywgTWUsIHN0KS5jYWxsKHRoaXMpOwogICAgfSBlbHNlCiAgICAgIFModGhpcywgd2UsIEZlKS5jYWxsKHRoaXMpOwogICAgdCh0aGlzLCBDKSAmJiBTKHRoaXMsIG5lLCBFZSkuY2FsbCh0aGlzKSwgUyh0aGlzLCBSZSwgUGUpLmNhbGwodGhpcyk7CiAgfQogIHVwZGF0ZUNvbmZpZyhlKSB7CiAgICBPYmplY3QuYXNzaWduKHQodGhpcywgdGUpLCBlKTsKICB9CiAgZGVzdHJveSgpIHsKICAgIHZhciBlLCByLCBzLCBvLCBhLCB1LCB2LCBtLCBjLCB4LCBwOwogICAgaWYgKGwodGhpcywgWGUsICEwKSwgdGhpcy5zdG9wKCksIFModGhpcywgR2UsIG90KS5jYWxsKHRoaXMpLCBTKHRoaXMsIEllLCBhdCkuY2FsbCh0aGlzKSwgdCh0aGlzLCBBKSAmJiAodCh0aGlzLCBBKS5jbG9zZSgpLCBsKHRoaXMsIEEsIG51bGwpKSwgdCh0aGlzLCBPKSkKICAgICAgKGUgPSB0KHRoaXMsIHBlKSkgPT0gbnVsbCB8fCBlLmRlc3Ryb3koKSwgKHIgPSB0KHRoaXMsIHhlKSkgPT0gbnVsbCB8fCByLmRlc3Ryb3koKSwgKHMgPSB0KHRoaXMsIG1lKSkgPT0gbnVsbCB8fCBzLmRlc3Ryb3koKSwgKG8gPSB0KHRoaXMsIGRlKSkgPT0gbnVsbCB8fCBvLmRlc3Ryb3koKSwgKGEgPSB0KHRoaXMsIGhlKSkgPT0gbnVsbCB8fCBhLmRlc3Ryb3koKSwgKHUgPSB0KHRoaXMsIEopKSA9PSBudWxsIHx8IHUuZGVzdHJveSgpLCAodiA9IHQodGhpcywgWikpID09IG51bGwgfHwgdi5kZXN0cm95KCksIChtID0gdCh0aGlzLCBnZSkpID09IG51bGwgfHwgbS5kZXN0cm95KCksIChjID0gdCh0aGlzLCBiZSkpID09IG51bGwgfHwgYy5kZXN0cm95KCksICh4ID0gdCh0aGlzLCBUZSkpID09IG51bGwgfHwgeC5kZXN0cm95KCksIChwID0gdCh0aGlzLCB2ZSkpID09IG51bGwgfHwgcC5kZXN0cm95KCksIHQodGhpcywgTykuZGV2aWNlLmRlc3Ryb3koKTsKICAgIGVsc2UgewogICAgICBjb25zdCBuID0gdCh0aGlzLCBNKTsKICAgICAgZm9yIChjb25zdCBiIG9mIE9iamVjdC52YWx1ZXModCh0aGlzLCBmZSkpKQogICAgICAgIGIuZGlzcG9zZSgpOwogICAgICBjb25zdCBkID0gbi5nZXRFeHRlbnNpb24oIldFQkdMX2xvc2VfY29udGV4dCIpOwogICAgICBkID09IG51bGwgfHwgZC5sb3NlQ29udGV4dCgpOwogICAgfQogIH0KICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBMb29wIGNvbnRyb2wKICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICBzdGFydCgpIHsKICAgIGlmICh0KHRoaXMsIGopICE9PSBudWxsKQogICAgICByZXR1cm47CiAgICBjb25zdCBlID0gKCkgPT4gewogICAgICBTKHRoaXMsIFFlLCB4dCkuY2FsbCh0aGlzKSwgbCh0aGlzLCBqLCBjdChlKSk7CiAgICB9OwogICAgbCh0aGlzLCBqLCBjdChlKSk7CiAgfQogIHN0b3AoKSB7CiAgICB0KHRoaXMsIGopICE9PSBudWxsICYmIChpcih0KHRoaXMsIGopKSwgbCh0aGlzLCBqLCBudWxsKSk7CiAgfQogIGdldCBpc1J1bm5pbmcoKSB7CiAgICByZXR1cm4gdCh0aGlzLCBqKSAhPT0gbnVsbDsKICB9Cn07CmNlID0gbmV3IFdlYWtNYXAoKSwgTSA9IG5ldyBXZWFrTWFwKCksIHplID0gbmV3IFdlYWtNYXAoKSwgZmUgPSBuZXcgV2Vha01hcCgpLCBVZSA9IG5ldyBXZWFrTWFwKCksIEIgPSBuZXcgV2Vha01hcCgpLCBSID0gbmV3IFdlYWtNYXAoKSwgJCA9IG5ldyBXZWFrTWFwKCksIHEgPSBuZXcgV2Vha01hcCgpLCBIID0gbmV3IFdlYWtNYXAoKSwgSyA9IG5ldyBXZWFrTWFwKCksIEwgPSBuZXcgV2Vha01hcCgpLCBZID0gbmV3IFdlYWtNYXAoKSwgTyA9IG5ldyBXZWFrTWFwKCksIERlID0gbmV3IFdlYWtNYXAoKSwgdmUgPSBuZXcgV2Vha01hcCgpLCBfZSA9IG5ldyBXZWFrTWFwKCksIFYgPSBuZXcgV2Vha01hcCgpLCBUID0gbmV3IFdlYWtNYXAoKSwgb2UgPSBuZXcgV2Vha01hcCgpLCBRID0gbmV3IFdlYWtNYXAoKSwgYWUgPSBuZXcgV2Vha01hcCgpLCB6ID0gbmV3IFdlYWtNYXAoKSwgcGUgPSBuZXcgV2Vha01hcCgpLCB4ZSA9IG5ldyBXZWFrTWFwKCksIG1lID0gbmV3IFdlYWtNYXAoKSwgZGUgPSBuZXcgV2Vha01hcCgpLCBoZSA9IG5ldyBXZWFrTWFwKCksIEogPSBuZXcgV2Vha01hcCgpLCBaID0gbmV3IFdlYWtNYXAoKSwgZ2UgPSBuZXcgV2Vha01hcCgpLCBiZSA9IG5ldyBXZWFrTWFwKCksIFRlID0gbmV3IFdlYWtNYXAoKSwgdyA9IG5ldyBXZWFrTWFwKCksIFUgPSBuZXcgV2Vha01hcCgpLCBHID0gbmV3IFdlYWtNYXAoKSwgSSA9IG5ldyBXZWFrTWFwKCksIEYgPSBuZXcgV2Vha01hcCgpLCBDZSA9IG5ldyBXZWFrTWFwKCksIGVlID0gbmV3IFdlYWtNYXAoKSwgQSA9IG5ldyBXZWFrTWFwKCksIHVlID0gbmV3IFdlYWtNYXAoKSwgdGUgPSBuZXcgV2Vha01hcCgpLCBoID0gbmV3IFdlYWtNYXAoKSwgQyA9IG5ldyBXZWFrTWFwKCksIGogPSBuZXcgV2Vha01hcCgpLCB5ZSA9IG5ldyBXZWFrTWFwKCksIFhlID0gbmV3IFdlYWtNYXAoKSwgU2UgPSBuZXcgV2Vha01hcCgpLCBZZSA9IG5ldyBXZWFrU2V0KCksIHB0ID0gZnVuY3Rpb24oZSkgewogIGNvbnN0IHsgZGV2aWNlOiByLCBmb3JtYXQ6IHMgfSA9IGU7CiAgbCh0aGlzLCBEZSwgSHQociwgcywgdCh0aGlzLCBTZSkpKSwgbCh0aGlzLCB2ZSwgJHQocikpLCBsKHRoaXMsIF9lLCBZdChyKSksIGwodGhpcywgcGUsIFcociwgMTYpKSwgbCh0aGlzLCB4ZSwgVyhyLCAxNikpLCBsKHRoaXMsIG1lLCBXKHIsIDE2KSksIGwodGhpcywgZGUsIFcociwgMTYpKSwgbCh0aGlzLCBoZSwgVyhyLCAxNikpLCBsKHRoaXMsIEosIFcociwgNDgpKSwgbCh0aGlzLCBaLCBXKHIsIDQ4KSksIGwodGhpcywgZ2UsIFcociwgMTYpKSwgbCh0aGlzLCBiZSwgVyhyLCAxNikpLCBsKHRoaXMsIFRlLCBXKHIsIDY0KSk7Cn0sIHdlID0gbmV3IFdlYWtTZXQoKSwgRmUgPSBmdW5jdGlvbigpIHsKICBjb25zdCBlID0gdCh0aGlzLCBjZSk7CiAgImNsaWVudFdpZHRoIiBpbiBlICYmIGUuY2xpZW50V2lkdGggPiAwID8gKGwodGhpcywgRiwgKHR5cGVvZiB3aW5kb3cgPCAidSIgJiYgd2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMSkgKiB0KHRoaXMsIENlKSksIGwodGhpcywgdywgZS53aWR0aCA9IE1hdGgucm91bmQoZS5jbGllbnRXaWR0aCAqIHQodGhpcywgRikpKSwgbCh0aGlzLCBVLCBlLmhlaWdodCA9IE1hdGgucm91bmQoZS5jbGllbnRIZWlnaHQgKiB0KHRoaXMsIEYpKSkpIDogKGwodGhpcywgdywgZS53aWR0aCksIGwodGhpcywgVSwgZS5oZWlnaHQpKSwgISh0KHRoaXMsIHcpID09PSAwIHx8IHQodGhpcywgVSkgPT09IDApICYmIChsKHRoaXMsIEcsIE1hdGgubWF4KDEsIE1hdGgucm91bmQodCh0aGlzLCB3KSAqIHQodGhpcywgZWUpKSkpLCBsKHRoaXMsIEksIE1hdGgubWF4KDEsIE1hdGgucm91bmQodCh0aGlzLCBVKSAqIHQodGhpcywgZWUpKSkpLCBTKHRoaXMsIE1lLCBzdCkuY2FsbCh0aGlzKSk7Cn0sIE1lID0gbmV3IFdlYWtTZXQoKSwgc3QgPSBmdW5jdGlvbigpIHsKICBpZiAoUyh0aGlzLCBHZSwgb3QpLmNhbGwodGhpcyksIHQodGhpcywgTykpIHsKICAgIGNvbnN0IHsgZGV2aWNlOiBlIH0gPSB0KHRoaXMsIE8pLCByID0gInJnYmExNmZsb2F0IiwgcyA9IHQodGhpcywgRyksIG8gPSB0KHRoaXMsIEkpOwogICAgbCh0aGlzLCBWLCBydChlLCByLCBzLCBvKSksIGwodGhpcywgVCwgcnQoZSwgciwgcywgbykpLCBsKHRoaXMsIFEsIHJ0KGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBvZSwgSGUoZSwgciwgcywgbykpLCBsKHRoaXMsIGFlLCBIZShlLCByLCBzLCBvKSk7CiAgfSBlbHNlIHsKICAgIGNvbnN0IGUgPSB0KHRoaXMsIE0pLCByID0gdCh0aGlzLCB6ZSksIHMgPSB0KHRoaXMsIEcpLCBvID0gdCh0aGlzLCBJKTsKICAgIGwodGhpcywgQiwgdHQoZSwgciwgcywgbykpLCBsKHRoaXMsIFIsIHR0KGUsIHIsIHMsIG8pKSwgbCh0aGlzLCBxLCB0dChlLCByLCBzLCBvKSksIGwodGhpcywgJCwgcWUoZSwgciwgcywgbykpLCBsKHRoaXMsIEgsIHFlKGUsIHIsIHMsIG8pKTsKICB9Cn0sIG5lID0gbmV3IFdlYWtTZXQoKSwgRWUgPSBmdW5jdGlvbigpIHsKICBpZiAoISghdCh0aGlzLCBDKSB8fCB0KHRoaXMsIHcpID09PSAwIHx8IHQodGhpcywgVSkgPT09IDApKSB7CiAgICBpZiAoUyh0aGlzLCBJZSwgYXQpLmNhbGwodGhpcyksIHQodGhpcywgTykpIHsKICAgICAgY29uc3QgeyBkZXZpY2U6IGUgfSA9IHQodGhpcywgTyk7CiAgICAgIHQodGhpcywgQykudHlwZSA9PT0gInRleHQiID8gbCh0aGlzLCB6LCBlcigKICAgICAgICBlLAogICAgICAgIHQodGhpcywgdyksCiAgICAgICAgdCh0aGlzLCBVKSwKICAgICAgICB0KHRoaXMsIEMpLm9wdHMsCiAgICAgICAgdCh0aGlzLCBBKSwKICAgICAgICB0KHRoaXMsIHVlKQogICAgICApKSA6IGwodGhpcywgeiwgdHIoCiAgICAgICAgZSwKICAgICAgICB0KHRoaXMsIEMpLmJpdG1hcCwKICAgICAgICB0KHRoaXMsIHcpLAogICAgICAgIHQodGhpcywgVSksCiAgICAgICAgdCh0aGlzLCBDKS5lZmZlY3QsCiAgICAgICAgdCh0aGlzLCBDKS5zaXplLAogICAgICAgIHQodGhpcywgQSksCiAgICAgICAgdCh0aGlzLCB1ZSkKICAgICAgKSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBlID0gdCh0aGlzLCBNKTsKICAgICAgaWYgKHQodGhpcywgQykudHlwZSA9PT0gInRleHQiKSB7CiAgICAgICAgY29uc3QgeyBiYWNrZ3JvdW5kVGV4OiByLCBvYnN0YWNsZVRleDogcywgY292ZXJhZ2VUZXg6IG8gfSA9IEp0KAogICAgICAgICAgZSwKICAgICAgICAgIHQodGhpcywgdyksCiAgICAgICAgICB0KHRoaXMsIFUpLAogICAgICAgICAgdCh0aGlzLCBDKS5vcHRzLAogICAgICAgICAgdCh0aGlzLCBBKSwKICAgICAgICAgIHQodGhpcywgdWUpCiAgICAgICAgKTsKICAgICAgICBsKHRoaXMsIEssIHIpLCBsKHRoaXMsIEwsIHMpLCBsKHRoaXMsIFksIG8pOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IHsgYmFja2dyb3VuZFRleDogciwgb2JzdGFjbGVUZXg6IHMsIGNvdmVyYWdlVGV4OiBvIH0gPSBadCgKICAgICAgICAgIGUsCiAgICAgICAgICB0KHRoaXMsIEMpLmJpdG1hcCwKICAgICAgICAgIHQodGhpcywgdyksCiAgICAgICAgICB0KHRoaXMsIFUpLAogICAgICAgICAgdCh0aGlzLCBDKS5lZmZlY3QsCiAgICAgICAgICB0KHRoaXMsIEMpLnNpemUsCiAgICAgICAgICB0KHRoaXMsIEEpLAogICAgICAgICAgdCh0aGlzLCB1ZSkKICAgICAgICApOwogICAgICAgIGwodGhpcywgSywgciksIGwodGhpcywgTCwgcyksIGwodGhpcywgWSwgbyk7CiAgICAgIH0KICAgIH0KICAgIGwodGhpcywgeWUsICEwKTsKICB9Cn0sIFJlID0gbmV3IFdlYWtTZXQoKSwgUGUgPSBmdW5jdGlvbigpIHsKICB0KHRoaXMsIHllKSAmJiAhdGhpcy5pc1J1bm5pbmcgJiYgdGhpcy5zdGFydCgpOwp9LCBHZSA9IG5ldyBXZWFrU2V0KCksIG90ID0gZnVuY3Rpb24oKSB7CiAgdmFyIGUsIHIsIHMsIG8sIGEsIHUsIHYsIG07CiAgaWYgKHQodGhpcywgTykpCiAgICAoZSA9IHQodGhpcywgVikpID09IG51bGwgfHwgZS5kaXNwb3NlKCksIChyID0gdCh0aGlzLCBUKSkgPT0gbnVsbCB8fCByLmRpc3Bvc2UoKSwgKHMgPSB0KHRoaXMsIFEpKSA9PSBudWxsIHx8IHMuZGlzcG9zZSgpLCAobyA9IHQodGhpcywgb2UpKSA9PSBudWxsIHx8IG8udGV4LmRlc3Ryb3koKSwgKGEgPSB0KHRoaXMsIGFlKSkgPT0gbnVsbCB8fCBhLnRleC5kZXN0cm95KCksIGwodGhpcywgViwgbCh0aGlzLCBULCBsKHRoaXMsIFEsIG51bGwpKSksIGwodGhpcywgb2UsIGwodGhpcywgYWUsIG51bGwpKTsKICBlbHNlIHsKICAgIGNvbnN0IGMgPSB0KHRoaXMsIE0pOwogICAgKHUgPSB0KHRoaXMsIEIpKSA9PSBudWxsIHx8IHUuZGlzcG9zZSgpLCAodiA9IHQodGhpcywgUikpID09IG51bGwgfHwgdi5kaXNwb3NlKCksIChtID0gdCh0aGlzLCBxKSkgPT0gbnVsbCB8fCBtLmRpc3Bvc2UoKSwgdCh0aGlzLCAkKSAmJiAoYy5kZWxldGVUZXh0dXJlKHQodGhpcywgJCkudGV4KSwgYy5kZWxldGVGcmFtZWJ1ZmZlcih0KHRoaXMsICQpLmZibykpLCB0KHRoaXMsIEgpICYmIChjLmRlbGV0ZVRleHR1cmUodCh0aGlzLCBIKS50ZXgpLCBjLmRlbGV0ZUZyYW1lYnVmZmVyKHQodGhpcywgSCkuZmJvKSksIGwodGhpcywgQiwgbCh0aGlzLCBSLCBsKHRoaXMsIHEsIGwodGhpcywgJCwgbCh0aGlzLCBILCBudWxsKSkpKSk7CiAgfQp9LCBJZSA9IG5ldyBXZWFrU2V0KCksIGF0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHQodGhpcywgTykpCiAgICB0KHRoaXMsIHopICYmICh0KHRoaXMsIHopLmJhY2tncm91bmRUZXguZGVzdHJveSgpLCB0KHRoaXMsIHopLm9ic3RhY2xlVGV4LmRlc3Ryb3koKSwgdCh0aGlzLCB6KS5zaGFyZWRDb3ZlcmFnZSB8fCB0KHRoaXMsIHopLmNvdmVyYWdlVGV4LmRlc3Ryb3koKSwgbCh0aGlzLCB6LCBudWxsKSk7CiAgZWxzZSB7CiAgICBjb25zdCBlID0gdCh0aGlzLCBNKTsKICAgIHQodGhpcywgSykgJiYgZS5kZWxldGVUZXh0dXJlKHQodGhpcywgSykpLCB0KHRoaXMsIEwpICYmIGUuZGVsZXRlVGV4dHVyZSh0KHRoaXMsIEwpKSwgdCh0aGlzLCBZKSAmJiB0KHRoaXMsIFkpICE9PSB0KHRoaXMsIEwpICYmIGUuZGVsZXRlVGV4dHVyZSh0KHRoaXMsIFkpKSwgbCh0aGlzLCBLLCBsKHRoaXMsIEwsIGwodGhpcywgWSwgbnVsbCkpKTsKICB9Cn0sIFFlID0gbmV3IFdlYWtTZXQoKSwgeHQgPSBmdW5jdGlvbigpIHsKICAhdCh0aGlzLCB5ZSkgfHwgdCh0aGlzLCB3KSA9PT0gMCB8fCAodCh0aGlzLCBPKSA/IFModGhpcywgamUsIG10KS5jYWxsKHRoaXMpIDogUyh0aGlzLCBaZSwgZ3QpLmNhbGwodGhpcykpOwp9LCBqZSA9IG5ldyBXZWFrU2V0KCksIG10ID0gZnVuY3Rpb24oKSB7CiAgY29uc3QgZSA9IHQodGhpcywgTyksIHIgPSBlLmRldmljZSwgcyA9IHQodGhpcywgRGUpLCBvID0gdCh0aGlzLCB2ZSksIGEgPSB0KHRoaXMsIF9lKSwgdSA9IHQodGhpcywgdGUpLCB2ID0gdCh0aGlzLCB6KTsKICBpZiAoIXQodGhpcywgVikgfHwgIXQodGhpcywgVCkpCiAgICByZXR1cm47CiAgdCh0aGlzLCBoKS54ICs9ICh0KHRoaXMsIGgpLnRhcmdldFggLSB0KHRoaXMsIGgpLngpICogMC4xNSwgdCh0aGlzLCBoKS55ICs9ICh0KHRoaXMsIGgpLnRhcmdldFkgLSB0KHRoaXMsIGgpLnkpICogMC4xNTsKICBjb25zdCBtID0gdCh0aGlzLCBHKSwgYyA9IHQodGhpcywgSSksIHggPSB0KHRoaXMsIHcpLCBwID0gdCh0aGlzLCBVKSwgbiA9IDEgLyBtLCBkID0gMSAvIGM7CiAgbHQociwgdCh0aGlzLCBwZSksIG4sIGQsIE9lLCB1LnZlbG9jaXR5RGlzc2lwYXRpb24pLCBOZShyLCB0KHRoaXMsIG1lKSwgbiwgZCksIE5lKHIsIHQodGhpcywgZGUpLCBuLCBkKSwgTmUociwgdCh0aGlzLCBoZSksIG4sIGQpLCBOZShyLCB0KHRoaXMsIGdlKSwgbiwgZCksIFF0KHIsIHQodGhpcywgYmUpLCBuLCBkLCB1LmN1cmwsIE9lKSwganQoCiAgICByLAogICAgdCh0aGlzLCBUZSksCiAgICAxIC8geCwKICAgIDEgLyBwLAogICAgdS5yZWZyYWN0aW9uLAogICAgdS5zcGVjdWxhckV4cCwKICAgIFdlKHUud2F0ZXJDb2xvciksCiAgICBXZSh1Lmdsb3dDb2xvciksCiAgICB1LnNoaW5lLAogICAgdS53YXJwU3RyZW5ndGggPz8gMC4wMTUsCiAgICBmdFt1LmFsZ29yaXRobV0gPz8gMCwKICAgIHQodGhpcywgU2UpCiAgKTsKICBjb25zdCBiID0gci5jcmVhdGVDb21tYW5kRW5jb2RlcigpLCB5ID0gKGcsIF8pID0+IHIuY3JlYXRlQmluZEdyb3VwKHsgbGF5b3V0OiBnLmdldEJpbmRHcm91cExheW91dCgwKSwgZW50cmllczogXyB9KSwgRCA9IHsgYmluZGluZzogMSwgcmVzb3VyY2U6IGEgfTsKICB7CiAgICBjb25zdCBnID0geShzLmFkdmVjdGlvbiwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBwZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDQsIHJlc291cmNlOiB2Lm9ic3RhY2xlVmlldyB9CiAgICBdKTsKICAgIFgoYiwgcy5hZHZlY3Rpb24sIGcsIG8sIHQodGhpcywgVCkud3JpdGUudmlldyk7CiAgfQogIHQodGhpcywgVCkuc3dhcCgpOwogIHsKICAgIGx0KHIsIHQodGhpcywgeGUpLCBuLCBkLCBPZSwgdS5kZW5zaXR5RGlzc2lwYXRpb24pOwogICAgY29uc3QgZyA9IHkocy5hZHZlY3Rpb24sIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgeGUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdCh0aGlzLCBWKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA0LCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuYWR2ZWN0aW9uLCBnLCBvLCB0KHRoaXMsIFYpLndyaXRlLnZpZXcpOwogIH0KICB0KHRoaXMsIFYpLnN3YXAoKTsKICB7CiAgICBjb25zdCBnID0geShzLmN1cmwsIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgZ2UpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuY3VybCwgZywgbywgdCh0aGlzLCBhZSkudmlldyk7CiAgfQogIHsKICAgIGNvbnN0IGcgPSB5KHMudm9ydGljaXR5LCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIGJlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVCkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHQodGhpcywgYWUpLnZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMudm9ydGljaXR5LCBnLCBvLCB0KHRoaXMsIFQpLndyaXRlLnZpZXcpOwogIH0KICBpZiAodCh0aGlzLCBUKS5zd2FwKCksIHQodGhpcywgaCkubW92ZWQpIHsKICAgIGNvbnN0IGcgPSB0KHRoaXMsIGgpLnggKiB0KHRoaXMsIEYpIC8geCwgXyA9IHQodGhpcywgaCkueSAqIHQodGhpcywgRikgLyBwOwogICAgJGUoCiAgICAgIHIsCiAgICAgIHQodGhpcywgSiksCiAgICAgIG4sCiAgICAgIGQsCiAgICAgIHggLyBwLAogICAgICB1LnNwbGF0UmFkaXVzLAogICAgICB0KHRoaXMsIGgpLmR4ICogdS5zcGxhdEZvcmNlLAogICAgICB0KHRoaXMsIGgpLmR5ICogdS5zcGxhdEZvcmNlLAogICAgICAwLAogICAgICBnLAogICAgICBfCiAgICApOwogICAgewogICAgICBjb25zdCBQID0geShzLnNwbGF0LCBbCiAgICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgSikgfSB9LAogICAgICAgIEQsCiAgICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfQogICAgICBdKTsKICAgICAgWChiLCBzLnNwbGF0LCBQLCBvLCB0KHRoaXMsIFQpLndyaXRlLnZpZXcpOwogICAgfQogICAgdCh0aGlzLCBUKS5zd2FwKCksICRlKAogICAgICByLAogICAgICB0KHRoaXMsIFopLAogICAgICBuLAogICAgICBkLAogICAgICB4IC8gcCwKICAgICAgdS5zcGxhdFJhZGl1cywKICAgICAgMSwKICAgICAgMSwKICAgICAgMSwKICAgICAgZywKICAgICAgXwogICAgKTsKICAgIHsKICAgICAgY29uc3QgUCA9IHkocy5zcGxhdCwgWwogICAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIFopIH0gfSwKICAgICAgICBELAogICAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVikucmVhZC52aWV3IH0KICAgICAgXSk7CiAgICAgIFgoYiwgcy5zcGxhdCwgUCwgbywgdCh0aGlzLCBWKS53cml0ZS52aWV3KTsKICAgIH0KICAgIHQodGhpcywgVikuc3dhcCgpLCB0KHRoaXMsIGgpLm1vdmVkID0gITE7CiAgfQogIHsKICAgIGNvbnN0IGcgPSB5KHMuZGl2ZXJnZW5jZSwgWwogICAgICB7IGJpbmRpbmc6IDAsIHJlc291cmNlOiB7IGJ1ZmZlcjogdCh0aGlzLCBtZSkgfSB9LAogICAgICBELAogICAgICB7IGJpbmRpbmc6IDIsIHJlc291cmNlOiB0KHRoaXMsIFQpLnJlYWQudmlldyB9LAogICAgICB7IGJpbmRpbmc6IDMsIHJlc291cmNlOiB2Lm9ic3RhY2xlVmlldyB9CiAgICBdKTsKICAgIFgoYiwgcy5kaXZlcmdlbmNlLCBnLCBvLCB0KHRoaXMsIG9lKS52aWV3KTsKICB9CiAgZm9yIChsZXQgZyA9IDA7IGcgPCB1LnByZXNzdXJlSXRlcmF0aW9uczsgZysrKSB7CiAgICBjb25zdCBfID0geShzLnByZXNzdXJlLCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIGRlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgUSkucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHQodGhpcywgb2UpLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA0LCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMucHJlc3N1cmUsIF8sIG8sIHQodGhpcywgUSkud3JpdGUudmlldyksIHQodGhpcywgUSkuc3dhcCgpOwogIH0KICB7CiAgICBjb25zdCBnID0geShzLmdyYWRpZW50U3VidHJhY3QsIFsKICAgICAgeyBiaW5kaW5nOiAwLCByZXNvdXJjZTogeyBidWZmZXI6IHQodGhpcywgaGUpIH0gfSwKICAgICAgRCwKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBRKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiAzLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA0LCByZXNvdXJjZTogdi5vYnN0YWNsZVZpZXcgfQogICAgXSk7CiAgICBYKGIsIHMuZ3JhZGllbnRTdWJ0cmFjdCwgZywgbywgdCh0aGlzLCBUKS53cml0ZS52aWV3KTsKICB9CiAgdCh0aGlzLCBUKS5zd2FwKCk7CiAgewogICAgY29uc3QgZyA9IGUuY29udGV4dC5nZXRDdXJyZW50VGV4dHVyZSgpLmNyZWF0ZVZpZXcoKSwgXyA9IHkocy5kaXNwbGF5LCBbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIFRlKSB9IH0sCiAgICAgIEQsCiAgICAgIHsgYmluZGluZzogMiwgcmVzb3VyY2U6IHQodGhpcywgVikucmVhZC52aWV3IH0sCiAgICAgIHsgYmluZGluZzogMywgcmVzb3VyY2U6IHYub2JzdGFjbGVWaWV3IH0sCiAgICAgIHsgYmluZGluZzogNCwgcmVzb3VyY2U6IHYuYmFja2dyb3VuZFZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA1LCByZXNvdXJjZTogdi5jb3ZlcmFnZVZpZXcgfSwKICAgICAgeyBiaW5kaW5nOiA2LCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfQogICAgXSk7CiAgICBLdChiLCBzLmRpc3BsYXksIF8sIG8sIGcpOwogIH0KICByLnF1ZXVlLnN1Ym1pdChbYi5maW5pc2goKV0pOwp9LCBLZSA9IG5ldyBXZWFrU2V0KCksIGR0ID0gZnVuY3Rpb24oZSwgciwgcywgbywgYSkgewogIGNvbnN0IHYgPSB0KHRoaXMsIE8pLmRldmljZSwgbSA9IHQodGhpcywgRGUpLnNwbGF0LCBjID0gdCh0aGlzLCB2ZSksIHggPSB0KHRoaXMsIF9lKSwgcCA9IHQodGhpcywgdGUpLCBuID0gdCh0aGlzLCBHKSwgZCA9IHQodGhpcywgSSksIGIgPSAxIC8gbiwgeSA9IDEgLyBkLCBEID0gdi5jcmVhdGVDb21tYW5kRW5jb2RlcigpLCBnID0geyBiaW5kaW5nOiAxLCByZXNvdXJjZTogeCB9LCBfID0gKFZlKSA9PiB2LmNyZWF0ZUJpbmRHcm91cCh7IGxheW91dDogbS5nZXRCaW5kR3JvdXBMYXlvdXQoMCksIGVudHJpZXM6IFZlIH0pLCBQID0gZSAqIHQodGhpcywgRikgLyB0KHRoaXMsIHcpLCBrID0gciAqIHQodGhpcywgRikgLyB0KHRoaXMsIFUpOwogICRlKAogICAgdiwKICAgIHQodGhpcywgSiksCiAgICBiLAogICAgeSwKICAgIHQodGhpcywgdykgLyB0KHRoaXMsIFUpLAogICAgcC5zcGxhdFJhZGl1cywKICAgIHMgKiBwLnNwbGF0Rm9yY2UgKiBhLAogICAgbyAqIHAuc3BsYXRGb3JjZSAqIGEsCiAgICAwLAogICAgUCwKICAgIGsKICApOwogIHsKICAgIGNvbnN0IFZlID0gXyhbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIEopIH0gfSwKICAgICAgZywKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBUKS5yZWFkLnZpZXcgfQogICAgXSk7CiAgICBYKEQsIG0sIFZlLCBjLCB0KHRoaXMsIFQpLndyaXRlLnZpZXcpOwogIH0KICB0KHRoaXMsIFQpLnN3YXAoKSwgJGUoCiAgICB2LAogICAgdCh0aGlzLCBaKSwKICAgIGIsCiAgICB5LAogICAgdCh0aGlzLCB3KSAvIHQodGhpcywgVSksCiAgICBwLnNwbGF0UmFkaXVzLAogICAgYSwKICAgIGEsCiAgICBhLAogICAgUCwKICAgIGsKICApOwogIHsKICAgIGNvbnN0IFZlID0gXyhbCiAgICAgIHsgYmluZGluZzogMCwgcmVzb3VyY2U6IHsgYnVmZmVyOiB0KHRoaXMsIFopIH0gfSwKICAgICAgZywKICAgICAgeyBiaW5kaW5nOiAyLCByZXNvdXJjZTogdCh0aGlzLCBWKS5yZWFkLnZpZXcgfQogICAgXSk7CiAgICBYKEQsIG0sIFZlLCBjLCB0KHRoaXMsIFYpLndyaXRlLnZpZXcpOwogIH0KICB0KHRoaXMsIFYpLnN3YXAoKSwgdi5xdWV1ZS5zdWJtaXQoW0QuZmluaXNoKCldKTsKfSwgSmUgPSBuZXcgV2Vha1NldCgpLCBodCA9IGZ1bmN0aW9uKGUsIHIsIHMsIG8sIGEpIHsKICBjb25zdCB1ID0gdCh0aGlzLCBNKSwgdiA9IHQodGhpcywgdGUpLCBtID0gdCh0aGlzLCBmZSkuc3BsYXQsIGMgPSB0KHRoaXMsIFVlKTsKICB1LnZpZXdwb3J0KDAsIDAsIHQodGhpcywgRyksIHQodGhpcywgSSkpLCBtLmJpbmQoKSwgdS51bmlmb3JtMWYobS51bmlmb3Jtcy5hc3BlY3RSYXRpbywgdCh0aGlzLCB3KSAvIHQodGhpcywgVSkpLCB1LnVuaWZvcm0yZihtLnVuaWZvcm1zLnBvaW50LCBlICogdCh0aGlzLCBGKSAvIHQodGhpcywgdyksIDEgLSByICogdCh0aGlzLCBGKSAvIHQodGhpcywgVSkpLCB1LnVuaWZvcm0xZihtLnVuaWZvcm1zLnJhZGl1cywgdi5zcGxhdFJhZGl1cyksIHUudW5pZm9ybTFpKG0udW5pZm9ybXMudVRhcmdldCwgMCksIHUuYWN0aXZlVGV4dHVyZSh1LlRFWFRVUkUwKSwgdS5iaW5kVGV4dHVyZSh1LlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCB1LnVuaWZvcm0zZihtLnVuaWZvcm1zLmNvbG9yLCBzICogdi5zcGxhdEZvcmNlICogYSwgLW8gKiB2LnNwbGF0Rm9yY2UgKiBhLCAwKSwgYyh0KHRoaXMsIFIpLndyaXRlLmZibyksIHQodGhpcywgUikuc3dhcCgpLCB1LmFjdGl2ZVRleHR1cmUodS5URVhUVVJFMCksIHUuYmluZFRleHR1cmUodS5URVhUVVJFXzJELCB0KHRoaXMsIEIpLnJlYWQudGV4KSwgdS51bmlmb3JtM2YobS51bmlmb3Jtcy5jb2xvciwgYSwgYSwgYSksIGModCh0aGlzLCBCKS53cml0ZS5mYm8pLCB0KHRoaXMsIEIpLnN3YXAoKTsKfSwgWmUgPSBuZXcgV2Vha1NldCgpLCBndCA9IGZ1bmN0aW9uKCkgewogIGlmICghdCh0aGlzLCBCKSB8fCAhdCh0aGlzLCBSKSkKICAgIHJldHVybjsKICBjb25zdCBlID0gdCh0aGlzLCBNKSwgciA9IHQodGhpcywgdGUpLCB7IGFkdmVjdGlvbjogcywgZGl2ZXJnZW5jZTogbywgcHJlc3N1cmU6IGEsIGdyYWRpZW50U3VidHJhY3Q6IHUsIHNwbGF0OiB2LCBjdXJsOiBtLCB2b3J0aWNpdHk6IGMsIGRpc3BsYXk6IHggfSA9IHQodGhpcywgZmUpOwogIHQodGhpcywgaCkueCArPSAodCh0aGlzLCBoKS50YXJnZXRYIC0gdCh0aGlzLCBoKS54KSAqIDAuMTUsIHQodGhpcywgaCkueSArPSAodCh0aGlzLCBoKS50YXJnZXRZIC0gdCh0aGlzLCBoKS55KSAqIDAuMTU7CiAgY29uc3QgcCA9IHQodGhpcywgRyksIG4gPSB0KHRoaXMsIEkpLCBkID0gdCh0aGlzLCBVZSk7CiAgZS52aWV3cG9ydCgwLCAwLCBwLCBuKSwgcy5iaW5kKCksIGUudW5pZm9ybTJmKHMudW5pZm9ybXMudGV4ZWxTaXplLCAxIC8gcCwgMSAvIG4pLCBlLnVuaWZvcm0xZihzLnVuaWZvcm1zLmR0LCBPZSksIGUudW5pZm9ybTFpKHMudW5pZm9ybXMudU9ic3RhY2xlLCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBMKSksIGUudW5pZm9ybTFmKHMudW5pZm9ybXMuZGlzc2lwYXRpb24sIHIudmVsb2NpdHlEaXNzaXBhdGlvbiksIGUudW5pZm9ybTFpKHMudW5pZm9ybXMudVZlbG9jaXR5LCAxKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGUudW5pZm9ybTFpKHMudW5pZm9ybXMudVNvdXJjZSwgMSksIGQodCh0aGlzLCBSKS53cml0ZS5mYm8pLCB0KHRoaXMsIFIpLnN3YXAoKSwgZS51bmlmb3JtMWYocy51bmlmb3Jtcy5kaXNzaXBhdGlvbiwgci5kZW5zaXR5RGlzc2lwYXRpb24pLCBlLnVuaWZvcm0xaShzLnVuaWZvcm1zLnVTb3VyY2UsIDIpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMiksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEIpLnJlYWQudGV4KSwgZCh0KHRoaXMsIEIpLndyaXRlLmZibyksIHQodGhpcywgQikuc3dhcCgpLCBtLmJpbmQoKSwgZS51bmlmb3JtMmYobS51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyBwLCAxIC8gbiksIGUudW5pZm9ybTFpKG0udW5pZm9ybXMudVZlbG9jaXR5LCAwKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBSKS5yZWFkLnRleCksIGQodCh0aGlzLCBIKS5mYm8pLCBjLmJpbmQoKSwgZS51bmlmb3JtMmYoYy51bmlmb3Jtcy50ZXhlbFNpemUsIDEgLyBwLCAxIC8gbiksIGUudW5pZm9ybTFmKGMudW5pZm9ybXMuY3VybCwgci5jdXJsKSwgZS51bmlmb3JtMWYoYy51bmlmb3Jtcy5kdCwgT2UpLCBlLnVuaWZvcm0xaShjLnVuaWZvcm1zLnVWZWxvY2l0eSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBlLnVuaWZvcm0xaShjLnVuaWZvcm1zLnVDdXJsLCAxKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTEpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBIKS50ZXgpLCBkKHQodGhpcywgUikud3JpdGUuZmJvKSwgdCh0aGlzLCBSKS5zd2FwKCksIHQodGhpcywgaCkubW92ZWQgJiYgKHYuYmluZCgpLCBlLnVuaWZvcm0xZih2LnVuaWZvcm1zLmFzcGVjdFJhdGlvLCB0KHRoaXMsIHcpIC8gdCh0aGlzLCBVKSksIGUudW5pZm9ybTJmKHYudW5pZm9ybXMucG9pbnQsIHQodGhpcywgaCkueCAqIHQodGhpcywgRikgLyB0KHRoaXMsIHcpLCAxIC0gdCh0aGlzLCBoKS55ICogdCh0aGlzLCBGKSAvIHQodGhpcywgVSkpLCBlLnVuaWZvcm0xZih2LnVuaWZvcm1zLnJhZGl1cywgci5zcGxhdFJhZGl1cyksIGUudW5pZm9ybTFpKHYudW5pZm9ybXMudVRhcmdldCwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBlLnVuaWZvcm0zZih2LnVuaWZvcm1zLmNvbG9yLCB0KHRoaXMsIGgpLmR4ICogci5zcGxhdEZvcmNlLCAtdCh0aGlzLCBoKS5keSAqIHIuc3BsYXRGb3JjZSwgMCksIGQodCh0aGlzLCBSKS53cml0ZS5mYm8pLCB0KHRoaXMsIFIpLnN3YXAoKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTApLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBCKS5yZWFkLnRleCksIGUudW5pZm9ybTNmKHYudW5pZm9ybXMuY29sb3IsIDEsIDEsIDEpLCBkKHQodGhpcywgQikud3JpdGUuZmJvKSwgdCh0aGlzLCBCKS5zd2FwKCksIHQodGhpcywgaCkubW92ZWQgPSAhMSksIG8uYmluZCgpLCBlLnVuaWZvcm0yZihvLnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHAsIDEgLyBuKSwgZS51bmlmb3JtMWkoby51bmlmb3Jtcy51VmVsb2NpdHksIDApLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkoby51bmlmb3Jtcy51T2JzdGFjbGUsIDEpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEwpKSwgZCh0KHRoaXMsICQpLmZibyksIGEuYmluZCgpLCBlLnVuaWZvcm0yZihhLnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHAsIDEgLyBuKSwgZS51bmlmb3JtMWkoYS51bmlmb3Jtcy51RGl2ZXJnZW5jZSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgJCkudGV4KSwgZS51bmlmb3JtMWkoYS51bmlmb3Jtcy51T2JzdGFjbGUsIDEpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEwpKTsKICBmb3IgKGxldCBiID0gMDsgYiA8IHIucHJlc3N1cmVJdGVyYXRpb25zOyBiKyspCiAgICBlLnVuaWZvcm0xaShhLnVuaWZvcm1zLnVQcmVzc3VyZSwgMiksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUyKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgcSkucmVhZC50ZXgpLCBkKHQodGhpcywgcSkud3JpdGUuZmJvKSwgdCh0aGlzLCBxKS5zd2FwKCk7CiAgdS5iaW5kKCksIGUudW5pZm9ybTJmKHUudW5pZm9ybXMudGV4ZWxTaXplLCAxIC8gcCwgMSAvIG4pLCBlLnVuaWZvcm0xaSh1LnVuaWZvcm1zLnVQcmVzc3VyZSwgMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgcSkucmVhZC50ZXgpLCBlLnVuaWZvcm0xaSh1LnVuaWZvcm1zLnVWZWxvY2l0eSwgMSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUxKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgUikucmVhZC50ZXgpLCBlLnVuaWZvcm0xaSh1LnVuaWZvcm1zLnVPYnN0YWNsZSwgMiksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUyKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgTCkpLCBkKHQodGhpcywgUikud3JpdGUuZmJvKSwgdCh0aGlzLCBSKS5zd2FwKCksIGUudmlld3BvcnQoMCwgMCwgdCh0aGlzLCB3KSwgdCh0aGlzLCBVKSksIGUuYmluZEZyYW1lYnVmZmVyKGUuRlJBTUVCVUZGRVIsIG51bGwpLCBlLmNsZWFyKGUuQ09MT1JfQlVGRkVSX0JJVCksIHguYmluZCgpLCBlLnVuaWZvcm0yZih4LnVuaWZvcm1zLnRleGVsU2l6ZSwgMSAvIHQodGhpcywgdyksIDEgLyB0KHRoaXMsIFUpKSwgZS51bmlmb3JtM2Z2KHgudW5pZm9ybXMudVdhdGVyQ29sb3IsIFdlKHIud2F0ZXJDb2xvcikpLCBlLnVuaWZvcm0zZnYoeC51bmlmb3Jtcy51R2xvd0NvbG9yLCBXZShyLmdsb3dDb2xvcikpLCBlLnVuaWZvcm0xZih4LnVuaWZvcm1zLnVSZWZyYWN0aW9uLCByLnJlZnJhY3Rpb24pLCBlLnVuaWZvcm0xZih4LnVuaWZvcm1zLnVTcGVjdWxhckV4cCwgci5zcGVjdWxhckV4cCksIGUudW5pZm9ybTFmKHgudW5pZm9ybXMudVNoaW5lLCByLnNoaW5lKSwgZS51bmlmb3JtMWYoeC51bmlmb3Jtcy51V2FycFN0cmVuZ3RoLCByLndhcnBTdHJlbmd0aCA/PyAwLjAxNSksIGUudW5pZm9ybTFpKHgudW5pZm9ybXMudUFsZ29yaXRobSwgZnRbci5hbGdvcml0aG1dID8/IDApLCBlLnVuaWZvcm0xaSh4LnVuaWZvcm1zLnVFbmFibGVBbHBoYSwgdCh0aGlzLCBTZSkgPyAxIDogMCksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUwKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgQikucmVhZC50ZXgpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFMSksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIEwpKSwgZS5hY3RpdmVUZXh0dXJlKGUuVEVYVFVSRTIpLCBlLmJpbmRUZXh0dXJlKGUuVEVYVFVSRV8yRCwgdCh0aGlzLCBLKSksIGUuYWN0aXZlVGV4dHVyZShlLlRFWFRVUkUzKSwgZS5iaW5kVGV4dHVyZShlLlRFWFRVUkVfMkQsIHQodGhpcywgWSkpLCBlLmFjdGl2ZVRleHR1cmUoZS5URVhUVVJFNCksIGUuYmluZFRleHR1cmUoZS5URVhUVVJFXzJELCB0KHRoaXMsIFIpLnJlYWQudGV4KSwgZS51bmlmb3JtMWkoeC51bmlmb3Jtcy51VGV4dHVyZSwgMCksIGUudW5pZm9ybTFpKHgudW5pZm9ybXMudU9ic3RhY2xlLCAxKSwgZS51bmlmb3JtMWkoeC51bmlmb3Jtcy51QmFja2dyb3VuZCwgMiksIGUudW5pZm9ybTFpKHgudW5pZm9ybXMudUNvdmVyYWdlLCAzKSwgZS51bmlmb3JtMWkoeC51bmlmb3Jtcy51VmVsb2NpdHksIDQpLCBkKG51bGwpOwp9OwpsZXQgaXQgPSB1dCwgRSA9IG51bGwsIGJ0Owpjb25zdCBOID0gbmV3IFByb21pc2UoKGkpID0+IHsKICBidCA9IGk7Cn0pOwpzZWxmLm9ubWVzc2FnZSA9IGFzeW5jIChpKSA9PiB7CiAgY29uc3QgeyB0eXBlOiBlLCAuLi5yIH0gPSBpLmRhdGE7CiAgdHJ5IHsKICAgIHN3aXRjaCAoZSkgewogICAgICBjYXNlICJpbml0IjogewogICAgICAgIGNvbnN0IHsgY2FudmFzOiBzLCB3aWR0aDogbywgaGVpZ2h0OiBhLCBjb25maWc6IHUsIGRwcjogdiwgcXVhbGl0eTogbSwgdXNlV2ViR1BVOiBjLCBlbmFibGVBbHBoYTogeCB9ID0gcjsKICAgICAgICBzLndpZHRoID0gbywgcy5oZWlnaHQgPSBhLCBFID0gYXdhaXQgaXQuY3JlYXRlKHMsIHUsIG0gPz8ge30sIGMgPz8gITAsIHggPz8gITApLCBFLnJlc2l6ZShvLCBhLCB2IHx8IDEpLCBidCgpLCBzZWxmLnBvc3RNZXNzYWdlKHsgdHlwZTogInJlYWR5IiB9KTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzZXRUZXh0U291cmNlIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnNldFRleHRTb3VyY2Uoci5vcHRzKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJzZXRJbWFnZVNvdXJjZSI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgYXdhaXQgRS5zZXRJbWFnZVNvdXJjZSgKICAgICAgICAgIHIuc3JjLAogICAgICAgICAgci5lZmZlY3QsCiAgICAgICAgICByLnNpemUKICAgICAgICApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInNldEltYWdlQml0bWFwIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnNldEltYWdlQml0bWFwKAogICAgICAgICAgci5iaXRtYXAsCiAgICAgICAgICByLmVmZmVjdCwKICAgICAgICAgIHIuc2l6ZQogICAgICAgICk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAic2V0QmFja2dyb3VuZCI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS5zZXRCYWNrZ3JvdW5kKHIuYml0bWFwLCByLnNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgInNwbGF0IjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnNwbGF0KAogICAgICAgICAgci54LAogICAgICAgICAgci55LAogICAgICAgICAgci52eCwKICAgICAgICAgIHIudnksCiAgICAgICAgICByLnN0cmVuZ3RoID8/IDEKICAgICAgICApOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgIm1vdmUiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUuaGFuZGxlTW92ZShyLngsIHIueSwgci5zdHJlbmd0aCA/PyAxKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlICJyZXNpemUiOiB7CiAgICAgICAgaWYgKGF3YWl0IE4sICFFKQogICAgICAgICAgcmV0dXJuOwogICAgICAgIEUucmVzaXplKHIud2lkdGgsIHIuaGVpZ2h0LCByLmRwcik7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAidXBkYXRlUXVhbGl0eSI6IHsKICAgICAgICBpZiAoYXdhaXQgTiwgIUUpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgRS51cGRhdGVRdWFsaXR5KHIucXVhbGl0eSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAidXBkYXRlQ29uZmlnIjogewogICAgICAgIGlmIChhd2FpdCBOLCAhRSkKICAgICAgICAgIHJldHVybjsKICAgICAgICBFLnVwZGF0ZUNvbmZpZyhyLmNvbmZpZyk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAiZGVzdHJveSI6IHsKICAgICAgICBhd2FpdCBOLCBFID09IG51bGwgfHwgRS5kZXN0cm95KCksIEUgPSBudWxsOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgY29uc29sZS53YXJuKCJbZmx1aWRpdHktanMgd29ya2VyXSBVbmtub3duIG1lc3NhZ2UgdHlwZToiLCBlKTsKICAgIH0KICB9IGNhdGNoIChzKSB7CiAgICBzZWxmLnBvc3RNZXNzYWdlKHsgdHlwZTogImVycm9yIiwgbWVzc2FnZTogKHMgPT0gbnVsbCA/IHZvaWQgMCA6IHMubWVzc2FnZSkgPz8gU3RyaW5nKHMpIH0pOwogIH0KfTsK", fI = typeof window < "u" && window.Blob && new Blob([atob(jI)], { type: "text/javascript;charset=utf-8" });
1566
- function YC() {
1605
+ let yI = NI;
1606
+ 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" });
1607
+ function PC() {
1567
1608
  let e;
1568
1609
  try {
1569
- if (e = fI && (window.URL || window.webkitURL).createObjectURL(fI), !e)
1610
+ if (e = qI && (window.URL || window.webkitURL).createObjectURL(qI), !e)
1570
1611
  throw "";
1571
1612
  return new Worker(e);
1572
1613
  } catch {
1573
- return new Worker("data:application/javascript;base64," + jI, { type: "module" });
1614
+ return new Worker("data:application/javascript;base64," + cC, { type: "module" });
1574
1615
  } finally {
1575
1616
  e && (window.URL || window.webkitURL).revokeObjectURL(e);
1576
1617
  }
1577
1618
  }
1578
- const kC = typeof Worker < "u" && typeof OffscreenCanvas < "u";
1579
- var R, x, Og, Eg, Fg, P, dg, wg, Lg, tI, HI, rI, PI;
1580
- class MC {
1619
+ const _C = typeof Worker < "u" && typeof OffscreenCanvas < "u";
1620
+ var v, f, qg, $g, Jg, q, ag, Lg, hg, GI, TI, YI, dC;
1621
+ class qC {
1581
1622
  constructor(g, {
1582
- isWorkerEnabled: C = !0,
1583
- useWebGPU: i = !0,
1584
- enableAlpha: s = !0,
1623
+ workerEnabled: C = !0,
1624
+ webGPUEnabled: i = !0,
1625
+ alphaEnabled: s = !0,
1585
1626
  quality: l = {},
1586
1627
  config: t = {}
1587
1628
  } = {}) {
@@ -1598,40 +1639,40 @@ class MC {
1598
1639
  * this is the common path in jsdom/test environments and keeps the
1599
1640
  * constructor behaviour synchronous where possible.
1600
1641
  */
1601
- d(this, tI);
1602
- d(this, rI);
1603
- d(this, R, null);
1604
- d(this, x, null);
1605
- d(this, Og, void 0);
1606
- d(this, Eg, void 0);
1607
- d(this, Fg, void 0);
1608
- d(this, P, void 0);
1609
- d(this, dg, void 0);
1642
+ d(this, GI);
1643
+ d(this, YI);
1644
+ d(this, v, null);
1645
+ d(this, f, null);
1646
+ d(this, qg, void 0);
1647
+ d(this, $g, void 0);
1648
+ d(this, Jg, void 0);
1649
+ d(this, q, void 0);
1650
+ d(this, ag, void 0);
1610
1651
  // Pending source calls queued while WebGPU async init is in progress (main-thread only)
1611
- d(this, wg, null);
1612
1652
  d(this, Lg, null);
1613
- o(this, P, Math.max(0.1, Math.min(1, l.dpr ?? 1))), o(this, dg, Math.max(0.1, Math.min(1, l.sim ?? 0.5))), o(this, Eg, i), o(this, Fg, s), o(this, Og, C && kC), I(this, Og) ? h(this, rI, PI).call(this, g, t) : h(this, tI, HI).call(this, g, t);
1653
+ 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, GI, TI).call(this, g, t);
1614
1655
  }
1615
1656
  // ---------------------------------------------------------------------------
1616
1657
  // Source setters
1617
1658
  // ---------------------------------------------------------------------------
1618
1659
  setTextSource(g) {
1619
- I(this, R) ? I(this, R).postMessage({ type: "setTextSource", opts: g }) : I(this, x) ? I(this, x).setTextSource(g) : (o(this, wg, g), o(this, Lg, null));
1660
+ I(this, v) ? I(this, v).postMessage({ type: "setTextSource", opts: g }) : I(this, f) ? I(this, f).setTextSource(g) : (o(this, Lg, g), o(this, hg, null));
1620
1661
  }
1621
- setImageSource(g, C = ng.effect, i = ng.imageSize) {
1622
- if (I(this, R)) {
1662
+ setImageSource(g, C = Gg.effect, i = Gg.imageSize) {
1663
+ if (I(this, v)) {
1623
1664
  const s = new URL(g, location.href).href;
1624
- I(this, R).postMessage({ type: "setImageSource", src: s, effect: C, size: i });
1665
+ I(this, v).postMessage({ type: "setImageSource", src: s, effect: C, size: i });
1625
1666
  } else
1626
- I(this, x) ? I(this, x).setImageSource(g, C, i) : (o(this, Lg, { src: g, effect: C, size: i }), o(this, wg, null));
1667
+ I(this, f) ? I(this, f).setImageSource(g, C, i) : (o(this, hg, { src: g, effect: C, size: i }), o(this, Lg, null));
1627
1668
  }
1628
1669
  setBackground(g, C = "cover") {
1629
1670
  var i;
1630
- if (I(this, R)) {
1671
+ if (I(this, v)) {
1631
1672
  const s = g ? [g] : [];
1632
- I(this, R).postMessage({ type: "setBackground", bitmap: g ?? null, size: C }, s);
1673
+ I(this, v).postMessage({ type: "setBackground", bitmap: g ?? null, size: C }, s);
1633
1674
  } else
1634
- (i = I(this, x)) == null || i.setBackground(g ?? null, C);
1675
+ (i = I(this, f)) == null || i.setBackground(g ?? null, C);
1635
1676
  }
1636
1677
  // ---------------------------------------------------------------------------
1637
1678
  // Interaction
@@ -1641,47 +1682,47 @@ class MC {
1641
1682
  * Safe to call multiple times per frame. See FluidSimulation.splat for details.
1642
1683
  */
1643
1684
  splat(g, C, i, s, l = 1) {
1644
- I(this, R) ? I(this, R).postMessage({ type: "splat", x: g, y: C, vx: i, vy: s, strength: l }) : I(this, x).splat(g, C, i, s, l);
1685
+ I(this, v) ? I(this, v).postMessage({ type: "splat", x: g, y: C, vx: i, vy: s, strength: l }) : I(this, f).splat(g, C, i, s, l);
1645
1686
  }
1646
1687
  handleMove(g, C, i = 1) {
1647
- I(this, R) ? I(this, R).postMessage({ type: "move", x: g, y: C, strength: i }) : I(this, x).handleMove(g, C, i);
1688
+ I(this, v) ? I(this, v).postMessage({ type: "move", x: g, y: C, strength: i }) : I(this, f).handleMove(g, C, i);
1648
1689
  }
1649
1690
  // ---------------------------------------------------------------------------
1650
1691
  // Config + control
1651
1692
  // ---------------------------------------------------------------------------
1652
1693
  updateQuality(g) {
1653
- o(this, P, Math.max(0.1, Math.min(1, g.dpr ?? I(this, P)))), o(this, dg, Math.max(0.1, Math.min(1, g.sim ?? I(this, dg)))), I(this, R) ? I(this, R).postMessage({ type: "updateQuality", quality: { dpr: I(this, P), sim: I(this, dg) } }) : I(this, x).updateQuality(g);
1694
+ o(this, q, Math.max(0.1, Math.min(1, g.dpr ?? I(this, q)))), o(this, ag, Math.max(0.1, Math.min(1, g.sim ?? I(this, ag)))), I(this, v) ? I(this, v).postMessage({ type: "updateQuality", quality: { dpr: I(this, q), sim: I(this, ag) } }) : I(this, f).updateQuality(g);
1654
1695
  }
1655
1696
  updateConfig(g) {
1656
- I(this, R) ? I(this, R).postMessage({ type: "updateConfig", config: g }) : I(this, x).updateConfig(g);
1697
+ I(this, v) ? I(this, v).postMessage({ type: "updateConfig", config: g }) : I(this, f).updateConfig(g);
1657
1698
  }
1658
1699
  resize(g, C) {
1659
- const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, P);
1660
- I(this, R) ? I(this, R).postMessage({ type: "resize", width: g, height: C, dpr: i }) : I(this, x).resize(g, C, i);
1700
+ const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, q);
1701
+ I(this, v) ? I(this, v).postMessage({ type: "resize", width: g, height: C, dpr: i }) : I(this, f).resize(g, C, i);
1661
1702
  }
1662
1703
  destroy() {
1663
1704
  var g;
1664
- if (I(this, R)) {
1665
- const C = I(this, R);
1666
- o(this, R, null), C.postMessage({ type: "destroy" }), setTimeout(() => C.terminate(), 50);
1705
+ if (I(this, v)) {
1706
+ const C = I(this, v);
1707
+ o(this, v, null), C.postMessage({ type: "destroy" }), setTimeout(() => C.terminate(), 50);
1667
1708
  } else
1668
- (g = I(this, x)) == null || g.destroy(), o(this, x, null);
1709
+ (g = I(this, f)) == null || g.destroy(), o(this, f, null);
1669
1710
  }
1670
1711
  }
1671
- R = new WeakMap(), x = new WeakMap(), Og = new WeakMap(), Eg = new WeakMap(), Fg = new WeakMap(), P = new WeakMap(), dg = new WeakMap(), wg = new WeakMap(), Lg = new WeakMap(), tI = new WeakSet(), HI = function(g, C) {
1672
- const i = { dpr: I(this, P), sim: I(this, dg) };
1673
- I(this, Eg) && typeof navigator < "u" && !!navigator.gpu ? ZI.create(g, C, i, !0, I(this, Fg)).then((l) => {
1674
- if (o(this, x, l), I(this, wg))
1675
- l.setTextSource(I(this, wg)), o(this, wg, null);
1676
- else if (I(this, Lg)) {
1677
- const { src: t, effect: a, size: u } = I(this, Lg);
1678
- l.setImageSource(t, a, u), o(this, Lg, null);
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(), GI = new WeakSet(), TI = function(g, C) {
1713
+ const i = { dpr: I(this, q), sim: I(this, ag) };
1714
+ I(this, $g) && typeof navigator < "u" && !!navigator.gpu ? yI.create(g, C, i, !0, I(this, Jg)).then((l) => {
1715
+ if (o(this, f, l), I(this, Lg))
1716
+ l.setTextSource(I(this, Lg)), o(this, Lg, null);
1717
+ else if (I(this, hg)) {
1718
+ const { src: t, effect: S, size: u } = I(this, hg);
1719
+ l.setImageSource(t, S, u), o(this, hg, null);
1679
1720
  }
1680
1721
  }).catch((l) => {
1681
1722
  console.error("[fluidity-js] Renderer init failed:", l);
1682
- }) : o(this, x, new ZI(g, C, i, void 0, I(this, Fg)));
1683
- }, rI = new WeakSet(), PI = function(g, C) {
1684
- const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, P), s = Math.round(g.clientWidth * i), l = Math.round(g.clientHeight * i);
1723
+ }) : o(this, f, new yI(g, C, i, void 0, I(this, Jg)));
1724
+ }, YI = new WeakSet(), dC = function(g, C) {
1725
+ const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, q), s = Math.round(g.clientWidth * i), l = Math.round(g.clientHeight * i);
1685
1726
  g.width = s, g.height = l;
1686
1727
  let t;
1687
1728
  try {
@@ -1689,299 +1730,334 @@ R = new WeakMap(), x = new WeakMap(), Og = new WeakMap(), Eg = new WeakMap(), Fg
1689
1730
  } catch {
1690
1731
  console.warn(
1691
1732
  "[fluidity-js] OffscreenCanvas transfer failed — falling back to main-thread mode. This is expected in React StrictMode development."
1692
- ), o(this, Og, !1), h(this, tI, HI).call(this, g, C);
1733
+ ), o(this, qg, !1), L(this, GI, TI).call(this, g, C);
1693
1734
  return;
1694
1735
  }
1695
- const a = o(this, R, new YC());
1696
- a.onerror = (u) => {
1736
+ const S = o(this, v, new PC());
1737
+ S.onerror = (u) => {
1697
1738
  console.error("[fluidity-js] Worker error:", u.message);
1698
- }, a.onmessage = (u) => {
1739
+ }, S.onmessage = (u) => {
1699
1740
  u.data.type === "error" && console.error("[fluidity-js] Simulation error:", u.data.message);
1700
- }, a.postMessage(
1701
- { type: "init", canvas: t, width: s, height: l, config: C, dpr: i, quality: { dpr: I(this, P), sim: I(this, dg) }, useWebGPU: I(this, Eg), enableAlpha: I(this, Fg) },
1741
+ }, S.postMessage(
1742
+ { type: "init", canvas: t, width: s, height: l, config: C, dpr: i, quality: { dpr: I(this, q), sim: I(this, ag) }, useWebGPU: I(this, $g), enableAlpha: I(this, Jg) },
1702
1743
  [t]
1703
1744
  );
1704
1745
  };
1705
- function _I(e, {
1706
- isWorkerEnabled: g = !0,
1707
- useWebGPU: C = !0,
1708
- enableAlpha: i = !0,
1709
- quality: s = {},
1710
- config: l = {}
1746
+ function SC(e, {
1747
+ workerEnabled: g = !0,
1748
+ webGPUEnabled: C = !0,
1749
+ alphaEnabled: i = !0,
1750
+ pixelRatio: s,
1751
+ simResolution: l,
1752
+ config: t = {}
1711
1753
  } = {}) {
1712
- const t = Tg(null), a = Tg({ isWorkerEnabled: g, quality: s, config: l }), u = Tg(Math.max(0.1, Math.min(1, s.dpr ?? 1))), c = Tg({
1713
- dpr: s.dpr,
1714
- sim: s.sim
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({
1755
+ pixelRatio: s,
1756
+ simResolution: l
1715
1757
  });
1716
- return sg(() => {
1717
- const Z = e.current;
1718
- if (!Z)
1758
+ return tg(() => {
1759
+ const A = e.current;
1760
+ if (!A)
1719
1761
  return;
1720
- const S = document.createElement("canvas");
1721
- S.id = `fluid_canvas_${Date.now()}`, S.style.cssText = "position:absolute;inset:0;width:100%;height:100%;display:block;", Z.appendChild(S);
1722
- const { isWorkerEnabled: A, quality: B, config: m } = a.current, r = (window.devicePixelRatio || 1) * u.current, L = Z.getBoundingClientRect(), G = Math.round((L.width || Z.clientWidth) * r) || 0, K = Math.round((L.height || Z.clientHeight) * r) || 0;
1723
- G > 0 && (S.width = G, S.height = K), K === 0 && console.warn(
1762
+ const m = document.createElement("canvas");
1763
+ m.id = `fluid_canvas_${Date.now()}`, m.style.cssText = "position:absolute;inset:0;width:100%;height:100%;display:block;", A.appendChild(m);
1764
+ const { workerEnabled: Z, quality: r, config: b } = c.current, B = (window.devicePixelRatio || 1) * p.current, K = A.getBoundingClientRect(), W = Math.round((K.width || A.clientWidth) * B) || 0, x = Math.round((K.height || A.clientHeight) * B) || 0;
1765
+ W > 0 && (m.width = W, m.height = x), x === 0 && console.warn(
1724
1766
  "[fluidity-js] Container has zero height — simulation will not render. Avoid height:auto or percentage heights without a sized ancestor. Use explicit pixel values instead."
1725
1767
  );
1726
- const b = new MC(S, {
1727
- isWorkerEnabled: A,
1728
- useWebGPU: C,
1729
- enableAlpha: i,
1730
- quality: B,
1731
- config: m
1768
+ const Q = new qC(m, {
1769
+ workerEnabled: Z,
1770
+ webGPUEnabled: C,
1771
+ alphaEnabled: i,
1772
+ quality: r,
1773
+ config: b
1732
1774
  });
1733
- t.current = b;
1734
- const Y = new ResizeObserver((n) => {
1735
- for (const F of n) {
1736
- const p = (window.devicePixelRatio || 1) * u.current, { inlineSize: V, blockSize: W } = F.contentBoxSize[0];
1737
- b.resize(Math.round(V * p), Math.round(W * p));
1775
+ u.current = Q;
1776
+ const Tg = new ResizeObserver((II) => {
1777
+ for (const CI of II) {
1778
+ const zg = (window.devicePixelRatio || 1) * p.current, { inlineSize: iI, blockSize: eI } = CI.contentBoxSize[0];
1779
+ Q.resize(Math.round(iI * zg), Math.round(eI * zg));
1738
1780
  }
1739
1781
  });
1740
- return Y.observe(Z), () => {
1741
- Y.disconnect(), b.destroy(), S.remove(), t.current = null;
1782
+ return Tg.observe(A), () => {
1783
+ Tg.disconnect(), Q.destroy(), m.remove(), u.current = null;
1742
1784
  };
1743
- }, [C, i]), sg(() => {
1744
- u.current = Math.max(0.1, Math.min(1, s.dpr ?? 1));
1745
- const Z = c.current;
1746
- c.current = { dpr: s.dpr, sim: s.sim };
1747
- const S = t.current, A = e.current;
1748
- if (!S || !A || Z.dpr === s.dpr && Z.sim === s.sim)
1785
+ }, [C, i]), tg(() => {
1786
+ p.current = Math.max(0.1, Math.min(1, s ?? 1));
1787
+ const A = a.current;
1788
+ a.current = { pixelRatio: s, simResolution: l };
1789
+ const m = u.current, Z = e.current;
1790
+ if (!m || !Z || A.pixelRatio === s && A.simResolution === l)
1749
1791
  return;
1750
- S.updateQuality(s);
1751
- const B = (window.devicePixelRatio || 1) * u.current, m = A.clientWidth, r = A.clientHeight;
1752
- m > 0 && r > 0 && S.resize(Math.round(m * B), Math.round(r * B));
1753
- }, [s.dpr, s.sim, C, i]), t;
1792
+ m.updateQuality({ dpr: s, sim: l });
1793
+ const r = (window.devicePixelRatio || 1) * p.current, b = Z.clientWidth, B = Z.clientHeight;
1794
+ b > 0 && B > 0 && m.resize(Math.round(b * r), Math.round(B * r));
1795
+ }, [s, l, C, i]), u;
1754
1796
  }
1755
- const DC = FI(function({
1797
+ const Ci = gC(function({
1756
1798
  text: g,
1757
- fontSize: C = ag.fontSize,
1758
- color: i = ag.color,
1759
- fontFamily: s = ag.fontFamily,
1760
- fontWeight: l = ag.fontWeight,
1799
+ fontSize: C = mg.fontSize,
1800
+ color: i = mg.color,
1801
+ fontFamily: s = mg.fontFamily,
1802
+ fontWeight: l = mg.fontWeight,
1761
1803
  className: t,
1762
- style: a,
1763
- config: u,
1764
- preset: c,
1765
- algorithm: Z,
1766
- backgroundColor: S = ag.backgroundColor,
1767
- backgroundSrc: A,
1768
- backgroundSize: B = ag.backgroundSize,
1769
- isMouseEnabled: m = ag.isMouseEnabled,
1770
- isWorkerEnabled: r = ag.isWorkerEnabled,
1771
- useWebGPU: L = !0,
1772
- enableAlpha: G = !0,
1773
- quality: K = wI.quality
1774
- }, b) {
1775
- const Y = Tg(null), n = _I(Y, {
1776
- isWorkerEnabled: r,
1777
- useWebGPU: L,
1778
- enableAlpha: G,
1779
- quality: K,
1780
- config: II({ ...u, ...Z ? { algorithm: Z } : {} }, c, UI)
1804
+ style: S,
1805
+ preset: u,
1806
+ algorithm: c,
1807
+ backgroundColor: p = mg.backgroundColor,
1808
+ backgroundSrc: a,
1809
+ backgroundSize: A = mg.backgroundSize,
1810
+ mouseEnabled: m = mg.mouseEnabled,
1811
+ workerEnabled: Z = mg.workerEnabled,
1812
+ webGPUEnabled: r = !0,
1813
+ alphaEnabled: b = !0,
1814
+ pixelRatio: B = LI.dpr,
1815
+ simResolution: K = LI.sim,
1816
+ // FluidConfig flat props
1817
+ densityDissipation: W,
1818
+ velocityDissipation: x,
1819
+ pressureIterations: Q,
1820
+ curl: Tg,
1821
+ splatRadius: II,
1822
+ splatForce: CI,
1823
+ refraction: zg,
1824
+ specularExp: iI,
1825
+ shine: eI,
1826
+ waterColor: UI,
1827
+ glowColor: xI,
1828
+ warpStrength: sI
1829
+ }, lI) {
1830
+ const J = Qg(null), tI = Object.fromEntries(
1831
+ Object.entries({ densityDissipation: W, velocityDissipation: x, pressureIterations: Q, curl: Tg, splatRadius: II, splatForce: CI, refraction: zg, specularExp: iI, shine: eI, waterColor: UI, glowColor: xI, algorithm: c, warpStrength: sI }).filter(([, G]) => G !== void 0)
1832
+ ), n = SC(J, {
1833
+ workerEnabled: Z,
1834
+ webGPUEnabled: r,
1835
+ alphaEnabled: b,
1836
+ pixelRatio: B,
1837
+ simResolution: K,
1838
+ config: Eg(aI(tI, u, EI))
1781
1839
  });
1782
- DI(
1783
- b,
1840
+ IC(
1841
+ lI,
1784
1842
  () => ({
1785
1843
  reset() {
1786
- var p;
1787
- (p = n.current) == null || p.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: l });
1844
+ var G;
1845
+ (G = n.current) == null || G.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: l });
1788
1846
  },
1789
- move(p, V, W = 1) {
1790
- var U;
1791
- (U = n.current) == null || U.handleMove(p, V, W);
1847
+ move(G, y, Y = 1) {
1848
+ var R;
1849
+ (R = n.current) == null || R.handleMove(G, y, Y);
1792
1850
  },
1793
- splat(p, V, W, U, _ = 1) {
1794
- var Sg;
1795
- (Sg = n.current) == null || Sg.splat(p, V, W, U, _);
1851
+ splat(G, y, Y, R, $ = 1) {
1852
+ var ug;
1853
+ (ug = n.current) == null || ug.splat(G, y, Y, R, $);
1796
1854
  },
1797
- updateConfig(p) {
1798
- var V;
1799
- (V = n.current) == null || V.updateConfig(p);
1855
+ updateConfig(G) {
1856
+ var y;
1857
+ (y = n.current) == null || y.updateConfig(Eg(G));
1800
1858
  }
1801
1859
  }),
1802
1860
  [g, C, i, s, l]
1803
- ), sg(() => {
1804
- var p;
1805
- (p = n.current) == null || p.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: l });
1806
- }, [g, C, i, s, l, L, G]);
1807
- const F = JSON.stringify(u);
1808
- return sg(() => {
1809
- var p;
1810
- (p = n.current) == null || p.updateConfig(
1811
- II({ ...u, ...Z !== void 0 ? { algorithm: Z } : {} }, c, UI)
1861
+ ), tg(() => {
1862
+ var G;
1863
+ (G = n.current) == null || G.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: l });
1864
+ }, [g, C, i, s, l, r, b]);
1865
+ const T = JSON.stringify(tI);
1866
+ return tg(() => {
1867
+ var G;
1868
+ (G = n.current) == null || G.updateConfig(
1869
+ Eg(aI(tI, u, EI))
1812
1870
  );
1813
- }, [c, Z, F, L, G]), sg(() => {
1814
- var V;
1815
- if (!A) {
1816
- (V = n.current) == null || V.setBackground(null);
1871
+ }, [u, T, r, b]), tg(() => {
1872
+ var y;
1873
+ if (!a) {
1874
+ (y = n.current) == null || y.setBackground(null);
1817
1875
  return;
1818
1876
  }
1819
- let p = !1;
1820
- return XI(A).then((W) => {
1821
- var U;
1822
- if (p) {
1823
- W.close();
1877
+ let G = !1;
1878
+ return zI(a).then((Y) => {
1879
+ var R;
1880
+ if (G) {
1881
+ Y.close();
1824
1882
  return;
1825
1883
  }
1826
- (U = n.current) == null || U.setBackground(W, B);
1827
- }).catch((W) => console.error("[fluidity-js] backgroundSrc load failed:", W)), () => {
1828
- p = !0;
1884
+ (R = n.current) == null || R.setBackground(Y, A);
1885
+ }).catch((Y) => console.error("[fluidity-js] backgroundSrc load failed:", Y)), () => {
1886
+ G = !0;
1829
1887
  };
1830
- }, [A, B, L, G]), sg(() => {
1888
+ }, [a, A, r, b]), tg(() => {
1831
1889
  if (!m)
1832
1890
  return;
1833
- const p = Y.current;
1834
- if (!p)
1891
+ const G = J.current;
1892
+ if (!G)
1835
1893
  return;
1836
- const V = (U) => {
1837
- var Sg;
1838
- const _ = p.getBoundingClientRect();
1839
- (Sg = n.current) == null || Sg.handleMove(U.clientX - _.left, U.clientY - _.top, 2);
1840
- }, W = (U) => {
1841
- var RI;
1842
- U.preventDefault();
1843
- const _ = p.getBoundingClientRect(), Sg = U.touches[0];
1844
- (RI = n.current) == null || RI.handleMove(Sg.clientX - _.left, Sg.clientY - _.top, 1);
1894
+ const y = (R) => {
1895
+ var ug;
1896
+ const $ = G.getBoundingClientRect();
1897
+ (ug = n.current) == null || ug.handleMove(R.clientX - $.left, R.clientY - $.top, 2);
1898
+ }, Y = (R) => {
1899
+ var QI;
1900
+ R.preventDefault();
1901
+ const $ = G.getBoundingClientRect(), ug = R.touches[0];
1902
+ (QI = n.current) == null || QI.handleMove(ug.clientX - $.left, ug.clientY - $.top, 1);
1845
1903
  };
1846
- return p.addEventListener("mousemove", V), p.addEventListener("touchmove", W, { passive: !1 }), () => {
1847
- p.removeEventListener("mousemove", V), p.removeEventListener("touchmove", W);
1904
+ return G.addEventListener("mousemove", y), G.addEventListener("touchmove", Y, { passive: !1 }), () => {
1905
+ G.removeEventListener("mousemove", y), G.removeEventListener("touchmove", Y);
1848
1906
  };
1849
- }, [m]), /* @__PURE__ */ xI(
1907
+ }, [m]), /* @__PURE__ */ $I(
1850
1908
  "div",
1851
1909
  {
1852
- ref: Y,
1910
+ ref: J,
1853
1911
  className: t,
1854
1912
  style: {
1855
1913
  position: "relative",
1856
1914
  display: "block",
1857
1915
  width: "100%",
1858
1916
  height: "100%",
1859
- background: S,
1860
- ...a
1917
+ background: p,
1918
+ ...S
1861
1919
  }
1862
1920
  }
1863
1921
  );
1864
- }), TC = FI(function({
1922
+ }), ii = gC(function({
1865
1923
  src: g,
1866
- effect: C = ng.effect,
1867
- imageSize: i = ng.imageSize,
1924
+ effect: C = Gg.effect,
1925
+ imageSize: i = Gg.imageSize,
1868
1926
  className: s,
1869
1927
  style: l,
1870
- config: t,
1871
- preset: a,
1872
- algorithm: u,
1873
- backgroundColor: c = ng.backgroundColor,
1874
- backgroundSrc: Z,
1875
- backgroundSize: S = ng.backgroundSize,
1876
- isMouseEnabled: A = ng.isMouseEnabled,
1877
- isWorkerEnabled: B = ng.isWorkerEnabled,
1878
- useWebGPU: m = !0,
1879
- enableAlpha: r = !0,
1880
- quality: L = wI.quality
1881
- }, G) {
1882
- const K = Tg(null), b = _I(K, {
1883
- isWorkerEnabled: B,
1884
- useWebGPU: m,
1885
- enableAlpha: r,
1886
- quality: L,
1887
- config: II({ ...t, ...u ? { algorithm: u } : {} }, a)
1928
+ preset: t,
1929
+ algorithm: S,
1930
+ backgroundColor: u = Gg.backgroundColor,
1931
+ backgroundSrc: c,
1932
+ backgroundSize: p = Gg.backgroundSize,
1933
+ mouseEnabled: a = Gg.mouseEnabled,
1934
+ workerEnabled: A = Gg.workerEnabled,
1935
+ webGPUEnabled: m = !0,
1936
+ alphaEnabled: Z = !0,
1937
+ pixelRatio: r = LI.dpr,
1938
+ simResolution: b = LI.sim,
1939
+ // FluidConfig flat props
1940
+ densityDissipation: B,
1941
+ velocityDissipation: K,
1942
+ pressureIterations: W,
1943
+ curl: x,
1944
+ splatRadius: Q,
1945
+ splatForce: Tg,
1946
+ refraction: II,
1947
+ specularExp: CI,
1948
+ shine: zg,
1949
+ waterColor: iI,
1950
+ glowColor: eI,
1951
+ warpStrength: UI
1952
+ }, xI) {
1953
+ const sI = Qg(null), lI = Object.fromEntries(
1954
+ Object.entries({ densityDissipation: B, velocityDissipation: K, pressureIterations: W, curl: x, splatRadius: Q, splatForce: Tg, refraction: II, specularExp: CI, shine: zg, waterColor: iI, glowColor: eI, algorithm: S, warpStrength: UI }).filter(([, n]) => n !== void 0)
1955
+ ), J = SC(sI, {
1956
+ workerEnabled: A,
1957
+ webGPUEnabled: m,
1958
+ alphaEnabled: Z,
1959
+ pixelRatio: r,
1960
+ simResolution: b,
1961
+ config: Eg(aI(lI, t))
1888
1962
  });
1889
- DI(
1890
- G,
1963
+ IC(
1964
+ xI,
1891
1965
  () => ({
1892
1966
  reset() {
1893
1967
  var n;
1894
- g && ((n = b.current) == null || n.setImageSource(g, C, i));
1968
+ g && ((n = J.current) == null || n.setImageSource(g, C, i));
1895
1969
  },
1896
- move(n, F, p = 1) {
1897
- var V;
1898
- (V = b.current) == null || V.handleMove(n, F, p);
1970
+ move(n, T, G = 1) {
1971
+ var y;
1972
+ (y = J.current) == null || y.handleMove(n, T, G);
1899
1973
  },
1900
- splat(n, F, p, V, W = 1) {
1901
- var U;
1902
- (U = b.current) == null || U.splat(n, F, p, V, W);
1974
+ splat(n, T, G, y, Y = 1) {
1975
+ var R;
1976
+ (R = J.current) == null || R.splat(n, T, G, y, Y);
1903
1977
  },
1904
1978
  updateConfig(n) {
1905
- var F;
1906
- (F = b.current) == null || F.updateConfig(n);
1979
+ var T;
1980
+ (T = J.current) == null || T.updateConfig(Eg(n));
1907
1981
  }
1908
1982
  }),
1909
1983
  [g, C, i]
1910
- ), sg(() => {
1984
+ ), tg(() => {
1911
1985
  var n;
1912
- g && ((n = b.current) == null || n.setImageSource(g, C, i));
1913
- }, [g, C, i, m, r]);
1914
- const Y = JSON.stringify(t);
1915
- return sg(() => {
1986
+ g && ((n = J.current) == null || n.setImageSource(g, C, i));
1987
+ }, [g, C, i, m, Z]);
1988
+ const tI = JSON.stringify(lI);
1989
+ return tg(() => {
1916
1990
  var n;
1917
- (n = b.current) == null || n.updateConfig(
1918
- II({ ...t, ...u !== void 0 ? { algorithm: u } : {} }, a)
1991
+ (n = J.current) == null || n.updateConfig(
1992
+ Eg(aI(lI, t))
1919
1993
  );
1920
- }, [a, u, Y, m, r]), sg(() => {
1921
- var F;
1922
- if (!Z) {
1923
- (F = b.current) == null || F.setBackground(null);
1994
+ }, [t, tI, m, Z]), tg(() => {
1995
+ var T;
1996
+ if (!c) {
1997
+ (T = J.current) == null || T.setBackground(null);
1924
1998
  return;
1925
1999
  }
1926
2000
  let n = !1;
1927
- return XI(Z).then((p) => {
1928
- var V;
2001
+ return zI(c).then((G) => {
2002
+ var y;
1929
2003
  if (n) {
1930
- p.close();
2004
+ G.close();
1931
2005
  return;
1932
2006
  }
1933
- (V = b.current) == null || V.setBackground(p, S);
1934
- }).catch((p) => console.error("[fluidity-js] backgroundSrc load failed:", p)), () => {
2007
+ (y = J.current) == null || y.setBackground(G, p);
2008
+ }).catch((G) => console.error("[fluidity-js] backgroundSrc load failed:", G)), () => {
1935
2009
  n = !0;
1936
2010
  };
1937
- }, [Z, S, m, r]), sg(() => {
1938
- if (!A)
2011
+ }, [c, p, m, Z]), tg(() => {
2012
+ if (!a)
1939
2013
  return;
1940
- const n = K.current;
2014
+ const n = sI.current;
1941
2015
  if (!n)
1942
2016
  return;
1943
- const F = (V) => {
1944
- var U;
1945
- const W = n.getBoundingClientRect();
1946
- (U = b.current) == null || U.handleMove(V.clientX - W.left, V.clientY - W.top, 2);
1947
- }, p = (V) => {
1948
- var _;
1949
- V.preventDefault();
1950
- const W = n.getBoundingClientRect(), U = V.touches[0];
1951
- (_ = b.current) == null || _.handleMove(U.clientX - W.left, U.clientY - W.top, 1);
2017
+ const T = (y) => {
2018
+ var R;
2019
+ const Y = n.getBoundingClientRect();
2020
+ (R = J.current) == null || R.handleMove(y.clientX - Y.left, y.clientY - Y.top, 2);
2021
+ }, G = (y) => {
2022
+ var $;
2023
+ y.preventDefault();
2024
+ const Y = n.getBoundingClientRect(), R = y.touches[0];
2025
+ ($ = J.current) == null || $.handleMove(R.clientX - Y.left, R.clientY - Y.top, 1);
1952
2026
  };
1953
- return n.addEventListener("mousemove", F), n.addEventListener("touchmove", p, { passive: !1 }), () => {
1954
- n.removeEventListener("mousemove", F), n.removeEventListener("touchmove", p);
2027
+ return n.addEventListener("mousemove", T), n.addEventListener("touchmove", G, { passive: !1 }), () => {
2028
+ n.removeEventListener("mousemove", T), n.removeEventListener("touchmove", G);
1955
2029
  };
1956
- }, [A]), /* @__PURE__ */ xI(
2030
+ }, [a]), /* @__PURE__ */ $I(
1957
2031
  "div",
1958
2032
  {
1959
- ref: K,
2033
+ ref: sI,
1960
2034
  className: s,
1961
2035
  style: {
1962
2036
  position: "relative",
1963
2037
  display: "block",
1964
2038
  width: "100%",
1965
2039
  height: "100%",
1966
- background: c,
2040
+ background: u,
1967
2041
  ...l
1968
2042
  }
1969
2043
  }
1970
2044
  );
1971
2045
  });
1972
2046
  export {
1973
- TI as DEFAULT_CONFIG,
1974
- UI as DEFAULT_CONFIG_TEXT,
1975
- ng as DEFAULT_PROPS_IMAGE,
1976
- wI as DEFAULT_PROPS_SHARED,
1977
- ag as DEFAULT_PROPS_TEXT,
1978
- MC as FluidController,
1979
- TC as FluidImage,
1980
- ZI as FluidSimulation,
1981
- DC as FluidText,
1982
- IC as PRESETS,
1983
- XI as loadImageBitmap,
1984
- II as mergeConfig,
1985
- AI as parseColor,
1986
- _I as useFluid
2047
+ CC as DEFAULT_CONFIG,
2048
+ EI as DEFAULT_CONFIG_TEXT,
2049
+ Gg as DEFAULT_PROPS_IMAGE,
2050
+ iC as DEFAULT_PROPS_SHARED,
2051
+ mg as DEFAULT_PROPS_TEXT,
2052
+ qC as FluidController,
2053
+ ii as FluidImage,
2054
+ yI as FluidSimulation,
2055
+ Ci as FluidText,
2056
+ pC as PRESETS,
2057
+ mC as PROP_RANGES,
2058
+ zI as loadImageBitmap,
2059
+ aI as mergeConfig,
2060
+ Eg as normalizeConfig,
2061
+ nI as parseColor,
2062
+ SC as useFluid
1987
2063
  };