@c4h/chuci 0.1.0 → 0.2.1

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.
@@ -1,2125 +0,0 @@
1
- class I {
2
- constructor(t = 0, F = 0, U = 0) {
3
- this.x = t, this.y = F, this.z = U;
4
- }
5
- equals(t) {
6
- return this.x === t.x && this.y === t.y && this.z === t.z;
7
- }
8
- add(t) {
9
- return typeof t == "number" ? new I(this.x + t, this.y + t, this.z + t) : new I(this.x + t.x, this.y + t.y, this.z + t.z);
10
- }
11
- subtract(t) {
12
- return typeof t == "number" ? new I(this.x - t, this.y - t, this.z - t) : new I(this.x - t.x, this.y - t.y, this.z - t.z);
13
- }
14
- multiply(t) {
15
- return typeof t == "number" ? new I(this.x * t, this.y * t, this.z * t) : t instanceof I ? new I(this.x * t.x, this.y * t.y, this.z * t.z) : new I(this.x * t.buffer[0] + this.y * t.buffer[4] + this.z * t.buffer[8] + t.buffer[12], this.x * t.buffer[1] + this.y * t.buffer[5] + this.z * t.buffer[9] + t.buffer[13], this.x * t.buffer[2] + this.y * t.buffer[6] + this.z * t.buffer[10] + t.buffer[14]);
16
- }
17
- divide(t) {
18
- return typeof t == "number" ? new I(this.x / t, this.y / t, this.z / t) : new I(this.x / t.x, this.y / t.y, this.z / t.z);
19
- }
20
- cross(t) {
21
- const F = this.y * t.z - this.z * t.y, U = this.z * t.x - this.x * t.z, l = this.x * t.y - this.y * t.x;
22
- return new I(F, U, l);
23
- }
24
- dot(t) {
25
- return this.x * t.x + this.y * t.y + this.z * t.z;
26
- }
27
- lerp(t, F) {
28
- return new I(this.x + (t.x - this.x) * F, this.y + (t.y - this.y) * F, this.z + (t.z - this.z) * F);
29
- }
30
- min(t) {
31
- return new I(Math.min(this.x, t.x), Math.min(this.y, t.y), Math.min(this.z, t.z));
32
- }
33
- max(t) {
34
- return new I(Math.max(this.x, t.x), Math.max(this.y, t.y), Math.max(this.z, t.z));
35
- }
36
- getComponent(t) {
37
- switch (t) {
38
- case 0:
39
- return this.x;
40
- case 1:
41
- return this.y;
42
- case 2:
43
- return this.z;
44
- default:
45
- throw new Error(`Invalid component index: ${t}`);
46
- }
47
- }
48
- minComponent() {
49
- return this.x < this.y && this.x < this.z ? 0 : this.y < this.z ? 1 : 2;
50
- }
51
- maxComponent() {
52
- return this.x > this.y && this.x > this.z ? 0 : this.y > this.z ? 1 : 2;
53
- }
54
- magnitude() {
55
- return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
56
- }
57
- distanceTo(t) {
58
- return Math.sqrt((this.x - t.x) ** 2 + (this.y - t.y) ** 2 + (this.z - t.z) ** 2);
59
- }
60
- normalize() {
61
- const t = this.magnitude();
62
- return new I(this.x / t, this.y / t, this.z / t);
63
- }
64
- flat() {
65
- return [this.x, this.y, this.z];
66
- }
67
- clone() {
68
- return new I(this.x, this.y, this.z);
69
- }
70
- toString() {
71
- return `[${this.flat().join(", ")}]`;
72
- }
73
- static One(t = 1) {
74
- return new I(t, t, t);
75
- }
76
- }
77
- class z {
78
- constructor(t = 0, F = 0, U = 0, l = 1) {
79
- this.x = t, this.y = F, this.z = U, this.w = l;
80
- }
81
- equals(t) {
82
- return this.x === t.x && this.y === t.y && this.z === t.z && this.w === t.w;
83
- }
84
- normalize() {
85
- const t = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
86
- return new z(this.x / t, this.y / t, this.z / t, this.w / t);
87
- }
88
- multiply(t) {
89
- const F = this.w, U = this.x, l = this.y, a = this.z, n = t.w, e = t.x, Q = t.y, d = t.z;
90
- return new z(F * e + U * n + l * d - a * Q, F * Q - U * d + l * n + a * e, F * d + U * Q - l * e + a * n, F * n - U * e - l * Q - a * d);
91
- }
92
- inverse() {
93
- const t = this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
94
- return new z(-this.x / t, -this.y / t, -this.z / t, this.w / t);
95
- }
96
- apply(t) {
97
- const F = new z(t.x, t.y, t.z, 0), U = new z(-this.x, -this.y, -this.z, this.w), l = this.multiply(F).multiply(U);
98
- return new I(l.x, l.y, l.z);
99
- }
100
- flat() {
101
- return [this.x, this.y, this.z, this.w];
102
- }
103
- clone() {
104
- return new z(this.x, this.y, this.z, this.w);
105
- }
106
- static FromEuler(t) {
107
- const F = t.x / 2, U = t.y / 2, l = t.z / 2, a = Math.cos(U), n = Math.sin(U), e = Math.cos(F), Q = Math.sin(F), d = Math.cos(l), A = Math.sin(l);
108
- return new z(a * Q * d + n * e * A, n * e * d - a * Q * A, a * e * A - n * Q * d, a * e * d + n * Q * A);
109
- }
110
- toEuler() {
111
- const t = 2 * (this.w * this.x + this.y * this.z), F = 1 - 2 * (this.x * this.x + this.y * this.y), U = Math.atan2(t, F);
112
- let l;
113
- const a = 2 * (this.w * this.y - this.z * this.x);
114
- l = Math.abs(a) >= 1 ? Math.sign(a) * Math.PI / 2 : Math.asin(a);
115
- const n = 2 * (this.w * this.z + this.x * this.y), e = 1 - 2 * (this.y * this.y + this.z * this.z), Q = Math.atan2(n, e);
116
- return new I(U, l, Q);
117
- }
118
- static FromMatrix3(t) {
119
- const F = t.buffer, U = F[0] + F[4] + F[8];
120
- let l, a, n, e;
121
- if (U > 0) {
122
- const Q = 0.5 / Math.sqrt(U + 1);
123
- e = 0.25 / Q, l = (F[7] - F[5]) * Q, a = (F[2] - F[6]) * Q, n = (F[3] - F[1]) * Q;
124
- } else if (F[0] > F[4] && F[0] > F[8]) {
125
- const Q = 2 * Math.sqrt(1 + F[0] - F[4] - F[8]);
126
- e = (F[7] - F[5]) / Q, l = 0.25 * Q, a = (F[1] + F[3]) / Q, n = (F[2] + F[6]) / Q;
127
- } else if (F[4] > F[8]) {
128
- const Q = 2 * Math.sqrt(1 + F[4] - F[0] - F[8]);
129
- e = (F[2] - F[6]) / Q, l = (F[1] + F[3]) / Q, a = 0.25 * Q, n = (F[5] + F[7]) / Q;
130
- } else {
131
- const Q = 2 * Math.sqrt(1 + F[8] - F[0] - F[4]);
132
- e = (F[3] - F[1]) / Q, l = (F[2] + F[6]) / Q, a = (F[5] + F[7]) / Q, n = 0.25 * Q;
133
- }
134
- return new z(l, a, n, e);
135
- }
136
- static FromAxisAngle(t, F) {
137
- const U = F / 2, l = Math.sin(U), a = Math.cos(U);
138
- return new z(t.x * l, t.y * l, t.z * l, a);
139
- }
140
- static LookRotation(t) {
141
- const F = new I(0, 0, 1), U = F.dot(t);
142
- if (Math.abs(U - -1) < 1e-6) return new z(0, 1, 0, Math.PI);
143
- if (Math.abs(U - 1) < 1e-6) return new z();
144
- const l = Math.acos(U), a = F.cross(t).normalize();
145
- return z.FromAxisAngle(a, l);
146
- }
147
- toString() {
148
- return `[${this.flat().join(", ")}]`;
149
- }
150
- }
151
- class Et {
152
- constructor() {
153
- const t = /* @__PURE__ */ new Map();
154
- this.addEventListener = (F, U) => {
155
- t.has(F) || t.set(F, /* @__PURE__ */ new Set()), t.get(F).add(U);
156
- }, this.removeEventListener = (F, U) => {
157
- t.has(F) && t.get(F).delete(U);
158
- }, this.hasEventListener = (F, U) => !!t.has(F) && t.get(F).has(U), this.dispatchEvent = (F) => {
159
- if (t.has(F.type)) for (const U of t.get(F.type)) U(F);
160
- };
161
- }
162
- }
163
- class Ut {
164
- constructor(t = 1, F = 0, U = 0, l = 0, a = 0, n = 1, e = 0, Q = 0, d = 0, A = 0, i = 1, r = 0, c = 0, B = 0, W = 0, J = 1) {
165
- this.buffer = [t, F, U, l, a, n, e, Q, d, A, i, r, c, B, W, J];
166
- }
167
- equals(t) {
168
- if (this.buffer.length !== t.buffer.length) return !1;
169
- if (this.buffer === t.buffer) return !0;
170
- for (let F = 0; F < this.buffer.length; F++) if (this.buffer[F] !== t.buffer[F]) return !1;
171
- return !0;
172
- }
173
- multiply(t) {
174
- const F = this.buffer, U = t.buffer;
175
- return new Ut(U[0] * F[0] + U[1] * F[4] + U[2] * F[8] + U[3] * F[12], U[0] * F[1] + U[1] * F[5] + U[2] * F[9] + U[3] * F[13], U[0] * F[2] + U[1] * F[6] + U[2] * F[10] + U[3] * F[14], U[0] * F[3] + U[1] * F[7] + U[2] * F[11] + U[3] * F[15], U[4] * F[0] + U[5] * F[4] + U[6] * F[8] + U[7] * F[12], U[4] * F[1] + U[5] * F[5] + U[6] * F[9] + U[7] * F[13], U[4] * F[2] + U[5] * F[6] + U[6] * F[10] + U[7] * F[14], U[4] * F[3] + U[5] * F[7] + U[6] * F[11] + U[7] * F[15], U[8] * F[0] + U[9] * F[4] + U[10] * F[8] + U[11] * F[12], U[8] * F[1] + U[9] * F[5] + U[10] * F[9] + U[11] * F[13], U[8] * F[2] + U[9] * F[6] + U[10] * F[10] + U[11] * F[14], U[8] * F[3] + U[9] * F[7] + U[10] * F[11] + U[11] * F[15], U[12] * F[0] + U[13] * F[4] + U[14] * F[8] + U[15] * F[12], U[12] * F[1] + U[13] * F[5] + U[14] * F[9] + U[15] * F[13], U[12] * F[2] + U[13] * F[6] + U[14] * F[10] + U[15] * F[14], U[12] * F[3] + U[13] * F[7] + U[14] * F[11] + U[15] * F[15]);
176
- }
177
- clone() {
178
- const t = this.buffer;
179
- return new Ut(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10], t[11], t[12], t[13], t[14], t[15]);
180
- }
181
- determinant() {
182
- const t = this.buffer;
183
- return t[12] * t[9] * t[6] * t[3] - t[8] * t[13] * t[6] * t[3] - t[12] * t[5] * t[10] * t[3] + t[4] * t[13] * t[10] * t[3] + t[8] * t[5] * t[14] * t[3] - t[4] * t[9] * t[14] * t[3] - t[12] * t[9] * t[2] * t[7] + t[8] * t[13] * t[2] * t[7] + t[12] * t[1] * t[10] * t[7] - t[0] * t[13] * t[10] * t[7] - t[8] * t[1] * t[14] * t[7] + t[0] * t[9] * t[14] * t[7] + t[12] * t[5] * t[2] * t[11] - t[4] * t[13] * t[2] * t[11] - t[12] * t[1] * t[6] * t[11] + t[0] * t[13] * t[6] * t[11] + t[4] * t[1] * t[14] * t[11] - t[0] * t[5] * t[14] * t[11] - t[8] * t[5] * t[2] * t[15] + t[4] * t[9] * t[2] * t[15] + t[8] * t[1] * t[6] * t[15] - t[0] * t[9] * t[6] * t[15] - t[4] * t[1] * t[10] * t[15] + t[0] * t[5] * t[10] * t[15];
184
- }
185
- invert() {
186
- const t = this.buffer, F = this.determinant();
187
- if (F === 0) throw new Error("Matrix is not invertible.");
188
- const U = 1 / F;
189
- return new Ut(U * (t[5] * t[10] * t[15] - t[5] * t[11] * t[14] - t[9] * t[6] * t[15] + t[9] * t[7] * t[14] + t[13] * t[6] * t[11] - t[13] * t[7] * t[10]), U * (-t[1] * t[10] * t[15] + t[1] * t[11] * t[14] + t[9] * t[2] * t[15] - t[9] * t[3] * t[14] - t[13] * t[2] * t[11] + t[13] * t[3] * t[10]), U * (t[1] * t[6] * t[15] - t[1] * t[7] * t[14] - t[5] * t[2] * t[15] + t[5] * t[3] * t[14] + t[13] * t[2] * t[7] - t[13] * t[3] * t[6]), U * (-t[1] * t[6] * t[11] + t[1] * t[7] * t[10] + t[5] * t[2] * t[11] - t[5] * t[3] * t[10] - t[9] * t[2] * t[7] + t[9] * t[3] * t[6]), U * (-t[4] * t[10] * t[15] + t[4] * t[11] * t[14] + t[8] * t[6] * t[15] - t[8] * t[7] * t[14] - t[12] * t[6] * t[11] + t[12] * t[7] * t[10]), U * (t[0] * t[10] * t[15] - t[0] * t[11] * t[14] - t[8] * t[2] * t[15] + t[8] * t[3] * t[14] + t[12] * t[2] * t[11] - t[12] * t[3] * t[10]), U * (-t[0] * t[6] * t[15] + t[0] * t[7] * t[14] + t[4] * t[2] * t[15] - t[4] * t[3] * t[14] - t[12] * t[2] * t[7] + t[12] * t[3] * t[6]), U * (t[0] * t[6] * t[11] - t[0] * t[7] * t[10] - t[4] * t[2] * t[11] + t[4] * t[3] * t[10] + t[8] * t[2] * t[7] - t[8] * t[3] * t[6]), U * (t[4] * t[9] * t[15] - t[4] * t[11] * t[13] - t[8] * t[5] * t[15] + t[8] * t[7] * t[13] + t[12] * t[5] * t[11] - t[12] * t[7] * t[9]), U * (-t[0] * t[9] * t[15] + t[0] * t[11] * t[13] + t[8] * t[1] * t[15] - t[8] * t[3] * t[13] - t[12] * t[1] * t[11] + t[12] * t[3] * t[9]), U * (t[0] * t[5] * t[15] - t[0] * t[7] * t[13] - t[4] * t[1] * t[15] + t[4] * t[3] * t[13] + t[12] * t[1] * t[7] - t[12] * t[3] * t[5]), U * (-t[0] * t[5] * t[11] + t[0] * t[7] * t[9] + t[4] * t[1] * t[11] - t[4] * t[3] * t[9] - t[8] * t[1] * t[7] + t[8] * t[3] * t[5]), U * (-t[4] * t[9] * t[14] + t[4] * t[10] * t[13] + t[8] * t[5] * t[14] - t[8] * t[6] * t[13] - t[12] * t[5] * t[10] + t[12] * t[6] * t[9]), U * (t[0] * t[9] * t[14] - t[0] * t[10] * t[13] - t[8] * t[1] * t[14] + t[8] * t[2] * t[13] + t[12] * t[1] * t[10] - t[12] * t[2] * t[9]), U * (-t[0] * t[5] * t[14] + t[0] * t[6] * t[13] + t[4] * t[1] * t[14] - t[4] * t[2] * t[13] - t[12] * t[1] * t[6] + t[12] * t[2] * t[5]), U * (t[0] * t[5] * t[10] - t[0] * t[6] * t[9] - t[4] * t[1] * t[10] + t[4] * t[2] * t[9] + t[8] * t[1] * t[6] - t[8] * t[2] * t[5]));
190
- }
191
- static Compose(t, F, U) {
192
- const l = F.x, a = F.y, n = F.z, e = F.w, Q = l + l, d = a + a, A = n + n, i = l * Q, r = l * d, c = l * A, B = a * d, W = a * A, J = n * A, h = e * Q, C = e * d, k = e * A, p = U.x, X = U.y, D = U.z;
193
- return new Ut((1 - (B + J)) * p, (r + k) * p, (c - C) * p, 0, (r - k) * X, (1 - (i + J)) * X, (W + h) * X, 0, (c + C) * D, (W - h) * D, (1 - (i + B)) * D, 0, t.x, t.y, t.z, 1);
194
- }
195
- toString() {
196
- return `[${this.buffer.join(", ")}]`;
197
- }
198
- }
199
- class Lt extends Event {
200
- constructor(t) {
201
- super("objectAdded"), this.object = t;
202
- }
203
- }
204
- class Pt extends Event {
205
- constructor(t) {
206
- super("objectRemoved"), this.object = t;
207
- }
208
- }
209
- class _t extends Event {
210
- constructor(t) {
211
- super("objectChanged"), this.object = t;
212
- }
213
- }
214
- class bt extends Et {
215
- constructor() {
216
- super(), this.positionChanged = !1, this.rotationChanged = !1, this.scaleChanged = !1, this._position = new I(), this._rotation = new z(), this._scale = new I(1, 1, 1), this._transform = new Ut(), this._changeEvent = new _t(this), this.update = () => {
217
- }, this.applyPosition = () => {
218
- this.position = new I();
219
- }, this.applyRotation = () => {
220
- this.rotation = new z();
221
- }, this.applyScale = () => {
222
- this.scale = new I(1, 1, 1);
223
- }, this.raiseChangeEvent = () => {
224
- this.dispatchEvent(this._changeEvent);
225
- };
226
- }
227
- _updateMatrix() {
228
- this._transform = Ut.Compose(this._position, this._rotation, this._scale);
229
- }
230
- get position() {
231
- return this._position;
232
- }
233
- set position(t) {
234
- this._position.equals(t) || (this._position = t, this.positionChanged = !0, this._updateMatrix(), this.dispatchEvent(this._changeEvent));
235
- }
236
- get rotation() {
237
- return this._rotation;
238
- }
239
- set rotation(t) {
240
- this._rotation.equals(t) || (this._rotation = t, this.rotationChanged = !0, this._updateMatrix(), this.dispatchEvent(this._changeEvent));
241
- }
242
- get scale() {
243
- return this._scale;
244
- }
245
- set scale(t) {
246
- this._scale.equals(t) || (this._scale = t, this.scaleChanged = !0, this._updateMatrix(), this.dispatchEvent(this._changeEvent));
247
- }
248
- get forward() {
249
- let t = new I(0, 0, 1);
250
- return t = this.rotation.apply(t), t;
251
- }
252
- get transform() {
253
- return this._transform;
254
- }
255
- }
256
- class tt {
257
- constructor(t = 1, F = 0, U = 0, l = 0, a = 1, n = 0, e = 0, Q = 0, d = 1) {
258
- this.buffer = [t, F, U, l, a, n, e, Q, d];
259
- }
260
- equals(t) {
261
- if (this.buffer.length !== t.buffer.length) return !1;
262
- if (this.buffer === t.buffer) return !0;
263
- for (let F = 0; F < this.buffer.length; F++) if (this.buffer[F] !== t.buffer[F]) return !1;
264
- return !0;
265
- }
266
- multiply(t) {
267
- const F = this.buffer, U = t.buffer;
268
- return new tt(U[0] * F[0] + U[3] * F[1] + U[6] * F[2], U[1] * F[0] + U[4] * F[1] + U[7] * F[2], U[2] * F[0] + U[5] * F[1] + U[8] * F[2], U[0] * F[3] + U[3] * F[4] + U[6] * F[5], U[1] * F[3] + U[4] * F[4] + U[7] * F[5], U[2] * F[3] + U[5] * F[4] + U[8] * F[5], U[0] * F[6] + U[3] * F[7] + U[6] * F[8], U[1] * F[6] + U[4] * F[7] + U[7] * F[8], U[2] * F[6] + U[5] * F[7] + U[8] * F[8]);
269
- }
270
- clone() {
271
- const t = this.buffer;
272
- return new tt(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8]);
273
- }
274
- static Eye(t = 1) {
275
- return new tt(t, 0, 0, 0, t, 0, 0, 0, t);
276
- }
277
- static Diagonal(t) {
278
- return new tt(t.x, 0, 0, 0, t.y, 0, 0, 0, t.z);
279
- }
280
- static RotationFromQuaternion(t) {
281
- return new tt(1 - 2 * t.y * t.y - 2 * t.z * t.z, 2 * t.x * t.y - 2 * t.z * t.w, 2 * t.x * t.z + 2 * t.y * t.w, 2 * t.x * t.y + 2 * t.z * t.w, 1 - 2 * t.x * t.x - 2 * t.z * t.z, 2 * t.y * t.z - 2 * t.x * t.w, 2 * t.x * t.z - 2 * t.y * t.w, 2 * t.y * t.z + 2 * t.x * t.w, 1 - 2 * t.x * t.x - 2 * t.y * t.y);
282
- }
283
- static RotationFromEuler(t) {
284
- const F = Math.cos(t.x), U = Math.sin(t.x), l = Math.cos(t.y), a = Math.sin(t.y), n = Math.cos(t.z), e = Math.sin(t.z);
285
- return new tt(l * n + a * U * e, -l * e + a * U * n, a * F, F * e, F * n, -U, -a * n + l * U * e, a * e + l * U * n, l * F);
286
- }
287
- toString() {
288
- return `[${this.buffer.join(", ")}]`;
289
- }
290
- }
291
- class lt {
292
- constructor(t = 0, F = null, U = null, l = null, a = null) {
293
- this.changed = !1, this.detached = !1, this._vertexCount = t, this._positions = F || new Float32Array(0), this._rotations = U || new Float32Array(0), this._scales = l || new Float32Array(0), this._colors = a || new Uint8Array(0), this._selection = new Uint8Array(this.vertexCount), this.translate = (n) => {
294
- for (let e = 0; e < this.vertexCount; e++) this.positions[3 * e + 0] += n.x, this.positions[3 * e + 1] += n.y, this.positions[3 * e + 2] += n.z;
295
- this.changed = !0;
296
- }, this.rotate = (n) => {
297
- const e = tt.RotationFromQuaternion(n).buffer;
298
- for (let Q = 0; Q < this.vertexCount; Q++) {
299
- const d = this.positions[3 * Q + 0], A = this.positions[3 * Q + 1], i = this.positions[3 * Q + 2];
300
- this.positions[3 * Q + 0] = e[0] * d + e[1] * A + e[2] * i, this.positions[3 * Q + 1] = e[3] * d + e[4] * A + e[5] * i, this.positions[3 * Q + 2] = e[6] * d + e[7] * A + e[8] * i;
301
- const r = new z(this.rotations[4 * Q + 1], this.rotations[4 * Q + 2], this.rotations[4 * Q + 3], this.rotations[4 * Q + 0]), c = n.multiply(r);
302
- this.rotations[4 * Q + 1] = c.x, this.rotations[4 * Q + 2] = c.y, this.rotations[4 * Q + 3] = c.z, this.rotations[4 * Q + 0] = c.w;
303
- }
304
- this.changed = !0;
305
- }, this.scale = (n) => {
306
- for (let e = 0; e < this.vertexCount; e++) this.positions[3 * e + 0] *= n.x, this.positions[3 * e + 1] *= n.y, this.positions[3 * e + 2] *= n.z, this.scales[3 * e + 0] *= n.x, this.scales[3 * e + 1] *= n.y, this.scales[3 * e + 2] *= n.z;
307
- this.changed = !0;
308
- }, this.serialize = () => {
309
- const n = new Uint8Array(this.vertexCount * lt.RowLength), e = new Float32Array(n.buffer), Q = new Uint8Array(n.buffer);
310
- for (let d = 0; d < this.vertexCount; d++) e[8 * d + 0] = this.positions[3 * d + 0], e[8 * d + 1] = this.positions[3 * d + 1], e[8 * d + 2] = this.positions[3 * d + 2], Q[32 * d + 24 + 0] = this.colors[4 * d + 0], Q[32 * d + 24 + 1] = this.colors[4 * d + 1], Q[32 * d + 24 + 2] = this.colors[4 * d + 2], Q[32 * d + 24 + 3] = this.colors[4 * d + 3], e[8 * d + 3 + 0] = this.scales[3 * d + 0], e[8 * d + 3 + 1] = this.scales[3 * d + 1], e[8 * d + 3 + 2] = this.scales[3 * d + 2], Q[32 * d + 28 + 0] = 128 * this.rotations[4 * d + 0] + 128 & 255, Q[32 * d + 28 + 1] = 128 * this.rotations[4 * d + 1] + 128 & 255, Q[32 * d + 28 + 2] = 128 * this.rotations[4 * d + 2] + 128 & 255, Q[32 * d + 28 + 3] = 128 * this.rotations[4 * d + 3] + 128 & 255;
311
- return n;
312
- }, this.reattach = (n, e, Q, d, A) => {
313
- console.assert(n.byteLength === 3 * this.vertexCount * 4, `Expected ${3 * this.vertexCount * 4} bytes, got ${n.byteLength} bytes`), this._positions = new Float32Array(n), this._rotations = new Float32Array(e), this._scales = new Float32Array(Q), this._colors = new Uint8Array(d), this._selection = new Uint8Array(A), this.detached = !1;
314
- };
315
- }
316
- static Deserialize(t) {
317
- const F = t.length / lt.RowLength, U = new Float32Array(3 * F), l = new Float32Array(4 * F), a = new Float32Array(3 * F), n = new Uint8Array(4 * F), e = new Float32Array(t.buffer), Q = new Uint8Array(t.buffer);
318
- for (let d = 0; d < F; d++) U[3 * d + 0] = e[8 * d + 0], U[3 * d + 1] = e[8 * d + 1], U[3 * d + 2] = e[8 * d + 2], l[4 * d + 0] = (Q[32 * d + 28 + 0] - 128) / 128, l[4 * d + 1] = (Q[32 * d + 28 + 1] - 128) / 128, l[4 * d + 2] = (Q[32 * d + 28 + 2] - 128) / 128, l[4 * d + 3] = (Q[32 * d + 28 + 3] - 128) / 128, a[3 * d + 0] = e[8 * d + 3 + 0], a[3 * d + 1] = e[8 * d + 3 + 1], a[3 * d + 2] = e[8 * d + 3 + 2], n[4 * d + 0] = Q[32 * d + 24 + 0], n[4 * d + 1] = Q[32 * d + 24 + 1], n[4 * d + 2] = Q[32 * d + 24 + 2], n[4 * d + 3] = Q[32 * d + 24 + 3];
319
- return new lt(F, U, l, a, n);
320
- }
321
- get vertexCount() {
322
- return this._vertexCount;
323
- }
324
- get positions() {
325
- return this._positions;
326
- }
327
- get rotations() {
328
- return this._rotations;
329
- }
330
- get scales() {
331
- return this._scales;
332
- }
333
- get colors() {
334
- return this._colors;
335
- }
336
- get selection() {
337
- return this._selection;
338
- }
339
- }
340
- lt.RowLength = 32;
341
- class mt {
342
- constructor(t, F, U, l, a) {
343
- this._vertexCount = t, this._positions = F, this._data = U, this._width = l, this._height = a, this.serialize = () => new Uint8Array(this._data.buffer);
344
- }
345
- static Deserialize(t, F, U) {
346
- const l = new Uint32Array(t.buffer), a = new Float32Array(t.buffer), n = Math.floor(a.byteLength / this.RowLength), e = new Float32Array(3 * n);
347
- for (let Q = 0; Q < n; Q++) e[3 * Q + 0] = a[16 * Q + 0], e[3 * Q + 1] = a[16 * Q + 1], e[3 * Q + 2] = a[16 * Q + 2], e[3 * Q + 0] = a[16 * Q + 3];
348
- return new mt(n, e, l, F, U);
349
- }
350
- get vertexCount() {
351
- return this._vertexCount;
352
- }
353
- get positions() {
354
- return this._positions;
355
- }
356
- get data() {
357
- return this._data;
358
- }
359
- get width() {
360
- return this._width;
361
- }
362
- get height() {
363
- return this._height;
364
- }
365
- }
366
- mt.RowLength = 64;
367
- class Zt {
368
- static SplatToPLY(t, F) {
369
- let U = `ply
370
- format binary_little_endian 1.0
371
- `;
372
- U += `element vertex ${F}
373
- `;
374
- const l = ["x", "y", "z", "nx", "ny", "nz", "f_dc_0", "f_dc_1", "f_dc_2"];
375
- for (let B = 0; B < 45; B++) l.push(`f_rest_${B}`);
376
- l.push("opacity"), l.push("scale_0"), l.push("scale_1"), l.push("scale_2"), l.push("rot_0"), l.push("rot_1"), l.push("rot_2"), l.push("rot_3");
377
- for (const B of l) U += `property float ${B}
378
- `;
379
- U += `end_header
380
- `;
381
- const a = new TextEncoder().encode(U), n = 248, e = F * n, Q = new DataView(new ArrayBuffer(a.length + e));
382
- new Uint8Array(Q.buffer).set(a, 0);
383
- const d = new Float32Array(t), A = new Uint8Array(t), i = a.length, r = 220, c = 232;
384
- for (let B = 0; B < F; B++) {
385
- const W = d[8 * B + 0], J = d[8 * B + 1], h = d[8 * B + 2], C = (A[32 * B + 24 + 0] / 255 - 0.5) / this.SH_C0, k = (A[32 * B + 24 + 1] / 255 - 0.5) / this.SH_C0, p = (A[32 * B + 24 + 2] / 255 - 0.5) / this.SH_C0, X = A[32 * B + 24 + 3] / 255, D = Math.log(X / (1 - X)), u = Math.log(d[8 * B + 3 + 0]), M = Math.log(d[8 * B + 3 + 1]), E = Math.log(d[8 * B + 3 + 2]);
386
- let w = new z((A[32 * B + 28 + 1] - 128) / 128, (A[32 * B + 28 + 2] - 128) / 128, (A[32 * B + 28 + 3] - 128) / 128, (A[32 * B + 28 + 0] - 128) / 128);
387
- w = w.normalize();
388
- const Ft = w.w, Y = w.x, H = w.y, at = w.z;
389
- Q.setFloat32(i + n * B + 0, W, !0), Q.setFloat32(i + n * B + 4, J, !0), Q.setFloat32(i + n * B + 8, h, !0), Q.setFloat32(i + n * B + 24 + 0, C, !0), Q.setFloat32(i + n * B + 24 + 4, k, !0), Q.setFloat32(i + n * B + 24 + 8, p, !0), Q.setFloat32(i + n * B + 216, D, !0), Q.setFloat32(i + n * B + r + 0, u, !0), Q.setFloat32(i + n * B + r + 4, M, !0), Q.setFloat32(i + n * B + r + 8, E, !0), Q.setFloat32(i + n * B + c + 0, Ft, !0), Q.setFloat32(i + n * B + c + 4, Y, !0), Q.setFloat32(i + n * B + c + 8, H, !0), Q.setFloat32(i + n * B + c + 12, at, !0);
390
- }
391
- return Q.buffer;
392
- }
393
- }
394
- Zt.SH_C0 = 0.28209479177387814;
395
- class ot {
396
- constructor(t, F) {
397
- this.min = t, this.max = F;
398
- }
399
- contains(t) {
400
- return t.x >= this.min.x && t.x <= this.max.x && t.y >= this.min.y && t.y <= this.max.y && t.z >= this.min.z && t.z <= this.max.z;
401
- }
402
- intersects(t) {
403
- return this.max.x >= t.min.x && this.min.x <= t.max.x && this.max.y >= t.min.y && this.min.y <= t.max.y && this.max.z >= t.min.z && this.min.z <= t.max.z;
404
- }
405
- size() {
406
- return this.max.subtract(this.min);
407
- }
408
- center() {
409
- return this.min.add(this.max).divide(2);
410
- }
411
- expand(t) {
412
- this.min = this.min.min(t), this.max = this.max.max(t);
413
- }
414
- permute() {
415
- const t = this.min, F = this.max;
416
- this.min = new I(Math.min(t.x, F.x), Math.min(t.y, F.y), Math.min(t.z, F.z)), this.max = new I(Math.max(t.x, F.x), Math.max(t.y, F.y), Math.max(t.z, F.z));
417
- }
418
- }
419
- class dt extends bt {
420
- constructor(t = void 0) {
421
- super(), this.selectedChanged = !1, this.colorTransformChanged = !1, this._selected = !1, this._colorTransforms = [], this._colorTransformsMap = /* @__PURE__ */ new Map(), this._data = t || new lt(), this._bounds = new ot(new I(1 / 0, 1 / 0, 1 / 0), new I(-1 / 0, -1 / 0, -1 / 0)), this.recalculateBounds = () => {
422
- this._bounds = new ot(new I(1 / 0, 1 / 0, 1 / 0), new I(-1 / 0, -1 / 0, -1 / 0));
423
- for (let F = 0; F < this._data.vertexCount; F++) this._bounds.expand(new I(this._data.positions[3 * F], this._data.positions[3 * F + 1], this._data.positions[3 * F + 2]));
424
- }, this.applyPosition = () => {
425
- this.data.translate(this.position), this.position = new I();
426
- }, this.applyRotation = () => {
427
- this.data.rotate(this.rotation), this.rotation = new z();
428
- }, this.applyScale = () => {
429
- this.data.scale(this.scale), this.scale = new I(1, 1, 1);
430
- }, this.recalculateBounds();
431
- }
432
- saveToFile(t = null, F = null) {
433
- if (!document) return;
434
- if (F) {
435
- if (F !== "splat" && F !== "ply") throw new Error("Invalid format. Must be 'splat' or 'ply'");
436
- } else F = "splat";
437
- if (!t) {
438
- const n = /* @__PURE__ */ new Date();
439
- t = `splat-${n.getFullYear()}-${n.getMonth() + 1}-${n.getDate()}.${F}`;
440
- }
441
- this.applyRotation(), this.applyScale(), this.applyPosition();
442
- const U = this.data.serialize();
443
- let l;
444
- if (F === "ply") {
445
- const n = Zt.SplatToPLY(U.buffer, this.data.vertexCount);
446
- l = new Blob([n], { type: "application/octet-stream" });
447
- } else l = new Blob([U.buffer], { type: "application/octet-stream" });
448
- const a = document.createElement("a");
449
- a.download = t, a.href = URL.createObjectURL(l), a.click();
450
- }
451
- get data() {
452
- return this._data;
453
- }
454
- get selected() {
455
- return this._selected;
456
- }
457
- set selected(t) {
458
- this._selected !== t && (this._selected = t, this.selectedChanged = !0, this.dispatchEvent(this._changeEvent));
459
- }
460
- get colorTransforms() {
461
- return this._colorTransforms;
462
- }
463
- get colorTransformsMap() {
464
- return this._colorTransformsMap;
465
- }
466
- get bounds() {
467
- let t = this._bounds.center();
468
- t = t.add(this.position);
469
- let F = this._bounds.size();
470
- return F = F.multiply(this.scale), new ot(t.subtract(F.divide(2)), t.add(F.divide(2)));
471
- }
472
- }
473
- class ct extends bt {
474
- constructor(t) {
475
- super(), this._data = t;
476
- }
477
- get data() {
478
- return this._data;
479
- }
480
- }
481
- class qt {
482
- constructor() {
483
- this._fx = 1132, this._fy = 1132, this._near = 0.1, this._far = 100, this._width = 512, this._height = 512, this._projectionMatrix = new Ut(), this._viewMatrix = new Ut(), this._viewProj = new Ut(), this._updateProjectionMatrix = () => {
484
- this._projectionMatrix = new Ut(2 * this.fx / this.width, 0, 0, 0, 0, -2 * this.fy / this.height, 0, 0, 0, 0, this.far / (this.far - this.near), 1, 0, 0, -this.far * this.near / (this.far - this.near), 0), this._viewProj = this.projectionMatrix.multiply(this.viewMatrix);
485
- }, this.update = (t, F) => {
486
- const U = tt.RotationFromQuaternion(F).buffer, l = t.flat();
487
- this._viewMatrix = new Ut(U[0], U[1], U[2], 0, U[3], U[4], U[5], 0, U[6], U[7], U[8], 0, -l[0] * U[0] - l[1] * U[3] - l[2] * U[6], -l[0] * U[1] - l[1] * U[4] - l[2] * U[7], -l[0] * U[2] - l[1] * U[5] - l[2] * U[8], 1), this._viewProj = this.projectionMatrix.multiply(this.viewMatrix);
488
- }, this.setSize = (t, F) => {
489
- this._width = t, this._height = F, this._updateProjectionMatrix();
490
- };
491
- }
492
- get fx() {
493
- return this._fx;
494
- }
495
- set fx(t) {
496
- this._fx !== t && (this._fx = t, this._updateProjectionMatrix());
497
- }
498
- get fy() {
499
- return this._fy;
500
- }
501
- set fy(t) {
502
- this._fy !== t && (this._fy = t, this._updateProjectionMatrix());
503
- }
504
- get near() {
505
- return this._near;
506
- }
507
- set near(t) {
508
- this._near !== t && (this._near = t, this._updateProjectionMatrix());
509
- }
510
- get far() {
511
- return this._far;
512
- }
513
- set far(t) {
514
- this._far !== t && (this._far = t, this._updateProjectionMatrix());
515
- }
516
- get width() {
517
- return this._width;
518
- }
519
- get height() {
520
- return this._height;
521
- }
522
- get projectionMatrix() {
523
- return this._projectionMatrix;
524
- }
525
- get viewMatrix() {
526
- return this._viewMatrix;
527
- }
528
- get viewProj() {
529
- return this._viewProj;
530
- }
531
- }
532
- class nt {
533
- constructor(t = 0, F = 0, U = 0, l = 0) {
534
- this.x = t, this.y = F, this.z = U, this.w = l;
535
- }
536
- equals(t) {
537
- return this.x === t.x && this.y === t.y && this.z === t.z && this.w === t.w;
538
- }
539
- add(t) {
540
- return typeof t == "number" ? new nt(this.x + t, this.y + t, this.z + t, this.w + t) : new nt(this.x + t.x, this.y + t.y, this.z + t.z, this.w + t.w);
541
- }
542
- subtract(t) {
543
- return typeof t == "number" ? new nt(this.x - t, this.y - t, this.z - t, this.w - t) : new nt(this.x - t.x, this.y - t.y, this.z - t.z, this.w - t.w);
544
- }
545
- multiply(t) {
546
- return typeof t == "number" ? new nt(this.x * t, this.y * t, this.z * t, this.w * t) : t instanceof nt ? new nt(this.x * t.x, this.y * t.y, this.z * t.z, this.w * t.w) : new nt(this.x * t.buffer[0] + this.y * t.buffer[4] + this.z * t.buffer[8] + this.w * t.buffer[12], this.x * t.buffer[1] + this.y * t.buffer[5] + this.z * t.buffer[9] + this.w * t.buffer[13], this.x * t.buffer[2] + this.y * t.buffer[6] + this.z * t.buffer[10] + this.w * t.buffer[14], this.x * t.buffer[3] + this.y * t.buffer[7] + this.z * t.buffer[11] + this.w * t.buffer[15]);
547
- }
548
- dot(t) {
549
- return this.x * t.x + this.y * t.y + this.z * t.z + this.w * t.w;
550
- }
551
- lerp(t, F) {
552
- return new nt(this.x + (t.x - this.x) * F, this.y + (t.y - this.y) * F, this.z + (t.z - this.z) * F, this.w + (t.w - this.w) * F);
553
- }
554
- magnitude() {
555
- return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
556
- }
557
- distanceTo(t) {
558
- return Math.sqrt((this.x - t.x) ** 2 + (this.y - t.y) ** 2 + (this.z - t.z) ** 2 + (this.w - t.w) ** 2);
559
- }
560
- normalize() {
561
- const t = this.magnitude();
562
- return new nt(this.x / t, this.y / t, this.z / t, this.w / t);
563
- }
564
- flat() {
565
- return [this.x, this.y, this.z, this.w];
566
- }
567
- clone() {
568
- return new nt(this.x, this.y, this.z, this.w);
569
- }
570
- toString() {
571
- return `[${this.flat().join(", ")}]`;
572
- }
573
- }
574
- class Ql extends bt {
575
- constructor(t = void 0) {
576
- super(), this._data = t || new qt(), this._position = new I(0, 0, -5), this.update = () => {
577
- this.data.update(this.position, this.rotation);
578
- }, this.screenPointToRay = (F, U) => {
579
- const l = new nt(F, U, -1, 1), a = this._data.projectionMatrix.invert(), n = l.multiply(a), e = this._data.viewMatrix.invert(), Q = n.multiply(e);
580
- return new I(Q.x / Q.w, Q.y / Q.w, Q.z / Q.w).subtract(this.position).normalize();
581
- };
582
- }
583
- get data() {
584
- return this._data;
585
- }
586
- }
587
- class dl extends Et {
588
- constructor() {
589
- super(), this._objects = [], this.addObject = (t) => {
590
- this.objects.push(t), this.dispatchEvent(new Lt(t));
591
- }, this.removeObject = (t) => {
592
- const F = this.objects.indexOf(t);
593
- if (F < 0) throw new Error("Object not found in scene");
594
- this.objects.splice(F, 1), this.dispatchEvent(new Pt(t));
595
- }, this.findObject = (t) => {
596
- for (const F of this.objects) if (t(F)) return F;
597
- }, this.findObjectOfType = (t) => {
598
- for (const F of this.objects) if (F instanceof t) return F;
599
- }, this.reset = () => {
600
- const t = this.objects.slice();
601
- for (const F of t) this.removeObject(F);
602
- }, this.reset();
603
- }
604
- saveToFile(t = null, F = null) {
605
- if (!document) return;
606
- if (F) {
607
- if (F !== "splat" && F !== "ply") throw new Error("Invalid format. Must be 'splat' or 'ply'");
608
- } else F = "splat";
609
- if (!t) {
610
- const d = /* @__PURE__ */ new Date();
611
- t = `scene-${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}.${F}`;
612
- }
613
- const U = [];
614
- let l = 0;
615
- for (const d of this.objects) if (d.applyRotation(), d.applyScale(), d.applyPosition(), d instanceof dt) {
616
- const A = d.data.serialize();
617
- U.push(A), l += d.data.vertexCount;
618
- }
619
- const a = new Uint8Array(l * lt.RowLength);
620
- let n, e = 0;
621
- for (const d of U) a.set(d, e), e += d.length;
622
- if (F === "ply") {
623
- const d = Zt.SplatToPLY(a.buffer, l);
624
- n = new Blob([d], { type: "application/octet-stream" });
625
- } else n = new Blob([a.buffer], { type: "application/octet-stream" });
626
- const Q = document.createElement("a");
627
- Q.download = t, Q.href = URL.createObjectURL(n), Q.click();
628
- }
629
- get objects() {
630
- return this._objects;
631
- }
632
- }
633
- async function Ct(G, t) {
634
- const F = await fetch(G, { mode: "cors", credentials: "omit", cache: t ? "force-cache" : "default" });
635
- if (F.status != 200) throw new Error(F.status + " Unable to load " + F.url);
636
- return F;
637
- }
638
- async function gt(G, t) {
639
- return G.headers.has("content-length") ? async function(F, U) {
640
- const l = F.body.getReader(), a = parseInt(F.headers.get("content-length")), n = new Uint8Array(a);
641
- let e = 0;
642
- for (; ; ) {
643
- const { done: Q, value: d } = await l.read();
644
- if (Q) break;
645
- n.set(d, e), e += d.length, U == null || U(e / a);
646
- }
647
- return n;
648
- }(G, t) : async function(F, U) {
649
- const l = F.body.getReader(), a = [];
650
- let n = 0;
651
- for (; ; ) {
652
- const { done: d, value: A } = await l.read();
653
- if (d) break;
654
- a.push(A), n += A.length;
655
- }
656
- const e = new Uint8Array(n);
657
- let Q = 0;
658
- for (const d of a) e.set(d, Q), Q += d.length, U == null || U(Q / n);
659
- return e;
660
- }(G, t);
661
- }
662
- class al {
663
- static async LoadAsync(t, F, U, l = !1) {
664
- const a = await Ct(t, l), n = await gt(a, U);
665
- return this.LoadFromArrayBuffer(n, F);
666
- }
667
- static async LoadFromFileAsync(t, F, U) {
668
- const l = new FileReader();
669
- let a = new dt();
670
- return l.onload = (n) => {
671
- a = this.LoadFromArrayBuffer(n.target.result, F);
672
- }, l.onprogress = (n) => {
673
- U == null || U(n.loaded / n.total);
674
- }, l.readAsArrayBuffer(t), await new Promise((n) => {
675
- l.onloadend = () => {
676
- n();
677
- };
678
- }), a;
679
- }
680
- static LoadFromArrayBuffer(t, F) {
681
- const U = new Uint8Array(t), l = lt.Deserialize(U), a = new dt(l);
682
- return F.addObject(a), a;
683
- }
684
- }
685
- class Al {
686
- static async LoadAsync(t, F, U, l = "", a = !1) {
687
- const n = await Ct(t, a), e = await gt(n, U);
688
- if (e[0] !== 112 || e[1] !== 108 || e[2] !== 121 || e[3] !== 10) throw new Error("Invalid PLY file");
689
- return this.LoadFromArrayBuffer(e.buffer, F, l);
690
- }
691
- static async LoadFromFileAsync(t, F, U, l = "") {
692
- const a = new FileReader();
693
- let n = new dt();
694
- return a.onload = (e) => {
695
- n = this.LoadFromArrayBuffer(e.target.result, F, l);
696
- }, a.onprogress = (e) => {
697
- U == null || U(e.loaded / e.total);
698
- }, a.readAsArrayBuffer(t), await new Promise((e) => {
699
- a.onloadend = () => {
700
- e();
701
- };
702
- }), n;
703
- }
704
- static LoadFromArrayBuffer(t, F, U = "") {
705
- const l = new Uint8Array(this._ParsePLYBuffer(t, U)), a = lt.Deserialize(l), n = new dt(a);
706
- return F.addObject(n), n;
707
- }
708
- static _ParsePLYBuffer(t, F) {
709
- const U = new Uint8Array(t), l = new TextDecoder().decode(U.slice(0, 10240)), a = `end_header
710
- `, n = l.indexOf(a);
711
- if (n < 0) throw new Error("Unable to read .ply file header");
712
- const e = parseInt(/element vertex (\d+)\n/.exec(l)[1]);
713
- let Q = 0;
714
- const d = { double: 8, int: 4, uint: 4, float: 4, short: 2, ushort: 2, uchar: 1 }, A = [];
715
- for (const B of l.slice(0, n).split(`
716
- `).filter((W) => W.startsWith("property "))) {
717
- const [W, J, h] = B.split(" ");
718
- if (A.push({ name: h, type: J, offset: Q }), console.log(h, J, Q), !d[J]) throw new Error(`Unsupported property type: ${J}`);
719
- Q += d[J];
720
- }
721
- const i = new DataView(t, n + 11), r = new ArrayBuffer(lt.RowLength * e), c = z.FromEuler(new I(Math.PI / 2, 0, 0));
722
- for (let B = 0; B < e; B++) {
723
- const W = new Float32Array(r, B * lt.RowLength, 3), J = new Float32Array(r, B * lt.RowLength + 12, 3), h = new Uint8ClampedArray(r, B * lt.RowLength + 24, 4), C = new Uint8ClampedArray(r, B * lt.RowLength + 28, 4);
724
- let k = 255, p = 0, X = 0, D = 0;
725
- A.forEach((M) => {
726
- let E;
727
- switch (M.type) {
728
- case "float":
729
- E = i.getFloat32(M.offset + B * Q, !0);
730
- break;
731
- case "int":
732
- E = i.getInt32(M.offset + B * Q, !0);
733
- break;
734
- default:
735
- throw new Error(`Unsupported property type: ${M.type}`);
736
- }
737
- switch (M.name) {
738
- case "x":
739
- W[0] = E;
740
- break;
741
- case "y":
742
- W[1] = E;
743
- break;
744
- case "z":
745
- W[2] = E;
746
- break;
747
- case "scale_0":
748
- case "scaling_0":
749
- J[0] = Math.exp(E);
750
- break;
751
- case "scale_1":
752
- case "scaling_1":
753
- J[1] = Math.exp(E);
754
- break;
755
- case "scale_2":
756
- case "scaling_2":
757
- J[2] = Math.exp(E);
758
- break;
759
- case "red":
760
- h[0] = E;
761
- break;
762
- case "green":
763
- h[1] = E;
764
- break;
765
- case "blue":
766
- h[2] = E;
767
- break;
768
- case "f_dc_0":
769
- case "features_0":
770
- h[0] = 255 * (0.5 + Zt.SH_C0 * E);
771
- break;
772
- case "f_dc_1":
773
- case "features_1":
774
- h[1] = 255 * (0.5 + Zt.SH_C0 * E);
775
- break;
776
- case "f_dc_2":
777
- case "features_2":
778
- h[2] = 255 * (0.5 + Zt.SH_C0 * E);
779
- break;
780
- case "f_dc_3":
781
- h[3] = 255 * (0.5 + Zt.SH_C0 * E);
782
- break;
783
- case "opacity":
784
- case "opacity_0":
785
- h[3] = 1 / (1 + Math.exp(-E)) * 255;
786
- break;
787
- case "rot_0":
788
- case "rotation_0":
789
- k = E;
790
- break;
791
- case "rot_1":
792
- case "rotation_1":
793
- p = E;
794
- break;
795
- case "rot_2":
796
- case "rotation_2":
797
- X = E;
798
- break;
799
- case "rot_3":
800
- case "rotation_3":
801
- D = E;
802
- }
803
- });
804
- let u = new z(p, X, D, k);
805
- switch (F) {
806
- case "polycam": {
807
- const M = W[1];
808
- W[1] = -W[2], W[2] = M, u = c.multiply(u);
809
- break;
810
- }
811
- case "":
812
- break;
813
- default:
814
- throw new Error(`Unsupported format: ${F}`);
815
- }
816
- u = u.normalize(), C[0] = 128 * u.w + 128, C[1] = 128 * u.x + 128, C[2] = 128 * u.y + 128, C[3] = 128 * u.z + 128;
817
- }
818
- return r;
819
- }
820
- }
821
- class Vl {
822
- static async LoadAsync(t, F, U, l, a = !1) {
823
- const n = await Ct(t, a), e = await gt(n, l);
824
- return this._ParseSplatvBuffer(e.buffer, F, U);
825
- }
826
- static async LoadFromFileAsync(t, F, U, l) {
827
- const a = new FileReader();
828
- let n = null;
829
- if (a.onload = (e) => {
830
- n = this._ParseSplatvBuffer(e.target.result, F, U);
831
- }, a.onprogress = (e) => {
832
- l == null || l(e.loaded / e.total);
833
- }, a.readAsArrayBuffer(t), await new Promise((e) => {
834
- a.onloadend = () => {
835
- e();
836
- };
837
- }), !n) throw new Error("Failed to load splatv file");
838
- return n;
839
- }
840
- static _ParseSplatvBuffer(t, F, U) {
841
- let l = null;
842
- const a = (r, c, B) => {
843
- if (r.type === "magic") {
844
- const W = new Int32Array(c.buffer);
845
- if (W[0] !== 26443) throw new Error("Invalid splatv file");
846
- B.push({ size: W[1], type: "chunks" });
847
- } else if (r.type === "chunks") {
848
- const W = JSON.parse(new TextDecoder("utf-8").decode(c));
849
- if (W.length == 0) throw new Error("Invalid splatv file");
850
- W.length > 1 && console.warn("Splatv file contains more than one chunk, only the first one will be loaded");
851
- const J = W[0], h = J.cameras;
852
- if (U && h && h.length) {
853
- const C = h[0], k = new I(C.position[0], C.position[1], C.position[2]), p = z.FromMatrix3(new tt(C.rotation[0][0], C.rotation[0][1], C.rotation[0][2], C.rotation[1][0], C.rotation[1][1], C.rotation[1][2], C.rotation[2][0], C.rotation[2][1], C.rotation[2][2]));
854
- U.position = k, U.rotation = p;
855
- }
856
- B.push(J);
857
- } else if (r.type === "splat") {
858
- const W = mt.Deserialize(c, r.texwidth, r.texheight), J = new ct(W);
859
- F.addObject(J), l = J;
860
- }
861
- }, n = new Uint8Array(t), e = [{ size: 8, type: "magic", texwidth: 0, texheight: 0 }];
862
- let Q = e.shift(), d = new Uint8Array(Q.size), A = 0, i = 0;
863
- for (; Q; ) {
864
- for (; A < Q.size; ) {
865
- const r = Math.min(Q.size - A, n.length - i);
866
- d.set(n.subarray(i, i + r), A), A += r, i += r;
867
- }
868
- if (a(Q, d, e), l) return l;
869
- Q = e.shift(), Q && (d = new Uint8Array(Q.size), A = 0);
870
- }
871
- throw new Error("Invalid splatv file");
872
- }
873
- }
874
- function $t(G, t, F) {
875
- var U = t === void 0 ? null : t, l = function(Q, d) {
876
- var A = atob(Q);
877
- return A;
878
- }(G), a = l.indexOf(`
879
- `, 10) + 1, n = l.substring(a) + (U ? "//# sourceMappingURL=" + U : ""), e = new Blob([n], { type: "application/javascript" });
880
- return URL.createObjectURL(e);
881
- }
882
- function yt(G, t, F) {
883
- var U;
884
- return function(l) {
885
- return U = U || $t(G, t), new Worker(U, l);
886
- };
887
- }
888
- var tl = yt("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgdmFyIGxvYWRXYXNtID0gKCgpID0+IHsKICAgIAogICAgcmV0dXJuICgKICBmdW5jdGlvbihtb2R1bGVBcmcgPSB7fSkgewoKICB2YXIgTW9kdWxlPW1vZHVsZUFyZzt2YXIgcmVhZHlQcm9taXNlUmVzb2x2ZSxyZWFkeVByb21pc2VSZWplY3Q7TW9kdWxlWyJyZWFkeSJdPW5ldyBQcm9taXNlKChyZXNvbHZlLHJlamVjdCk9PntyZWFkeVByb21pc2VSZXNvbHZlPXJlc29sdmU7cmVhZHlQcm9taXNlUmVqZWN0PXJlamVjdDt9KTt2YXIgbW9kdWxlT3ZlcnJpZGVzPU9iamVjdC5hc3NpZ24oe30sTW9kdWxlKTt2YXIgc2NyaXB0RGlyZWN0b3J5PSIiO2Z1bmN0aW9uIGxvY2F0ZUZpbGUocGF0aCl7aWYoTW9kdWxlWyJsb2NhdGVGaWxlIl0pe3JldHVybiBNb2R1bGVbImxvY2F0ZUZpbGUiXShwYXRoLHNjcmlwdERpcmVjdG9yeSl9cmV0dXJuIHNjcmlwdERpcmVjdG9yeStwYXRofXZhciByZWFkQmluYXJ5O3t7c2NyaXB0RGlyZWN0b3J5PXNlbGYubG9jYXRpb24uaHJlZjt9aWYoc2NyaXB0RGlyZWN0b3J5LmluZGV4T2YoImJsb2I6IikhPT0wKXtzY3JpcHREaXJlY3Rvcnk9c2NyaXB0RGlyZWN0b3J5LnN1YnN0cigwLHNjcmlwdERpcmVjdG9yeS5yZXBsYWNlKC9bPyNdLiovLCIiKS5sYXN0SW5kZXhPZigiLyIpKzEpO31lbHNlIHtzY3JpcHREaXJlY3Rvcnk9IiI7fXt7cmVhZEJpbmFyeT11cmw9Pnt2YXIgeGhyPW5ldyBYTUxIdHRwUmVxdWVzdDt4aHIub3BlbigiR0VUIix1cmwsZmFsc2UpO3hoci5yZXNwb25zZVR5cGU9ImFycmF5YnVmZmVyIjt4aHIuc2VuZChudWxsKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoeGhyLnJlc3BvbnNlKX07fX19TW9kdWxlWyJwcmludCJdfHxjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpO3ZhciBlcnI9TW9kdWxlWyJwcmludEVyciJdfHxjb25zb2xlLmVycm9yLmJpbmQoY29uc29sZSk7T2JqZWN0LmFzc2lnbihNb2R1bGUsbW9kdWxlT3ZlcnJpZGVzKTttb2R1bGVPdmVycmlkZXM9bnVsbDtpZihNb2R1bGVbImFyZ3VtZW50cyJdKU1vZHVsZVsiYXJndW1lbnRzIl07aWYoTW9kdWxlWyJ0aGlzUHJvZ3JhbSJdKU1vZHVsZVsidGhpc1Byb2dyYW0iXTtpZihNb2R1bGVbInF1aXQiXSlNb2R1bGVbInF1aXQiXTt2YXIgd2FzbUJpbmFyeTtpZihNb2R1bGVbIndhc21CaW5hcnkiXSl3YXNtQmluYXJ5PU1vZHVsZVsid2FzbUJpbmFyeSJdO2lmKHR5cGVvZiBXZWJBc3NlbWJseSE9Im9iamVjdCIpe2Fib3J0KCJubyBuYXRpdmUgd2FzbSBzdXBwb3J0IGRldGVjdGVkIik7fXZhciB3YXNtTWVtb3J5O3ZhciBBQk9SVD1mYWxzZTt2YXIgSEVBUDgsSEVBUFU4LEhFQVAxNixIRUFQVTE2LEhFQVAzMixIRUFQVTMyLEhFQVBGMzIsSEVBUEY2NDtmdW5jdGlvbiB1cGRhdGVNZW1vcnlWaWV3cygpe3ZhciBiPXdhc21NZW1vcnkuYnVmZmVyO01vZHVsZVsiSEVBUDgiXT1IRUFQOD1uZXcgSW50OEFycmF5KGIpO01vZHVsZVsiSEVBUDE2Il09SEVBUDE2PW5ldyBJbnQxNkFycmF5KGIpO01vZHVsZVsiSEVBUFU4Il09SEVBUFU4PW5ldyBVaW50OEFycmF5KGIpO01vZHVsZVsiSEVBUFUxNiJdPUhFQVBVMTY9bmV3IFVpbnQxNkFycmF5KGIpO01vZHVsZVsiSEVBUDMyIl09SEVBUDMyPW5ldyBJbnQzMkFycmF5KGIpO01vZHVsZVsiSEVBUFUzMiJdPUhFQVBVMzI9bmV3IFVpbnQzMkFycmF5KGIpO01vZHVsZVsiSEVBUEYzMiJdPUhFQVBGMzI9bmV3IEZsb2F0MzJBcnJheShiKTtNb2R1bGVbIkhFQVBGNjQiXT1IRUFQRjY0PW5ldyBGbG9hdDY0QXJyYXkoYik7fXZhciBfX0FUUFJFUlVOX189W107dmFyIF9fQVRJTklUX189W107dmFyIF9fQVRQT1NUUlVOX189W107ZnVuY3Rpb24gcHJlUnVuKCl7aWYoTW9kdWxlWyJwcmVSdW4iXSl7aWYodHlwZW9mIE1vZHVsZVsicHJlUnVuIl09PSJmdW5jdGlvbiIpTW9kdWxlWyJwcmVSdW4iXT1bTW9kdWxlWyJwcmVSdW4iXV07d2hpbGUoTW9kdWxlWyJwcmVSdW4iXS5sZW5ndGgpe2FkZE9uUHJlUnVuKE1vZHVsZVsicHJlUnVuIl0uc2hpZnQoKSk7fX1jYWxsUnVudGltZUNhbGxiYWNrcyhfX0FUUFJFUlVOX18pO31mdW5jdGlvbiBpbml0UnVudGltZSgpe2NhbGxSdW50aW1lQ2FsbGJhY2tzKF9fQVRJTklUX18pO31mdW5jdGlvbiBwb3N0UnVuKCl7aWYoTW9kdWxlWyJwb3N0UnVuIl0pe2lmKHR5cGVvZiBNb2R1bGVbInBvc3RSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInBvc3RSdW4iXT1bTW9kdWxlWyJwb3N0UnVuIl1dO3doaWxlKE1vZHVsZVsicG9zdFJ1biJdLmxlbmd0aCl7YWRkT25Qb3N0UnVuKE1vZHVsZVsicG9zdFJ1biJdLnNoaWZ0KCkpO319Y2FsbFJ1bnRpbWVDYWxsYmFja3MoX19BVFBPU1RSVU5fXyk7fWZ1bmN0aW9uIGFkZE9uUHJlUnVuKGNiKXtfX0FUUFJFUlVOX18udW5zaGlmdChjYik7fWZ1bmN0aW9uIGFkZE9uSW5pdChjYil7X19BVElOSVRfXy51bnNoaWZ0KGNiKTt9ZnVuY3Rpb24gYWRkT25Qb3N0UnVuKGNiKXtfX0FUUE9TVFJVTl9fLnVuc2hpZnQoY2IpO312YXIgcnVuRGVwZW5kZW5jaWVzPTA7dmFyIGRlcGVuZGVuY2llc0Z1bGZpbGxlZD1udWxsO2Z1bmN0aW9uIGFkZFJ1bkRlcGVuZGVuY3koaWQpe3J1bkRlcGVuZGVuY2llcysrO2lmKE1vZHVsZVsibW9uaXRvclJ1bkRlcGVuZGVuY2llcyJdKXtNb2R1bGVbIm1vbml0b3JSdW5EZXBlbmRlbmNpZXMiXShydW5EZXBlbmRlbmNpZXMpO319ZnVuY3Rpb24gcmVtb3ZlUnVuRGVwZW5kZW5jeShpZCl7cnVuRGVwZW5kZW5jaWVzLS07aWYoTW9kdWxlWyJtb25pdG9yUnVuRGVwZW5kZW5jaWVzIl0pe01vZHVsZVsibW9uaXRvclJ1bkRlcGVuZGVuY2llcyJdKHJ1bkRlcGVuZGVuY2llcyk7fWlmKHJ1bkRlcGVuZGVuY2llcz09MCl7aWYoZGVwZW5kZW5jaWVzRnVsZmlsbGVkKXt2YXIgY2FsbGJhY2s9ZGVwZW5kZW5jaWVzRnVsZmlsbGVkO2RlcGVuZGVuY2llc0Z1bGZpbGxlZD1udWxsO2NhbGxiYWNrKCk7fX19ZnVuY3Rpb24gYWJvcnQod2hhdCl7aWYoTW9kdWxlWyJvbkFib3J0Il0pe01vZHVsZVsib25BYm9ydCJdKHdoYXQpO313aGF0PSJBYm9ydGVkKCIrd2hhdCsiKSI7ZXJyKHdoYXQpO0FCT1JUPXRydWU7d2hhdCs9Ii4gQnVpbGQgd2l0aCAtc0FTU0VSVElPTlMgZm9yIG1vcmUgaW5mby4iO3ZhciBlPW5ldyBXZWJBc3NlbWJseS5SdW50aW1lRXJyb3Iod2hhdCk7cmVhZHlQcm9taXNlUmVqZWN0KGUpO3Rocm93IGV9dmFyIGRhdGFVUklQcmVmaXg9ImRhdGE6YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtO2Jhc2U2NCwiO3ZhciBpc0RhdGFVUkk9ZmlsZW5hbWU9PmZpbGVuYW1lLnN0YXJ0c1dpdGgoZGF0YVVSSVByZWZpeCk7dmFyIHdhc21CaW5hcnlGaWxlO3dhc21CaW5hcnlGaWxlPSJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsQUdGemJRRUFBQUFCV2cxZ0JIOS9mMzhBWUFOL2YzOEFZQVYvZjM5L2Z3QmdCbjkvZjM5L2Z3QmdBWDhCZjJBQUFHQUNmMzhBWUFOL2YzOEJmMkFCZndCZ0IzOS9mMzkvZjM4QVlBSi9md0YvWUFSL2YzNStBR0FKZjM5L2YzOS9mMzkvQUFJOUNnRmhBV0VBQVFGaEFXSUFBZ0ZoQVdNQUFRRmhBV1FBQmdGaEFXVUFBUUZoQVdZQUNRRmhBV2NBQkFGaEFXZ0FCZ0ZoQVdrQUFBRmhBV29BQmdNWkdBY0VDQVVJQ2dVTEFRQUJDQVFGQXdNQ0FnQUFCd2NFREFRRkFYQUJFQkFGQndFQmdBS0FnQUlHQ0FGL0FVSGduUVFMQngwSEFXc0NBQUZzQUEwQmJRQWhBVzRBRndGdkFRQUJjQUFXQVhFQURna1ZBUUJCQVFzUEVDQU1GUlVmREI0WUdoME1HUnNjQ3ZCSUdIRUJBWDhnQWtVRVFDQUFLQUlFSUFFb0FnUkdEd3NnQUNBQlJnUkFRUUVQQ3dKQUlBQW9BZ1FpQWkwQUFDSUFSU0FBSUFFb0FnUWlBUzBBQUNJRFIzSU5BQU5BSUFFdEFBRWhBeUFDTFFBQklnQkZEUUVnQVVFQmFpRUJJQUpCQVdvaEFpQUFJQU5HRFFBTEN5QUFJQU5HQzA4QkFuOUIyQmtvQWdBaUFTQUFRUWRxUVhoeElnSnFJUUFDUUNBQ1FRQWdBQ0FCVFJzTkFDQUFQd0JCRUhSTEJFQWdBQkFHUlEwQkMwSFlHU0FBTmdJQUlBRVBDMEhvR1VFd05nSUFRWDhMQmdBZ0FCQU9DeWtBUWVBWlFRRTJBZ0JCNUJsQkFEWUNBQkFRUWVRWlFkd1pLQUlBTmdJQVFkd1pRZUFaTmdJQUM5SUxBUWQvQWtBZ0FFVU5BQ0FBUVFocklnSWdBRUVFYXlnQ0FDSUJRWGh4SWdCcUlRVUNRQ0FCUVFGeERRQWdBVUVEY1VVTkFTQUNJQUlvQWdBaUFXc2lBa0g4R1NnQ0FFa05BU0FBSUFGcUlRQUNRQUpBUVlBYUtBSUFJQUpIQkVBZ0FVSC9BVTBFUUNBQlFRTjJJUVFnQWlnQ0RDSUJJQUlvQWdnaUEwWUVRRUhzR1VIc0dTZ0NBRUYrSUFSM2NUWUNBQXdGQ3lBRElBRTJBZ3dnQVNBRE5nSUlEQVFMSUFJb0FoZ2hCaUFDSUFJb0Fnd2lBVWNFUUNBQ0tBSUlJZ01nQVRZQ0RDQUJJQU0yQWdnTUF3c2dBa0VVYWlJRUtBSUFJZ05GQkVBZ0FpZ0NFQ0lEUlEwQ0lBSkJFR29oQkFzRFFDQUVJUWNnQXlJQlFSUnFJZ1FvQWdBaUF3MEFJQUZCRUdvaEJDQUJLQUlRSWdNTkFBc2dCMEVBTmdJQURBSUxJQVVvQWdRaUFVRURjVUVEUncwQ1FmUVpJQUEyQWdBZ0JTQUJRWDV4TmdJRUlBSWdBRUVCY2pZQ0JDQUZJQUEyQWdBUEMwRUFJUUVMSUFaRkRRQUNRQ0FDS0FJY0lnTkJBblJCbkJ4cUlnUW9BZ0FnQWtZRVFDQUVJQUUyQWdBZ0FRMEJRZkFaUWZBWktBSUFRWDRnQTNkeE5nSUFEQUlMSUFaQkVFRVVJQVlvQWhBZ0FrWWJhaUFCTmdJQUlBRkZEUUVMSUFFZ0JqWUNHQ0FDS0FJUUlnTUVRQ0FCSUFNMkFoQWdBeUFCTmdJWUN5QUNLQUlVSWdORkRRQWdBU0FETmdJVUlBTWdBVFlDR0FzZ0FpQUZUdzBBSUFVb0FnUWlBVUVCY1VVTkFBSkFBa0FDUUFKQUlBRkJBbkZGQkVCQmhCb29BZ0FnQlVZRVFFR0VHaUFDTmdJQVFmZ1pRZmdaS0FJQUlBQnFJZ0EyQWdBZ0FpQUFRUUZ5TmdJRUlBSkJnQm9vQWdCSERRWkI5QmxCQURZQ0FFR0FHa0VBTmdJQUR3dEJnQm9vQWdBZ0JVWUVRRUdBR2lBQ05nSUFRZlFaUWZRWktBSUFJQUJxSWdBMkFnQWdBaUFBUVFGeU5nSUVJQUFnQW1vZ0FEWUNBQThMSUFGQmVIRWdBR29oQUNBQlFmOEJUUVJBSUFGQkEzWWhCQ0FGS0FJTUlnRWdCU2dDQ0NJRFJnUkFRZXdaUWV3WktBSUFRWDRnQkhkeE5nSUFEQVVMSUFNZ0FUWUNEQ0FCSUFNMkFnZ01CQXNnQlNnQ0dDRUdJQVVnQlNnQ0RDSUJSd1JBUWZ3WktBSUFHaUFGS0FJSUlnTWdBVFlDRENBQklBTTJBZ2dNQXdzZ0JVRVVhaUlFS0FJQUlnTkZCRUFnQlNnQ0VDSURSUTBDSUFWQkVHb2hCQXNEUUNBRUlRY2dBeUlCUVJScUlnUW9BZ0FpQXcwQUlBRkJFR29oQkNBQktBSVFJZ01OQUFzZ0IwRUFOZ0lBREFJTElBVWdBVUYrY1RZQ0JDQUNJQUJCQVhJMkFnUWdBQ0FDYWlBQU5nSUFEQU1MUVFBaEFRc2dCa1VOQUFKQUlBVW9BaHdpQTBFQ2RFR2NIR29pQkNnQ0FDQUZSZ1JBSUFRZ0FUWUNBQ0FCRFFGQjhCbEI4QmtvQWdCQmZpQURkM0UyQWdBTUFnc2dCa0VRUVJRZ0JpZ0NFQ0FGUmh0cUlBRTJBZ0FnQVVVTkFRc2dBU0FHTmdJWUlBVW9BaEFpQXdSQUlBRWdBellDRUNBRElBRTJBaGdMSUFVb0FoUWlBMFVOQUNBQklBTTJBaFFnQXlBQk5nSVlDeUFDSUFCQkFYSTJBZ1FnQUNBQ2FpQUFOZ0lBSUFKQmdCb29BZ0JIRFFCQjlCa2dBRFlDQUE4TElBQkIvd0ZOQkVBZ0FFRjRjVUdVR21vaEFRSi9RZXdaS0FJQUlnTkJBU0FBUVFOMmRDSUFjVVVFUUVIc0dTQUFJQU55TmdJQUlBRU1BUXNnQVNnQ0NBc2hBQ0FCSUFJMkFnZ2dBQ0FDTmdJTUlBSWdBVFlDRENBQ0lBQTJBZ2dQQzBFZklRTWdBRUgvLy84SFRRUkFJQUJCSmlBQVFRaDJaeUlCYTNaQkFYRWdBVUVCZEd0QlBtb2hBd3NnQWlBRE5nSWNJQUpDQURjQ0VDQURRUUowUVp3Y2FpRUJBa0FDUUFKQVFmQVpLQUlBSWdSQkFTQURkQ0lIY1VVRVFFSHdHU0FFSUFkeU5nSUFJQUVnQWpZQ0FDQUNJQUUyQWhnTUFRc2dBRUVaSUFOQkFYWnJRUUFnQTBFZlJ4dDBJUU1nQVNnQ0FDRUJBMEFnQVNJRUtBSUVRWGh4SUFCR0RRSWdBMEVkZGlFQklBTkJBWFFoQXlBRUlBRkJCSEZxSWdkQkVHb29BZ0FpQVEwQUN5QUhJQUkyQWhBZ0FpQUVOZ0lZQ3lBQ0lBSTJBZ3dnQWlBQ05nSUlEQUVMSUFRb0FnZ2lBQ0FDTmdJTUlBUWdBallDQ0NBQ1FRQTJBaGdnQWlBRU5nSU1JQUlnQURZQ0NBdEJqQnBCakJvb0FnQkJBV3NpQUVGL0lBQWJOZ0lBQ3dzcEFRRi9JQUVFUUNBQUlRSURRQ0FDUVFBNkFBQWdBa0VCYWlFQ0lBRkJBV3NpQVEwQUN3c2dBQXZoQXdCQmpCZEJtZ2tRQ1VHWUYwRzVDRUVCUVFBUUNFR2tGMEcwQ0VFQlFZQi9RZjhBRUFGQnZCZEJyUWhCQVVHQWYwSC9BQkFCUWJBWFFhc0lRUUZCQUVIL0FSQUJRY2dYUVlrSVFRSkJnSUIrUWYvL0FSQUJRZFFYUVlBSVFRSkJBRUgvL3dNUUFVSGdGMEdZQ0VFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCN0JkQmp3aEJCRUVBUVg4UUFVSDRGMEhYQ0VFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCaEJoQnpnaEJCRUVBUVg4UUFVR1FHRUdqQ0VLQWdJQ0FnSUNBZ0lCL1F2Ly8vLy8vLy8vLy93QVFFVUdjR0VHaUNFSUFRbjhRRVVHb0dFR2NDRUVFRUFSQnRCaEJrd2xCQ0JBRVFZUVBRZWtJRUFOQnpBOUJsdzBRQTBHVUVFRUVRZHdJRUFKQjRCQkJBa0gxQ0JBQ1Fhd1JRUVJCaEFrUUFrSElFVUcrQ0JBSFFmQVJRUUJCMGd3UUFFR1lFa0VBUWJnTkVBQkJ3QkpCQVVId0RCQUFRZWdTUVFKQm53a1FBRUdRRTBFRFFiNEpFQUJCdUJOQkJFSG1DUkFBUWVBVFFRVkJnd29RQUVHSUZFRUVRZDBORUFCQnNCUkJCVUg3RFJBQVFaZ1NRUUJCNlFvUUFFSEFFa0VCUWNnS0VBQkI2QkpCQWtHckN4QUFRWkFUUVFOQmlRc1FBRUc0RTBFRVFiRU1FQUJCNEJOQkJVR1BEQkFBUWRnVVFRaEI3Z3NRQUVHQUZVRUpRY3dMRUFCQnFCVkJCa0dwQ2hBQVFkQVZRUWRCb2c0UUFBc2NBQ0FBSUFGQkNDQUNweUFDUWlDSXB5QURweUFEUWlDSXB4QUZDeUFBQWtBZ0FDZ0NCQ0FCUncwQUlBQW9BaHhCQVVZTkFDQUFJQUkyQWh3TEM1b0JBQ0FBUVFFNkFEVUNRQ0FBS0FJRUlBSkhEUUFnQUVFQk9nQTBBa0FnQUNnQ0VDSUNSUVJBSUFCQkFUWUNKQ0FBSUFNMkFoZ2dBQ0FCTmdJUUlBTkJBVWNOQWlBQUtBSXdRUUZHRFFFTUFnc2dBU0FDUmdSQUlBQW9BaGdpQWtFQ1JnUkFJQUFnQXpZQ0dDQURJUUlMSUFBb0FqQkJBVWNOQWlBQ1FRRkdEUUVNQWdzZ0FDQUFLQUlrUVFGcU5nSWtDeUFBUVFFNkFEWUxDMTBCQVg4Z0FDZ0NFQ0lEUlFSQUlBQkJBVFlDSkNBQUlBSTJBaGdnQUNBQk5nSVFEd3NDUUNBQklBTkdCRUFnQUNnQ0dFRUNSdzBCSUFBZ0FqWUNHQThMSUFCQkFUb0FOaUFBUVFJMkFoZ2dBQ0FBS0FJa1FRRnFOZ0lrQ3dzQ0FBdTlKd0VNZnlNQVFSQnJJZ29rQUFKQUFrQUNRQUpBQWtBQ1FBSkFBa0FDUUFKQUFrQUNRQUpBQWtBZ0FFSDBBVTBFUUVIc0dTZ0NBQ0lHUVJBZ0FFRUxha0Y0Y1NBQVFRdEpHeUlGUVFOMklnQjJJZ0ZCQTNFRVFBSkFJQUZCZjNOQkFYRWdBR29pQWtFRGRDSUJRWlFhYWlJQUlBRkJuQnBxS0FJQUlnRW9BZ2dpQkVZRVFFSHNHU0FHUVg0Z0FuZHhOZ0lBREFFTElBUWdBRFlDRENBQUlBUTJBZ2dMSUFGQkNHb2hBQ0FCSUFKQkEzUWlBa0VEY2pZQ0JDQUJJQUpxSWdFZ0FTZ0NCRUVCY2pZQ0JBd1BDeUFGUWZRWktBSUFJZ2RORFFFZ0FRUkFBa0JCQWlBQWRDSUNRUUFnQW10eUlBRWdBSFJ4YUNJQlFRTjBJZ0JCbEJwcUlnSWdBRUdjR21vb0FnQWlBQ2dDQ0NJRVJnUkFRZXdaSUFaQmZpQUJkM0VpQmpZQ0FBd0JDeUFFSUFJMkFnd2dBaUFFTmdJSUN5QUFJQVZCQTNJMkFnUWdBQ0FGYWlJSUlBRkJBM1FpQVNBRmF5SUVRUUZ5TmdJRUlBQWdBV29nQkRZQ0FDQUhCRUFnQjBGNGNVR1VHbW9oQVVHQUdpZ0NBQ0VDQW44Z0JrRUJJQWRCQTNaMElnTnhSUVJBUWV3WklBTWdCbkkyQWdBZ0FRd0JDeUFCS0FJSUN5RURJQUVnQWpZQ0NDQURJQUkyQWd3Z0FpQUJOZ0lNSUFJZ0F6WUNDQXNnQUVFSWFpRUFRWUFhSUFnMkFnQkI5QmtnQkRZQ0FBd1BDMEh3R1NnQ0FDSUxSUTBCSUF0b1FRSjBRWndjYWlnQ0FDSUNLQUlFUVhoeElBVnJJUU1nQWlFQkEwQUNRQ0FCS0FJUUlnQkZCRUFnQVNnQ0ZDSUFSUTBCQ3lBQUtBSUVRWGh4SUFWcklnRWdBeUFCSUFOSklnRWJJUU1nQUNBQ0lBRWJJUUlnQUNFQkRBRUxDeUFDS0FJWUlRa2dBaUFDS0FJTUlnUkhCRUJCL0Jrb0FnQWFJQUlvQWdnaUFDQUVOZ0lNSUFRZ0FEWUNDQXdPQ3lBQ1FSUnFJZ0VvQWdBaUFFVUVRQ0FDS0FJUUlnQkZEUU1nQWtFUWFpRUJDd05BSUFFaENDQUFJZ1JCRkdvaUFTZ0NBQ0lBRFFBZ0JFRVFhaUVCSUFRb0FoQWlBQTBBQ3lBSVFRQTJBZ0FNRFF0QmZ5RUZJQUJCdjM5TERRQWdBRUVMYWlJQVFYaHhJUVZCOEJrb0FnQWlDRVVOQUVFQUlBVnJJUU1DUUFKQUFrQUNmMEVBSUFWQmdBSkpEUUFhUVI4Z0JVSC8vLzhIU3cwQUdpQUZRU1lnQUVFSWRtY2lBR3QyUVFGeElBQkJBWFJyUVQ1cUN5SUhRUUowUVp3Y2FpZ0NBQ0lCUlFSQVFRQWhBQXdCQzBFQUlRQWdCVUVaSUFkQkFYWnJRUUFnQjBFZlJ4dDBJUUlEUUFKQUlBRW9BZ1JCZUhFZ0JXc2lCaUFEVHcwQUlBRWhCQ0FHSWdNTkFFRUFJUU1nQVNFQURBTUxJQUFnQVNnQ0ZDSUdJQVlnQVNBQ1FSMTJRUVJ4YWlnQ0VDSUJSaHNnQUNBR0d5RUFJQUpCQVhRaEFpQUJEUUFMQ3lBQUlBUnlSUVJBUVFBaEJFRUNJQWQwSWdCQkFDQUFhM0lnQ0hFaUFFVU5BeUFBYUVFQ2RFR2NIR29vQWdBaEFBc2dBRVVOQVFzRFFDQUFLQUlFUVhoeElBVnJJZ0lnQTBraEFTQUNJQU1nQVJzaEF5QUFJQVFnQVJzaEJDQUFLQUlRSWdFRWZ5QUJCU0FBS0FJVUN5SUFEUUFMQ3lBRVJRMEFJQU5COUJrb0FnQWdCV3RQRFFBZ0JDZ0NHQ0VISUFRZ0JDZ0NEQ0lDUndSQVFmd1pLQUlBR2lBRUtBSUlJZ0FnQWpZQ0RDQUNJQUEyQWdnTURBc2dCRUVVYWlJQktBSUFJZ0JGQkVBZ0JDZ0NFQ0lBUlEwRElBUkJFR29oQVFzRFFDQUJJUVlnQUNJQ1FSUnFJZ0VvQWdBaUFBMEFJQUpCRUdvaEFTQUNLQUlRSWdBTkFBc2dCa0VBTmdJQURBc0xJQVZCOUJrb0FnQWlCRTBFUUVHQUdpZ0NBQ0VBQWtBZ0JDQUZheUlCUVJCUEJFQWdBQ0FGYWlJQ0lBRkJBWEkyQWdRZ0FDQUVhaUFCTmdJQUlBQWdCVUVEY2pZQ0JBd0JDeUFBSUFSQkEzSTJBZ1FnQUNBRWFpSUJJQUVvQWdSQkFYSTJBZ1JCQUNFQ1FRQWhBUXRCOUJrZ0FUWUNBRUdBR2lBQ05nSUFJQUJCQ0dvaEFBd05DeUFGUWZnWktBSUFJZ0pKQkVCQitCa2dBaUFGYXlJQk5nSUFRWVFhUVlRYUtBSUFJZ0FnQldvaUFqWUNBQ0FDSUFGQkFYSTJBZ1FnQUNBRlFRTnlOZ0lFSUFCQkNHb2hBQXdOQzBFQUlRQWdCVUV2YWlJREFuOUJ4QjBvQWdBRVFFSE1IU2dDQUF3QkMwSFFIVUovTndJQVFjZ2RRb0NnZ0lDQWdBUTNBZ0JCeEIwZ0NrRU1ha0Z3Y1VIWXF0V3FCWE0yQWdCQjJCMUJBRFlDQUVHb0hVRUFOZ0lBUVlBZ0N5SUJhaUlHUVFBZ0FXc2lDSEVpQVNBRlRRME1RYVFkS0FJQUlnUUVRRUdjSFNnQ0FDSUhJQUZxSWdrZ0IwMGdCQ0FKU1hJTkRRc0NRRUdvSFMwQUFFRUVjVVVFUUFKQUFrQUNRQUpBUVlRYUtBSUFJZ1FFUUVHc0hTRUFBMEFnQkNBQUtBSUFJZ2RQQkVBZ0J5QUFLQUlFYWlBRVN3MERDeUFBS0FJSUlnQU5BQXNMUVFBUUN5SUNRWDlHRFFNZ0FTRUdRY2dkS0FJQUlnQkJBV3NpQkNBQ2NRUkFJQUVnQW1zZ0FpQUVha0VBSUFCcmNXb2hCZ3NnQlNBR1R3MERRYVFkS0FJQUlnQUVRRUdjSFNnQ0FDSUVJQVpxSWdnZ0JFMGdBQ0FJU1hJTkJBc2dCaEFMSWdBZ0FrY05BUXdGQ3lBR0lBSnJJQWh4SWdZUUN5SUNJQUFvQWdBZ0FDZ0NCR3BHRFFFZ0FpRUFDeUFBUVg5R0RRRWdCVUV3YWlBR1RRUkFJQUFoQWd3RUMwSE1IU2dDQUNJQ0lBTWdCbXRxUVFBZ0FtdHhJZ0lRQzBGL1JnMEJJQUlnQm1vaEJpQUFJUUlNQXdzZ0FrRi9SdzBDQzBHb0hVR29IU2dDQUVFRWNqWUNBQXNnQVJBTElnSkJmMFpCQUJBTElnQkJmMFp5SUFBZ0FrMXlEUVVnQUNBQ2F5SUdJQVZCS0dwTkRRVUxRWndkUVp3ZEtBSUFJQVpxSWdBMkFnQkJvQjBvQWdBZ0FFa0VRRUdnSFNBQU5nSUFDd0pBUVlRYUtBSUFJZ01FUUVHc0hTRUFBMEFnQWlBQUtBSUFJZ0VnQUNnQ0JDSUVha1lOQWlBQUtBSUlJZ0FOQUFzTUJBdEIvQmtvQWdBaUFFRUFJQUFnQWswYlJRUkFRZndaSUFJMkFnQUxRUUFoQUVHd0hTQUdOZ0lBUWF3ZElBSTJBZ0JCakJwQmZ6WUNBRUdRR2tIRUhTZ0NBRFlDQUVHNEhVRUFOZ0lBQTBBZ0FFRURkQ0lCUVp3YWFpQUJRWlFhYWlJRU5nSUFJQUZCb0JwcUlBUTJBZ0FnQUVFQmFpSUFRU0JIRFFBTFFmZ1pJQVpCS0dzaUFFRjRJQUpyUVFkeElnRnJJZ1EyQWdCQmhCb2dBU0FDYWlJQk5nSUFJQUVnQkVFQmNqWUNCQ0FBSUFKcVFTZzJBZ1JCaUJwQjFCMG9BZ0EyQWdBTUJBc2dBaUFEVFNBQklBTkxjZzBDSUFBb0FneEJDSEVOQWlBQUlBUWdCbW8yQWdSQmhCb2dBMEY0SUFOclFRZHhJZ0JxSWdFMkFnQkIrQmxCK0Jrb0FnQWdCbW9pQWlBQWF5SUFOZ0lBSUFFZ0FFRUJjallDQkNBQ0lBTnFRU2cyQWdSQmlCcEIxQjBvQWdBMkFnQU1Bd3RCQUNFRURBb0xRUUFoQWd3SUMwSDhHU2dDQUNBQ1N3UkFRZndaSUFJMkFnQUxJQUlnQm1vaEFVR3NIU0VBQWtBQ1FBSkFBMEFnQVNBQUtBSUFSd1JBSUFBb0FnZ2lBQTBCREFJTEN5QUFMUUFNUVFoeFJRMEJDMEdzSFNFQUEwQWdBeUFBS0FJQUlnRlBCRUFnQVNBQUtBSUVhaUlFSUFOTERRTUxJQUFvQWdnaEFBd0FDd0FMSUFBZ0FqWUNBQ0FBSUFBb0FnUWdCbW8yQWdRZ0FrRjRJQUpyUVFkeGFpSUhJQVZCQTNJMkFnUWdBVUY0SUFGclFRZHhhaUlHSUFVZ0Iyb2lCV3NoQUNBRElBWkdCRUJCaEJvZ0JUWUNBRUg0R1VINEdTZ0NBQ0FBYWlJQU5nSUFJQVVnQUVFQmNqWUNCQXdJQzBHQUdpZ0NBQ0FHUmdSQVFZQWFJQVUyQWdCQjlCbEI5QmtvQWdBZ0FHb2lBRFlDQUNBRklBQkJBWEkyQWdRZ0FDQUZhaUFBTmdJQURBZ0xJQVlvQWdRaUEwRURjVUVCUncwR0lBTkJlSEVoQ1NBRFFmOEJUUVJBSUFZb0Fnd2lBU0FHS0FJSUlnSkdCRUJCN0JsQjdCa29BZ0JCZmlBRFFRTjJkM0UyQWdBTUJ3c2dBaUFCTmdJTUlBRWdBallDQ0F3R0N5QUdLQUlZSVFnZ0JpQUdLQUlNSWdKSEJFQWdCaWdDQ0NJQklBSTJBZ3dnQWlBQk5nSUlEQVVMSUFaQkZHb2lBU2dDQUNJRFJRUkFJQVlvQWhBaUEwVU5CQ0FHUVJCcUlRRUxBMEFnQVNFRUlBTWlBa0VVYWlJQktBSUFJZ01OQUNBQ1FSQnFJUUVnQWlnQ0VDSUREUUFMSUFSQkFEWUNBQXdFQzBINEdTQUdRU2hySWdCQmVDQUNhMEVIY1NJQmF5SUlOZ0lBUVlRYUlBRWdBbW9pQVRZQ0FDQUJJQWhCQVhJMkFnUWdBQ0FDYWtFb05nSUVRWWdhUWRRZEtBSUFOZ0lBSUFNZ0JFRW5JQVJyUVFkeGFrRXZheUlBSUFBZ0EwRVFha2tiSWdGQkd6WUNCQ0FCUWJRZEtRSUFOd0lRSUFGQnJCMHBBZ0EzQWdoQnRCMGdBVUVJYWpZQ0FFR3dIU0FHTmdJQVFhd2RJQUkyQWdCQnVCMUJBRFlDQUNBQlFSaHFJUUFEUUNBQVFRYzJBZ1FnQUVFSWFpRU1JQUJCQkdvaEFDQU1JQVJKRFFBTElBRWdBMFlOQUNBQklBRW9BZ1JCZm5FMkFnUWdBeUFCSUFOcklnSkJBWEkyQWdRZ0FTQUNOZ0lBSUFKQi93Rk5CRUFnQWtGNGNVR1VHbW9oQUFKL1Fld1pLQUlBSWdGQkFTQUNRUU4yZENJQ2NVVUVRRUhzR1NBQklBSnlOZ0lBSUFBTUFRc2dBQ2dDQ0FzaEFTQUFJQU0yQWdnZ0FTQUROZ0lNSUFNZ0FEWUNEQ0FESUFFMkFnZ01BUXRCSHlFQUlBSkIvLy8vQjAwRVFDQUNRU1lnQWtFSWRtY2lBR3QyUVFGeElBQkJBWFJyUVQ1cUlRQUxJQU1nQURZQ0hDQURRZ0EzQWhBZ0FFRUNkRUdjSEdvaEFRSkFBa0JCOEJrb0FnQWlCRUVCSUFCMElnWnhSUVJBUWZBWklBUWdCbkkyQWdBZ0FTQUROZ0lBREFFTElBSkJHU0FBUVFGMmEwRUFJQUJCSDBjYmRDRUFJQUVvQWdBaEJBTkFJQVFpQVNnQ0JFRjRjU0FDUmcwQ0lBQkJIWFloQkNBQVFRRjBJUUFnQVNBRVFRUnhhaUlHS0FJUUlnUU5BQXNnQmlBRE5nSVFDeUFESUFFMkFoZ2dBeUFETmdJTUlBTWdBellDQ0F3QkN5QUJLQUlJSWdBZ0F6WUNEQ0FCSUFNMkFnZ2dBMEVBTmdJWUlBTWdBVFlDRENBRElBQTJBZ2dMUWZnWktBSUFJZ0FnQlUwTkFFSDRHU0FBSUFWcklnRTJBZ0JCaEJwQmhCb29BZ0FpQUNBRmFpSUNOZ0lBSUFJZ0FVRUJjallDQkNBQUlBVkJBM0kyQWdRZ0FFRUlhaUVBREFnTFFlZ1pRVEEyQWdCQkFDRUFEQWNMUVFBaEFnc2dDRVVOQUFKQUlBWW9BaHdpQVVFQ2RFR2NIR29pQkNnQ0FDQUdSZ1JBSUFRZ0FqWUNBQ0FDRFFGQjhCbEI4QmtvQWdCQmZpQUJkM0UyQWdBTUFnc2dDRUVRUVJRZ0NDZ0NFQ0FHUmh0cUlBSTJBZ0FnQWtVTkFRc2dBaUFJTmdJWUlBWW9BaEFpQVFSQUlBSWdBVFlDRUNBQklBSTJBaGdMSUFZb0FoUWlBVVVOQUNBQ0lBRTJBaFFnQVNBQ05nSVlDeUFBSUFscUlRQWdCaUFKYWlJR0tBSUVJUU1MSUFZZ0EwRitjVFlDQkNBRklBQkJBWEkyQWdRZ0FDQUZhaUFBTmdJQUlBQkIvd0ZOQkVBZ0FFRjRjVUdVR21vaEFRSi9RZXdaS0FJQUlnSkJBU0FBUVFOMmRDSUFjVVVFUUVIc0dTQUFJQUp5TmdJQUlBRU1BUXNnQVNnQ0NBc2hBQ0FCSUFVMkFnZ2dBQ0FGTmdJTUlBVWdBVFlDRENBRklBQTJBZ2dNQVF0Qkh5RURJQUJCLy8vL0IwMEVRQ0FBUVNZZ0FFRUlkbWNpQVd0MlFRRnhJQUZCQVhSclFUNXFJUU1MSUFVZ0F6WUNIQ0FGUWdBM0FoQWdBMEVDZEVHY0hHb2hBUUpBQWtCQjhCa29BZ0FpQWtFQklBTjBJZ1J4UlFSQVFmQVpJQUlnQkhJMkFnQWdBU0FGTmdJQURBRUxJQUJCR1NBRFFRRjJhMEVBSUFOQkgwY2JkQ0VESUFFb0FnQWhBZ05BSUFJaUFTZ0NCRUY0Y1NBQVJnMENJQU5CSFhZaEFpQURRUUYwSVFNZ0FTQUNRUVJ4YWlJRUtBSVFJZ0lOQUFzZ0JDQUZOZ0lRQ3lBRklBRTJBaGdnQlNBRk5nSU1JQVVnQlRZQ0NBd0JDeUFCS0FJSUlnQWdCVFlDRENBQklBVTJBZ2dnQlVFQU5nSVlJQVVnQVRZQ0RDQUZJQUEyQWdnTElBZEJDR29oQUF3Q0N3SkFJQWRGRFFBQ1FDQUVLQUljSWdCQkFuUkJuQnhxSWdFb0FnQWdCRVlFUUNBQklBSTJBZ0FnQWcwQlFmQVpJQWhCZmlBQWQzRWlDRFlDQUF3Q0N5QUhRUkJCRkNBSEtBSVFJQVJHRzJvZ0FqWUNBQ0FDUlEwQkN5QUNJQWMyQWhnZ0JDZ0NFQ0lBQkVBZ0FpQUFOZ0lRSUFBZ0FqWUNHQXNnQkNnQ0ZDSUFSUTBBSUFJZ0FEWUNGQ0FBSUFJMkFoZ0xBa0FnQTBFUFRRUkFJQVFnQXlBRmFpSUFRUU55TmdJRUlBQWdCR29pQUNBQUtBSUVRUUZ5TmdJRURBRUxJQVFnQlVFRGNqWUNCQ0FFSUFWcUlnSWdBMEVCY2pZQ0JDQUNJQU5xSUFNMkFnQWdBMEgvQVUwRVFDQURRWGh4UVpRYWFpRUFBbjlCN0Jrb0FnQWlBVUVCSUFOQkEzWjBJZ054UlFSQVFld1pJQUVnQTNJMkFnQWdBQXdCQ3lBQUtBSUlDeUVCSUFBZ0FqWUNDQ0FCSUFJMkFnd2dBaUFBTmdJTUlBSWdBVFlDQ0F3QkMwRWZJUUFnQTBILy8vOEhUUVJBSUFOQkppQURRUWgyWnlJQWEzWkJBWEVnQUVFQmRHdEJQbW9oQUFzZ0FpQUFOZ0ljSUFKQ0FEY0NFQ0FBUVFKMFFad2NhaUVCQWtBQ1FDQUlRUUVnQUhRaUJuRkZCRUJCOEJrZ0JpQUljallDQUNBQklBSTJBZ0FNQVFzZ0EwRVpJQUJCQVhaclFRQWdBRUVmUnh0MElRQWdBU2dDQUNFRkEwQWdCU0lCS0FJRVFYaHhJQU5HRFFJZ0FFRWRkaUVHSUFCQkFYUWhBQ0FCSUFaQkJIRnFJZ1lvQWhBaUJRMEFDeUFHSUFJMkFoQUxJQUlnQVRZQ0dDQUNJQUkyQWd3Z0FpQUNOZ0lJREFFTElBRW9BZ2dpQUNBQ05nSU1JQUVnQWpZQ0NDQUNRUUEyQWhnZ0FpQUJOZ0lNSUFJZ0FEWUNDQXNnQkVFSWFpRUFEQUVMQWtBZ0NVVU5BQUpBSUFJb0Fod2lBRUVDZEVHY0hHb2lBU2dDQUNBQ1JnUkFJQUVnQkRZQ0FDQUVEUUZCOEJrZ0MwRitJQUIzY1RZQ0FBd0NDeUFKUVJCQkZDQUpLQUlRSUFKR0cyb2dCRFlDQUNBRVJRMEJDeUFFSUFrMkFoZ2dBaWdDRUNJQUJFQWdCQ0FBTmdJUUlBQWdCRFlDR0FzZ0FpZ0NGQ0lBUlEwQUlBUWdBRFlDRkNBQUlBUTJBaGdMQWtBZ0EwRVBUUVJBSUFJZ0F5QUZhaUlBUVFOeU5nSUVJQUFnQW1vaUFDQUFLQUlFUVFGeU5nSUVEQUVMSUFJZ0JVRURjallDQkNBQ0lBVnFJZ1FnQTBFQmNqWUNCQ0FESUFScUlBTTJBZ0FnQndSQUlBZEJlSEZCbEJwcUlRQkJnQm9vQWdBaEFRSi9RUUVnQjBFRGRuUWlCU0FHY1VVRVFFSHNHU0FGSUFaeU5nSUFJQUFNQVFzZ0FDZ0NDQXNoQmlBQUlBRTJBZ2dnQmlBQk5nSU1JQUVnQURZQ0RDQUJJQVkyQWdnTFFZQWFJQVEyQWdCQjlCa2dBellDQUFzZ0FrRUlhaUVBQ3lBS1FSQnFKQUFnQUFzakFRRi9RZHdaS0FJQUlnQUVRQU5BSUFBb0FnQVJCUUFnQUNnQ0JDSUFEUUFMQ3dzYUFDQUFJQUVvQWdnZ0JSQUtCRUFnQVNBQ0lBTWdCQkFUQ3dzM0FDQUFJQUVvQWdnZ0JSQUtCRUFnQVNBQ0lBTWdCQkFURHdzZ0FDZ0NDQ0lBSUFFZ0FpQURJQVFnQlNBQUtBSUFLQUlVRVFNQUM1RUJBQ0FBSUFFb0FnZ2dCQkFLQkVBZ0FTQUNJQU1RRWc4TEFrQWdBQ0FCS0FJQUlBUVFDa1VOQUFKQUlBSWdBU2dDRUVjRVFDQUJLQUlVSUFKSERRRUxJQU5CQVVjTkFTQUJRUUUyQWlBUEN5QUJJQUkyQWhRZ0FTQUROZ0lnSUFFZ0FTZ0NLRUVCYWpZQ0tBSkFJQUVvQWlSQkFVY05BQ0FCS0FJWVFRSkhEUUFnQVVFQk9nQTJDeUFCUVFRMkFpd0xDL0lCQUNBQUlBRW9BZ2dnQkJBS0JFQWdBU0FDSUFNUUVnOExBa0FnQUNBQktBSUFJQVFRQ2dSQUFrQWdBaUFCS0FJUVJ3UkFJQUVvQWhRZ0FrY05BUXNnQTBFQlJ3MENJQUZCQVRZQ0lBOExJQUVnQXpZQ0lBSkFJQUVvQWl4QkJFWU5BQ0FCUVFBN0FUUWdBQ2dDQ0NJQUlBRWdBaUFDUVFFZ0JDQUFLQUlBS0FJVUVRTUFJQUV0QURVRVFDQUJRUU0yQWl3Z0FTMEFORVVOQVF3REN5QUJRUVEyQWl3TElBRWdBallDRkNBQklBRW9BaWhCQVdvMkFpZ2dBU2dDSkVFQlJ3MEJJQUVvQWhoQkFrY05BU0FCUVFFNkFEWVBDeUFBS0FJSUlnQWdBU0FDSUFNZ0JDQUFLQUlBS0FJWUVRSUFDd3N4QUNBQUlBRW9BZ2hCQUJBS0JFQWdBU0FDSUFNUUZBOExJQUFvQWdnaUFDQUJJQUlnQXlBQUtBSUFLQUljRVFBQUN4Z0FJQUFnQVNnQ0NFRUFFQW9FUUNBQklBSWdBeEFVQ3d2S0F3RUZmeU1BUVVCcUlnUWtBQUovUVFFZ0FDQUJRUUFRQ2cwQUdrRUFJQUZGRFFBYUl3QkJRR29pQXlRQUlBRW9BZ0FpQlVFRWF5Z0NBQ0VHSUFWQkNHc29BZ0FoQlNBRFFnQTNBaUFnQTBJQU53SW9JQU5DQURjQ01DQURRZ0EzQURjZ0EwSUFOd0lZSUFOQkFEWUNGQ0FEUWZ3Vk5nSVFJQU1nQVRZQ0RDQURRYXdXTmdJSUlBRWdCV29oQVVFQUlRVUNRQ0FHUWF3V1FRQVFDZ1JBSUFOQkFUWUNPQ0FHSUFOQkNHb2dBU0FCUVFGQkFDQUdLQUlBS0FJVUVRTUFJQUZCQUNBREtBSWdRUUZHR3lFRkRBRUxJQVlnQTBFSWFpQUJRUUZCQUNBR0tBSUFLQUlZRVFJQUFrQUNRQ0FES0FJc0RnSUFBUUlMSUFNb0FoeEJBQ0FES0FJb1FRRkdHMEVBSUFNb0FpUkJBVVliUVFBZ0F5Z0NNRUVCUmhzaEJRd0JDeUFES0FJZ1FRRkhCRUFnQXlnQ01BMEJJQU1vQWlSQkFVY05BU0FES0FJb1FRRkhEUUVMSUFNb0FoZ2hCUXNnQTBGQWF5UUFRUUFnQlNJQlJRMEFHaUFFUVF4cVFUUVFEeG9nQkVFQk5nSTRJQVJCZnpZQ0ZDQUVJQUEyQWhBZ0JDQUJOZ0lJSUFFZ0JFRUlhaUFDS0FJQVFRRWdBU2dDQUNnQ0hCRUFBQ0FFS0FJZ0lnQkJBVVlFUUNBQ0lBUW9BaGcyQWdBTElBQkJBVVlMSVFjZ0JFRkFheVFBSUFjTENnQWdBQ0FCUVFBUUNnc0VBQ0FBQy9vRUFnWi9DbjFCLy8vLy93Y2hERUdBZ0lDQWVDRU5RWDhoQ2dOQUlBTWdDMFlFUUVFQUlRa2dDRUdBZ0JBUUR5RUFRd0QvZjBjZ0RTQU1hN0tWSVJBRFFDQURJQWxHQkVCQkFDRUpJQWRCQURZQ0FDQUFRUVJySVFCQkFDRU1RUUVoQ3dOQUlBdEJnSUFFUmtVRVFDQUhJQXRCQW5RaUFXb2dBQ0FCYWlnQ0FDQU1haUlNTmdJQUlBdEJBV29oQ3d3QkN3c0RRQ0FESUFsR1JRUkFJQWNnQlNBSlFRSjBhaWdDQUVFQ2RHb2lBQ0FBS0FJQUlnQkJBV28yQWdBZ0JpQUFRUUowYWlBSk5nSUFJQWxCQVdvaENRd0JDd3NGQW44Z0VDQUZJQWxCQW5ScUlnRW9BZ0FnREd1emxDSVBRd0FBZ0U5ZElBOURBQUFBQUdCeEJFQWdENmtNQVF0QkFBc2hDeUFCSUFzMkFnQWdBQ0FMUVFKMGFpSUJJQUVvQWdCQkFXbzJBZ0FnQ1VFQmFpRUpEQUVMQ3dVZ0JDQUxRUXhzYWlJSktnSUFJUk1nQ1NvQ0NDRVVJQWtxQWdRaEZTQUtJQUlnQzBFQ2RDSU9haWdDQUNJSlJ3UkFJQUVnQ1VIUUFHeHFJZ29xQWp3Z0FDb0NPQ0lQbENBS0tnSTRJQUFxQWlnaUVKUWdDaW9DTUNBQUtnSUlJaEdVSUFBcUFoZ2lFaUFLS2dJMGxKS1NraUVXSUFvcUFpd2dENVFnQ2lvQ0tDQVFsQ0FLS2dJZ0lCR1VJQklnQ2lvQ0pKU1NrcEloRnlBS0tnSWNJQStVSUFvcUFoZ2dFSlFnQ2lvQ0VDQVJsQ0FTSUFvcUFoU1VrcEtTSVJnZ0Npb0NEQ0FQbENBS0tnSUlJQkNVSUFvcUFnQWdFWlFnQ2lvQ0JDQVNsSktTa2lFUElBa2hDZ3NnQlNBT2FnSi9JQllnRnlBVWxDQVBJQk9VSUJVZ0dKU1NrcEpEQUFDQVJaUWlFSXREQUFBQVQxMEVRQ0FRcUF3QkMwR0FnSUNBZUFzaUNUWUNBQ0FNSUFrZ0NTQU1TaHNoRENBTklBa2dDU0FOU0JzaERTQUxRUUZxSVFzTUFRc0xDd3ZuRVFJQVFZQUlDOVlSZFc1emFXZHVaV1FnYzJodmNuUUFkVzV6YVdkdVpXUWdhVzUwQUdac2IyRjBBSFZwYm5RMk5GOTBBSFZ1YzJsbmJtVmtJR05vWVhJQVltOXZiQUJsYlhOamNtbHdkR1Z1T2pwMllXd0FkVzV6YVdkdVpXUWdiRzl1WndCemRHUTZPbmR6ZEhKcGJtY0FjM1JrT2pwemRISnBibWNBYzNSa09qcDFNVFp6ZEhKcGJtY0FjM1JrT2pwMU16SnpkSEpwYm1jQVpHOTFZbXhsQUhadmFXUUFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGMyaHZjblErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQSFZ1YzJsbmJtVmtJSE5vYjNKMFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4cGJuUStBR1Z0YzJOeWFYQjBaVzQ2T20xbGJXOXllVjkyYVdWM1BIVnVjMmxuYm1Wa0lHbHVkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhabXh2WVhRK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEhWcGJuUTRYM1ErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQR2x1ZERoZmRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXbHVkREUyWDNRK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEdsdWRERTJYM1ErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQSFZwYm5RMk5GOTBQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eHBiblEyTkY5MFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4MWFXNTBNekpmZEQ0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4YVc1ME16SmZkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhZMmhoY2o0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4ZFc1emFXZHVaV1FnWTJoaGNqNEFjM1JrT2pwaVlYTnBZMTl6ZEhKcGJtYzhkVzV6YVdkdVpXUWdZMmhoY2o0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4YzJsbmJtVmtJR05vWVhJK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEd4dmJtYytBR1Z0YzJOeWFYQjBaVzQ2T20xbGJXOXllVjkyYVdWM1BIVnVjMmxuYm1Wa0lHeHZibWMrQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQR1J2ZFdKc1pUNEFUbE4wTTE5Zk1qRXlZbUZ6YVdOZmMzUnlhVzVuU1dOT1UxOHhNV05vWVhKZmRISmhhWFJ6U1dORlJVNVRYemxoYkd4dlkyRjBiM0pKWTBWRlJVVUFBQUFBUkF3QUFFSUhBQUJPVTNRelgxOHlNVEppWVhOcFkxOXpkSEpwYm1kSmFFNVRYekV4WTJoaGNsOTBjbUZwZEhOSmFFVkZUbE5mT1dGc2JHOWpZWFJ2Y2tsb1JVVkZSUUFBUkF3QUFJd0hBQUJPVTNRelgxOHlNVEppWVhOcFkxOXpkSEpwYm1kSmQwNVRYekV4WTJoaGNsOTBjbUZwZEhOSmQwVkZUbE5mT1dGc2JHOWpZWFJ2Y2tsM1JVVkZSUUFBUkF3QUFOUUhBQUJPVTNRelgxOHlNVEppWVhOcFkxOXpkSEpwYm1kSlJITk9VMTh4TVdOb1lYSmZkSEpoYVhSelNVUnpSVVZPVTE4NVlXeHNiMk5oZEc5eVNVUnpSVVZGUlFBQUFFUU1BQUFjQ0FBQVRsTjBNMTlmTWpFeVltRnphV05mYzNSeWFXNW5TVVJwVGxOZk1URmphR0Z5WDNSeVlXbDBjMGxFYVVWRlRsTmZPV0ZzYkc5allYUnZja2xFYVVWRlJVVUFBQUJFREFBQWFBZ0FBRTR4TUdWdGMyTnlhWEIwWlc0emRtRnNSUUFBUkF3QUFMUUlBQUJPTVRCbGJYTmpjbWx3ZEdWdU1URnRaVzF2Y25sZmRtbGxkMGxqUlVVQUFFUU1BQURRQ0FBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSllVVkZBQUJFREFBQStBZ0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTV2hGUlFBQVJBd0FBQ0FKQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBselJVVUFBRVFNQUFCSUNRQUFUakV3WlcxelkzSnBjSFJsYmpFeGJXVnRiM0o1WDNacFpYZEpkRVZGQUFCRURBQUFjQWtBQUU0eE1HVnRjMk55YVhCMFpXNHhNVzFsYlc5eWVWOTJhV1YzU1dsRlJRQUFSQXdBQUpnSkFBQk9NVEJsYlhOamNtbHdkR1Z1TVRGdFpXMXZjbmxmZG1sbGQwbHFSVVVBQUVRTUFBREFDUUFBVGpFd1pXMXpZM0pwY0hSbGJqRXhiV1Z0YjNKNVgzWnBaWGRKYkVWRkFBQkVEQUFBNkFrQUFFNHhNR1Z0YzJOeWFYQjBaVzR4TVcxbGJXOXllVjkyYVdWM1NXMUZSUUFBUkF3QUFCQUtBQUJPTVRCbGJYTmpjbWx3ZEdWdU1URnRaVzF2Y25sZmRtbGxkMGw0UlVVQUFFUU1BQUE0Q2dBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSmVVVkZBQUJFREFBQVlBb0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTV1pGUlFBQVJBd0FBSWdLQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBsa1JVVUFBRVFNQUFDd0NnQUFUakV3WDE5amVIaGhZbWwyTVRFMlgxOXphR2x0WDNSNWNHVmZhVzVtYjBVQUFBQUFiQXdBQU5nS0FBRFFEQUFBVGpFd1gxOWplSGhoWW1sMk1URTNYMTlqYkdGemMxOTBlWEJsWDJsdVptOUZBQUFBYkF3QUFBZ0xBQUQ4Q2dBQUFBQUFBSHdMQUFBQ0FBQUFBd0FBQUFRQUFBQUZBQUFBQmdBQUFFNHhNRjlmWTNoNFlXSnBkakV5TTE5ZlpuVnVaR0Z0Wlc1MFlXeGZkSGx3WlY5cGJtWnZSUUJzREFBQVZBc0FBUHdLQUFCMkFBQUFRQXNBQUlnTEFBQmlBQUFBUUFzQUFKUUxBQUJqQUFBQVFBc0FBS0FMQUFCb0FBQUFRQXNBQUt3TEFBQmhBQUFBUUFzQUFMZ0xBQUJ6QUFBQVFBc0FBTVFMQUFCMEFBQUFRQXNBQU5BTEFBQnBBQUFBUUFzQUFOd0xBQUJxQUFBQVFBc0FBT2dMQUFCc0FBQUFRQXNBQVBRTEFBQnRBQUFBUUFzQUFBQU1BQUI0QUFBQVFBc0FBQXdNQUFCNUFBQUFRQXNBQUJnTUFBQm1BQUFBUUFzQUFDUU1BQUJrQUFBQVFBc0FBREFNQUFBQUFBQUFMQXNBQUFJQUFBQUhBQUFBQkFBQUFBVUFBQUFJQUFBQUNRQUFBQW9BQUFBTEFBQUFBQUFBQUxRTUFBQUNBQUFBREFBQUFBUUFBQUFGQUFBQUNBQUFBQTBBQUFBT0FBQUFEd0FBQUU0eE1GOWZZM2g0WVdKcGRqRXlNRjlmYzJsZlkyeGhjM05mZEhsd1pWOXBibVp2UlFBQUFBQnNEQUFBakF3QUFDd0xBQUJUZERsMGVYQmxYMmx1Wm04QUFBQUFSQXdBQU1BTUFFSFlHUXNENEE0QiI7aWYoIWlzRGF0YVVSSSh3YXNtQmluYXJ5RmlsZSkpe3dhc21CaW5hcnlGaWxlPWxvY2F0ZUZpbGUod2FzbUJpbmFyeUZpbGUpO31mdW5jdGlvbiBnZXRCaW5hcnlTeW5jKGZpbGUpe2lmKGZpbGU9PXdhc21CaW5hcnlGaWxlJiZ3YXNtQmluYXJ5KXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkod2FzbUJpbmFyeSl9dmFyIGJpbmFyeT10cnlQYXJzZUFzRGF0YVVSSShmaWxlKTtpZihiaW5hcnkpe3JldHVybiBiaW5hcnl9aWYocmVhZEJpbmFyeSl7cmV0dXJuIHJlYWRCaW5hcnkoZmlsZSl9dGhyb3cgImJvdGggYXN5bmMgYW5kIHN5bmMgZmV0Y2hpbmcgb2YgdGhlIHdhc20gZmFpbGVkIn1mdW5jdGlvbiBnZXRCaW5hcnlQcm9taXNlKGJpbmFyeUZpbGUpe3JldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpPT5nZXRCaW5hcnlTeW5jKGJpbmFyeUZpbGUpKX1mdW5jdGlvbiBpbnN0YW50aWF0ZUFycmF5QnVmZmVyKGJpbmFyeUZpbGUsaW1wb3J0cyxyZWNlaXZlcil7cmV0dXJuIGdldEJpbmFyeVByb21pc2UoYmluYXJ5RmlsZSkudGhlbihiaW5hcnk9PldlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGJpbmFyeSxpbXBvcnRzKSkudGhlbihpbnN0YW5jZT0+aW5zdGFuY2UpLnRoZW4ocmVjZWl2ZXIscmVhc29uPT57ZXJyKGBmYWlsZWQgdG8gYXN5bmNocm9ub3VzbHkgcHJlcGFyZSB3YXNtOiAke3JlYXNvbn1gKTthYm9ydChyZWFzb24pO30pfWZ1bmN0aW9uIGluc3RhbnRpYXRlQXN5bmMoYmluYXJ5LGJpbmFyeUZpbGUsaW1wb3J0cyxjYWxsYmFjayl7cmV0dXJuIGluc3RhbnRpYXRlQXJyYXlCdWZmZXIoYmluYXJ5RmlsZSxpbXBvcnRzLGNhbGxiYWNrKX1mdW5jdGlvbiBjcmVhdGVXYXNtKCl7dmFyIGluZm89eyJhIjp3YXNtSW1wb3J0c307ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbmNlKGluc3RhbmNlLG1vZHVsZSl7d2FzbUV4cG9ydHM9aW5zdGFuY2UuZXhwb3J0czt3YXNtTWVtb3J5PXdhc21FeHBvcnRzWyJrIl07dXBkYXRlTWVtb3J5Vmlld3MoKTthZGRPbkluaXQod2FzbUV4cG9ydHNbImwiXSk7cmVtb3ZlUnVuRGVwZW5kZW5jeSgpO3JldHVybiB3YXNtRXhwb3J0c31hZGRSdW5EZXBlbmRlbmN5KCk7ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbnRpYXRpb25SZXN1bHQocmVzdWx0KXtyZWNlaXZlSW5zdGFuY2UocmVzdWx0WyJpbnN0YW5jZSJdKTt9aWYoTW9kdWxlWyJpbnN0YW50aWF0ZVdhc20iXSl7dHJ5e3JldHVybiBNb2R1bGVbImluc3RhbnRpYXRlV2FzbSJdKGluZm8scmVjZWl2ZUluc3RhbmNlKX1jYXRjaChlKXtlcnIoYE1vZHVsZS5pbnN0YW50aWF0ZVdhc20gY2FsbGJhY2sgZmFpbGVkIHdpdGggZXJyb3I6ICR7ZX1gKTtyZWFkeVByb21pc2VSZWplY3QoZSk7fX1pbnN0YW50aWF0ZUFzeW5jKHdhc21CaW5hcnksd2FzbUJpbmFyeUZpbGUsaW5mbyxyZWNlaXZlSW5zdGFudGlhdGlvblJlc3VsdCkuY2F0Y2gocmVhZHlQcm9taXNlUmVqZWN0KTtyZXR1cm4ge319dmFyIGNhbGxSdW50aW1lQ2FsbGJhY2tzPWNhbGxiYWNrcz0+e3doaWxlKGNhbGxiYWNrcy5sZW5ndGg+MCl7Y2FsbGJhY2tzLnNoaWZ0KCkoTW9kdWxlKTt9fTtNb2R1bGVbIm5vRXhpdFJ1bnRpbWUiXXx8dHJ1ZTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfYmlnaW50PShwcmltaXRpdmVUeXBlLG5hbWUsc2l6ZSxtaW5SYW5nZSxtYXhSYW5nZSk9Pnt9O3ZhciBlbWJpbmRfaW5pdF9jaGFyQ29kZXM9KCk9Pnt2YXIgY29kZXM9bmV3IEFycmF5KDI1Nik7Zm9yKHZhciBpPTA7aTwyNTY7KytpKXtjb2Rlc1tpXT1TdHJpbmcuZnJvbUNoYXJDb2RlKGkpO31lbWJpbmRfY2hhckNvZGVzPWNvZGVzO307dmFyIGVtYmluZF9jaGFyQ29kZXM7dmFyIHJlYWRMYXRpbjFTdHJpbmc9cHRyPT57dmFyIHJldD0iIjt2YXIgYz1wdHI7d2hpbGUoSEVBUFU4W2NdKXtyZXQrPWVtYmluZF9jaGFyQ29kZXNbSEVBUFU4W2MrK11dO31yZXR1cm4gcmV0fTt2YXIgYXdhaXRpbmdEZXBlbmRlbmNpZXM9e307dmFyIHJlZ2lzdGVyZWRUeXBlcz17fTt2YXIgQmluZGluZ0Vycm9yO3ZhciB0aHJvd0JpbmRpbmdFcnJvcj1tZXNzYWdlPT57dGhyb3cgbmV3IEJpbmRpbmdFcnJvcihtZXNzYWdlKX07ZnVuY3Rpb24gc2hhcmVkUmVnaXN0ZXJUeXBlKHJhd1R5cGUscmVnaXN0ZXJlZEluc3RhbmNlLG9wdGlvbnM9e30pe3ZhciBuYW1lPXJlZ2lzdGVyZWRJbnN0YW5jZS5uYW1lO2lmKCFyYXdUeXBlKXt0aHJvd0JpbmRpbmdFcnJvcihgdHlwZSAiJHtuYW1lfSIgbXVzdCBoYXZlIGEgcG9zaXRpdmUgaW50ZWdlciB0eXBlaWQgcG9pbnRlcmApO31pZihyZWdpc3RlcmVkVHlwZXMuaGFzT3duUHJvcGVydHkocmF3VHlwZSkpe2lmKG9wdGlvbnMuaWdub3JlRHVwbGljYXRlUmVnaXN0cmF0aW9ucyl7cmV0dXJufWVsc2Uge3Rocm93QmluZGluZ0Vycm9yKGBDYW5ub3QgcmVnaXN0ZXIgdHlwZSAnJHtuYW1lfScgdHdpY2VgKTt9fXJlZ2lzdGVyZWRUeXBlc1tyYXdUeXBlXT1yZWdpc3RlcmVkSW5zdGFuY2U7aWYoYXdhaXRpbmdEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocmF3VHlwZSkpe3ZhciBjYWxsYmFja3M9YXdhaXRpbmdEZXBlbmRlbmNpZXNbcmF3VHlwZV07ZGVsZXRlIGF3YWl0aW5nRGVwZW5kZW5jaWVzW3Jhd1R5cGVdO2NhbGxiYWNrcy5mb3JFYWNoKGNiPT5jYigpKTt9fWZ1bmN0aW9uIHJlZ2lzdGVyVHlwZShyYXdUeXBlLHJlZ2lzdGVyZWRJbnN0YW5jZSxvcHRpb25zPXt9KXtpZighKCJhcmdQYWNrQWR2YW5jZSJpbiByZWdpc3RlcmVkSW5zdGFuY2UpKXt0aHJvdyBuZXcgVHlwZUVycm9yKCJyZWdpc3RlclR5cGUgcmVnaXN0ZXJlZEluc3RhbmNlIHJlcXVpcmVzIGFyZ1BhY2tBZHZhbmNlIil9cmV0dXJuIHNoYXJlZFJlZ2lzdGVyVHlwZShyYXdUeXBlLHJlZ2lzdGVyZWRJbnN0YW5jZSxvcHRpb25zKX12YXIgR2VuZXJpY1dpcmVUeXBlU2l6ZT04O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9ib29sPShyYXdUeXBlLG5hbWUsdHJ1ZVZhbHVlLGZhbHNlVmFsdWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lOm5hbWUsImZyb21XaXJlVHlwZSI6ZnVuY3Rpb24od3Qpe3JldHVybiAhIXd0fSwidG9XaXJlVHlwZSI6ZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsbyl7cmV0dXJuIG8/dHJ1ZVZhbHVlOmZhbHNlVmFsdWV9LCJhcmdQYWNrQWR2YW5jZSI6R2VuZXJpY1dpcmVUeXBlU2l6ZSwicmVhZFZhbHVlRnJvbVBvaW50ZXIiOmZ1bmN0aW9uKHBvaW50ZXIpe3JldHVybiB0aGlzWyJmcm9tV2lyZVR5cGUiXShIRUFQVThbcG9pbnRlcl0pfSxkZXN0cnVjdG9yRnVuY3Rpb246bnVsbH0pO307ZnVuY3Rpb24gaGFuZGxlQWxsb2NhdG9ySW5pdCgpe09iamVjdC5hc3NpZ24oSGFuZGxlQWxsb2NhdG9yLnByb3RvdHlwZSx7Z2V0KGlkKXtyZXR1cm4gdGhpcy5hbGxvY2F0ZWRbaWRdfSxoYXMoaWQpe3JldHVybiB0aGlzLmFsbG9jYXRlZFtpZF0hPT11bmRlZmluZWR9LGFsbG9jYXRlKGhhbmRsZSl7dmFyIGlkPXRoaXMuZnJlZWxpc3QucG9wKCl8fHRoaXMuYWxsb2NhdGVkLmxlbmd0aDt0aGlzLmFsbG9jYXRlZFtpZF09aGFuZGxlO3JldHVybiBpZH0sZnJlZShpZCl7dGhpcy5hbGxvY2F0ZWRbaWRdPXVuZGVmaW5lZDt0aGlzLmZyZWVsaXN0LnB1c2goaWQpO319KTt9ZnVuY3Rpb24gSGFuZGxlQWxsb2NhdG9yKCl7dGhpcy5hbGxvY2F0ZWQ9W3VuZGVmaW5lZF07dGhpcy5mcmVlbGlzdD1bXTt9dmFyIGVtdmFsX2hhbmRsZXM9bmV3IEhhbmRsZUFsbG9jYXRvcjt2YXIgX19lbXZhbF9kZWNyZWY9aGFuZGxlPT57aWYoaGFuZGxlPj1lbXZhbF9oYW5kbGVzLnJlc2VydmVkJiYwPT09LS1lbXZhbF9oYW5kbGVzLmdldChoYW5kbGUpLnJlZmNvdW50KXtlbXZhbF9oYW5kbGVzLmZyZWUoaGFuZGxlKTt9fTt2YXIgY291bnRfZW12YWxfaGFuZGxlcz0oKT0+e3ZhciBjb3VudD0wO2Zvcih2YXIgaT1lbXZhbF9oYW5kbGVzLnJlc2VydmVkO2k8ZW12YWxfaGFuZGxlcy5hbGxvY2F0ZWQubGVuZ3RoOysraSl7aWYoZW12YWxfaGFuZGxlcy5hbGxvY2F0ZWRbaV0hPT11bmRlZmluZWQpeysrY291bnQ7fX1yZXR1cm4gY291bnR9O3ZhciBpbml0X2VtdmFsPSgpPT57ZW12YWxfaGFuZGxlcy5hbGxvY2F0ZWQucHVzaCh7dmFsdWU6dW5kZWZpbmVkfSx7dmFsdWU6bnVsbH0se3ZhbHVlOnRydWV9LHt2YWx1ZTpmYWxzZX0pO2VtdmFsX2hhbmRsZXMucmVzZXJ2ZWQ9ZW12YWxfaGFuZGxlcy5hbGxvY2F0ZWQubGVuZ3RoO01vZHVsZVsiY291bnRfZW12YWxfaGFuZGxlcyJdPWNvdW50X2VtdmFsX2hhbmRsZXM7fTt2YXIgRW12YWw9e3RvVmFsdWU6aGFuZGxlPT57aWYoIWhhbmRsZSl7dGhyb3dCaW5kaW5nRXJyb3IoIkNhbm5vdCB1c2UgZGVsZXRlZCB2YWwuIGhhbmRsZSA9ICIraGFuZGxlKTt9cmV0dXJuIGVtdmFsX2hhbmRsZXMuZ2V0KGhhbmRsZSkudmFsdWV9LHRvSGFuZGxlOnZhbHVlPT57c3dpdGNoKHZhbHVlKXtjYXNlIHVuZGVmaW5lZDpyZXR1cm4gMTtjYXNlIG51bGw6cmV0dXJuIDI7Y2FzZSB0cnVlOnJldHVybiAzO2Nhc2UgZmFsc2U6cmV0dXJuIDQ7ZGVmYXVsdDp7cmV0dXJuIGVtdmFsX2hhbmRsZXMuYWxsb2NhdGUoe3JlZmNvdW50OjEsdmFsdWU6dmFsdWV9KX19fX07ZnVuY3Rpb24gc2ltcGxlUmVhZFZhbHVlRnJvbVBvaW50ZXIocG9pbnRlcil7cmV0dXJuIHRoaXNbImZyb21XaXJlVHlwZSJdKEhFQVAzMltwb2ludGVyPj4yXSl9dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX2VtdmFsPShyYXdUeXBlLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lOm5hbWUsImZyb21XaXJlVHlwZSI6aGFuZGxlPT57dmFyIHJ2PUVtdmFsLnRvVmFsdWUoaGFuZGxlKTtfX2VtdmFsX2RlY3JlZihoYW5kbGUpO3JldHVybiBydn0sInRvV2lyZVR5cGUiOihkZXN0cnVjdG9ycyx2YWx1ZSk9PkVtdmFsLnRvSGFuZGxlKHZhbHVlKSwiYXJnUGFja0FkdmFuY2UiOkdlbmVyaWNXaXJlVHlwZVNpemUsInJlYWRWYWx1ZUZyb21Qb2ludGVyIjpzaW1wbGVSZWFkVmFsdWVGcm9tUG9pbnRlcixkZXN0cnVjdG9yRnVuY3Rpb246bnVsbH0pO307dmFyIGZsb2F0UmVhZFZhbHVlRnJvbVBvaW50ZXI9KG5hbWUsd2lkdGgpPT57c3dpdGNoKHdpZHRoKXtjYXNlIDQ6cmV0dXJuIGZ1bmN0aW9uKHBvaW50ZXIpe3JldHVybiB0aGlzWyJmcm9tV2lyZVR5cGUiXShIRUFQRjMyW3BvaW50ZXI+PjJdKX07Y2FzZSA4OnJldHVybiBmdW5jdGlvbihwb2ludGVyKXtyZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUEY2NFtwb2ludGVyPj4zXSl9O2RlZmF1bHQ6dGhyb3cgbmV3IFR5cGVFcnJvcihgaW52YWxpZCBmbG9hdCB3aWR0aCAoJHt3aWR0aH0pOiAke25hbWV9YCl9fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfZmxvYXQ9KHJhd1R5cGUsbmFtZSxzaXplKT0+e25hbWU9cmVhZExhdGluMVN0cmluZyhuYW1lKTtyZWdpc3RlclR5cGUocmF3VHlwZSx7bmFtZTpuYW1lLCJmcm9tV2lyZVR5cGUiOnZhbHVlPT52YWx1ZSwidG9XaXJlVHlwZSI6KGRlc3RydWN0b3JzLHZhbHVlKT0+dmFsdWUsImFyZ1BhY2tBZHZhbmNlIjpHZW5lcmljV2lyZVR5cGVTaXplLCJyZWFkVmFsdWVGcm9tUG9pbnRlciI6ZmxvYXRSZWFkVmFsdWVGcm9tUG9pbnRlcihuYW1lLHNpemUpLGRlc3RydWN0b3JGdW5jdGlvbjpudWxsfSk7fTt2YXIgaW50ZWdlclJlYWRWYWx1ZUZyb21Qb2ludGVyPShuYW1lLHdpZHRoLHNpZ25lZCk9Pntzd2l0Y2god2lkdGgpe2Nhc2UgMTpyZXR1cm4gc2lnbmVkP3BvaW50ZXI9PkhFQVA4W3BvaW50ZXI+PjBdOnBvaW50ZXI9PkhFQVBVOFtwb2ludGVyPj4wXTtjYXNlIDI6cmV0dXJuIHNpZ25lZD9wb2ludGVyPT5IRUFQMTZbcG9pbnRlcj4+MV06cG9pbnRlcj0+SEVBUFUxNltwb2ludGVyPj4xXTtjYXNlIDQ6cmV0dXJuIHNpZ25lZD9wb2ludGVyPT5IRUFQMzJbcG9pbnRlcj4+Ml06cG9pbnRlcj0+SEVBUFUzMltwb2ludGVyPj4yXTtkZWZhdWx0OnRocm93IG5ldyBUeXBlRXJyb3IoYGludmFsaWQgaW50ZWdlciB3aWR0aCAoJHt3aWR0aH0pOiAke25hbWV9YCl9fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfaW50ZWdlcj0ocHJpbWl0aXZlVHlwZSxuYW1lLHNpemUsbWluUmFuZ2UsbWF4UmFuZ2UpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3ZhciBmcm9tV2lyZVR5cGU9dmFsdWU9PnZhbHVlO2lmKG1pblJhbmdlPT09MCl7dmFyIGJpdHNoaWZ0PTMyLTgqc2l6ZTtmcm9tV2lyZVR5cGU9dmFsdWU9PnZhbHVlPDxiaXRzaGlmdD4+PmJpdHNoaWZ0O312YXIgaXNVbnNpZ25lZFR5cGU9bmFtZS5pbmNsdWRlcygidW5zaWduZWQiKTt2YXIgY2hlY2tBc3NlcnRpb25zPSh2YWx1ZSx0b1R5cGVOYW1lKT0+e307dmFyIHRvV2lyZVR5cGU7aWYoaXNVbnNpZ25lZFR5cGUpe3RvV2lyZVR5cGU9ZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsdmFsdWUpe2NoZWNrQXNzZXJ0aW9ucyh2YWx1ZSx0aGlzLm5hbWUpO3JldHVybiB2YWx1ZT4+PjB9O31lbHNlIHt0b1dpcmVUeXBlPWZ1bmN0aW9uKGRlc3RydWN0b3JzLHZhbHVlKXtjaGVja0Fzc2VydGlvbnModmFsdWUsdGhpcy5uYW1lKTtyZXR1cm4gdmFsdWV9O31yZWdpc3RlclR5cGUocHJpbWl0aXZlVHlwZSx7bmFtZTpuYW1lLCJmcm9tV2lyZVR5cGUiOmZyb21XaXJlVHlwZSwidG9XaXJlVHlwZSI6dG9XaXJlVHlwZSwiYXJnUGFja0FkdmFuY2UiOkdlbmVyaWNXaXJlVHlwZVNpemUsInJlYWRWYWx1ZUZyb21Qb2ludGVyIjppbnRlZ2VyUmVhZFZhbHVlRnJvbVBvaW50ZXIobmFtZSxzaXplLG1pblJhbmdlIT09MCksZGVzdHJ1Y3RvckZ1bmN0aW9uOm51bGx9KTt9O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9tZW1vcnlfdmlldz0ocmF3VHlwZSxkYXRhVHlwZUluZGV4LG5hbWUpPT57dmFyIHR5cGVNYXBwaW5nPVtJbnQ4QXJyYXksVWludDhBcnJheSxJbnQxNkFycmF5LFVpbnQxNkFycmF5LEludDMyQXJyYXksVWludDMyQXJyYXksRmxvYXQzMkFycmF5LEZsb2F0NjRBcnJheV07dmFyIFRBPXR5cGVNYXBwaW5nW2RhdGFUeXBlSW5kZXhdO2Z1bmN0aW9uIGRlY29kZU1lbW9yeVZpZXcoaGFuZGxlKXt2YXIgc2l6ZT1IRUFQVTMyW2hhbmRsZT4+Ml07dmFyIGRhdGE9SEVBUFUzMltoYW5kbGUrND4+Ml07cmV0dXJuIG5ldyBUQShIRUFQOC5idWZmZXIsZGF0YSxzaXplKX1uYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7cmVnaXN0ZXJUeXBlKHJhd1R5cGUse25hbWU6bmFtZSwiZnJvbVdpcmVUeXBlIjpkZWNvZGVNZW1vcnlWaWV3LCJhcmdQYWNrQWR2YW5jZSI6R2VuZXJpY1dpcmVUeXBlU2l6ZSwicmVhZFZhbHVlRnJvbVBvaW50ZXIiOmRlY29kZU1lbW9yeVZpZXd9LHtpZ25vcmVEdXBsaWNhdGVSZWdpc3RyYXRpb25zOnRydWV9KTt9O2Z1bmN0aW9uIHJlYWRQb2ludGVyKHBvaW50ZXIpe3JldHVybiB0aGlzWyJmcm9tV2lyZVR5cGUiXShIRUFQVTMyW3BvaW50ZXI+PjJdKX12YXIgc3RyaW5nVG9VVEY4QXJyYXk9KHN0cixoZWFwLG91dElkeCxtYXhCeXRlc1RvV3JpdGUpPT57aWYoIShtYXhCeXRlc1RvV3JpdGU+MCkpcmV0dXJuIDA7dmFyIHN0YXJ0SWR4PW91dElkeDt2YXIgZW5kSWR4PW91dElkeCttYXhCeXRlc1RvV3JpdGUtMTtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXt2YXIgdT1zdHIuY2hhckNvZGVBdChpKTtpZih1Pj01NTI5NiYmdTw9NTczNDMpe3ZhciB1MT1zdHIuY2hhckNvZGVBdCgrK2kpO3U9NjU1MzYrKCh1JjEwMjMpPDwxMCl8dTEmMTAyMzt9aWYodTw9MTI3KXtpZihvdXRJZHg+PWVuZElkeClicmVhaztoZWFwW291dElkeCsrXT11O31lbHNlIGlmKHU8PTIwNDcpe2lmKG91dElkeCsxPj1lbmRJZHgpYnJlYWs7aGVhcFtvdXRJZHgrK109MTkyfHU+PjY7aGVhcFtvdXRJZHgrK109MTI4fHUmNjM7fWVsc2UgaWYodTw9NjU1MzUpe2lmKG91dElkeCsyPj1lbmRJZHgpYnJlYWs7aGVhcFtvdXRJZHgrK109MjI0fHU+PjEyO2hlYXBbb3V0SWR4KytdPTEyOHx1Pj42JjYzO2hlYXBbb3V0SWR4KytdPTEyOHx1JjYzO31lbHNlIHtpZihvdXRJZHgrMz49ZW5kSWR4KWJyZWFrO2hlYXBbb3V0SWR4KytdPTI0MHx1Pj4xODtoZWFwW291dElkeCsrXT0xMjh8dT4+MTImNjM7aGVhcFtvdXRJZHgrK109MTI4fHU+PjYmNjM7aGVhcFtvdXRJZHgrK109MTI4fHUmNjM7fX1oZWFwW291dElkeF09MDtyZXR1cm4gb3V0SWR4LXN0YXJ0SWR4fTt2YXIgc3RyaW5nVG9VVEY4PShzdHIsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk9PnN0cmluZ1RvVVRGOEFycmF5KHN0cixIRUFQVTgsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk7dmFyIGxlbmd0aEJ5dGVzVVRGOD1zdHI9Pnt2YXIgbGVuPTA7Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7dmFyIGM9c3RyLmNoYXJDb2RlQXQoaSk7aWYoYzw9MTI3KXtsZW4rKzt9ZWxzZSBpZihjPD0yMDQ3KXtsZW4rPTI7fWVsc2UgaWYoYz49NTUyOTYmJmM8PTU3MzQzKXtsZW4rPTQ7KytpO31lbHNlIHtsZW4rPTM7fX1yZXR1cm4gbGVufTt2YXIgVVRGOERlY29kZXI9dHlwZW9mIFRleHREZWNvZGVyIT0idW5kZWZpbmVkIj9uZXcgVGV4dERlY29kZXIoInV0ZjgiKTp1bmRlZmluZWQ7dmFyIFVURjhBcnJheVRvU3RyaW5nPShoZWFwT3JBcnJheSxpZHgsbWF4Qnl0ZXNUb1JlYWQpPT57dmFyIGVuZElkeD1pZHgrbWF4Qnl0ZXNUb1JlYWQ7dmFyIGVuZFB0cj1pZHg7d2hpbGUoaGVhcE9yQXJyYXlbZW5kUHRyXSYmIShlbmRQdHI+PWVuZElkeCkpKytlbmRQdHI7aWYoZW5kUHRyLWlkeD4xNiYmaGVhcE9yQXJyYXkuYnVmZmVyJiZVVEY4RGVjb2Rlcil7cmV0dXJuIFVURjhEZWNvZGVyLmRlY29kZShoZWFwT3JBcnJheS5zdWJhcnJheShpZHgsZW5kUHRyKSl9dmFyIHN0cj0iIjt3aGlsZShpZHg8ZW5kUHRyKXt2YXIgdTA9aGVhcE9yQXJyYXlbaWR4KytdO2lmKCEodTAmMTI4KSl7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHUwKTtjb250aW51ZX12YXIgdTE9aGVhcE9yQXJyYXlbaWR4KytdJjYzO2lmKCh1MCYyMjQpPT0xOTIpe3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSgodTAmMzEpPDw2fHUxKTtjb250aW51ZX12YXIgdTI9aGVhcE9yQXJyYXlbaWR4KytdJjYzO2lmKCh1MCYyNDApPT0yMjQpe3UwPSh1MCYxNSk8PDEyfHUxPDw2fHUyO31lbHNlIHt1MD0odTAmNyk8PDE4fHUxPDwxMnx1Mjw8NnxoZWFwT3JBcnJheVtpZHgrK10mNjM7fWlmKHUwPDY1NTM2KXtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUodTApO31lbHNlIHt2YXIgY2g9dTAtNjU1MzY7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fGNoPj4xMCw1NjMyMHxjaCYxMDIzKTt9fXJldHVybiBzdHJ9O3ZhciBVVEY4VG9TdHJpbmc9KHB0cixtYXhCeXRlc1RvUmVhZCk9PnB0cj9VVEY4QXJyYXlUb1N0cmluZyhIRUFQVTgscHRyLG1heEJ5dGVzVG9SZWFkKToiIjt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfc3RkX3N0cmluZz0ocmF3VHlwZSxuYW1lKT0+e25hbWU9cmVhZExhdGluMVN0cmluZyhuYW1lKTt2YXIgc3RkU3RyaW5nSXNVVEY4PW5hbWU9PT0ic3RkOjpzdHJpbmciO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lOm5hbWUsImZyb21XaXJlVHlwZSIodmFsdWUpe3ZhciBsZW5ndGg9SEVBUFUzMlt2YWx1ZT4+Ml07dmFyIHBheWxvYWQ9dmFsdWUrNDt2YXIgc3RyO2lmKHN0ZFN0cmluZ0lzVVRGOCl7dmFyIGRlY29kZVN0YXJ0UHRyPXBheWxvYWQ7Zm9yKHZhciBpPTA7aTw9bGVuZ3RoOysraSl7dmFyIGN1cnJlbnRCeXRlUHRyPXBheWxvYWQraTtpZihpPT1sZW5ndGh8fEhFQVBVOFtjdXJyZW50Qnl0ZVB0cl09PTApe3ZhciBtYXhSZWFkPWN1cnJlbnRCeXRlUHRyLWRlY29kZVN0YXJ0UHRyO3ZhciBzdHJpbmdTZWdtZW50PVVURjhUb1N0cmluZyhkZWNvZGVTdGFydFB0cixtYXhSZWFkKTtpZihzdHI9PT11bmRlZmluZWQpe3N0cj1zdHJpbmdTZWdtZW50O31lbHNlIHtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUoMCk7c3RyKz1zdHJpbmdTZWdtZW50O31kZWNvZGVTdGFydFB0cj1jdXJyZW50Qnl0ZVB0cisxO319fWVsc2Uge3ZhciBhPW5ldyBBcnJheShsZW5ndGgpO2Zvcih2YXIgaT0wO2k8bGVuZ3RoOysraSl7YVtpXT1TdHJpbmcuZnJvbUNoYXJDb2RlKEhFQVBVOFtwYXlsb2FkK2ldKTt9c3RyPWEuam9pbigiIik7fV9mcmVlKHZhbHVlKTtyZXR1cm4gc3RyfSwidG9XaXJlVHlwZSIoZGVzdHJ1Y3RvcnMsdmFsdWUpe2lmKHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpe3ZhbHVlPW5ldyBVaW50OEFycmF5KHZhbHVlKTt9dmFyIGxlbmd0aDt2YXIgdmFsdWVJc09mVHlwZVN0cmluZz10eXBlb2YgdmFsdWU9PSJzdHJpbmciO2lmKCEodmFsdWVJc09mVHlwZVN0cmluZ3x8dmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5fHx2YWx1ZSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5fHx2YWx1ZSBpbnN0YW5jZW9mIEludDhBcnJheSkpe3Rocm93QmluZGluZ0Vycm9yKCJDYW5ub3QgcGFzcyBub24tc3RyaW5nIHRvIHN0ZDo6c3RyaW5nIik7fWlmKHN0ZFN0cmluZ0lzVVRGOCYmdmFsdWVJc09mVHlwZVN0cmluZyl7bGVuZ3RoPWxlbmd0aEJ5dGVzVVRGOCh2YWx1ZSk7fWVsc2Uge2xlbmd0aD12YWx1ZS5sZW5ndGg7fXZhciBiYXNlPV9tYWxsb2MoNCtsZW5ndGgrMSk7dmFyIHB0cj1iYXNlKzQ7SEVBUFUzMltiYXNlPj4yXT1sZW5ndGg7aWYoc3RkU3RyaW5nSXNVVEY4JiZ2YWx1ZUlzT2ZUeXBlU3RyaW5nKXtzdHJpbmdUb1VURjgodmFsdWUscHRyLGxlbmd0aCsxKTt9ZWxzZSB7aWYodmFsdWVJc09mVHlwZVN0cmluZyl7Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXt2YXIgY2hhckNvZGU9dmFsdWUuY2hhckNvZGVBdChpKTtpZihjaGFyQ29kZT4yNTUpe19mcmVlKHB0cik7dGhyb3dCaW5kaW5nRXJyb3IoIlN0cmluZyBoYXMgVVRGLTE2IGNvZGUgdW5pdHMgdGhhdCBkbyBub3QgZml0IGluIDggYml0cyIpO31IRUFQVThbcHRyK2ldPWNoYXJDb2RlO319ZWxzZSB7Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXtIRUFQVThbcHRyK2ldPXZhbHVlW2ldO319fWlmKGRlc3RydWN0b3JzIT09bnVsbCl7ZGVzdHJ1Y3RvcnMucHVzaChfZnJlZSxiYXNlKTt9cmV0dXJuIGJhc2V9LCJhcmdQYWNrQWR2YW5jZSI6R2VuZXJpY1dpcmVUeXBlU2l6ZSwicmVhZFZhbHVlRnJvbVBvaW50ZXIiOnJlYWRQb2ludGVyLGRlc3RydWN0b3JGdW5jdGlvbihwdHIpe19mcmVlKHB0cik7fX0pO307dmFyIFVURjE2RGVjb2Rlcj10eXBlb2YgVGV4dERlY29kZXIhPSJ1bmRlZmluZWQiP25ldyBUZXh0RGVjb2RlcigidXRmLTE2bGUiKTp1bmRlZmluZWQ7dmFyIFVURjE2VG9TdHJpbmc9KHB0cixtYXhCeXRlc1RvUmVhZCk9Pnt2YXIgZW5kUHRyPXB0cjt2YXIgaWR4PWVuZFB0cj4+MTt2YXIgbWF4SWR4PWlkeCttYXhCeXRlc1RvUmVhZC8yO3doaWxlKCEoaWR4Pj1tYXhJZHgpJiZIRUFQVTE2W2lkeF0pKytpZHg7ZW5kUHRyPWlkeDw8MTtpZihlbmRQdHItcHRyPjMyJiZVVEYxNkRlY29kZXIpcmV0dXJuIFVURjE2RGVjb2Rlci5kZWNvZGUoSEVBUFU4LnN1YmFycmF5KHB0cixlbmRQdHIpKTt2YXIgc3RyPSIiO2Zvcih2YXIgaT0wOyEoaT49bWF4Qnl0ZXNUb1JlYWQvMik7KytpKXt2YXIgY29kZVVuaXQ9SEVBUDE2W3B0citpKjI+PjFdO2lmKGNvZGVVbml0PT0wKWJyZWFrO3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZShjb2RlVW5pdCk7fXJldHVybiBzdHJ9O3ZhciBzdHJpbmdUb1VURjE2PShzdHIsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk9PntpZihtYXhCeXRlc1RvV3JpdGU9PT11bmRlZmluZWQpe21heEJ5dGVzVG9Xcml0ZT0yMTQ3NDgzNjQ3O31pZihtYXhCeXRlc1RvV3JpdGU8MilyZXR1cm4gMDttYXhCeXRlc1RvV3JpdGUtPTI7dmFyIHN0YXJ0UHRyPW91dFB0cjt2YXIgbnVtQ2hhcnNUb1dyaXRlPW1heEJ5dGVzVG9Xcml0ZTxzdHIubGVuZ3RoKjI/bWF4Qnl0ZXNUb1dyaXRlLzI6c3RyLmxlbmd0aDtmb3IodmFyIGk9MDtpPG51bUNoYXJzVG9Xcml0ZTsrK2kpe3ZhciBjb2RlVW5pdD1zdHIuY2hhckNvZGVBdChpKTtIRUFQMTZbb3V0UHRyPj4xXT1jb2RlVW5pdDtvdXRQdHIrPTI7fUhFQVAxNltvdXRQdHI+PjFdPTA7cmV0dXJuIG91dFB0ci1zdGFydFB0cn07dmFyIGxlbmd0aEJ5dGVzVVRGMTY9c3RyPT5zdHIubGVuZ3RoKjI7dmFyIFVURjMyVG9TdHJpbmc9KHB0cixtYXhCeXRlc1RvUmVhZCk9Pnt2YXIgaT0wO3ZhciBzdHI9IiI7d2hpbGUoIShpPj1tYXhCeXRlc1RvUmVhZC80KSl7dmFyIHV0ZjMyPUhFQVAzMltwdHIraSo0Pj4yXTtpZih1dGYzMj09MClicmVhazsrK2k7aWYodXRmMzI+PTY1NTM2KXt2YXIgY2g9dXRmMzItNjU1MzY7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fGNoPj4xMCw1NjMyMHxjaCYxMDIzKTt9ZWxzZSB7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHV0ZjMyKTt9fXJldHVybiBzdHJ9O3ZhciBzdHJpbmdUb1VURjMyPShzdHIsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk9PntpZihtYXhCeXRlc1RvV3JpdGU9PT11bmRlZmluZWQpe21heEJ5dGVzVG9Xcml0ZT0yMTQ3NDgzNjQ3O31pZihtYXhCeXRlc1RvV3JpdGU8NClyZXR1cm4gMDt2YXIgc3RhcnRQdHI9b3V0UHRyO3ZhciBlbmRQdHI9c3RhcnRQdHIrbWF4Qnl0ZXNUb1dyaXRlLTQ7Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7dmFyIGNvZGVVbml0PXN0ci5jaGFyQ29kZUF0KGkpO2lmKGNvZGVVbml0Pj01NTI5NiYmY29kZVVuaXQ8PTU3MzQzKXt2YXIgdHJhaWxTdXJyb2dhdGU9c3RyLmNoYXJDb2RlQXQoKytpKTtjb2RlVW5pdD02NTUzNisoKGNvZGVVbml0JjEwMjMpPDwxMCl8dHJhaWxTdXJyb2dhdGUmMTAyMzt9SEVBUDMyW291dFB0cj4+Ml09Y29kZVVuaXQ7b3V0UHRyKz00O2lmKG91dFB0cis0PmVuZFB0cilicmVha31IRUFQMzJbb3V0UHRyPj4yXT0wO3JldHVybiBvdXRQdHItc3RhcnRQdHJ9O3ZhciBsZW5ndGhCeXRlc1VURjMyPXN0cj0+e3ZhciBsZW49MDtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXt2YXIgY29kZVVuaXQ9c3RyLmNoYXJDb2RlQXQoaSk7aWYoY29kZVVuaXQ+PTU1Mjk2JiZjb2RlVW5pdDw9NTczNDMpKytpO2xlbis9NDt9cmV0dXJuIGxlbn07dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF93c3RyaW5nPShyYXdUeXBlLGNoYXJTaXplLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3ZhciBkZWNvZGVTdHJpbmcsZW5jb2RlU3RyaW5nLGdldEhlYXAsbGVuZ3RoQnl0ZXNVVEYsc2hpZnQ7aWYoY2hhclNpemU9PT0yKXtkZWNvZGVTdHJpbmc9VVRGMTZUb1N0cmluZztlbmNvZGVTdHJpbmc9c3RyaW5nVG9VVEYxNjtsZW5ndGhCeXRlc1VURj1sZW5ndGhCeXRlc1VURjE2O2dldEhlYXA9KCk9PkhFQVBVMTY7c2hpZnQ9MTt9ZWxzZSBpZihjaGFyU2l6ZT09PTQpe2RlY29kZVN0cmluZz1VVEYzMlRvU3RyaW5nO2VuY29kZVN0cmluZz1zdHJpbmdUb1VURjMyO2xlbmd0aEJ5dGVzVVRGPWxlbmd0aEJ5dGVzVVRGMzI7Z2V0SGVhcD0oKT0+SEVBUFUzMjtzaGlmdD0yO31yZWdpc3RlclR5cGUocmF3VHlwZSx7bmFtZTpuYW1lLCJmcm9tV2lyZVR5cGUiOnZhbHVlPT57dmFyIGxlbmd0aD1IRUFQVTMyW3ZhbHVlPj4yXTt2YXIgSEVBUD1nZXRIZWFwKCk7dmFyIHN0cjt2YXIgZGVjb2RlU3RhcnRQdHI9dmFsdWUrNDtmb3IodmFyIGk9MDtpPD1sZW5ndGg7KytpKXt2YXIgY3VycmVudEJ5dGVQdHI9dmFsdWUrNCtpKmNoYXJTaXplO2lmKGk9PWxlbmd0aHx8SEVBUFtjdXJyZW50Qnl0ZVB0cj4+c2hpZnRdPT0wKXt2YXIgbWF4UmVhZEJ5dGVzPWN1cnJlbnRCeXRlUHRyLWRlY29kZVN0YXJ0UHRyO3ZhciBzdHJpbmdTZWdtZW50PWRlY29kZVN0cmluZyhkZWNvZGVTdGFydFB0cixtYXhSZWFkQnl0ZXMpO2lmKHN0cj09PXVuZGVmaW5lZCl7c3RyPXN0cmluZ1NlZ21lbnQ7fWVsc2Uge3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSgwKTtzdHIrPXN0cmluZ1NlZ21lbnQ7fWRlY29kZVN0YXJ0UHRyPWN1cnJlbnRCeXRlUHRyK2NoYXJTaXplO319X2ZyZWUodmFsdWUpO3JldHVybiBzdHJ9LCJ0b1dpcmVUeXBlIjooZGVzdHJ1Y3RvcnMsdmFsdWUpPT57aWYoISh0eXBlb2YgdmFsdWU9PSJzdHJpbmciKSl7dGhyb3dCaW5kaW5nRXJyb3IoYENhbm5vdCBwYXNzIG5vbi1zdHJpbmcgdG8gQysrIHN0cmluZyB0eXBlICR7bmFtZX1gKTt9dmFyIGxlbmd0aD1sZW5ndGhCeXRlc1VURih2YWx1ZSk7dmFyIHB0cj1fbWFsbG9jKDQrbGVuZ3RoK2NoYXJTaXplKTtIRUFQVTMyW3B0cj4+Ml09bGVuZ3RoPj5zaGlmdDtlbmNvZGVTdHJpbmcodmFsdWUscHRyKzQsbGVuZ3RoK2NoYXJTaXplKTtpZihkZXN0cnVjdG9ycyE9PW51bGwpe2Rlc3RydWN0b3JzLnB1c2goX2ZyZWUscHRyKTt9cmV0dXJuIHB0cn0sImFyZ1BhY2tBZHZhbmNlIjpHZW5lcmljV2lyZVR5cGVTaXplLCJyZWFkVmFsdWVGcm9tUG9pbnRlciI6c2ltcGxlUmVhZFZhbHVlRnJvbVBvaW50ZXIsZGVzdHJ1Y3RvckZ1bmN0aW9uKHB0cil7X2ZyZWUocHRyKTt9fSk7fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfdm9pZD0ocmF3VHlwZSxuYW1lKT0+e25hbWU9cmVhZExhdGluMVN0cmluZyhuYW1lKTtyZWdpc3RlclR5cGUocmF3VHlwZSx7aXNWb2lkOnRydWUsbmFtZTpuYW1lLCJhcmdQYWNrQWR2YW5jZSI6MCwiZnJvbVdpcmVUeXBlIjooKT0+dW5kZWZpbmVkLCJ0b1dpcmVUeXBlIjooZGVzdHJ1Y3RvcnMsbyk9PnVuZGVmaW5lZH0pO307dmFyIGdldEhlYXBNYXg9KCk9PjIxNDc0ODM2NDg7dmFyIGdyb3dNZW1vcnk9c2l6ZT0+e3ZhciBiPXdhc21NZW1vcnkuYnVmZmVyO3ZhciBwYWdlcz0oc2l6ZS1iLmJ5dGVMZW5ndGgrNjU1MzUpLzY1NTM2O3RyeXt3YXNtTWVtb3J5Lmdyb3cocGFnZXMpO3VwZGF0ZU1lbW9yeVZpZXdzKCk7cmV0dXJuIDF9Y2F0Y2goZSl7fX07dmFyIF9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwPXJlcXVlc3RlZFNpemU9Pnt2YXIgb2xkU2l6ZT1IRUFQVTgubGVuZ3RoO3JlcXVlc3RlZFNpemU+Pj49MDt2YXIgbWF4SGVhcFNpemU9Z2V0SGVhcE1heCgpO2lmKHJlcXVlc3RlZFNpemU+bWF4SGVhcFNpemUpe3JldHVybiBmYWxzZX12YXIgYWxpZ25VcD0oeCxtdWx0aXBsZSk9PngrKG11bHRpcGxlLXglbXVsdGlwbGUpJW11bHRpcGxlO2Zvcih2YXIgY3V0RG93bj0xO2N1dERvd248PTQ7Y3V0RG93bio9Mil7dmFyIG92ZXJHcm93bkhlYXBTaXplPW9sZFNpemUqKDErLjIvY3V0RG93bik7b3Zlckdyb3duSGVhcFNpemU9TWF0aC5taW4ob3Zlckdyb3duSGVhcFNpemUscmVxdWVzdGVkU2l6ZSsxMDA2NjMyOTYpO3ZhciBuZXdTaXplPU1hdGgubWluKG1heEhlYXBTaXplLGFsaWduVXAoTWF0aC5tYXgocmVxdWVzdGVkU2l6ZSxvdmVyR3Jvd25IZWFwU2l6ZSksNjU1MzYpKTt2YXIgcmVwbGFjZW1lbnQ9Z3Jvd01lbW9yeShuZXdTaXplKTtpZihyZXBsYWNlbWVudCl7cmV0dXJuIHRydWV9fXJldHVybiBmYWxzZX07ZW1iaW5kX2luaXRfY2hhckNvZGVzKCk7QmluZGluZ0Vycm9yPU1vZHVsZVsiQmluZGluZ0Vycm9yIl09Y2xhc3MgQmluZGluZ0Vycm9yIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IobWVzc2FnZSl7c3VwZXIobWVzc2FnZSk7dGhpcy5uYW1lPSJCaW5kaW5nRXJyb3IiO319O01vZHVsZVsiSW50ZXJuYWxFcnJvciJdPWNsYXNzIEludGVybmFsRXJyb3IgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcihtZXNzYWdlKXtzdXBlcihtZXNzYWdlKTt0aGlzLm5hbWU9IkludGVybmFsRXJyb3IiO319O2hhbmRsZUFsbG9jYXRvckluaXQoKTtpbml0X2VtdmFsKCk7dmFyIHdhc21JbXBvcnRzPXtmOl9fZW1iaW5kX3JlZ2lzdGVyX2JpZ2ludCxpOl9fZW1iaW5kX3JlZ2lzdGVyX2Jvb2wsaDpfX2VtYmluZF9yZWdpc3Rlcl9lbXZhbCxlOl9fZW1iaW5kX3JlZ2lzdGVyX2Zsb2F0LGI6X19lbWJpbmRfcmVnaXN0ZXJfaW50ZWdlcixhOl9fZW1iaW5kX3JlZ2lzdGVyX21lbW9yeV92aWV3LGQ6X19lbWJpbmRfcmVnaXN0ZXJfc3RkX3N0cmluZyxjOl9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF93c3RyaW5nLGo6X19lbWJpbmRfcmVnaXN0ZXJfdm9pZCxnOl9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwfTt2YXIgd2FzbUV4cG9ydHM9Y3JlYXRlV2FzbSgpO01vZHVsZVsiX3NvcnQiXT0oYTAsYTEsYTIsYTMsYTQsYTUsYTYsYTcsYTgpPT4oTW9kdWxlWyJfc29ydCJdPXdhc21FeHBvcnRzWyJtIl0pKGEwLGExLGEyLGEzLGE0LGE1LGE2LGE3LGE4KTtNb2R1bGVbIl9fZW1iaW5kX2luaXRpYWxpemVfYmluZGluZ3MiXT0oKT0+KE1vZHVsZVsiX19lbWJpbmRfaW5pdGlhbGl6ZV9iaW5kaW5ncyJdPXdhc21FeHBvcnRzWyJuIl0pKCk7dmFyIF9tYWxsb2M9TW9kdWxlWyJfbWFsbG9jIl09YTA9PihfbWFsbG9jPU1vZHVsZVsiX21hbGxvYyJdPXdhc21FeHBvcnRzWyJwIl0pKGEwKTt2YXIgX2ZyZWU9TW9kdWxlWyJfZnJlZSJdPWEwPT4oX2ZyZWU9TW9kdWxlWyJfZnJlZSJdPXdhc21FeHBvcnRzWyJxIl0pKGEwKTtmdW5jdGlvbiBpbnRBcnJheUZyb21CYXNlNjQocyl7dmFyIGRlY29kZWQ9YXRvYihzKTt2YXIgYnl0ZXM9bmV3IFVpbnQ4QXJyYXkoZGVjb2RlZC5sZW5ndGgpO2Zvcih2YXIgaT0wO2k8ZGVjb2RlZC5sZW5ndGg7KytpKXtieXRlc1tpXT1kZWNvZGVkLmNoYXJDb2RlQXQoaSk7fXJldHVybiBieXRlc31mdW5jdGlvbiB0cnlQYXJzZUFzRGF0YVVSSShmaWxlbmFtZSl7aWYoIWlzRGF0YVVSSShmaWxlbmFtZSkpe3JldHVybn1yZXR1cm4gaW50QXJyYXlGcm9tQmFzZTY0KGZpbGVuYW1lLnNsaWNlKGRhdGFVUklQcmVmaXgubGVuZ3RoKSl9dmFyIGNhbGxlZFJ1bjtkZXBlbmRlbmNpZXNGdWxmaWxsZWQ9ZnVuY3Rpb24gcnVuQ2FsbGVyKCl7aWYoIWNhbGxlZFJ1bilydW4oKTtpZighY2FsbGVkUnVuKWRlcGVuZGVuY2llc0Z1bGZpbGxlZD1ydW5DYWxsZXI7fTtmdW5jdGlvbiBydW4oKXtpZihydW5EZXBlbmRlbmNpZXM+MCl7cmV0dXJufXByZVJ1bigpO2lmKHJ1bkRlcGVuZGVuY2llcz4wKXtyZXR1cm59ZnVuY3Rpb24gZG9SdW4oKXtpZihjYWxsZWRSdW4pcmV0dXJuO2NhbGxlZFJ1bj10cnVlO01vZHVsZVsiY2FsbGVkUnVuIl09dHJ1ZTtpZihBQk9SVClyZXR1cm47aW5pdFJ1bnRpbWUoKTtyZWFkeVByb21pc2VSZXNvbHZlKE1vZHVsZSk7aWYoTW9kdWxlWyJvblJ1bnRpbWVJbml0aWFsaXplZCJdKU1vZHVsZVsib25SdW50aW1lSW5pdGlhbGl6ZWQiXSgpO3Bvc3RSdW4oKTt9aWYoTW9kdWxlWyJzZXRTdGF0dXMiXSl7TW9kdWxlWyJzZXRTdGF0dXMiXSgiUnVubmluZy4uLiIpO3NldFRpbWVvdXQoZnVuY3Rpb24oKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7TW9kdWxlWyJzZXRTdGF0dXMiXSgiIik7fSwxKTtkb1J1bigpO30sMSk7fWVsc2Uge2RvUnVuKCk7fX1pZihNb2R1bGVbInByZUluaXQiXSl7aWYodHlwZW9mIE1vZHVsZVsicHJlSW5pdCJdPT0iZnVuY3Rpb24iKU1vZHVsZVsicHJlSW5pdCJdPVtNb2R1bGVbInByZUluaXQiXV07d2hpbGUoTW9kdWxlWyJwcmVJbml0Il0ubGVuZ3RoPjApe01vZHVsZVsicHJlSW5pdCJdLnBvcCgpKCk7fX1ydW4oKTsKCgogICAgcmV0dXJuIG1vZHVsZUFyZy5yZWFkeQogIH0KCiAgKTsKICB9KSgpOwoKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogIGxldCB3YXNtTW9kdWxlOwogIGFzeW5jIGZ1bmN0aW9uIGluaXRXYXNtKCkgewogICAgICB3YXNtTW9kdWxlID0gYXdhaXQgbG9hZFdhc20oKTsKICB9CiAgbGV0IHNvcnREYXRhOwogIGxldCB2aWV3UHJvalB0cjsKICBsZXQgdHJhbnNmb3Jtc1B0cjsKICBsZXQgdHJhbnNmb3JtSW5kaWNlc1B0cjsKICBsZXQgcG9zaXRpb25zUHRyOwogIGxldCBkZXB0aEJ1ZmZlclB0cjsKICBsZXQgZGVwdGhJbmRleFB0cjsKICBsZXQgc3RhcnRzUHRyOwogIGxldCBjb3VudHNQdHI7CiAgbGV0IGFsbG9jYXRlZFZlcnRleENvdW50ID0gMDsKICBsZXQgYWxsb2NhdGVkVHJhbnNmb3JtQ291bnQgPSAwOwogIGxldCB2aWV3UHJvaiA9IG5ldyBGbG9hdDMyQXJyYXkoMTYpOwogIGxldCBsb2NrID0gZmFsc2U7CiAgbGV0IGFsbG9jYXRpb25QZW5kaW5nID0gZmFsc2U7CiAgbGV0IHNvcnRpbmcgPSBmYWxzZTsKICBjb25zdCBhbGxvY2F0ZUJ1ZmZlcnMgPSBhc3luYyAoKSA9PiB7CiAgICAgIGlmIChsb2NrKSB7CiAgICAgICAgICBhbGxvY2F0aW9uUGVuZGluZyA9IHRydWU7CiAgICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgbG9jayA9IHRydWU7CiAgICAgIGFsbG9jYXRpb25QZW5kaW5nID0gZmFsc2U7CiAgICAgIGlmICghd2FzbU1vZHVsZSkKICAgICAgICAgIGF3YWl0IGluaXRXYXNtKCk7CiAgICAgIGNvbnN0IHRhcmdldEFsbG9jYXRlZFZlcnRleENvdW50ID0gTWF0aC5wb3coMiwgTWF0aC5jZWlsKE1hdGgubG9nMihzb3J0RGF0YS52ZXJ0ZXhDb3VudCkpKTsKICAgICAgaWYgKGFsbG9jYXRlZFZlcnRleENvdW50IDwgdGFyZ2V0QWxsb2NhdGVkVmVydGV4Q291bnQpIHsKICAgICAgICAgIGlmIChhbGxvY2F0ZWRWZXJ0ZXhDb3VudCA+IDApIHsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHZpZXdQcm9qUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHRyYW5zZm9ybUluZGljZXNQdHIpOwogICAgICAgICAgICAgIHdhc21Nb2R1bGUuX2ZyZWUocG9zaXRpb25zUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKGRlcHRoQnVmZmVyUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKGRlcHRoSW5kZXhQdHIpOwogICAgICAgICAgICAgIHdhc21Nb2R1bGUuX2ZyZWUoc3RhcnRzUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKGNvdW50c1B0cik7CiAgICAgICAgICB9CiAgICAgICAgICBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCA9IHRhcmdldEFsbG9jYXRlZFZlcnRleENvdW50OwogICAgICAgICAgdmlld1Byb2pQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoMTYgKiA0KTsKICAgICAgICAgIHRyYW5zZm9ybUluZGljZXNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoYWxsb2NhdGVkVmVydGV4Q291bnQgKiA0KTsKICAgICAgICAgIHBvc2l0aW9uc1B0ciA9IHdhc21Nb2R1bGUuX21hbGxvYygzICogYWxsb2NhdGVkVmVydGV4Q291bnQgKiA0KTsKICAgICAgICAgIGRlcHRoQnVmZmVyUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICBkZXB0aEluZGV4UHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICBzdGFydHNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoYWxsb2NhdGVkVmVydGV4Q291bnQgKiA0KTsKICAgICAgICAgIGNvdW50c1B0ciA9IHdhc21Nb2R1bGUuX21hbGxvYyhhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICB9CiAgICAgIGlmIChhbGxvY2F0ZWRUcmFuc2Zvcm1Db3VudCA8IHNvcnREYXRhLnRyYW5zZm9ybXMubGVuZ3RoKSB7CiAgICAgICAgICBpZiAoYWxsb2NhdGVkVHJhbnNmb3JtQ291bnQgPiAwKSB7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZSh0cmFuc2Zvcm1zUHRyKTsKICAgICAgICAgIH0KICAgICAgICAgIGFsbG9jYXRlZFRyYW5zZm9ybUNvdW50ID0gc29ydERhdGEudHJhbnNmb3Jtcy5sZW5ndGg7CiAgICAgICAgICB0cmFuc2Zvcm1zUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKGFsbG9jYXRlZFRyYW5zZm9ybUNvdW50ICogNCk7CiAgICAgIH0KICAgICAgbG9jayA9IGZhbHNlOwogICAgICBpZiAoYWxsb2NhdGlvblBlbmRpbmcpIHsKICAgICAgICAgIGFsbG9jYXRpb25QZW5kaW5nID0gZmFsc2U7CiAgICAgICAgICBhd2FpdCBhbGxvY2F0ZUJ1ZmZlcnMoKTsKICAgICAgfQogIH07CiAgY29uc3QgcnVuU29ydCA9ICgpID0+IHsKICAgICAgaWYgKGxvY2sgfHwgYWxsb2NhdGlvblBlbmRpbmcgfHwgIXdhc21Nb2R1bGUpCiAgICAgICAgICByZXR1cm47CiAgICAgIGxvY2sgPSB0cnVlOwogICAgICB3YXNtTW9kdWxlLkhFQVBGMzIuc2V0KHNvcnREYXRhLnBvc2l0aW9ucywgcG9zaXRpb25zUHRyIC8gNCk7CiAgICAgIHdhc21Nb2R1bGUuSEVBUEYzMi5zZXQoc29ydERhdGEudHJhbnNmb3JtcywgdHJhbnNmb3Jtc1B0ciAvIDQpOwogICAgICB3YXNtTW9kdWxlLkhFQVBVMzIuc2V0KHNvcnREYXRhLnRyYW5zZm9ybUluZGljZXMsIHRyYW5zZm9ybUluZGljZXNQdHIgLyA0KTsKICAgICAgd2FzbU1vZHVsZS5IRUFQRjMyLnNldCh2aWV3UHJvaiwgdmlld1Byb2pQdHIgLyA0KTsKICAgICAgd2FzbU1vZHVsZS5fc29ydCh2aWV3UHJvalB0ciwgdHJhbnNmb3Jtc1B0ciwgdHJhbnNmb3JtSW5kaWNlc1B0ciwgc29ydERhdGEudmVydGV4Q291bnQsIHBvc2l0aW9uc1B0ciwgZGVwdGhCdWZmZXJQdHIsIGRlcHRoSW5kZXhQdHIsIHN0YXJ0c1B0ciwgY291bnRzUHRyKTsKICAgICAgY29uc3QgZGVwdGhJbmRleCA9IG5ldyBVaW50MzJBcnJheSh3YXNtTW9kdWxlLkhFQVBVMzIuYnVmZmVyLCBkZXB0aEluZGV4UHRyLCBzb3J0RGF0YS52ZXJ0ZXhDb3VudCk7CiAgICAgIGNvbnN0IGRldGFjaGVkRGVwdGhJbmRleCA9IG5ldyBVaW50MzJBcnJheShkZXB0aEluZGV4LnNsaWNlKCkuYnVmZmVyKTsKICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7IGRlcHRoSW5kZXg6IGRldGFjaGVkRGVwdGhJbmRleCB9LCBbZGV0YWNoZWREZXB0aEluZGV4LmJ1ZmZlcl0pOwogICAgICBsb2NrID0gZmFsc2U7CiAgfTsKICBjb25zdCB0aHJvdHRsZWRTb3J0ID0gKCkgPT4gewogICAgICBpZiAoIXNvcnRpbmcpIHsKICAgICAgICAgIHNvcnRpbmcgPSB0cnVlOwogICAgICAgICAgcnVuU29ydCgpOwogICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7CiAgICAgICAgICAgICAgc29ydGluZyA9IGZhbHNlOwogICAgICAgICAgICAgIHRocm90dGxlZFNvcnQoKTsKICAgICAgICAgIH0pOwogICAgICB9CiAgfTsKICBzZWxmLm9ubWVzc2FnZSA9IChlKSA9PiB7CiAgICAgIGlmIChlLmRhdGEuc29ydERhdGEpIHsKICAgICAgICAgIC8vUmVjcmVhdGluZyB0aGUgdHlwZWQgYXJyYXlzIGV2ZXJ5IHRpbWUsIHdpbGwgY2F1c2UgZmlyZWZveCB0byBsZWFrIG1lbW9yeQogICAgICAgICAgaWYgKCFzb3J0RGF0YSkgewogICAgICAgICAgICAgIHNvcnREYXRhID0gewogICAgICAgICAgICAgICAgICBwb3NpdGlvbnM6IG5ldyBGbG9hdDMyQXJyYXkoZS5kYXRhLnNvcnREYXRhLnBvc2l0aW9ucyksCiAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybXM6IG5ldyBGbG9hdDMyQXJyYXkoZS5kYXRhLnNvcnREYXRhLnRyYW5zZm9ybXMpLAogICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1JbmRpY2VzOiBuZXcgVWludDMyQXJyYXkoZS5kYXRhLnNvcnREYXRhLnRyYW5zZm9ybUluZGljZXMpLAogICAgICAgICAgICAgICAgICB2ZXJ0ZXhDb3VudDogZS5kYXRhLnNvcnREYXRhLnZlcnRleENvdW50LAogICAgICAgICAgICAgIH07CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICBzb3J0RGF0YS5wb3NpdGlvbnMuc2V0KGUuZGF0YS5zb3J0RGF0YS5wb3NpdGlvbnMpOwogICAgICAgICAgICAgIHNvcnREYXRhLnRyYW5zZm9ybXMuc2V0KGUuZGF0YS5zb3J0RGF0YS50cmFuc2Zvcm1zKTsKICAgICAgICAgICAgICBzb3J0RGF0YS50cmFuc2Zvcm1JbmRpY2VzLnNldChlLmRhdGEuc29ydERhdGEudHJhbnNmb3JtSW5kaWNlcyk7CiAgICAgICAgICAgICAgc29ydERhdGEudmVydGV4Q291bnQgPSBlLmRhdGEuc29ydERhdGEudmVydGV4Q291bnQ7CiAgICAgICAgICB9CiAgICAgICAgICBhbGxvY2F0ZUJ1ZmZlcnMoKTsKICAgICAgfQogICAgICBpZiAoZS5kYXRhLnZpZXdQcm9qKSB7CiAgICAgICAgICB2aWV3UHJvaiA9IEZsb2F0MzJBcnJheS5mcm9tKGUuZGF0YS52aWV3UHJvaik7CiAgICAgICAgICB0aHJvdHRsZWRTb3J0KCk7CiAgICAgIH0KICB9OwoKfSkoKTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9U29ydFdvcmtlci5qcy5tYXAKCg==", null);
889
- class St {
890
- constructor(t, F) {
891
- this._scene = null, this._camera = null, this._started = !1, this._initialized = !1, this._renderer = t;
892
- const U = t.gl;
893
- this._program = U.createProgram(), this._passes = F || [];
894
- const l = U.createShader(U.VERTEX_SHADER);
895
- U.shaderSource(l, this._getVertexSource()), U.compileShader(l), U.getShaderParameter(l, U.COMPILE_STATUS) || console.error(U.getShaderInfoLog(l));
896
- const a = U.createShader(U.FRAGMENT_SHADER);
897
- U.shaderSource(a, this._getFragmentSource()), U.compileShader(a), U.getShaderParameter(a, U.COMPILE_STATUS) || console.error(U.getShaderInfoLog(a)), U.attachShader(this.program, l), U.attachShader(this.program, a), U.linkProgram(this.program), U.getProgramParameter(this.program, U.LINK_STATUS) || console.error(U.getProgramInfoLog(this.program)), this.resize = () => {
898
- U.useProgram(this._program), this._resize();
899
- }, this.initialize = () => {
900
- console.assert(!this._initialized, "ShaderProgram already initialized"), U.useProgram(this._program), this._initialize();
901
- for (const n of this.passes) n.initialize(this);
902
- this._initialized = !0, this._started = !0;
903
- }, this.render = (n, e) => {
904
- U.useProgram(this._program), this._scene === n && this._camera === e || (this.dispose(), this._scene = n, this._camera = e, this.initialize());
905
- for (const Q of this.passes) Q.render();
906
- this._render();
907
- }, this.dispose = () => {
908
- if (this._initialized) {
909
- U.useProgram(this._program);
910
- for (const n of this.passes) n.dispose();
911
- this._dispose(), this._scene = null, this._camera = null, this._initialized = !1;
912
- }
913
- };
914
- }
915
- get renderer() {
916
- return this._renderer;
917
- }
918
- get scene() {
919
- return this._scene;
920
- }
921
- get camera() {
922
- return this._camera;
923
- }
924
- get program() {
925
- return this._program;
926
- }
927
- get passes() {
928
- return this._passes;
929
- }
930
- get started() {
931
- return this._started;
932
- }
933
- }
934
- var ll = yt("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgdmFyIGxvYWRXYXNtID0gKCgpID0+IHsKICAgIAogICAgcmV0dXJuICgKICBmdW5jdGlvbihtb2R1bGVBcmcgPSB7fSkgewoKICB2YXIgTW9kdWxlPW1vZHVsZUFyZzt2YXIgcmVhZHlQcm9taXNlUmVzb2x2ZSxyZWFkeVByb21pc2VSZWplY3Q7TW9kdWxlWyJyZWFkeSJdPW5ldyBQcm9taXNlKChyZXNvbHZlLHJlamVjdCk9PntyZWFkeVByb21pc2VSZXNvbHZlPXJlc29sdmU7cmVhZHlQcm9taXNlUmVqZWN0PXJlamVjdDt9KTt2YXIgbW9kdWxlT3ZlcnJpZGVzPU9iamVjdC5hc3NpZ24oe30sTW9kdWxlKTt2YXIgc2NyaXB0RGlyZWN0b3J5PSIiO2Z1bmN0aW9uIGxvY2F0ZUZpbGUocGF0aCl7aWYoTW9kdWxlWyJsb2NhdGVGaWxlIl0pe3JldHVybiBNb2R1bGVbImxvY2F0ZUZpbGUiXShwYXRoLHNjcmlwdERpcmVjdG9yeSl9cmV0dXJuIHNjcmlwdERpcmVjdG9yeStwYXRofXZhciByZWFkQmluYXJ5O3t7c2NyaXB0RGlyZWN0b3J5PXNlbGYubG9jYXRpb24uaHJlZjt9aWYoc2NyaXB0RGlyZWN0b3J5LmluZGV4T2YoImJsb2I6IikhPT0wKXtzY3JpcHREaXJlY3Rvcnk9c2NyaXB0RGlyZWN0b3J5LnN1YnN0cigwLHNjcmlwdERpcmVjdG9yeS5yZXBsYWNlKC9bPyNdLiovLCIiKS5sYXN0SW5kZXhPZigiLyIpKzEpO31lbHNlIHtzY3JpcHREaXJlY3Rvcnk9IiI7fXt7cmVhZEJpbmFyeT11cmw9Pnt2YXIgeGhyPW5ldyBYTUxIdHRwUmVxdWVzdDt4aHIub3BlbigiR0VUIix1cmwsZmFsc2UpO3hoci5yZXNwb25zZVR5cGU9ImFycmF5YnVmZmVyIjt4aHIuc2VuZChudWxsKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoeGhyLnJlc3BvbnNlKX07fX19TW9kdWxlWyJwcmludCJdfHxjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpO3ZhciBlcnI9TW9kdWxlWyJwcmludEVyciJdfHxjb25zb2xlLmVycm9yLmJpbmQoY29uc29sZSk7T2JqZWN0LmFzc2lnbihNb2R1bGUsbW9kdWxlT3ZlcnJpZGVzKTttb2R1bGVPdmVycmlkZXM9bnVsbDtpZihNb2R1bGVbImFyZ3VtZW50cyJdKU1vZHVsZVsiYXJndW1lbnRzIl07aWYoTW9kdWxlWyJ0aGlzUHJvZ3JhbSJdKU1vZHVsZVsidGhpc1Byb2dyYW0iXTtpZihNb2R1bGVbInF1aXQiXSlNb2R1bGVbInF1aXQiXTt2YXIgd2FzbUJpbmFyeTtpZihNb2R1bGVbIndhc21CaW5hcnkiXSl3YXNtQmluYXJ5PU1vZHVsZVsid2FzbUJpbmFyeSJdO2lmKHR5cGVvZiBXZWJBc3NlbWJseSE9Im9iamVjdCIpe2Fib3J0KCJubyBuYXRpdmUgd2FzbSBzdXBwb3J0IGRldGVjdGVkIik7fXZhciB3YXNtTWVtb3J5O3ZhciBBQk9SVD1mYWxzZTt2YXIgSEVBUDgsSEVBUFU4LEhFQVAxNixIRUFQVTE2LEhFQVAzMixIRUFQVTMyLEhFQVBGMzIsSEVBUEY2NDtmdW5jdGlvbiB1cGRhdGVNZW1vcnlWaWV3cygpe3ZhciBiPXdhc21NZW1vcnkuYnVmZmVyO01vZHVsZVsiSEVBUDgiXT1IRUFQOD1uZXcgSW50OEFycmF5KGIpO01vZHVsZVsiSEVBUDE2Il09SEVBUDE2PW5ldyBJbnQxNkFycmF5KGIpO01vZHVsZVsiSEVBUFU4Il09SEVBUFU4PW5ldyBVaW50OEFycmF5KGIpO01vZHVsZVsiSEVBUFUxNiJdPUhFQVBVMTY9bmV3IFVpbnQxNkFycmF5KGIpO01vZHVsZVsiSEVBUDMyIl09SEVBUDMyPW5ldyBJbnQzMkFycmF5KGIpO01vZHVsZVsiSEVBUFUzMiJdPUhFQVBVMzI9bmV3IFVpbnQzMkFycmF5KGIpO01vZHVsZVsiSEVBUEYzMiJdPUhFQVBGMzI9bmV3IEZsb2F0MzJBcnJheShiKTtNb2R1bGVbIkhFQVBGNjQiXT1IRUFQRjY0PW5ldyBGbG9hdDY0QXJyYXkoYik7fXZhciBfX0FUUFJFUlVOX189W107dmFyIF9fQVRJTklUX189W107dmFyIF9fQVRQT1NUUlVOX189W107ZnVuY3Rpb24gcHJlUnVuKCl7aWYoTW9kdWxlWyJwcmVSdW4iXSl7aWYodHlwZW9mIE1vZHVsZVsicHJlUnVuIl09PSJmdW5jdGlvbiIpTW9kdWxlWyJwcmVSdW4iXT1bTW9kdWxlWyJwcmVSdW4iXV07d2hpbGUoTW9kdWxlWyJwcmVSdW4iXS5sZW5ndGgpe2FkZE9uUHJlUnVuKE1vZHVsZVsicHJlUnVuIl0uc2hpZnQoKSk7fX1jYWxsUnVudGltZUNhbGxiYWNrcyhfX0FUUFJFUlVOX18pO31mdW5jdGlvbiBpbml0UnVudGltZSgpe2NhbGxSdW50aW1lQ2FsbGJhY2tzKF9fQVRJTklUX18pO31mdW5jdGlvbiBwb3N0UnVuKCl7aWYoTW9kdWxlWyJwb3N0UnVuIl0pe2lmKHR5cGVvZiBNb2R1bGVbInBvc3RSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInBvc3RSdW4iXT1bTW9kdWxlWyJwb3N0UnVuIl1dO3doaWxlKE1vZHVsZVsicG9zdFJ1biJdLmxlbmd0aCl7YWRkT25Qb3N0UnVuKE1vZHVsZVsicG9zdFJ1biJdLnNoaWZ0KCkpO319Y2FsbFJ1bnRpbWVDYWxsYmFja3MoX19BVFBPU1RSVU5fXyk7fWZ1bmN0aW9uIGFkZE9uUHJlUnVuKGNiKXtfX0FUUFJFUlVOX18udW5zaGlmdChjYik7fWZ1bmN0aW9uIGFkZE9uSW5pdChjYil7X19BVElOSVRfXy51bnNoaWZ0KGNiKTt9ZnVuY3Rpb24gYWRkT25Qb3N0UnVuKGNiKXtfX0FUUE9TVFJVTl9fLnVuc2hpZnQoY2IpO312YXIgcnVuRGVwZW5kZW5jaWVzPTA7dmFyIGRlcGVuZGVuY2llc0Z1bGZpbGxlZD1udWxsO2Z1bmN0aW9uIGFkZFJ1bkRlcGVuZGVuY3koaWQpe3J1bkRlcGVuZGVuY2llcysrO2lmKE1vZHVsZVsibW9uaXRvclJ1bkRlcGVuZGVuY2llcyJdKXtNb2R1bGVbIm1vbml0b3JSdW5EZXBlbmRlbmNpZXMiXShydW5EZXBlbmRlbmNpZXMpO319ZnVuY3Rpb24gcmVtb3ZlUnVuRGVwZW5kZW5jeShpZCl7cnVuRGVwZW5kZW5jaWVzLS07aWYoTW9kdWxlWyJtb25pdG9yUnVuRGVwZW5kZW5jaWVzIl0pe01vZHVsZVsibW9uaXRvclJ1bkRlcGVuZGVuY2llcyJdKHJ1bkRlcGVuZGVuY2llcyk7fWlmKHJ1bkRlcGVuZGVuY2llcz09MCl7aWYoZGVwZW5kZW5jaWVzRnVsZmlsbGVkKXt2YXIgY2FsbGJhY2s9ZGVwZW5kZW5jaWVzRnVsZmlsbGVkO2RlcGVuZGVuY2llc0Z1bGZpbGxlZD1udWxsO2NhbGxiYWNrKCk7fX19ZnVuY3Rpb24gYWJvcnQod2hhdCl7aWYoTW9kdWxlWyJvbkFib3J0Il0pe01vZHVsZVsib25BYm9ydCJdKHdoYXQpO313aGF0PSJBYm9ydGVkKCIrd2hhdCsiKSI7ZXJyKHdoYXQpO0FCT1JUPXRydWU7d2hhdCs9Ii4gQnVpbGQgd2l0aCAtc0FTU0VSVElPTlMgZm9yIG1vcmUgaW5mby4iO3ZhciBlPW5ldyBXZWJBc3NlbWJseS5SdW50aW1lRXJyb3Iod2hhdCk7cmVhZHlQcm9taXNlUmVqZWN0KGUpO3Rocm93IGV9dmFyIGRhdGFVUklQcmVmaXg9ImRhdGE6YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtO2Jhc2U2NCwiO3ZhciBpc0RhdGFVUkk9ZmlsZW5hbWU9PmZpbGVuYW1lLnN0YXJ0c1dpdGgoZGF0YVVSSVByZWZpeCk7dmFyIHdhc21CaW5hcnlGaWxlO3dhc21CaW5hcnlGaWxlPSJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsQUdGemJRRUFBQUFCWVE1Z0JIOS9mMzhBWUFOL2YzOEFZQVYvZjM5L2Z3QmdCbjkvZjM5L2Z3QmdBbjkvQUdBQmZ3Ri9ZQUFBWUFOL2YzOEJmMkFCZndCZ0IzOS9mMzkvZjM4QVlBSjlmUUYvWUFSL2YzNStBR0FCZlFGL1lBdC9mMzkvZjM5L2YzOS9md0FDUFFvQllRRmhBQUVCWVFGaUFBSUJZUUZqQUFFQllRRmtBQVFCWVFGbEFBRUJZUUZtQUFrQllRRm5BQVVCWVFGb0FBUUJZUUZwQUFBQllRRnFBQVFER3hvSEJRb0lCZ1FHQ3dFQUFRZ0lEQVlOQXdNQ0FnQUFCd2NGQlFRRkFYQUJFQkFGQndFQmdBS0FnQUlHQ0FGL0FVSGduUVFMQngwSEFXc0NBQUZzQUE0QmJRQVpBVzRBR0FGdkFRQUJjQUFqQVhFQUZna1ZBUUJCQVFzUEVDSU5GUlVoRFNBYUhCOE5HeDBlQ3JKUUduRUJBWDhnQWtVRVFDQUFLQUlFSUFFb0FnUkdEd3NnQUNBQlJnUkFRUUVQQ3dKQUlBQW9BZ1FpQWkwQUFDSUFSU0FBSUFFb0FnUWlBUzBBQUNJRFIzSU5BQU5BSUFFdEFBRWhBeUFDTFFBQklnQkZEUUVnQVVFQmFpRUJJQUpCQVdvaEFpQUFJQU5HRFFBTEN5QUFJQU5HQzA4QkFuOUIyQmtvQWdBaUFTQUFRUWRxUVhoeElnSnFJUUFDUUNBQ1FRQWdBQ0FCVFJzTkFDQUFQd0JCRUhSTEJFQWdBQkFHUlEwQkMwSFlHU0FBTmdJQUlBRVBDMEhvR1VFd05nSUFRWDhMRGdBZ0FCQVhJQUVRRjBFUWRISUxCZ0FnQUJBV0N5a0FRZUFaUVFFMkFnQkI1QmxCQURZQ0FCQVFRZVFaUWR3WktBSUFOZ0lBUWR3WlFlQVpOZ0lBQ3lFQUlBRUVRQU5BSUFCQkFEb0FBQ0FBUVFGcUlRQWdBVUVCYXlJQkRRQUxDd3ZoQXdCQmpCZEJtZ2tRQ1VHWUYwRzVDRUVCUVFBUUNFR2tGMEcwQ0VFQlFZQi9RZjhBRUFGQnZCZEJyUWhCQVVHQWYwSC9BQkFCUWJBWFFhc0lRUUZCQUVIL0FSQUJRY2dYUVlrSVFRSkJnSUIrUWYvL0FSQUJRZFFYUVlBSVFRSkJBRUgvL3dNUUFVSGdGMEdZQ0VFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCN0JkQmp3aEJCRUVBUVg4UUFVSDRGMEhYQ0VFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCaEJoQnpnaEJCRUVBUVg4UUFVR1FHRUdqQ0VLQWdJQ0FnSUNBZ0lCL1F2Ly8vLy8vLy8vLy93QVFFVUdjR0VHaUNFSUFRbjhRRVVHb0dFR2NDRUVFRUFSQnRCaEJrd2xCQ0JBRVFZUVBRZWtJRUFOQnpBOUJsdzBRQTBHVUVFRUVRZHdJRUFKQjRCQkJBa0gxQ0JBQ1Fhd1JRUVJCaEFrUUFrSElFVUcrQ0JBSFFmQVJRUUJCMGd3UUFFR1lFa0VBUWJnTkVBQkJ3QkpCQVVId0RCQUFRZWdTUVFKQm53a1FBRUdRRTBFRFFiNEpFQUJCdUJOQkJFSG1DUkFBUWVBVFFRVkJnd29RQUVHSUZFRUVRZDBORUFCQnNCUkJCVUg3RFJBQVFaZ1NRUUJCNlFvUUFFSEFFa0VCUWNnS0VBQkI2QkpCQWtHckN4QUFRWkFUUVFOQmlRc1FBRUc0RTBFRVFiRU1FQUJCNEJOQkJVR1BEQkFBUWRnVVFRaEI3Z3NRQUVHQUZVRUpRY3dMRUFCQnFCVkJCa0dwQ2hBQVFkQVZRUWRCb2c0UUFBc2NBQ0FBSUFGQkNDQUNweUFDUWlDSXB5QURweUFEUWlDSXB4QUZDeUFBQWtBZ0FDZ0NCQ0FCUncwQUlBQW9BaHhCQVVZTkFDQUFJQUkyQWh3TEM1b0JBQ0FBUVFFNkFEVUNRQ0FBS0FJRUlBSkhEUUFnQUVFQk9nQTBBa0FnQUNnQ0VDSUNSUVJBSUFCQkFUWUNKQ0FBSUFNMkFoZ2dBQ0FCTmdJUUlBTkJBVWNOQWlBQUtBSXdRUUZHRFFFTUFnc2dBU0FDUmdSQUlBQW9BaGdpQWtFQ1JnUkFJQUFnQXpZQ0dDQURJUUlMSUFBb0FqQkJBVWNOQWlBQ1FRRkdEUUVNQWdzZ0FDQUFLQUlrUVFGcU5nSWtDeUFBUVFFNkFEWUxDMTBCQVg4Z0FDZ0NFQ0lEUlFSQUlBQkJBVFlDSkNBQUlBSTJBaGdnQUNBQk5nSVFEd3NDUUNBQklBTkdCRUFnQUNnQ0dFRUNSdzBCSUFBZ0FqWUNHQThMSUFCQkFUb0FOaUFBUVFJMkFoZ2dBQ0FBS0FJa1FRRnFOZ0lrQ3dzQ0FBdlNDd0VIZndKQUlBQkZEUUFnQUVFSWF5SUNJQUJCQkdzb0FnQWlBVUY0Y1NJQWFpRUZBa0FnQVVFQmNRMEFJQUZCQTNGRkRRRWdBaUFDS0FJQUlnRnJJZ0pCL0Jrb0FnQkpEUUVnQUNBQmFpRUFBa0FDUUVHQUdpZ0NBQ0FDUndSQUlBRkIvd0ZOQkVBZ0FVRURkaUVFSUFJb0Fnd2lBU0FDS0FJSUlnTkdCRUJCN0JsQjdCa29BZ0JCZmlBRWQzRTJBZ0FNQlFzZ0F5QUJOZ0lNSUFFZ0F6WUNDQXdFQ3lBQ0tBSVlJUVlnQWlBQ0tBSU1JZ0ZIQkVBZ0FpZ0NDQ0lESUFFMkFnd2dBU0FETmdJSURBTUxJQUpCRkdvaUJDZ0NBQ0lEUlFSQUlBSW9BaEFpQTBVTkFpQUNRUkJxSVFRTEEwQWdCQ0VISUFNaUFVRVVhaUlFS0FJQUlnTU5BQ0FCUVJCcUlRUWdBU2dDRUNJRERRQUxJQWRCQURZQ0FBd0NDeUFGS0FJRUlnRkJBM0ZCQTBjTkFrSDBHU0FBTmdJQUlBVWdBVUYrY1RZQ0JDQUNJQUJCQVhJMkFnUWdCU0FBTmdJQUR3dEJBQ0VCQ3lBR1JRMEFBa0FnQWlnQ0hDSURRUUowUVp3Y2FpSUVLQUlBSUFKR0JFQWdCQ0FCTmdJQUlBRU5BVUh3R1VId0dTZ0NBRUYrSUFOM2NUWUNBQXdDQ3lBR1FSQkJGQ0FHS0FJUUlBSkdHMm9nQVRZQ0FDQUJSUTBCQ3lBQklBWTJBaGdnQWlnQ0VDSURCRUFnQVNBRE5nSVFJQU1nQVRZQ0dBc2dBaWdDRkNJRFJRMEFJQUVnQXpZQ0ZDQURJQUUyQWhnTElBSWdCVThOQUNBRktBSUVJZ0ZCQVhGRkRRQUNRQUpBQWtBQ1FDQUJRUUp4UlFSQVFZUWFLQUlBSUFWR0JFQkJoQm9nQWpZQ0FFSDRHVUg0R1NnQ0FDQUFhaUlBTmdJQUlBSWdBRUVCY2pZQ0JDQUNRWUFhS0FJQVJ3MEdRZlFaUVFBMkFnQkJnQnBCQURZQ0FBOExRWUFhS0FJQUlBVkdCRUJCZ0JvZ0FqWUNBRUgwR1VIMEdTZ0NBQ0FBYWlJQU5nSUFJQUlnQUVFQmNqWUNCQ0FBSUFKcUlBQTJBZ0FQQ3lBQlFYaHhJQUJxSVFBZ0FVSC9BVTBFUUNBQlFRTjJJUVFnQlNnQ0RDSUJJQVVvQWdnaUEwWUVRRUhzR1VIc0dTZ0NBRUYrSUFSM2NUWUNBQXdGQ3lBRElBRTJBZ3dnQVNBRE5nSUlEQVFMSUFVb0FoZ2hCaUFGSUFVb0Fnd2lBVWNFUUVIOEdTZ0NBQm9nQlNnQ0NDSURJQUUyQWd3Z0FTQUROZ0lJREFNTElBVkJGR29pQkNnQ0FDSURSUVJBSUFVb0FoQWlBMFVOQWlBRlFSQnFJUVFMQTBBZ0JDRUhJQU1pQVVFVWFpSUVLQUlBSWdNTkFDQUJRUkJxSVFRZ0FTZ0NFQ0lERFFBTElBZEJBRFlDQUF3Q0N5QUZJQUZCZm5FMkFnUWdBaUFBUVFGeU5nSUVJQUFnQW1vZ0FEWUNBQXdEQzBFQUlRRUxJQVpGRFFBQ1FDQUZLQUljSWdOQkFuUkJuQnhxSWdRb0FnQWdCVVlFUUNBRUlBRTJBZ0FnQVEwQlFmQVpRZkFaS0FJQVFYNGdBM2R4TmdJQURBSUxJQVpCRUVFVUlBWW9BaEFnQlVZYmFpQUJOZ0lBSUFGRkRRRUxJQUVnQmpZQ0dDQUZLQUlRSWdNRVFDQUJJQU0yQWhBZ0F5QUJOZ0lZQ3lBRktBSVVJZ05GRFFBZ0FTQUROZ0lVSUFNZ0FUWUNHQXNnQWlBQVFRRnlOZ0lFSUFBZ0Ftb2dBRFlDQUNBQ1FZQWFLQUlBUncwQVFmUVpJQUEyQWdBUEN5QUFRZjhCVFFSQUlBQkJlSEZCbEJwcUlRRUNmMEhzR1NnQ0FDSURRUUVnQUVFRGRuUWlBSEZGQkVCQjdCa2dBQ0FEY2pZQ0FDQUJEQUVMSUFFb0FnZ0xJUUFnQVNBQ05nSUlJQUFnQWpZQ0RDQUNJQUUyQWd3Z0FpQUFOZ0lJRHd0Qkh5RURJQUJCLy8vL0IwMEVRQ0FBUVNZZ0FFRUlkbWNpQVd0MlFRRnhJQUZCQVhSclFUNXFJUU1MSUFJZ0F6WUNIQ0FDUWdBM0FoQWdBMEVDZEVHY0hHb2hBUUpBQWtBQ1FFSHdHU2dDQUNJRVFRRWdBM1FpQjNGRkJFQkI4QmtnQkNBSGNqWUNBQ0FCSUFJMkFnQWdBaUFCTmdJWURBRUxJQUJCR1NBRFFRRjJhMEVBSUFOQkgwY2JkQ0VESUFFb0FnQWhBUU5BSUFFaUJDZ0NCRUY0Y1NBQVJnMENJQU5CSFhZaEFTQURRUUYwSVFNZ0JDQUJRUVJ4YWlJSFFSQnFLQUlBSWdFTkFBc2dCeUFDTmdJUUlBSWdCRFlDR0FzZ0FpQUNOZ0lNSUFJZ0FqWUNDQXdCQ3lBRUtBSUlJZ0FnQWpZQ0RDQUVJQUkyQWdnZ0FrRUFOZ0lZSUFJZ0JEWUNEQ0FDSUFBMkFnZ0xRWXdhUVl3YUtBSUFRUUZySWdCQmZ5QUFHellDQUFzTGR3RUVmeUFBdkNJRVFmLy8vd054SVFFQ1FDQUVRUmQyUWY4QmNTSUNSUTBBSUFKQjhBQk5CRUFnQVVHQWdJQUVja0h4QUNBQ2EzWWhBUXdCQ3lBQ1FZMEJTd1JBUVlENEFTRURRUUFoQVF3QkN5QUNRUXAwUVlDQUIyc2hBd3NnQXlBRVFSQjJRWUNBQW5GeUlBRkJEWFp5UWYvL0EzRUxJd0VCZjBIY0dTZ0NBQ0lBQkVBRFFDQUFLQUlBRVFZQUlBQW9BZ1FpQUEwQUN3c0x2Z3NDQzM4SmZTTUFRYUFCYXlJTEpBQWdDMEV3YWtFa0VBOERRQ0FCSUExSEJFQWdBaUFOUVFOc0lneEJBbXBCQW5RaURtb3FBZ0FoRnlBQ0lBeEJBV3BCQW5RaUQyb3FBZ0FoR0NBSUlBeEJBblFpRUdvZ0FpQVFhaW9DQUNJWk9BSUFJQWdnRDJvZ0dEZ0NBQ0FJSUE1cUlCYzRBZ0FnQnlBTlFRVjBhaUlNSUJnNEFnUWdEQ0FaT0FJQUlBd2dGemdDQ0NBTVFRQTJBZ3dDUUNBQVJRUkFJQVlnRFdvdEFBQkZEUUVMSUF4QmdJQ0FDRFlDREFzZ0J5QU5RUVYwSWhGQkhISnFJQVVnRFVFQ2RDSU1RUUZ5SWhKcUxRQUFRUWgwSUFVZ0RHb3RBQUJ5SUFVZ0RFRUNjaUlUYWkwQUFFRVFkSElnQlNBTVFRTnlJZ3hxTFFBQVFSaDBjallDQUNBTElBTWdFa0VDZENJU2Fpb0NBQ0lYT0FLUUFTQUxJQU1nRTBFQ2RDSVRhaW9DQUNJWU9BS1VBU0FMSUFNZ0RFRUNkQ0lVYWlvQ0FDSVpPQUtZQVNBTElBTWdEVUVFZENJVmFpb0NBSXdpR2pnQ25BRWdDMEhnQUdvaURDQUxLZ0tZQVNJV1F3QUFBTUNVSUJhVUlBc3FBcFFCSWhaREFBQUF3SlFnRnBSREFBQ0FQNUtTT0FJQUlBd2dDeW9Da0FFaUZpQVdraUFMS2dLVUFaUWdDeW9DbUFGREFBQUF3SlFnQ3lvQ25BR1VramdDQkNBTUlBc3FBcEFCSWhZZ0ZwSWdDeW9DbUFHVUlBc3FBcFFCSWhZZ0ZwSWdDeW9DbkFHVWtqZ0NDQ0FNSUFzcUFwQUJJaFlnRnBJZ0N5b0NsQUdVSUFzcUFwZ0JJaFlnRnBJZ0N5b0NuQUdVa2pnQ0RDQU1JQXNxQXBnQkloWkRBQUFBd0pRZ0ZwUWdDeW9Da0FFaUZrTUFBQURBbENBV2xFTUFBSUEva3BJNEFoQWdEQ0FMS2dLVUFTSVdJQmFTSUFzcUFwZ0JsQ0FMS2dLUUFVTUFBQURBbENBTEtnS2NBWlNTT0FJVUlBd2dDeW9Da0FFaUZpQVdraUFMS2dLWUFaUWdDeW9DbEFGREFBQUF3SlFnQ3lvQ25BR1VramdDR0NBTUlBc3FBcFFCSWhZZ0ZwSWdDeW9DbUFHVUlBc3FBcEFCSWhZZ0ZwSWdDeW9DbkFHVWtqZ0NIQ0FNSUFzcUFwUUJJaFpEQUFBQXdKUWdGcFFnQ3lvQ2tBRWlGa01BQUFEQWxDQVdsRU1BQUlBL2twSTRBaUFnQ1NBVmFpQVhPQUlBSUFrZ0Vtb2dHRGdDQUNBSklCTnFJQms0QWdBZ0NTQVVhaUFhT0FJQUlBc2dCQ0FRYWlvQ0FDSVhPQUl3SUFzZ0JDQVBhaW9DQUNJWU9BSkFJQXNnQkNBT2Fpb0NBQ0laT0FKUUlBb2dFR29nRnpnQ0FDQUtJQTlxSUJnNEFnQWdDaUFPYWlBWk9BSUFJQXNnRENvQ0dDQUxLZ0k0bENBTUtnSUFJQXNxQWpDVUlBd3FBZ3dnQ3lvQ05KU1NramdDQUNBTElBd3FBaHdnQ3lvQ09KUWdEQ29DQkNBTEtnSXdsQ0FNS2dJUUlBc3FBalNVa3BJNEFnUWdDeUFNS2dJZ0lBc3FBamlVSUF3cUFnZ2dDeW9DTUpRZ0RDb0NGQ0FMS2dJMGxKS1NPQUlJSUFzZ0RDb0NHQ0FMS2dKRWxDQU1LZ0lBSUFzcUFqeVVJQXdxQWd3Z0N5b0NRSlNTa2pnQ0RDQUxJQXdxQWh3Z0N5b0NSSlFnRENvQ0JDQUxLZ0k4bENBTUtnSVFJQXNxQWtDVWtwSTRBaEFnQ3lBTUtnSWdJQXNxQWtTVUlBd3FBZ2dnQ3lvQ1BKUWdEQ29DRkNBTEtnSkFsSktTT0FJVUlBc2dEQ29DR0NBTEtnSlFsQ0FNS2dJQUlBc3FBa2lVSUF3cUFnd2dDeW9DVEpTU2tqZ0NHQ0FMSUF3cUFod2dDeW9DVUpRZ0RDb0NCQ0FMS2dKSWxDQU1LZ0lRSUFzcUFreVVrcEk0QWh3Z0N5QU1LZ0lnSUFzcUFsQ1VJQXdxQWdnZ0N5b0NTSlFnRENvQ0ZDQUxLZ0pNbEpLU09BSWdJQXNxQWlBaEZ5QUxLZ0lJSVJnZ0N5b0NGQ0VaSUFjZ0VVRVFjbW9nQ3lvQ0dDSWFJQnFVSUFzcUFnQWlGaUFXbENBTEtnSU1JaHNnRzVTU2trTUFBSUJBbENBYUlBc3FBaHdpSEpRZ0ZpQUxLZ0lFSWgyVUlCc2dDeW9DRUNJZWxKS1NRd0FBZ0VDVUVBdzJBZ0FnQnlBUlFSUnlhaUFhSUJlVUlCWWdHSlFnR3lBWmxKS1NRd0FBZ0VDVUlCd2dISlFnSFNBZGxDQWVJQjZVa3BKREFBQ0FRSlFRRERZQ0FDQUhJQkZCR0hKcUlCd2dGNVFnSFNBWWxDQWVJQm1Va3BKREFBQ0FRSlFnRnlBWGxDQVlJQmlVSUJrZ0daU1Nra01BQUlCQWxCQU1OZ0lBSUExQkFXb2hEUXdCQ3dzZ0MwR2dBV29rQUFzYUFDQUFJQUVvQWdnZ0JSQUtCRUFnQVNBQ0lBTWdCQkFUQ3dzM0FDQUFJQUVvQWdnZ0JSQUtCRUFnQVNBQ0lBTWdCQkFURHdzZ0FDZ0NDQ0lBSUFFZ0FpQURJQVFnQlNBQUtBSUFLQUlVRVFNQUM1RUJBQ0FBSUFFb0FnZ2dCQkFLQkVBZ0FTQUNJQU1RRWc4TEFrQWdBQ0FCS0FJQUlBUVFDa1VOQUFKQUlBSWdBU2dDRUVjRVFDQUJLQUlVSUFKSERRRUxJQU5CQVVjTkFTQUJRUUUyQWlBUEN5QUJJQUkyQWhRZ0FTQUROZ0lnSUFFZ0FTZ0NLRUVCYWpZQ0tBSkFJQUVvQWlSQkFVY05BQ0FCS0FJWVFRSkhEUUFnQVVFQk9nQTJDeUFCUVFRMkFpd0xDL0lCQUNBQUlBRW9BZ2dnQkJBS0JFQWdBU0FDSUFNUUVnOExBa0FnQUNBQktBSUFJQVFRQ2dSQUFrQWdBaUFCS0FJUVJ3UkFJQUVvQWhRZ0FrY05BUXNnQTBFQlJ3MENJQUZCQVRZQ0lBOExJQUVnQXpZQ0lBSkFJQUVvQWl4QkJFWU5BQ0FCUVFBN0FUUWdBQ2dDQ0NJQUlBRWdBaUFDUVFFZ0JDQUFLQUlBS0FJVUVRTUFJQUV0QURVRVFDQUJRUU0yQWl3Z0FTMEFORVVOQVF3REN5QUJRUVEyQWl3TElBRWdBallDRkNBQklBRW9BaWhCQVdvMkFpZ2dBU2dDSkVFQlJ3MEJJQUVvQWhoQkFrY05BU0FCUVFFNkFEWVBDeUFBS0FJSUlnQWdBU0FDSUFNZ0JDQUFLQUlBS0FJWUVRSUFDd3N4QUNBQUlBRW9BZ2hCQUJBS0JFQWdBU0FDSUFNUUZBOExJQUFvQWdnaUFDQUJJQUlnQXlBQUtBSUFLQUljRVFBQUN4Z0FJQUFnQVNnQ0NFRUFFQW9FUUNBQklBSWdBeEFVQ3d2SkF3RUZmeU1BUVVCcUlnUWtBQUovUVFFZ0FDQUJRUUFRQ2cwQUdrRUFJQUZGRFFBYUl3QkJRR29pQXlRQUlBRW9BZ0FpQlVFRWF5Z0NBQ0VHSUFWQkNHc29BZ0FoQlNBRFFnQTNBaUFnQTBJQU53SW9JQU5DQURjQ01DQURRZ0EzQURjZ0EwSUFOd0lZSUFOQkFEWUNGQ0FEUWZ3Vk5nSVFJQU1nQVRZQ0RDQURRYXdXTmdJSUlBRWdCV29oQVVFQUlRVUNRQ0FHUWF3V1FRQVFDZ1JBSUFOQkFUWUNPQ0FHSUFOQkNHb2dBU0FCUVFGQkFDQUdLQUlBS0FJVUVRTUFJQUZCQUNBREtBSWdRUUZHR3lFRkRBRUxJQVlnQTBFSWFpQUJRUUZCQUNBR0tBSUFLQUlZRVFJQUFrQUNRQ0FES0FJc0RnSUFBUUlMSUFNb0FoeEJBQ0FES0FJb1FRRkdHMEVBSUFNb0FpUkJBVVliUVFBZ0F5Z0NNRUVCUmhzaEJRd0JDeUFES0FJZ1FRRkhCRUFnQXlnQ01BMEJJQU1vQWlSQkFVY05BU0FES0FJb1FRRkhEUUVMSUFNb0FoZ2hCUXNnQTBGQWF5UUFRUUFnQlNJQlJRMEFHaUFFUVF4cVFUUVFEeUFFUVFFMkFqZ2dCRUYvTmdJVUlBUWdBRFlDRUNBRUlBRTJBZ2dnQVNBRVFRaHFJQUlvQWdCQkFTQUJLQUlBS0FJY0VRQUFJQVFvQWlBaUFFRUJSZ1JBSUFJZ0JDZ0NHRFlDQUFzZ0FFRUJSZ3NoQnlBRVFVQnJKQUFnQndzS0FDQUFJQUZCQUJBS0N3UUFJQUFMdlNjQkRIOGpBRUVRYXlJS0pBQUNRQUpBQWtBQ1FBSkFBa0FDUUFKQUFrQUNRQUpBQWtBQ1FBSkFJQUJCOUFGTkJFQkI3QmtvQWdBaUJrRVFJQUJCQzJwQmVIRWdBRUVMU1JzaUJVRURkaUlBZGlJQlFRTnhCRUFDUUNBQlFYOXpRUUZ4SUFCcUlnSkJBM1FpQVVHVUdtb2lBQ0FCUVp3YWFpZ0NBQ0lCS0FJSUlnUkdCRUJCN0JrZ0JrRitJQUozY1RZQ0FBd0JDeUFFSUFBMkFnd2dBQ0FFTmdJSUN5QUJRUWhxSVFBZ0FTQUNRUU4wSWdKQkEzSTJBZ1FnQVNBQ2FpSUJJQUVvQWdSQkFYSTJBZ1FNRHdzZ0JVSDBHU2dDQUNJSFRRMEJJQUVFUUFKQVFRSWdBSFFpQWtFQUlBSnJjaUFCSUFCMGNXZ2lBVUVEZENJQVFaUWFhaUlDSUFCQm5CcHFLQUlBSWdBb0FnZ2lCRVlFUUVIc0dTQUdRWDRnQVhkeElnWTJBZ0FNQVFzZ0JDQUNOZ0lNSUFJZ0JEWUNDQXNnQUNBRlFRTnlOZ0lFSUFBZ0JXb2lDQ0FCUVFOMElnRWdCV3NpQkVFQmNqWUNCQ0FBSUFGcUlBUTJBZ0FnQndSQUlBZEJlSEZCbEJwcUlRRkJnQm9vQWdBaEFnSi9JQVpCQVNBSFFRTjJkQ0lEY1VVRVFFSHNHU0FESUFaeU5nSUFJQUVNQVFzZ0FTZ0NDQXNoQXlBQklBSTJBZ2dnQXlBQ05nSU1JQUlnQVRZQ0RDQUNJQU0yQWdnTElBQkJDR29oQUVHQUdpQUlOZ0lBUWZRWklBUTJBZ0FNRHd0QjhCa29BZ0FpQzBVTkFTQUxhRUVDZEVHY0hHb29BZ0FpQWlnQ0JFRjRjU0FGYXlFRElBSWhBUU5BQWtBZ0FTZ0NFQ0lBUlFSQUlBRW9BaFFpQUVVTkFRc2dBQ2dDQkVGNGNTQUZheUlCSUFNZ0FTQURTU0lCR3lFRElBQWdBaUFCR3lFQ0lBQWhBUXdCQ3dzZ0FpZ0NHQ0VKSUFJZ0FpZ0NEQ0lFUndSQVFmd1pLQUlBR2lBQ0tBSUlJZ0FnQkRZQ0RDQUVJQUEyQWdnTURnc2dBa0VVYWlJQktBSUFJZ0JGQkVBZ0FpZ0NFQ0lBUlEwRElBSkJFR29oQVFzRFFDQUJJUWdnQUNJRVFSUnFJZ0VvQWdBaUFBMEFJQVJCRUdvaEFTQUVLQUlRSWdBTkFBc2dDRUVBTmdJQURBMExRWDhoQlNBQVFiOS9TdzBBSUFCQkMyb2lBRUY0Y1NFRlFmQVpLQUlBSWdoRkRRQkJBQ0FGYXlFREFrQUNRQUpBQW45QkFDQUZRWUFDU1EwQUdrRWZJQVZCLy8vL0Iwc05BQm9nQlVFbUlBQkJDSFpuSWdCcmRrRUJjU0FBUVFGMGEwRSthZ3NpQjBFQ2RFR2NIR29vQWdBaUFVVUVRRUVBSVFBTUFRdEJBQ0VBSUFWQkdTQUhRUUYyYTBFQUlBZEJIMGNiZENFQ0EwQUNRQ0FCS0FJRVFYaHhJQVZySWdZZ0EwOE5BQ0FCSVFRZ0JpSUREUUJCQUNFRElBRWhBQXdEQ3lBQUlBRW9BaFFpQmlBR0lBRWdBa0VkZGtFRWNXb29BaEFpQVVZYklBQWdCaHNoQUNBQ1FRRjBJUUlnQVEwQUN3c2dBQ0FFY2tVRVFFRUFJUVJCQWlBSGRDSUFRUUFnQUd0eUlBaHhJZ0JGRFFNZ0FHaEJBblJCbkJ4cUtBSUFJUUFMSUFCRkRRRUxBMEFnQUNnQ0JFRjRjU0FGYXlJQ0lBTkpJUUVnQWlBRElBRWJJUU1nQUNBRUlBRWJJUVFnQUNnQ0VDSUJCSDhnQVFVZ0FDZ0NGQXNpQUEwQUN3c2dCRVVOQUNBRFFmUVpLQUlBSUFWclR3MEFJQVFvQWhnaEJ5QUVJQVFvQWd3aUFrY0VRRUg4R1NnQ0FCb2dCQ2dDQ0NJQUlBSTJBZ3dnQWlBQU5nSUlEQXdMSUFSQkZHb2lBU2dDQUNJQVJRUkFJQVFvQWhBaUFFVU5BeUFFUVJCcUlRRUxBMEFnQVNFR0lBQWlBa0VVYWlJQktBSUFJZ0FOQUNBQ1FSQnFJUUVnQWlnQ0VDSUFEUUFMSUFaQkFEWUNBQXdMQ3lBRlFmUVpLQUlBSWdSTkJFQkJnQm9vQWdBaEFBSkFJQVFnQldzaUFVRVFUd1JBSUFBZ0JXb2lBaUFCUVFGeU5nSUVJQUFnQkdvZ0FUWUNBQ0FBSUFWQkEzSTJBZ1FNQVFzZ0FDQUVRUU55TmdJRUlBQWdCR29pQVNBQktBSUVRUUZ5TmdJRVFRQWhBa0VBSVFFTFFmUVpJQUUyQWdCQmdCb2dBallDQUNBQVFRaHFJUUFNRFFzZ0JVSDRHU2dDQUNJQ1NRUkFRZmdaSUFJZ0JXc2lBVFlDQUVHRUdrR0VHaWdDQUNJQUlBVnFJZ0kyQWdBZ0FpQUJRUUZ5TmdJRUlBQWdCVUVEY2pZQ0JDQUFRUWhxSVFBTURRdEJBQ0VBSUFWQkwyb2lBd0ovUWNRZEtBSUFCRUJCekIwb0FnQU1BUXRCMEIxQ2Z6Y0NBRUhJSFVLQW9JQ0FnSUFFTndJQVFjUWRJQXBCREdwQmNIRkIyS3JWcWdWek5nSUFRZGdkUVFBMkFnQkJxQjFCQURZQ0FFR0FJQXNpQVdvaUJrRUFJQUZySWdoeElnRWdCVTBOREVHa0hTZ0NBQ0lFQkVCQm5CMG9BZ0FpQnlBQmFpSUpJQWROSUFRZ0NVbHlEUTBMQWtCQnFCMHRBQUJCQkhGRkJFQUNRQUpBQWtBQ1FFR0VHaWdDQUNJRUJFQkJyQjBoQUFOQUlBUWdBQ2dDQUNJSFR3UkFJQWNnQUNnQ0JHb2dCRXNOQXdzZ0FDZ0NDQ0lBRFFBTEMwRUFFQXNpQWtGL1JnMERJQUVoQmtISUhTZ0NBQ0lBUVFGcklnUWdBbkVFUUNBQklBSnJJQUlnQkdwQkFDQUFhM0ZxSVFZTElBVWdCazhOQTBHa0hTZ0NBQ0lBQkVCQm5CMG9BZ0FpQkNBR2FpSUlJQVJOSUFBZ0NFbHlEUVFMSUFZUUN5SUFJQUpIRFFFTUJRc2dCaUFDYXlBSWNTSUdFQXNpQWlBQUtBSUFJQUFvQWdScVJnMEJJQUloQUFzZ0FFRi9SZzBCSUFWQk1Hb2dCazBFUUNBQUlRSU1CQXRCekIwb0FnQWlBaUFESUFacmFrRUFJQUpyY1NJQ0VBdEJmMFlOQVNBQ0lBWnFJUVlnQUNFQ0RBTUxJQUpCZjBjTkFndEJxQjFCcUIwb0FnQkJCSEkyQWdBTElBRVFDeUlDUVg5R1FRQVFDeUlBUVg5R2NpQUFJQUpOY2cwRklBQWdBbXNpQmlBRlFTaHFUUTBGQzBHY0hVR2NIU2dDQUNBR2FpSUFOZ0lBUWFBZEtBSUFJQUJKQkVCQm9CMGdBRFlDQUFzQ1FFR0VHaWdDQUNJREJFQkJyQjBoQUFOQUlBSWdBQ2dDQUNJQklBQW9BZ1FpQkdwR0RRSWdBQ2dDQ0NJQURRQUxEQVFMUWZ3WktBSUFJZ0JCQUNBQUlBSk5HMFVFUUVIOEdTQUNOZ0lBQzBFQUlRQkJzQjBnQmpZQ0FFR3NIU0FDTmdJQVFZd2FRWDgyQWdCQmtCcEJ4QjBvQWdBMkFnQkJ1QjFCQURZQ0FBTkFJQUJCQTNRaUFVR2NHbW9nQVVHVUdtb2lCRFlDQUNBQlFhQWFhaUFFTmdJQUlBQkJBV29pQUVFZ1J3MEFDMEg0R1NBR1FTaHJJZ0JCZUNBQ2EwRUhjU0lCYXlJRU5nSUFRWVFhSUFFZ0Ftb2lBVFlDQUNBQklBUkJBWEkyQWdRZ0FDQUNha0VvTmdJRVFZZ2FRZFFkS0FJQU5nSUFEQVFMSUFJZ0EwMGdBU0FEUzNJTkFpQUFLQUlNUVFoeERRSWdBQ0FFSUFacU5nSUVRWVFhSUFOQmVDQURhMEVIY1NJQWFpSUJOZ0lBUWZnWlFmZ1pLQUlBSUFacUlnSWdBR3NpQURZQ0FDQUJJQUJCQVhJMkFnUWdBaUFEYWtFb05nSUVRWWdhUWRRZEtBSUFOZ0lBREFNTFFRQWhCQXdLQzBFQUlRSU1DQXRCL0Jrb0FnQWdBa3NFUUVIOEdTQUNOZ0lBQ3lBQ0lBWnFJUUZCckIwaEFBSkFBa0FDUUFOQUlBRWdBQ2dDQUVjRVFDQUFLQUlJSWdBTkFRd0NDd3NnQUMwQURFRUljVVVOQVF0QnJCMGhBQU5BSUFNZ0FDZ0NBQ0lCVHdSQUlBRWdBQ2dDQkdvaUJDQURTdzBEQ3lBQUtBSUlJUUFNQUFzQUN5QUFJQUkyQWdBZ0FDQUFLQUlFSUFacU5nSUVJQUpCZUNBQ2EwRUhjV29pQnlBRlFRTnlOZ0lFSUFGQmVDQUJhMEVIY1dvaUJpQUZJQWRxSWdWcklRQWdBeUFHUmdSQVFZUWFJQVUyQWdCQitCbEIrQmtvQWdBZ0FHb2lBRFlDQUNBRklBQkJBWEkyQWdRTUNBdEJnQm9vQWdBZ0JrWUVRRUdBR2lBRk5nSUFRZlFaUWZRWktBSUFJQUJxSWdBMkFnQWdCU0FBUVFGeU5nSUVJQUFnQldvZ0FEWUNBQXdJQ3lBR0tBSUVJZ05CQTNGQkFVY05CaUFEUVhoeElRa2dBMEgvQVUwRVFDQUdLQUlNSWdFZ0JpZ0NDQ0lDUmdSQVFld1pRZXdaS0FJQVFYNGdBMEVEZG5keE5nSUFEQWNMSUFJZ0FUWUNEQ0FCSUFJMkFnZ01CZ3NnQmlnQ0dDRUlJQVlnQmlnQ0RDSUNSd1JBSUFZb0FnZ2lBU0FDTmdJTUlBSWdBVFlDQ0F3RkN5QUdRUlJxSWdFb0FnQWlBMFVFUUNBR0tBSVFJZ05GRFFRZ0JrRVFhaUVCQ3dOQUlBRWhCQ0FESWdKQkZHb2lBU2dDQUNJRERRQWdBa0VRYWlFQklBSW9BaEFpQXcwQUN5QUVRUUEyQWdBTUJBdEIrQmtnQmtFb2F5SUFRWGdnQW10QkIzRWlBV3NpQ0RZQ0FFR0VHaUFCSUFKcUlnRTJBZ0FnQVNBSVFRRnlOZ0lFSUFBZ0FtcEJLRFlDQkVHSUdrSFVIU2dDQURZQ0FDQURJQVJCSnlBRWEwRUhjV3BCTDJzaUFDQUFJQU5CRUdwSkd5SUJRUnMyQWdRZ0FVRzBIU2tDQURjQ0VDQUJRYXdkS1FJQU53SUlRYlFkSUFGQkNHbzJBZ0JCc0IwZ0JqWUNBRUdzSFNBQ05nSUFRYmdkUVFBMkFnQWdBVUVZYWlFQUEwQWdBRUVITmdJRUlBQkJDR29oRENBQVFRUnFJUUFnRENBRVNRMEFDeUFCSUFOR0RRQWdBU0FCS0FJRVFYNXhOZ0lFSUFNZ0FTQURheUlDUVFGeU5nSUVJQUVnQWpZQ0FDQUNRZjhCVFFSQUlBSkJlSEZCbEJwcUlRQUNmMEhzR1NnQ0FDSUJRUUVnQWtFRGRuUWlBbkZGQkVCQjdCa2dBU0FDY2pZQ0FDQUFEQUVMSUFBb0FnZ0xJUUVnQUNBRE5nSUlJQUVnQXpZQ0RDQURJQUEyQWd3Z0F5QUJOZ0lJREFFTFFSOGhBQ0FDUWYvLy93ZE5CRUFnQWtFbUlBSkJDSFpuSWdCcmRrRUJjU0FBUVFGMGEwRSthaUVBQ3lBRElBQTJBaHdnQTBJQU53SVFJQUJCQW5SQm5CeHFJUUVDUUFKQVFmQVpLQUlBSWdSQkFTQUFkQ0lHY1VVRVFFSHdHU0FFSUFaeU5nSUFJQUVnQXpZQ0FBd0JDeUFDUVJrZ0FFRUJkbXRCQUNBQVFSOUhHM1FoQUNBQktBSUFJUVFEUUNBRUlnRW9BZ1JCZUhFZ0FrWU5BaUFBUVIxMklRUWdBRUVCZENFQUlBRWdCRUVFY1dvaUJpZ0NFQ0lFRFFBTElBWWdBellDRUFzZ0F5QUJOZ0lZSUFNZ0F6WUNEQ0FESUFNMkFnZ01BUXNnQVNnQ0NDSUFJQU0yQWd3Z0FTQUROZ0lJSUFOQkFEWUNHQ0FESUFFMkFnd2dBeUFBTmdJSUMwSDRHU2dDQUNJQUlBVk5EUUJCK0JrZ0FDQUZheUlCTmdJQVFZUWFRWVFhS0FJQUlnQWdCV29pQWpZQ0FDQUNJQUZCQVhJMkFnUWdBQ0FGUVFOeU5nSUVJQUJCQ0dvaEFBd0lDMEhvR1VFd05nSUFRUUFoQUF3SEMwRUFJUUlMSUFoRkRRQUNRQ0FHS0FJY0lnRkJBblJCbkJ4cUlnUW9BZ0FnQmtZRVFDQUVJQUkyQWdBZ0FnMEJRZkFaUWZBWktBSUFRWDRnQVhkeE5nSUFEQUlMSUFoQkVFRVVJQWdvQWhBZ0JrWWJhaUFDTmdJQUlBSkZEUUVMSUFJZ0NEWUNHQ0FHS0FJUUlnRUVRQ0FDSUFFMkFoQWdBU0FDTmdJWUN5QUdLQUlVSWdGRkRRQWdBaUFCTmdJVUlBRWdBallDR0FzZ0FDQUphaUVBSUFZZ0NXb2lCaWdDQkNFREN5QUdJQU5CZm5FMkFnUWdCU0FBUVFGeU5nSUVJQUFnQldvZ0FEWUNBQ0FBUWY4QlRRUkFJQUJCZUhGQmxCcHFJUUVDZjBIc0dTZ0NBQ0lDUVFFZ0FFRURkblFpQUhGRkJFQkI3QmtnQUNBQ2NqWUNBQ0FCREFFTElBRW9BZ2dMSVFBZ0FTQUZOZ0lJSUFBZ0JUWUNEQ0FGSUFFMkFnd2dCU0FBTmdJSURBRUxRUjhoQXlBQVFmLy8vd2ROQkVBZ0FFRW1JQUJCQ0habklnRnJka0VCY1NBQlFRRjBhMEUrYWlFREN5QUZJQU0yQWh3Z0JVSUFOd0lRSUFOQkFuUkJuQnhxSVFFQ1FBSkFRZkFaS0FJQUlnSkJBU0FEZENJRWNVVUVRRUh3R1NBQ0lBUnlOZ0lBSUFFZ0JUWUNBQXdCQ3lBQVFSa2dBMEVCZG10QkFDQURRUjlIRzNRaEF5QUJLQUlBSVFJRFFDQUNJZ0VvQWdSQmVIRWdBRVlOQWlBRFFSMTJJUUlnQTBFQmRDRURJQUVnQWtFRWNXb2lCQ2dDRUNJQ0RRQUxJQVFnQlRZQ0VBc2dCU0FCTmdJWUlBVWdCVFlDRENBRklBVTJBZ2dNQVFzZ0FTZ0NDQ0lBSUFVMkFnd2dBU0FGTmdJSUlBVkJBRFlDR0NBRklBRTJBZ3dnQlNBQU5nSUlDeUFIUVFocUlRQU1BZ3NDUUNBSFJRMEFBa0FnQkNnQ0hDSUFRUUowUVp3Y2FpSUJLQUlBSUFSR0JFQWdBU0FDTmdJQUlBSU5BVUh3R1NBSVFYNGdBSGR4SWdnMkFnQU1BZ3NnQjBFUVFSUWdCeWdDRUNBRVJodHFJQUkyQWdBZ0FrVU5BUXNnQWlBSE5nSVlJQVFvQWhBaUFBUkFJQUlnQURZQ0VDQUFJQUkyQWhnTElBUW9BaFFpQUVVTkFDQUNJQUEyQWhRZ0FDQUNOZ0lZQ3dKQUlBTkJEMDBFUUNBRUlBTWdCV29pQUVFRGNqWUNCQ0FBSUFScUlnQWdBQ2dDQkVFQmNqWUNCQXdCQ3lBRUlBVkJBM0kyQWdRZ0JDQUZhaUlDSUFOQkFYSTJBZ1FnQWlBRGFpQUROZ0lBSUFOQi93Rk5CRUFnQTBGNGNVR1VHbW9oQUFKL1Fld1pLQUlBSWdGQkFTQURRUU4yZENJRGNVVUVRRUhzR1NBQklBTnlOZ0lBSUFBTUFRc2dBQ2dDQ0FzaEFTQUFJQUkyQWdnZ0FTQUNOZ0lNSUFJZ0FEWUNEQ0FDSUFFMkFnZ01BUXRCSHlFQUlBTkIvLy8vQjAwRVFDQURRU1lnQTBFSWRtY2lBR3QyUVFGeElBQkJBWFJyUVQ1cUlRQUxJQUlnQURZQ0hDQUNRZ0EzQWhBZ0FFRUNkRUdjSEdvaEFRSkFBa0FnQ0VFQklBQjBJZ1p4UlFSQVFmQVpJQVlnQ0hJMkFnQWdBU0FDTmdJQURBRUxJQU5CR1NBQVFRRjJhMEVBSUFCQkgwY2JkQ0VBSUFFb0FnQWhCUU5BSUFVaUFTZ0NCRUY0Y1NBRFJnMENJQUJCSFhZaEJpQUFRUUYwSVFBZ0FTQUdRUVJ4YWlJR0tBSVFJZ1VOQUFzZ0JpQUNOZ0lRQ3lBQ0lBRTJBaGdnQWlBQ05nSU1JQUlnQWpZQ0NBd0JDeUFCS0FJSUlnQWdBallDRENBQklBSTJBZ2dnQWtFQU5nSVlJQUlnQVRZQ0RDQUNJQUEyQWdnTElBUkJDR29oQUF3QkN3SkFJQWxGRFFBQ1FDQUNLQUljSWdCQkFuUkJuQnhxSWdFb0FnQWdBa1lFUUNBQklBUTJBZ0FnQkEwQlFmQVpJQXRCZmlBQWQzRTJBZ0FNQWdzZ0NVRVFRUlFnQ1NnQ0VDQUNSaHRxSUFRMkFnQWdCRVVOQVFzZ0JDQUpOZ0lZSUFJb0FoQWlBQVJBSUFRZ0FEWUNFQ0FBSUFRMkFoZ0xJQUlvQWhRaUFFVU5BQ0FFSUFBMkFoUWdBQ0FFTmdJWUN3SkFJQU5CRDAwRVFDQUNJQU1nQldvaUFFRURjallDQkNBQUlBSnFJZ0FnQUNnQ0JFRUJjallDQkF3QkN5QUNJQVZCQTNJMkFnUWdBaUFGYWlJRUlBTkJBWEkyQWdRZ0F5QUVhaUFETmdJQUlBY0VRQ0FIUVhoeFFaUWFhaUVBUVlBYUtBSUFJUUVDZjBFQklBZEJBM1owSWdVZ0JuRkZCRUJCN0JrZ0JTQUdjallDQUNBQURBRUxJQUFvQWdnTElRWWdBQ0FCTmdJSUlBWWdBVFlDRENBQklBQTJBZ3dnQVNBR05nSUlDMEdBR2lBRU5nSUFRZlFaSUFNMkFnQUxJQUpCQ0dvaEFBc2dDa0VRYWlRQUlBQUxDK2NSQWdCQmdBZ0wxaEYxYm5OcFoyNWxaQ0J6YUc5eWRBQjFibk5wWjI1bFpDQnBiblFBWm14dllYUUFkV2x1ZERZMFgzUUFkVzV6YVdkdVpXUWdZMmhoY2dCaWIyOXNBR1Z0YzJOeWFYQjBaVzQ2T25aaGJBQjFibk5wWjI1bFpDQnNiMjVuQUhOMFpEbzZkM04wY21sdVp3QnpkR1E2T25OMGNtbHVad0J6ZEdRNk9uVXhObk4wY21sdVp3QnpkR1E2T25Vek1uTjBjbWx1WndCa2IzVmliR1VBZG05cFpBQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4emFHOXlkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhkVzV6YVdkdVpXUWdjMmh2Y25RK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEdsdWRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXNXphV2R1WldRZ2FXNTBQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eG1iRzloZEQ0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4ZFdsdWREaGZkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhhVzUwT0Y5MFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4MWFXNTBNVFpmZEQ0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4YVc1ME1UWmZkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhkV2x1ZERZMFgzUStBR1Z0YzJOeWFYQjBaVzQ2T20xbGJXOXllVjkyYVdWM1BHbHVkRFkwWDNRK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEhWcGJuUXpNbDkwUGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkenhwYm5Rek1sOTBQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eGphR0Z5UGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkengxYm5OcFoyNWxaQ0JqYUdGeVBnQnpkR1E2T21KaGMybGpYM04wY21sdVp6eDFibk5wWjI1bFpDQmphR0Z5UGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkenh6YVdkdVpXUWdZMmhoY2o0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4Ykc5dVp6NEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXNXphV2R1WldRZ2JHOXVaejRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhaRzkxWW14bFBnQk9VM1F6WDE4eU1USmlZWE5wWTE5emRISnBibWRKWTA1VFh6RXhZMmhoY2w5MGNtRnBkSE5KWTBWRlRsTmZPV0ZzYkc5allYUnZja2xqUlVWRlJRQUFBQUJFREFBQVFnY0FBRTVUZEROZlh6SXhNbUpoYzJsalgzTjBjbWx1WjBsb1RsTmZNVEZqYUdGeVgzUnlZV2wwYzBsb1JVVk9VMTg1WVd4c2IyTmhkRzl5U1doRlJVVkZBQUJFREFBQWpBY0FBRTVUZEROZlh6SXhNbUpoYzJsalgzTjBjbWx1WjBsM1RsTmZNVEZqYUdGeVgzUnlZV2wwYzBsM1JVVk9VMTg1WVd4c2IyTmhkRzl5U1hkRlJVVkZBQUJFREFBQTFBY0FBRTVUZEROZlh6SXhNbUpoYzJsalgzTjBjbWx1WjBsRWMwNVRYekV4WTJoaGNsOTBjbUZwZEhOSlJITkZSVTVUWHpsaGJHeHZZMkYwYjNKSlJITkZSVVZGQUFBQVJBd0FBQndJQUFCT1UzUXpYMTh5TVRKaVlYTnBZMTl6ZEhKcGJtZEpSR2xPVTE4eE1XTm9ZWEpmZEhKaGFYUnpTVVJwUlVWT1UxODVZV3hzYjJOaGRHOXlTVVJwUlVWRlJRQUFBRVFNQUFCb0NBQUFUakV3WlcxelkzSnBjSFJsYmpOMllXeEZBQUJFREFBQXRBZ0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTV05GUlFBQVJBd0FBTkFJQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBsaFJVVUFBRVFNQUFENENBQUFUakV3WlcxelkzSnBjSFJsYmpFeGJXVnRiM0o1WDNacFpYZEphRVZGQUFCRURBQUFJQWtBQUU0eE1HVnRjMk55YVhCMFpXNHhNVzFsYlc5eWVWOTJhV1YzU1hORlJRQUFSQXdBQUVnSkFBQk9NVEJsYlhOamNtbHdkR1Z1TVRGdFpXMXZjbmxmZG1sbGQwbDBSVVVBQUVRTUFBQndDUUFBVGpFd1pXMXpZM0pwY0hSbGJqRXhiV1Z0YjNKNVgzWnBaWGRKYVVWRkFBQkVEQUFBbUFrQUFFNHhNR1Z0YzJOeWFYQjBaVzR4TVcxbGJXOXllVjkyYVdWM1NXcEZSUUFBUkF3QUFNQUpBQUJPTVRCbGJYTmpjbWx3ZEdWdU1URnRaVzF2Y25sZmRtbGxkMGxzUlVVQUFFUU1BQURvQ1FBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSmJVVkZBQUJFREFBQUVBb0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTWGhGUlFBQVJBd0FBRGdLQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBsNVJVVUFBRVFNQUFCZ0NnQUFUakV3WlcxelkzSnBjSFJsYmpFeGJXVnRiM0o1WDNacFpYZEpaa1ZGQUFCRURBQUFpQW9BQUU0eE1HVnRjMk55YVhCMFpXNHhNVzFsYlc5eWVWOTJhV1YzU1dSRlJRQUFSQXdBQUxBS0FBQk9NVEJmWDJONGVHRmlhWFl4TVRaZlgzTm9hVzFmZEhsd1pWOXBibVp2UlFBQUFBQnNEQUFBMkFvQUFOQU1BQUJPTVRCZlgyTjRlR0ZpYVhZeE1UZGZYMk5zWVhOelgzUjVjR1ZmYVc1bWIwVUFBQUJzREFBQUNBc0FBUHdLQUFBQUFBQUFmQXNBQUFJQUFBQURBQUFBQkFBQUFBVUFBQUFHQUFBQVRqRXdYMTlqZUhoaFltbDJNVEl6WDE5bWRXNWtZVzFsYm5SaGJGOTBlWEJsWDJsdVptOUZBR3dNQUFCVUN3QUEvQW9BQUhZQUFBQkFDd0FBaUFzQUFHSUFBQUJBQ3dBQWxBc0FBR01BQUFCQUN3QUFvQXNBQUdnQUFBQkFDd0FBckFzQUFHRUFBQUJBQ3dBQXVBc0FBSE1BQUFCQUN3QUF4QXNBQUhRQUFBQkFDd0FBMEFzQUFHa0FBQUJBQ3dBQTNBc0FBR29BQUFCQUN3QUE2QXNBQUd3QUFBQkFDd0FBOUFzQUFHMEFBQUJBQ3dBQUFBd0FBSGdBQUFCQUN3QUFEQXdBQUhrQUFBQkFDd0FBR0F3QUFHWUFBQUJBQ3dBQUpBd0FBR1FBQUFCQUN3QUFNQXdBQUFBQUFBQXNDd0FBQWdBQUFBY0FBQUFFQUFBQUJRQUFBQWdBQUFBSkFBQUFDZ0FBQUFzQUFBQUFBQUFBdEF3QUFBSUFBQUFNQUFBQUJBQUFBQVVBQUFBSUFBQUFEUUFBQUE0QUFBQVBBQUFBVGpFd1gxOWplSGhoWW1sMk1USXdYMTl6YVY5amJHRnpjMTkwZVhCbFgybHVabTlGQUFBQUFHd01BQUNNREFBQUxBc0FBRk4wT1hSNWNHVmZhVzVtYndBQUFBQkVEQUFBd0F3QVFkZ1pDd1BnRGdFPSI7aWYoIWlzRGF0YVVSSSh3YXNtQmluYXJ5RmlsZSkpe3dhc21CaW5hcnlGaWxlPWxvY2F0ZUZpbGUod2FzbUJpbmFyeUZpbGUpO31mdW5jdGlvbiBnZXRCaW5hcnlTeW5jKGZpbGUpe2lmKGZpbGU9PXdhc21CaW5hcnlGaWxlJiZ3YXNtQmluYXJ5KXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkod2FzbUJpbmFyeSl9dmFyIGJpbmFyeT10cnlQYXJzZUFzRGF0YVVSSShmaWxlKTtpZihiaW5hcnkpe3JldHVybiBiaW5hcnl9aWYocmVhZEJpbmFyeSl7cmV0dXJuIHJlYWRCaW5hcnkoZmlsZSl9dGhyb3cgImJvdGggYXN5bmMgYW5kIHN5bmMgZmV0Y2hpbmcgb2YgdGhlIHdhc20gZmFpbGVkIn1mdW5jdGlvbiBnZXRCaW5hcnlQcm9taXNlKGJpbmFyeUZpbGUpe3JldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpPT5nZXRCaW5hcnlTeW5jKGJpbmFyeUZpbGUpKX1mdW5jdGlvbiBpbnN0YW50aWF0ZUFycmF5QnVmZmVyKGJpbmFyeUZpbGUsaW1wb3J0cyxyZWNlaXZlcil7cmV0dXJuIGdldEJpbmFyeVByb21pc2UoYmluYXJ5RmlsZSkudGhlbihiaW5hcnk9PldlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGJpbmFyeSxpbXBvcnRzKSkudGhlbihpbnN0YW5jZT0+aW5zdGFuY2UpLnRoZW4ocmVjZWl2ZXIscmVhc29uPT57ZXJyKGBmYWlsZWQgdG8gYXN5bmNocm9ub3VzbHkgcHJlcGFyZSB3YXNtOiAke3JlYXNvbn1gKTthYm9ydChyZWFzb24pO30pfWZ1bmN0aW9uIGluc3RhbnRpYXRlQXN5bmMoYmluYXJ5LGJpbmFyeUZpbGUsaW1wb3J0cyxjYWxsYmFjayl7cmV0dXJuIGluc3RhbnRpYXRlQXJyYXlCdWZmZXIoYmluYXJ5RmlsZSxpbXBvcnRzLGNhbGxiYWNrKX1mdW5jdGlvbiBjcmVhdGVXYXNtKCl7dmFyIGluZm89eyJhIjp3YXNtSW1wb3J0c307ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbmNlKGluc3RhbmNlLG1vZHVsZSl7d2FzbUV4cG9ydHM9aW5zdGFuY2UuZXhwb3J0czt3YXNtTWVtb3J5PXdhc21FeHBvcnRzWyJrIl07dXBkYXRlTWVtb3J5Vmlld3MoKTthZGRPbkluaXQod2FzbUV4cG9ydHNbImwiXSk7cmVtb3ZlUnVuRGVwZW5kZW5jeSgpO3JldHVybiB3YXNtRXhwb3J0c31hZGRSdW5EZXBlbmRlbmN5KCk7ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbnRpYXRpb25SZXN1bHQocmVzdWx0KXtyZWNlaXZlSW5zdGFuY2UocmVzdWx0WyJpbnN0YW5jZSJdKTt9aWYoTW9kdWxlWyJpbnN0YW50aWF0ZVdhc20iXSl7dHJ5e3JldHVybiBNb2R1bGVbImluc3RhbnRpYXRlV2FzbSJdKGluZm8scmVjZWl2ZUluc3RhbmNlKX1jYXRjaChlKXtlcnIoYE1vZHVsZS5pbnN0YW50aWF0ZVdhc20gY2FsbGJhY2sgZmFpbGVkIHdpdGggZXJyb3I6ICR7ZX1gKTtyZWFkeVByb21pc2VSZWplY3QoZSk7fX1pbnN0YW50aWF0ZUFzeW5jKHdhc21CaW5hcnksd2FzbUJpbmFyeUZpbGUsaW5mbyxyZWNlaXZlSW5zdGFudGlhdGlvblJlc3VsdCkuY2F0Y2gocmVhZHlQcm9taXNlUmVqZWN0KTtyZXR1cm4ge319dmFyIGNhbGxSdW50aW1lQ2FsbGJhY2tzPWNhbGxiYWNrcz0+e3doaWxlKGNhbGxiYWNrcy5sZW5ndGg+MCl7Y2FsbGJhY2tzLnNoaWZ0KCkoTW9kdWxlKTt9fTtNb2R1bGVbIm5vRXhpdFJ1bnRpbWUiXXx8dHJ1ZTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfYmlnaW50PShwcmltaXRpdmVUeXBlLG5hbWUsc2l6ZSxtaW5SYW5nZSxtYXhSYW5nZSk9Pnt9O3ZhciBlbWJpbmRfaW5pdF9jaGFyQ29kZXM9KCk9Pnt2YXIgY29kZXM9bmV3IEFycmF5KDI1Nik7Zm9yKHZhciBpPTA7aTwyNTY7KytpKXtjb2Rlc1tpXT1TdHJpbmcuZnJvbUNoYXJDb2RlKGkpO31lbWJpbmRfY2hhckNvZGVzPWNvZGVzO307dmFyIGVtYmluZF9jaGFyQ29kZXM7dmFyIHJlYWRMYXRpbjFTdHJpbmc9cHRyPT57dmFyIHJldD0iIjt2YXIgYz1wdHI7d2hpbGUoSEVBUFU4W2NdKXtyZXQrPWVtYmluZF9jaGFyQ29kZXNbSEVBUFU4W2MrK11dO31yZXR1cm4gcmV0fTt2YXIgYXdhaXRpbmdEZXBlbmRlbmNpZXM9e307dmFyIHJlZ2lzdGVyZWRUeXBlcz17fTt2YXIgQmluZGluZ0Vycm9yO3ZhciB0aHJvd0JpbmRpbmdFcnJvcj1tZXNzYWdlPT57dGhyb3cgbmV3IEJpbmRpbmdFcnJvcihtZXNzYWdlKX07ZnVuY3Rpb24gc2hhcmVkUmVnaXN0ZXJUeXBlKHJhd1R5cGUscmVnaXN0ZXJlZEluc3RhbmNlLG9wdGlvbnM9e30pe3ZhciBuYW1lPXJlZ2lzdGVyZWRJbnN0YW5jZS5uYW1lO2lmKCFyYXdUeXBlKXt0aHJvd0JpbmRpbmdFcnJvcihgdHlwZSAiJHtuYW1lfSIgbXVzdCBoYXZlIGEgcG9zaXRpdmUgaW50ZWdlciB0eXBlaWQgcG9pbnRlcmApO31pZihyZWdpc3RlcmVkVHlwZXMuaGFzT3duUHJvcGVydHkocmF3VHlwZSkpe2lmKG9wdGlvbnMuaWdub3JlRHVwbGljYXRlUmVnaXN0cmF0aW9ucyl7cmV0dXJufWVsc2Uge3Rocm93QmluZGluZ0Vycm9yKGBDYW5ub3QgcmVnaXN0ZXIgdHlwZSAnJHtuYW1lfScgdHdpY2VgKTt9fXJlZ2lzdGVyZWRUeXBlc1tyYXdUeXBlXT1yZWdpc3RlcmVkSW5zdGFuY2U7aWYoYXdhaXRpbmdEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocmF3VHlwZSkpe3ZhciBjYWxsYmFja3M9YXdhaXRpbmdEZXBlbmRlbmNpZXNbcmF3VHlwZV07ZGVsZXRlIGF3YWl0aW5nRGVwZW5kZW5jaWVzW3Jhd1R5cGVdO2NhbGxiYWNrcy5mb3JFYWNoKGNiPT5jYigpKTt9fWZ1bmN0aW9uIHJlZ2lzdGVyVHlwZShyYXdUeXBlLHJlZ2lzdGVyZWRJbnN0YW5jZSxvcHRpb25zPXt9KXtpZighKCJhcmdQYWNrQWR2YW5jZSJpbiByZWdpc3RlcmVkSW5zdGFuY2UpKXt0aHJvdyBuZXcgVHlwZUVycm9yKCJyZWdpc3RlclR5cGUgcmVnaXN0ZXJlZEluc3RhbmNlIHJlcXVpcmVzIGFyZ1BhY2tBZHZhbmNlIil9cmV0dXJuIHNoYXJlZFJlZ2lzdGVyVHlwZShyYXdUeXBlLHJlZ2lzdGVyZWRJbnN0YW5jZSxvcHRpb25zKX12YXIgR2VuZXJpY1dpcmVUeXBlU2l6ZT04O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9ib29sPShyYXdUeXBlLG5hbWUsdHJ1ZVZhbHVlLGZhbHNlVmFsdWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lOm5hbWUsImZyb21XaXJlVHlwZSI6ZnVuY3Rpb24od3Qpe3JldHVybiAhIXd0fSwidG9XaXJlVHlwZSI6ZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsbyl7cmV0dXJuIG8/dHJ1ZVZhbHVlOmZhbHNlVmFsdWV9LCJhcmdQYWNrQWR2YW5jZSI6R2VuZXJpY1dpcmVUeXBlU2l6ZSwicmVhZFZhbHVlRnJvbVBvaW50ZXIiOmZ1bmN0aW9uKHBvaW50ZXIpe3JldHVybiB0aGlzWyJmcm9tV2lyZVR5cGUiXShIRUFQVThbcG9pbnRlcl0pfSxkZXN0cnVjdG9yRnVuY3Rpb246bnVsbH0pO307ZnVuY3Rpb24gaGFuZGxlQWxsb2NhdG9ySW5pdCgpe09iamVjdC5hc3NpZ24oSGFuZGxlQWxsb2NhdG9yLnByb3RvdHlwZSx7Z2V0KGlkKXtyZXR1cm4gdGhpcy5hbGxvY2F0ZWRbaWRdfSxoYXMoaWQpe3JldHVybiB0aGlzLmFsbG9jYXRlZFtpZF0hPT11bmRlZmluZWR9LGFsbG9jYXRlKGhhbmRsZSl7dmFyIGlkPXRoaXMuZnJlZWxpc3QucG9wKCl8fHRoaXMuYWxsb2NhdGVkLmxlbmd0aDt0aGlzLmFsbG9jYXRlZFtpZF09aGFuZGxlO3JldHVybiBpZH0sZnJlZShpZCl7dGhpcy5hbGxvY2F0ZWRbaWRdPXVuZGVmaW5lZDt0aGlzLmZyZWVsaXN0LnB1c2goaWQpO319KTt9ZnVuY3Rpb24gSGFuZGxlQWxsb2NhdG9yKCl7dGhpcy5hbGxvY2F0ZWQ9W3VuZGVmaW5lZF07dGhpcy5mcmVlbGlzdD1bXTt9dmFyIGVtdmFsX2hhbmRsZXM9bmV3IEhhbmRsZUFsbG9jYXRvcjt2YXIgX19lbXZhbF9kZWNyZWY9aGFuZGxlPT57aWYoaGFuZGxlPj1lbXZhbF9oYW5kbGVzLnJlc2VydmVkJiYwPT09LS1lbXZhbF9oYW5kbGVzLmdldChoYW5kbGUpLnJlZmNvdW50KXtlbXZhbF9oYW5kbGVzLmZyZWUoaGFuZGxlKTt9fTt2YXIgY291bnRfZW12YWxfaGFuZGxlcz0oKT0+e3ZhciBjb3VudD0wO2Zvcih2YXIgaT1lbXZhbF9oYW5kbGVzLnJlc2VydmVkO2k8ZW12YWxfaGFuZGxlcy5hbGxvY2F0ZWQubGVuZ3RoOysraSl7aWYoZW12YWxfaGFuZGxlcy5hbGxvY2F0ZWRbaV0hPT11bmRlZmluZWQpeysrY291bnQ7fX1yZXR1cm4gY291bnR9O3ZhciBpbml0X2VtdmFsPSgpPT57ZW12YWxfaGFuZGxlcy5hbGxvY2F0ZWQucHVzaCh7dmFsdWU6dW5kZWZpbmVkfSx7dmFsdWU6bnVsbH0se3ZhbHVlOnRydWV9LHt2YWx1ZTpmYWxzZX0pO2VtdmFsX2hhbmRsZXMucmVzZXJ2ZWQ9ZW12YWxfaGFuZGxlcy5hbGxvY2F0ZWQubGVuZ3RoO01vZHVsZVsiY291bnRfZW12YWxfaGFuZGxlcyJdPWNvdW50X2VtdmFsX2hhbmRsZXM7fTt2YXIgRW12YWw9e3RvVmFsdWU6aGFuZGxlPT57aWYoIWhhbmRsZSl7dGhyb3dCaW5kaW5nRXJyb3IoIkNhbm5vdCB1c2UgZGVsZXRlZCB2YWwuIGhhbmRsZSA9ICIraGFuZGxlKTt9cmV0dXJuIGVtdmFsX2hhbmRsZXMuZ2V0KGhhbmRsZSkudmFsdWV9LHRvSGFuZGxlOnZhbHVlPT57c3dpdGNoKHZhbHVlKXtjYXNlIHVuZGVmaW5lZDpyZXR1cm4gMTtjYXNlIG51bGw6cmV0dXJuIDI7Y2FzZSB0cnVlOnJldHVybiAzO2Nhc2UgZmFsc2U6cmV0dXJuIDQ7ZGVmYXVsdDp7cmV0dXJuIGVtdmFsX2hhbmRsZXMuYWxsb2NhdGUoe3JlZmNvdW50OjEsdmFsdWU6dmFsdWV9KX19fX07ZnVuY3Rpb24gc2ltcGxlUmVhZFZhbHVlRnJvbVBvaW50ZXIocG9pbnRlcil7cmV0dXJuIHRoaXNbImZyb21XaXJlVHlwZSJdKEhFQVAzMltwb2ludGVyPj4yXSl9dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX2VtdmFsPShyYXdUeXBlLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lOm5hbWUsImZyb21XaXJlVHlwZSI6aGFuZGxlPT57dmFyIHJ2PUVtdmFsLnRvVmFsdWUoaGFuZGxlKTtfX2VtdmFsX2RlY3JlZihoYW5kbGUpO3JldHVybiBydn0sInRvV2lyZVR5cGUiOihkZXN0cnVjdG9ycyx2YWx1ZSk9PkVtdmFsLnRvSGFuZGxlKHZhbHVlKSwiYXJnUGFja0FkdmFuY2UiOkdlbmVyaWNXaXJlVHlwZVNpemUsInJlYWRWYWx1ZUZyb21Qb2ludGVyIjpzaW1wbGVSZWFkVmFsdWVGcm9tUG9pbnRlcixkZXN0cnVjdG9yRnVuY3Rpb246bnVsbH0pO307dmFyIGZsb2F0UmVhZFZhbHVlRnJvbVBvaW50ZXI9KG5hbWUsd2lkdGgpPT57c3dpdGNoKHdpZHRoKXtjYXNlIDQ6cmV0dXJuIGZ1bmN0aW9uKHBvaW50ZXIpe3JldHVybiB0aGlzWyJmcm9tV2lyZVR5cGUiXShIRUFQRjMyW3BvaW50ZXI+PjJdKX07Y2FzZSA4OnJldHVybiBmdW5jdGlvbihwb2ludGVyKXtyZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUEY2NFtwb2ludGVyPj4zXSl9O2RlZmF1bHQ6dGhyb3cgbmV3IFR5cGVFcnJvcihgaW52YWxpZCBmbG9hdCB3aWR0aCAoJHt3aWR0aH0pOiAke25hbWV9YCl9fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfZmxvYXQ9KHJhd1R5cGUsbmFtZSxzaXplKT0+e25hbWU9cmVhZExhdGluMVN0cmluZyhuYW1lKTtyZWdpc3RlclR5cGUocmF3VHlwZSx7bmFtZTpuYW1lLCJmcm9tV2lyZVR5cGUiOnZhbHVlPT52YWx1ZSwidG9XaXJlVHlwZSI6KGRlc3RydWN0b3JzLHZhbHVlKT0+dmFsdWUsImFyZ1BhY2tBZHZhbmNlIjpHZW5lcmljV2lyZVR5cGVTaXplLCJyZWFkVmFsdWVGcm9tUG9pbnRlciI6ZmxvYXRSZWFkVmFsdWVGcm9tUG9pbnRlcihuYW1lLHNpemUpLGRlc3RydWN0b3JGdW5jdGlvbjpudWxsfSk7fTt2YXIgaW50ZWdlclJlYWRWYWx1ZUZyb21Qb2ludGVyPShuYW1lLHdpZHRoLHNpZ25lZCk9Pntzd2l0Y2god2lkdGgpe2Nhc2UgMTpyZXR1cm4gc2lnbmVkP3BvaW50ZXI9PkhFQVA4W3BvaW50ZXI+PjBdOnBvaW50ZXI9PkhFQVBVOFtwb2ludGVyPj4wXTtjYXNlIDI6cmV0dXJuIHNpZ25lZD9wb2ludGVyPT5IRUFQMTZbcG9pbnRlcj4+MV06cG9pbnRlcj0+SEVBUFUxNltwb2ludGVyPj4xXTtjYXNlIDQ6cmV0dXJuIHNpZ25lZD9wb2ludGVyPT5IRUFQMzJbcG9pbnRlcj4+Ml06cG9pbnRlcj0+SEVBUFUzMltwb2ludGVyPj4yXTtkZWZhdWx0OnRocm93IG5ldyBUeXBlRXJyb3IoYGludmFsaWQgaW50ZWdlciB3aWR0aCAoJHt3aWR0aH0pOiAke25hbWV9YCl9fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfaW50ZWdlcj0ocHJpbWl0aXZlVHlwZSxuYW1lLHNpemUsbWluUmFuZ2UsbWF4UmFuZ2UpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3ZhciBmcm9tV2lyZVR5cGU9dmFsdWU9PnZhbHVlO2lmKG1pblJhbmdlPT09MCl7dmFyIGJpdHNoaWZ0PTMyLTgqc2l6ZTtmcm9tV2lyZVR5cGU9dmFsdWU9PnZhbHVlPDxiaXRzaGlmdD4+PmJpdHNoaWZ0O312YXIgaXNVbnNpZ25lZFR5cGU9bmFtZS5pbmNsdWRlcygidW5zaWduZWQiKTt2YXIgY2hlY2tBc3NlcnRpb25zPSh2YWx1ZSx0b1R5cGVOYW1lKT0+e307dmFyIHRvV2lyZVR5cGU7aWYoaXNVbnNpZ25lZFR5cGUpe3RvV2lyZVR5cGU9ZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsdmFsdWUpe2NoZWNrQXNzZXJ0aW9ucyh2YWx1ZSx0aGlzLm5hbWUpO3JldHVybiB2YWx1ZT4+PjB9O31lbHNlIHt0b1dpcmVUeXBlPWZ1bmN0aW9uKGRlc3RydWN0b3JzLHZhbHVlKXtjaGVja0Fzc2VydGlvbnModmFsdWUsdGhpcy5uYW1lKTtyZXR1cm4gdmFsdWV9O31yZWdpc3RlclR5cGUocHJpbWl0aXZlVHlwZSx7bmFtZTpuYW1lLCJmcm9tV2lyZVR5cGUiOmZyb21XaXJlVHlwZSwidG9XaXJlVHlwZSI6dG9XaXJlVHlwZSwiYXJnUGFja0FkdmFuY2UiOkdlbmVyaWNXaXJlVHlwZVNpemUsInJlYWRWYWx1ZUZyb21Qb2ludGVyIjppbnRlZ2VyUmVhZFZhbHVlRnJvbVBvaW50ZXIobmFtZSxzaXplLG1pblJhbmdlIT09MCksZGVzdHJ1Y3RvckZ1bmN0aW9uOm51bGx9KTt9O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9tZW1vcnlfdmlldz0ocmF3VHlwZSxkYXRhVHlwZUluZGV4LG5hbWUpPT57dmFyIHR5cGVNYXBwaW5nPVtJbnQ4QXJyYXksVWludDhBcnJheSxJbnQxNkFycmF5LFVpbnQxNkFycmF5LEludDMyQXJyYXksVWludDMyQXJyYXksRmxvYXQzMkFycmF5LEZsb2F0NjRBcnJheV07dmFyIFRBPXR5cGVNYXBwaW5nW2RhdGFUeXBlSW5kZXhdO2Z1bmN0aW9uIGRlY29kZU1lbW9yeVZpZXcoaGFuZGxlKXt2YXIgc2l6ZT1IRUFQVTMyW2hhbmRsZT4+Ml07dmFyIGRhdGE9SEVBUFUzMltoYW5kbGUrND4+Ml07cmV0dXJuIG5ldyBUQShIRUFQOC5idWZmZXIsZGF0YSxzaXplKX1uYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7cmVnaXN0ZXJUeXBlKHJhd1R5cGUse25hbWU6bmFtZSwiZnJvbVdpcmVUeXBlIjpkZWNvZGVNZW1vcnlWaWV3LCJhcmdQYWNrQWR2YW5jZSI6R2VuZXJpY1dpcmVUeXBlU2l6ZSwicmVhZFZhbHVlRnJvbVBvaW50ZXIiOmRlY29kZU1lbW9yeVZpZXd9LHtpZ25vcmVEdXBsaWNhdGVSZWdpc3RyYXRpb25zOnRydWV9KTt9O2Z1bmN0aW9uIHJlYWRQb2ludGVyKHBvaW50ZXIpe3JldHVybiB0aGlzWyJmcm9tV2lyZVR5cGUiXShIRUFQVTMyW3BvaW50ZXI+PjJdKX12YXIgc3RyaW5nVG9VVEY4QXJyYXk9KHN0cixoZWFwLG91dElkeCxtYXhCeXRlc1RvV3JpdGUpPT57aWYoIShtYXhCeXRlc1RvV3JpdGU+MCkpcmV0dXJuIDA7dmFyIHN0YXJ0SWR4PW91dElkeDt2YXIgZW5kSWR4PW91dElkeCttYXhCeXRlc1RvV3JpdGUtMTtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXt2YXIgdT1zdHIuY2hhckNvZGVBdChpKTtpZih1Pj01NTI5NiYmdTw9NTczNDMpe3ZhciB1MT1zdHIuY2hhckNvZGVBdCgrK2kpO3U9NjU1MzYrKCh1JjEwMjMpPDwxMCl8dTEmMTAyMzt9aWYodTw9MTI3KXtpZihvdXRJZHg+PWVuZElkeClicmVhaztoZWFwW291dElkeCsrXT11O31lbHNlIGlmKHU8PTIwNDcpe2lmKG91dElkeCsxPj1lbmRJZHgpYnJlYWs7aGVhcFtvdXRJZHgrK109MTkyfHU+PjY7aGVhcFtvdXRJZHgrK109MTI4fHUmNjM7fWVsc2UgaWYodTw9NjU1MzUpe2lmKG91dElkeCsyPj1lbmRJZHgpYnJlYWs7aGVhcFtvdXRJZHgrK109MjI0fHU+PjEyO2hlYXBbb3V0SWR4KytdPTEyOHx1Pj42JjYzO2hlYXBbb3V0SWR4KytdPTEyOHx1JjYzO31lbHNlIHtpZihvdXRJZHgrMz49ZW5kSWR4KWJyZWFrO2hlYXBbb3V0SWR4KytdPTI0MHx1Pj4xODtoZWFwW291dElkeCsrXT0xMjh8dT4+MTImNjM7aGVhcFtvdXRJZHgrK109MTI4fHU+PjYmNjM7aGVhcFtvdXRJZHgrK109MTI4fHUmNjM7fX1oZWFwW291dElkeF09MDtyZXR1cm4gb3V0SWR4LXN0YXJ0SWR4fTt2YXIgc3RyaW5nVG9VVEY4PShzdHIsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk9PnN0cmluZ1RvVVRGOEFycmF5KHN0cixIRUFQVTgsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk7dmFyIGxlbmd0aEJ5dGVzVVRGOD1zdHI9Pnt2YXIgbGVuPTA7Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7dmFyIGM9c3RyLmNoYXJDb2RlQXQoaSk7aWYoYzw9MTI3KXtsZW4rKzt9ZWxzZSBpZihjPD0yMDQ3KXtsZW4rPTI7fWVsc2UgaWYoYz49NTUyOTYmJmM8PTU3MzQzKXtsZW4rPTQ7KytpO31lbHNlIHtsZW4rPTM7fX1yZXR1cm4gbGVufTt2YXIgVVRGOERlY29kZXI9dHlwZW9mIFRleHREZWNvZGVyIT0idW5kZWZpbmVkIj9uZXcgVGV4dERlY29kZXIoInV0ZjgiKTp1bmRlZmluZWQ7dmFyIFVURjhBcnJheVRvU3RyaW5nPShoZWFwT3JBcnJheSxpZHgsbWF4Qnl0ZXNUb1JlYWQpPT57dmFyIGVuZElkeD1pZHgrbWF4Qnl0ZXNUb1JlYWQ7dmFyIGVuZFB0cj1pZHg7d2hpbGUoaGVhcE9yQXJyYXlbZW5kUHRyXSYmIShlbmRQdHI+PWVuZElkeCkpKytlbmRQdHI7aWYoZW5kUHRyLWlkeD4xNiYmaGVhcE9yQXJyYXkuYnVmZmVyJiZVVEY4RGVjb2Rlcil7cmV0dXJuIFVURjhEZWNvZGVyLmRlY29kZShoZWFwT3JBcnJheS5zdWJhcnJheShpZHgsZW5kUHRyKSl9dmFyIHN0cj0iIjt3aGlsZShpZHg8ZW5kUHRyKXt2YXIgdTA9aGVhcE9yQXJyYXlbaWR4KytdO2lmKCEodTAmMTI4KSl7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHUwKTtjb250aW51ZX12YXIgdTE9aGVhcE9yQXJyYXlbaWR4KytdJjYzO2lmKCh1MCYyMjQpPT0xOTIpe3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSgodTAmMzEpPDw2fHUxKTtjb250aW51ZX12YXIgdTI9aGVhcE9yQXJyYXlbaWR4KytdJjYzO2lmKCh1MCYyNDApPT0yMjQpe3UwPSh1MCYxNSk8PDEyfHUxPDw2fHUyO31lbHNlIHt1MD0odTAmNyk8PDE4fHUxPDwxMnx1Mjw8NnxoZWFwT3JBcnJheVtpZHgrK10mNjM7fWlmKHUwPDY1NTM2KXtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUodTApO31lbHNlIHt2YXIgY2g9dTAtNjU1MzY7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fGNoPj4xMCw1NjMyMHxjaCYxMDIzKTt9fXJldHVybiBzdHJ9O3ZhciBVVEY4VG9TdHJpbmc9KHB0cixtYXhCeXRlc1RvUmVhZCk9PnB0cj9VVEY4QXJyYXlUb1N0cmluZyhIRUFQVTgscHRyLG1heEJ5dGVzVG9SZWFkKToiIjt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfc3RkX3N0cmluZz0ocmF3VHlwZSxuYW1lKT0+e25hbWU9cmVhZExhdGluMVN0cmluZyhuYW1lKTt2YXIgc3RkU3RyaW5nSXNVVEY4PW5hbWU9PT0ic3RkOjpzdHJpbmciO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lOm5hbWUsImZyb21XaXJlVHlwZSIodmFsdWUpe3ZhciBsZW5ndGg9SEVBUFUzMlt2YWx1ZT4+Ml07dmFyIHBheWxvYWQ9dmFsdWUrNDt2YXIgc3RyO2lmKHN0ZFN0cmluZ0lzVVRGOCl7dmFyIGRlY29kZVN0YXJ0UHRyPXBheWxvYWQ7Zm9yKHZhciBpPTA7aTw9bGVuZ3RoOysraSl7dmFyIGN1cnJlbnRCeXRlUHRyPXBheWxvYWQraTtpZihpPT1sZW5ndGh8fEhFQVBVOFtjdXJyZW50Qnl0ZVB0cl09PTApe3ZhciBtYXhSZWFkPWN1cnJlbnRCeXRlUHRyLWRlY29kZVN0YXJ0UHRyO3ZhciBzdHJpbmdTZWdtZW50PVVURjhUb1N0cmluZyhkZWNvZGVTdGFydFB0cixtYXhSZWFkKTtpZihzdHI9PT11bmRlZmluZWQpe3N0cj1zdHJpbmdTZWdtZW50O31lbHNlIHtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUoMCk7c3RyKz1zdHJpbmdTZWdtZW50O31kZWNvZGVTdGFydFB0cj1jdXJyZW50Qnl0ZVB0cisxO319fWVsc2Uge3ZhciBhPW5ldyBBcnJheShsZW5ndGgpO2Zvcih2YXIgaT0wO2k8bGVuZ3RoOysraSl7YVtpXT1TdHJpbmcuZnJvbUNoYXJDb2RlKEhFQVBVOFtwYXlsb2FkK2ldKTt9c3RyPWEuam9pbigiIik7fV9mcmVlKHZhbHVlKTtyZXR1cm4gc3RyfSwidG9XaXJlVHlwZSIoZGVzdHJ1Y3RvcnMsdmFsdWUpe2lmKHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpe3ZhbHVlPW5ldyBVaW50OEFycmF5KHZhbHVlKTt9dmFyIGxlbmd0aDt2YXIgdmFsdWVJc09mVHlwZVN0cmluZz10eXBlb2YgdmFsdWU9PSJzdHJpbmciO2lmKCEodmFsdWVJc09mVHlwZVN0cmluZ3x8dmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5fHx2YWx1ZSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5fHx2YWx1ZSBpbnN0YW5jZW9mIEludDhBcnJheSkpe3Rocm93QmluZGluZ0Vycm9yKCJDYW5ub3QgcGFzcyBub24tc3RyaW5nIHRvIHN0ZDo6c3RyaW5nIik7fWlmKHN0ZFN0cmluZ0lzVVRGOCYmdmFsdWVJc09mVHlwZVN0cmluZyl7bGVuZ3RoPWxlbmd0aEJ5dGVzVVRGOCh2YWx1ZSk7fWVsc2Uge2xlbmd0aD12YWx1ZS5sZW5ndGg7fXZhciBiYXNlPV9tYWxsb2MoNCtsZW5ndGgrMSk7dmFyIHB0cj1iYXNlKzQ7SEVBUFUzMltiYXNlPj4yXT1sZW5ndGg7aWYoc3RkU3RyaW5nSXNVVEY4JiZ2YWx1ZUlzT2ZUeXBlU3RyaW5nKXtzdHJpbmdUb1VURjgodmFsdWUscHRyLGxlbmd0aCsxKTt9ZWxzZSB7aWYodmFsdWVJc09mVHlwZVN0cmluZyl7Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXt2YXIgY2hhckNvZGU9dmFsdWUuY2hhckNvZGVBdChpKTtpZihjaGFyQ29kZT4yNTUpe19mcmVlKHB0cik7dGhyb3dCaW5kaW5nRXJyb3IoIlN0cmluZyBoYXMgVVRGLTE2IGNvZGUgdW5pdHMgdGhhdCBkbyBub3QgZml0IGluIDggYml0cyIpO31IRUFQVThbcHRyK2ldPWNoYXJDb2RlO319ZWxzZSB7Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXtIRUFQVThbcHRyK2ldPXZhbHVlW2ldO319fWlmKGRlc3RydWN0b3JzIT09bnVsbCl7ZGVzdHJ1Y3RvcnMucHVzaChfZnJlZSxiYXNlKTt9cmV0dXJuIGJhc2V9LCJhcmdQYWNrQWR2YW5jZSI6R2VuZXJpY1dpcmVUeXBlU2l6ZSwicmVhZFZhbHVlRnJvbVBvaW50ZXIiOnJlYWRQb2ludGVyLGRlc3RydWN0b3JGdW5jdGlvbihwdHIpe19mcmVlKHB0cik7fX0pO307dmFyIFVURjE2RGVjb2Rlcj10eXBlb2YgVGV4dERlY29kZXIhPSJ1bmRlZmluZWQiP25ldyBUZXh0RGVjb2RlcigidXRmLTE2bGUiKTp1bmRlZmluZWQ7dmFyIFVURjE2VG9TdHJpbmc9KHB0cixtYXhCeXRlc1RvUmVhZCk9Pnt2YXIgZW5kUHRyPXB0cjt2YXIgaWR4PWVuZFB0cj4+MTt2YXIgbWF4SWR4PWlkeCttYXhCeXRlc1RvUmVhZC8yO3doaWxlKCEoaWR4Pj1tYXhJZHgpJiZIRUFQVTE2W2lkeF0pKytpZHg7ZW5kUHRyPWlkeDw8MTtpZihlbmRQdHItcHRyPjMyJiZVVEYxNkRlY29kZXIpcmV0dXJuIFVURjE2RGVjb2Rlci5kZWNvZGUoSEVBUFU4LnN1YmFycmF5KHB0cixlbmRQdHIpKTt2YXIgc3RyPSIiO2Zvcih2YXIgaT0wOyEoaT49bWF4Qnl0ZXNUb1JlYWQvMik7KytpKXt2YXIgY29kZVVuaXQ9SEVBUDE2W3B0citpKjI+PjFdO2lmKGNvZGVVbml0PT0wKWJyZWFrO3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZShjb2RlVW5pdCk7fXJldHVybiBzdHJ9O3ZhciBzdHJpbmdUb1VURjE2PShzdHIsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk9PntpZihtYXhCeXRlc1RvV3JpdGU9PT11bmRlZmluZWQpe21heEJ5dGVzVG9Xcml0ZT0yMTQ3NDgzNjQ3O31pZihtYXhCeXRlc1RvV3JpdGU8MilyZXR1cm4gMDttYXhCeXRlc1RvV3JpdGUtPTI7dmFyIHN0YXJ0UHRyPW91dFB0cjt2YXIgbnVtQ2hhcnNUb1dyaXRlPW1heEJ5dGVzVG9Xcml0ZTxzdHIubGVuZ3RoKjI/bWF4Qnl0ZXNUb1dyaXRlLzI6c3RyLmxlbmd0aDtmb3IodmFyIGk9MDtpPG51bUNoYXJzVG9Xcml0ZTsrK2kpe3ZhciBjb2RlVW5pdD1zdHIuY2hhckNvZGVBdChpKTtIRUFQMTZbb3V0UHRyPj4xXT1jb2RlVW5pdDtvdXRQdHIrPTI7fUhFQVAxNltvdXRQdHI+PjFdPTA7cmV0dXJuIG91dFB0ci1zdGFydFB0cn07dmFyIGxlbmd0aEJ5dGVzVVRGMTY9c3RyPT5zdHIubGVuZ3RoKjI7dmFyIFVURjMyVG9TdHJpbmc9KHB0cixtYXhCeXRlc1RvUmVhZCk9Pnt2YXIgaT0wO3ZhciBzdHI9IiI7d2hpbGUoIShpPj1tYXhCeXRlc1RvUmVhZC80KSl7dmFyIHV0ZjMyPUhFQVAzMltwdHIraSo0Pj4yXTtpZih1dGYzMj09MClicmVhazsrK2k7aWYodXRmMzI+PTY1NTM2KXt2YXIgY2g9dXRmMzItNjU1MzY7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fGNoPj4xMCw1NjMyMHxjaCYxMDIzKTt9ZWxzZSB7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHV0ZjMyKTt9fXJldHVybiBzdHJ9O3ZhciBzdHJpbmdUb1VURjMyPShzdHIsb3V0UHRyLG1heEJ5dGVzVG9Xcml0ZSk9PntpZihtYXhCeXRlc1RvV3JpdGU9PT11bmRlZmluZWQpe21heEJ5dGVzVG9Xcml0ZT0yMTQ3NDgzNjQ3O31pZihtYXhCeXRlc1RvV3JpdGU8NClyZXR1cm4gMDt2YXIgc3RhcnRQdHI9b3V0UHRyO3ZhciBlbmRQdHI9c3RhcnRQdHIrbWF4Qnl0ZXNUb1dyaXRlLTQ7Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7dmFyIGNvZGVVbml0PXN0ci5jaGFyQ29kZUF0KGkpO2lmKGNvZGVVbml0Pj01NTI5NiYmY29kZVVuaXQ8PTU3MzQzKXt2YXIgdHJhaWxTdXJyb2dhdGU9c3RyLmNoYXJDb2RlQXQoKytpKTtjb2RlVW5pdD02NTUzNisoKGNvZGVVbml0JjEwMjMpPDwxMCl8dHJhaWxTdXJyb2dhdGUmMTAyMzt9SEVBUDMyW291dFB0cj4+Ml09Y29kZVVuaXQ7b3V0UHRyKz00O2lmKG91dFB0cis0PmVuZFB0cilicmVha31IRUFQMzJbb3V0UHRyPj4yXT0wO3JldHVybiBvdXRQdHItc3RhcnRQdHJ9O3ZhciBsZW5ndGhCeXRlc1VURjMyPXN0cj0+e3ZhciBsZW49MDtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXt2YXIgY29kZVVuaXQ9c3RyLmNoYXJDb2RlQXQoaSk7aWYoY29kZVVuaXQ+PTU1Mjk2JiZjb2RlVW5pdDw9NTczNDMpKytpO2xlbis9NDt9cmV0dXJuIGxlbn07dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF93c3RyaW5nPShyYXdUeXBlLGNoYXJTaXplLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3ZhciBkZWNvZGVTdHJpbmcsZW5jb2RlU3RyaW5nLGdldEhlYXAsbGVuZ3RoQnl0ZXNVVEYsc2hpZnQ7aWYoY2hhclNpemU9PT0yKXtkZWNvZGVTdHJpbmc9VVRGMTZUb1N0cmluZztlbmNvZGVTdHJpbmc9c3RyaW5nVG9VVEYxNjtsZW5ndGhCeXRlc1VURj1sZW5ndGhCeXRlc1VURjE2O2dldEhlYXA9KCk9PkhFQVBVMTY7c2hpZnQ9MTt9ZWxzZSBpZihjaGFyU2l6ZT09PTQpe2RlY29kZVN0cmluZz1VVEYzMlRvU3RyaW5nO2VuY29kZVN0cmluZz1zdHJpbmdUb1VURjMyO2xlbmd0aEJ5dGVzVVRGPWxlbmd0aEJ5dGVzVVRGMzI7Z2V0SGVhcD0oKT0+SEVBUFUzMjtzaGlmdD0yO31yZWdpc3RlclR5cGUocmF3VHlwZSx7bmFtZTpuYW1lLCJmcm9tV2lyZVR5cGUiOnZhbHVlPT57dmFyIGxlbmd0aD1IRUFQVTMyW3ZhbHVlPj4yXTt2YXIgSEVBUD1nZXRIZWFwKCk7dmFyIHN0cjt2YXIgZGVjb2RlU3RhcnRQdHI9dmFsdWUrNDtmb3IodmFyIGk9MDtpPD1sZW5ndGg7KytpKXt2YXIgY3VycmVudEJ5dGVQdHI9dmFsdWUrNCtpKmNoYXJTaXplO2lmKGk9PWxlbmd0aHx8SEVBUFtjdXJyZW50Qnl0ZVB0cj4+c2hpZnRdPT0wKXt2YXIgbWF4UmVhZEJ5dGVzPWN1cnJlbnRCeXRlUHRyLWRlY29kZVN0YXJ0UHRyO3ZhciBzdHJpbmdTZWdtZW50PWRlY29kZVN0cmluZyhkZWNvZGVTdGFydFB0cixtYXhSZWFkQnl0ZXMpO2lmKHN0cj09PXVuZGVmaW5lZCl7c3RyPXN0cmluZ1NlZ21lbnQ7fWVsc2Uge3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSgwKTtzdHIrPXN0cmluZ1NlZ21lbnQ7fWRlY29kZVN0YXJ0UHRyPWN1cnJlbnRCeXRlUHRyK2NoYXJTaXplO319X2ZyZWUodmFsdWUpO3JldHVybiBzdHJ9LCJ0b1dpcmVUeXBlIjooZGVzdHJ1Y3RvcnMsdmFsdWUpPT57aWYoISh0eXBlb2YgdmFsdWU9PSJzdHJpbmciKSl7dGhyb3dCaW5kaW5nRXJyb3IoYENhbm5vdCBwYXNzIG5vbi1zdHJpbmcgdG8gQysrIHN0cmluZyB0eXBlICR7bmFtZX1gKTt9dmFyIGxlbmd0aD1sZW5ndGhCeXRlc1VURih2YWx1ZSk7dmFyIHB0cj1fbWFsbG9jKDQrbGVuZ3RoK2NoYXJTaXplKTtIRUFQVTMyW3B0cj4+Ml09bGVuZ3RoPj5zaGlmdDtlbmNvZGVTdHJpbmcodmFsdWUscHRyKzQsbGVuZ3RoK2NoYXJTaXplKTtpZihkZXN0cnVjdG9ycyE9PW51bGwpe2Rlc3RydWN0b3JzLnB1c2goX2ZyZWUscHRyKTt9cmV0dXJuIHB0cn0sImFyZ1BhY2tBZHZhbmNlIjpHZW5lcmljV2lyZVR5cGVTaXplLCJyZWFkVmFsdWVGcm9tUG9pbnRlciI6c2ltcGxlUmVhZFZhbHVlRnJvbVBvaW50ZXIsZGVzdHJ1Y3RvckZ1bmN0aW9uKHB0cil7X2ZyZWUocHRyKTt9fSk7fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfdm9pZD0ocmF3VHlwZSxuYW1lKT0+e25hbWU9cmVhZExhdGluMVN0cmluZyhuYW1lKTtyZWdpc3RlclR5cGUocmF3VHlwZSx7aXNWb2lkOnRydWUsbmFtZTpuYW1lLCJhcmdQYWNrQWR2YW5jZSI6MCwiZnJvbVdpcmVUeXBlIjooKT0+dW5kZWZpbmVkLCJ0b1dpcmVUeXBlIjooZGVzdHJ1Y3RvcnMsbyk9PnVuZGVmaW5lZH0pO307dmFyIGdldEhlYXBNYXg9KCk9PjIxNDc0ODM2NDg7dmFyIGdyb3dNZW1vcnk9c2l6ZT0+e3ZhciBiPXdhc21NZW1vcnkuYnVmZmVyO3ZhciBwYWdlcz0oc2l6ZS1iLmJ5dGVMZW5ndGgrNjU1MzUpLzY1NTM2O3RyeXt3YXNtTWVtb3J5Lmdyb3cocGFnZXMpO3VwZGF0ZU1lbW9yeVZpZXdzKCk7cmV0dXJuIDF9Y2F0Y2goZSl7fX07dmFyIF9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwPXJlcXVlc3RlZFNpemU9Pnt2YXIgb2xkU2l6ZT1IRUFQVTgubGVuZ3RoO3JlcXVlc3RlZFNpemU+Pj49MDt2YXIgbWF4SGVhcFNpemU9Z2V0SGVhcE1heCgpO2lmKHJlcXVlc3RlZFNpemU+bWF4SGVhcFNpemUpe3JldHVybiBmYWxzZX12YXIgYWxpZ25VcD0oeCxtdWx0aXBsZSk9PngrKG11bHRpcGxlLXglbXVsdGlwbGUpJW11bHRpcGxlO2Zvcih2YXIgY3V0RG93bj0xO2N1dERvd248PTQ7Y3V0RG93bio9Mil7dmFyIG92ZXJHcm93bkhlYXBTaXplPW9sZFNpemUqKDErLjIvY3V0RG93bik7b3Zlckdyb3duSGVhcFNpemU9TWF0aC5taW4ob3Zlckdyb3duSGVhcFNpemUscmVxdWVzdGVkU2l6ZSsxMDA2NjMyOTYpO3ZhciBuZXdTaXplPU1hdGgubWluKG1heEhlYXBTaXplLGFsaWduVXAoTWF0aC5tYXgocmVxdWVzdGVkU2l6ZSxvdmVyR3Jvd25IZWFwU2l6ZSksNjU1MzYpKTt2YXIgcmVwbGFjZW1lbnQ9Z3Jvd01lbW9yeShuZXdTaXplKTtpZihyZXBsYWNlbWVudCl7cmV0dXJuIHRydWV9fXJldHVybiBmYWxzZX07ZW1iaW5kX2luaXRfY2hhckNvZGVzKCk7QmluZGluZ0Vycm9yPU1vZHVsZVsiQmluZGluZ0Vycm9yIl09Y2xhc3MgQmluZGluZ0Vycm9yIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IobWVzc2FnZSl7c3VwZXIobWVzc2FnZSk7dGhpcy5uYW1lPSJCaW5kaW5nRXJyb3IiO319O01vZHVsZVsiSW50ZXJuYWxFcnJvciJdPWNsYXNzIEludGVybmFsRXJyb3IgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcihtZXNzYWdlKXtzdXBlcihtZXNzYWdlKTt0aGlzLm5hbWU9IkludGVybmFsRXJyb3IiO319O2hhbmRsZUFsbG9jYXRvckluaXQoKTtpbml0X2VtdmFsKCk7dmFyIHdhc21JbXBvcnRzPXtmOl9fZW1iaW5kX3JlZ2lzdGVyX2JpZ2ludCxpOl9fZW1iaW5kX3JlZ2lzdGVyX2Jvb2wsaDpfX2VtYmluZF9yZWdpc3Rlcl9lbXZhbCxlOl9fZW1iaW5kX3JlZ2lzdGVyX2Zsb2F0LGI6X19lbWJpbmRfcmVnaXN0ZXJfaW50ZWdlcixhOl9fZW1iaW5kX3JlZ2lzdGVyX21lbW9yeV92aWV3LGQ6X19lbWJpbmRfcmVnaXN0ZXJfc3RkX3N0cmluZyxjOl9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF93c3RyaW5nLGo6X19lbWJpbmRfcmVnaXN0ZXJfdm9pZCxnOl9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwfTt2YXIgd2FzbUV4cG9ydHM9Y3JlYXRlV2FzbSgpO01vZHVsZVsiX3BhY2siXT0oYTAsYTEsYTIsYTMsYTQsYTUsYTYsYTcsYTgsYTksYTEwKT0+KE1vZHVsZVsiX3BhY2siXT13YXNtRXhwb3J0c1sibSJdKShhMCxhMSxhMixhMyxhNCxhNSxhNixhNyxhOCxhOSxhMTApO01vZHVsZVsiX19lbWJpbmRfaW5pdGlhbGl6ZV9iaW5kaW5ncyJdPSgpPT4oTW9kdWxlWyJfX2VtYmluZF9pbml0aWFsaXplX2JpbmRpbmdzIl09d2FzbUV4cG9ydHNbIm4iXSkoKTt2YXIgX21hbGxvYz1Nb2R1bGVbIl9tYWxsb2MiXT1hMD0+KF9tYWxsb2M9TW9kdWxlWyJfbWFsbG9jIl09d2FzbUV4cG9ydHNbInAiXSkoYTApO3ZhciBfZnJlZT1Nb2R1bGVbIl9mcmVlIl09YTA9PihfZnJlZT1Nb2R1bGVbIl9mcmVlIl09d2FzbUV4cG9ydHNbInEiXSkoYTApO2Z1bmN0aW9uIGludEFycmF5RnJvbUJhc2U2NChzKXt2YXIgZGVjb2RlZD1hdG9iKHMpO3ZhciBieXRlcz1uZXcgVWludDhBcnJheShkZWNvZGVkLmxlbmd0aCk7Zm9yKHZhciBpPTA7aTxkZWNvZGVkLmxlbmd0aDsrK2kpe2J5dGVzW2ldPWRlY29kZWQuY2hhckNvZGVBdChpKTt9cmV0dXJuIGJ5dGVzfWZ1bmN0aW9uIHRyeVBhcnNlQXNEYXRhVVJJKGZpbGVuYW1lKXtpZighaXNEYXRhVVJJKGZpbGVuYW1lKSl7cmV0dXJufXJldHVybiBpbnRBcnJheUZyb21CYXNlNjQoZmlsZW5hbWUuc2xpY2UoZGF0YVVSSVByZWZpeC5sZW5ndGgpKX12YXIgY2FsbGVkUnVuO2RlcGVuZGVuY2llc0Z1bGZpbGxlZD1mdW5jdGlvbiBydW5DYWxsZXIoKXtpZighY2FsbGVkUnVuKXJ1bigpO2lmKCFjYWxsZWRSdW4pZGVwZW5kZW5jaWVzRnVsZmlsbGVkPXJ1bkNhbGxlcjt9O2Z1bmN0aW9uIHJ1bigpe2lmKHJ1bkRlcGVuZGVuY2llcz4wKXtyZXR1cm59cHJlUnVuKCk7aWYocnVuRGVwZW5kZW5jaWVzPjApe3JldHVybn1mdW5jdGlvbiBkb1J1bigpe2lmKGNhbGxlZFJ1bilyZXR1cm47Y2FsbGVkUnVuPXRydWU7TW9kdWxlWyJjYWxsZWRSdW4iXT10cnVlO2lmKEFCT1JUKXJldHVybjtpbml0UnVudGltZSgpO3JlYWR5UHJvbWlzZVJlc29sdmUoTW9kdWxlKTtpZihNb2R1bGVbIm9uUnVudGltZUluaXRpYWxpemVkIl0pTW9kdWxlWyJvblJ1bnRpbWVJbml0aWFsaXplZCJdKCk7cG9zdFJ1bigpO31pZihNb2R1bGVbInNldFN0YXR1cyJdKXtNb2R1bGVbInNldFN0YXR1cyJdKCJSdW5uaW5nLi4uIik7c2V0VGltZW91dChmdW5jdGlvbigpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXtNb2R1bGVbInNldFN0YXR1cyJdKCIiKTt9LDEpO2RvUnVuKCk7fSwxKTt9ZWxzZSB7ZG9SdW4oKTt9fWlmKE1vZHVsZVsicHJlSW5pdCJdKXtpZih0eXBlb2YgTW9kdWxlWyJwcmVJbml0Il09PSJmdW5jdGlvbiIpTW9kdWxlWyJwcmVJbml0Il09W01vZHVsZVsicHJlSW5pdCJdXTt3aGlsZShNb2R1bGVbInByZUluaXQiXS5sZW5ndGg+MCl7TW9kdWxlWyJwcmVJbml0Il0ucG9wKCkoKTt9fXJ1bigpOwoKCiAgICByZXR1cm4gbW9kdWxlQXJnLnJlYWR5CiAgfQoKICApOwogIH0pKCk7CgogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55CiAgbGV0IHdhc21Nb2R1bGU7CiAgYXN5bmMgZnVuY3Rpb24gaW5pdFdhc20oKSB7CiAgICAgIHdhc21Nb2R1bGUgPSBhd2FpdCBsb2FkV2FzbSgpOwogIH0KICBsZXQgYWxsb2NhdGVkVmVydGV4Q291bnQgPSAwOwogIGNvbnN0IHVwZGF0ZVF1ZXVlID0gbmV3IEFycmF5KCk7CiAgbGV0IHJ1bm5pbmcgPSBmYWxzZTsKICBsZXQgbG9hZGluZyA9IGZhbHNlOwogIGxldCBwb3NpdGlvbnNQdHI7CiAgbGV0IHJvdGF0aW9uc1B0cjsKICBsZXQgc2NhbGVzUHRyOwogIGxldCBjb2xvcnNQdHI7CiAgbGV0IHNlbGVjdGlvblB0cjsKICBsZXQgZGF0YVB0cjsKICBsZXQgd29ybGRQb3NpdGlvbnNQdHI7CiAgbGV0IHdvcmxkUm90YXRpb25zUHRyOwogIGxldCB3b3JsZFNjYWxlc1B0cjsKICBjb25zdCBwYWNrID0gYXN5bmMgKHNwbGF0KSA9PiB7CiAgICAgIHdoaWxlIChsb2FkaW5nKSB7CiAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCAwKSk7CiAgICAgIH0KICAgICAgaWYgKCF3YXNtTW9kdWxlKSB7CiAgICAgICAgICBsb2FkaW5nID0gdHJ1ZTsKICAgICAgICAgIGF3YWl0IGluaXRXYXNtKCk7CiAgICAgICAgICBsb2FkaW5nID0gZmFsc2U7CiAgICAgIH0KICAgICAgY29uc3QgdGFyZ2V0QWxsb2NhdGVkVmVydGV4Q291bnQgPSBNYXRoLnBvdygyLCBNYXRoLmNlaWwoTWF0aC5sb2cyKHNwbGF0LnZlcnRleENvdW50KSkpOwogICAgICBpZiAodGFyZ2V0QWxsb2NhdGVkVmVydGV4Q291bnQgPiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCkgewogICAgICAgICAgaWYgKGFsbG9jYXRlZFZlcnRleENvdW50ID4gMCkgewogICAgICAgICAgICAgIHdhc21Nb2R1bGUuX2ZyZWUocG9zaXRpb25zUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHJvdGF0aW9uc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZShzY2FsZXNQdHIpOwogICAgICAgICAgICAgIHdhc21Nb2R1bGUuX2ZyZWUoY29sb3JzUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHNlbGVjdGlvblB0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZShkYXRhUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHdvcmxkUG9zaXRpb25zUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHdvcmxkUm90YXRpb25zUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHdvcmxkU2NhbGVzUHRyKTsKICAgICAgICAgIH0KICAgICAgICAgIGFsbG9jYXRlZFZlcnRleENvdW50ID0gdGFyZ2V0QWxsb2NhdGVkVmVydGV4Q291bnQ7CiAgICAgICAgICBwb3NpdGlvbnNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoMyAqIGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICByb3RhdGlvbnNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoNCAqIGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICBzY2FsZXNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoMyAqIGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICBjb2xvcnNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoNCAqIGFsbG9jYXRlZFZlcnRleENvdW50KTsKICAgICAgICAgIHNlbGVjdGlvblB0ciA9IHdhc21Nb2R1bGUuX21hbGxvYyhhbGxvY2F0ZWRWZXJ0ZXhDb3VudCk7CiAgICAgICAgICBkYXRhUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDggKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgd29ybGRQb3NpdGlvbnNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoMyAqIGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICB3b3JsZFJvdGF0aW9uc1B0ciA9IHdhc21Nb2R1bGUuX21hbGxvYyg0ICogYWxsb2NhdGVkVmVydGV4Q291bnQgKiA0KTsKICAgICAgICAgIHdvcmxkU2NhbGVzUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDMgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICB9CiAgICAgIHdhc21Nb2R1bGUuSEVBUEYzMi5zZXQoc3BsYXQucG9zaXRpb25zLCBwb3NpdGlvbnNQdHIgLyA0KTsKICAgICAgd2FzbU1vZHVsZS5IRUFQRjMyLnNldChzcGxhdC5yb3RhdGlvbnMsIHJvdGF0aW9uc1B0ciAvIDQpOwogICAgICB3YXNtTW9kdWxlLkhFQVBGMzIuc2V0KHNwbGF0LnNjYWxlcywgc2NhbGVzUHRyIC8gNCk7CiAgICAgIHdhc21Nb2R1bGUuSEVBUFU4LnNldChzcGxhdC5jb2xvcnMsIGNvbG9yc1B0cik7CiAgICAgIHdhc21Nb2R1bGUuSEVBUFU4LnNldChzcGxhdC5zZWxlY3Rpb24sIHNlbGVjdGlvblB0cik7CiAgICAgIHdhc21Nb2R1bGUuX3BhY2soc3BsYXQuc2VsZWN0ZWQsIHNwbGF0LnZlcnRleENvdW50LCBwb3NpdGlvbnNQdHIsIHJvdGF0aW9uc1B0ciwgc2NhbGVzUHRyLCBjb2xvcnNQdHIsIHNlbGVjdGlvblB0ciwgZGF0YVB0ciwgd29ybGRQb3NpdGlvbnNQdHIsIHdvcmxkUm90YXRpb25zUHRyLCB3b3JsZFNjYWxlc1B0cik7CiAgICAgIGNvbnN0IG91dERhdGEgPSBuZXcgVWludDMyQXJyYXkod2FzbU1vZHVsZS5IRUFQVTMyLmJ1ZmZlciwgZGF0YVB0ciwgc3BsYXQudmVydGV4Q291bnQgKiA4KTsKICAgICAgY29uc3QgZGV0YWNoZWREYXRhID0gbmV3IFVpbnQzMkFycmF5KG91dERhdGEuc2xpY2UoKS5idWZmZXIpOwogICAgICBjb25zdCB3b3JsZFBvc2l0aW9ucyA9IG5ldyBGbG9hdDMyQXJyYXkod2FzbU1vZHVsZS5IRUFQRjMyLmJ1ZmZlciwgd29ybGRQb3NpdGlvbnNQdHIsIHNwbGF0LnZlcnRleENvdW50ICogMyk7CiAgICAgIGNvbnN0IGRldGFjaGVkV29ybGRQb3NpdGlvbnMgPSBuZXcgRmxvYXQzMkFycmF5KHdvcmxkUG9zaXRpb25zLnNsaWNlKCkuYnVmZmVyKTsKICAgICAgY29uc3Qgd29ybGRSb3RhdGlvbnMgPSBuZXcgRmxvYXQzMkFycmF5KHdhc21Nb2R1bGUuSEVBUEYzMi5idWZmZXIsIHdvcmxkUm90YXRpb25zUHRyLCBzcGxhdC52ZXJ0ZXhDb3VudCAqIDQpOwogICAgICBjb25zdCBkZXRhY2hlZFdvcmxkUm90YXRpb25zID0gbmV3IEZsb2F0MzJBcnJheSh3b3JsZFJvdGF0aW9ucy5zbGljZSgpLmJ1ZmZlcik7CiAgICAgIGNvbnN0IHdvcmxkU2NhbGVzID0gbmV3IEZsb2F0MzJBcnJheSh3YXNtTW9kdWxlLkhFQVBGMzIuYnVmZmVyLCB3b3JsZFNjYWxlc1B0ciwgc3BsYXQudmVydGV4Q291bnQgKiAzKTsKICAgICAgY29uc3QgZGV0YWNoZWRXb3JsZFNjYWxlcyA9IG5ldyBGbG9hdDMyQXJyYXkod29ybGRTY2FsZXMuc2xpY2UoKS5idWZmZXIpOwogICAgICBjb25zdCByZXNwb25zZSA9IHsKICAgICAgICAgIGRhdGE6IGRldGFjaGVkRGF0YSwKICAgICAgICAgIHdvcmxkUG9zaXRpb25zOiBkZXRhY2hlZFdvcmxkUG9zaXRpb25zLAogICAgICAgICAgd29ybGRSb3RhdGlvbnM6IGRldGFjaGVkV29ybGRSb3RhdGlvbnMsCiAgICAgICAgICB3b3JsZFNjYWxlczogZGV0YWNoZWRXb3JsZFNjYWxlcywKICAgICAgICAgIG9mZnNldDogc3BsYXQub2Zmc2V0LAogICAgICAgICAgdmVydGV4Q291bnQ6IHNwbGF0LnZlcnRleENvdW50LAogICAgICAgICAgcG9zaXRpb25zOiBzcGxhdC5wb3NpdGlvbnMuYnVmZmVyLAogICAgICAgICAgcm90YXRpb25zOiBzcGxhdC5yb3RhdGlvbnMuYnVmZmVyLAogICAgICAgICAgc2NhbGVzOiBzcGxhdC5zY2FsZXMuYnVmZmVyLAogICAgICAgICAgY29sb3JzOiBzcGxhdC5jb2xvcnMuYnVmZmVyLAogICAgICAgICAgc2VsZWN0aW9uOiBzcGxhdC5zZWxlY3Rpb24uYnVmZmVyLAogICAgICB9OwogICAgICBzZWxmLnBvc3RNZXNzYWdlKHsgcmVzcG9uc2U6IHJlc3BvbnNlIH0sIFsKICAgICAgICAgIHJlc3BvbnNlLmRhdGEuYnVmZmVyLAogICAgICAgICAgcmVzcG9uc2Uud29ybGRQb3NpdGlvbnMuYnVmZmVyLAogICAgICAgICAgcmVzcG9uc2Uud29ybGRSb3RhdGlvbnMuYnVmZmVyLAogICAgICAgICAgcmVzcG9uc2Uud29ybGRTY2FsZXMuYnVmZmVyLAogICAgICAgICAgcmVzcG9uc2UucG9zaXRpb25zLAogICAgICAgICAgcmVzcG9uc2Uucm90YXRpb25zLAogICAgICAgICAgcmVzcG9uc2Uuc2NhbGVzLAogICAgICAgICAgcmVzcG9uc2UuY29sb3JzLAogICAgICAgICAgcmVzcG9uc2Uuc2VsZWN0aW9uLAogICAgICBdKTsKICAgICAgcnVubmluZyA9IGZhbHNlOwogIH07CiAgY29uc3QgcGFja1Rocm90dGxlZCA9ICgpID0+IHsKICAgICAgaWYgKHVwZGF0ZVF1ZXVlLmxlbmd0aCA9PT0gMCkKICAgICAgICAgIHJldHVybjsKICAgICAgaWYgKCFydW5uaW5nKSB7CiAgICAgICAgICBydW5uaW5nID0gdHJ1ZTsKICAgICAgICAgIGNvbnN0IHNwbGF0ID0gdXBkYXRlUXVldWUuc2hpZnQoKTsKICAgICAgICAgIHBhY2soc3BsYXQpOwogICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7CiAgICAgICAgICAgICAgcnVubmluZyA9IGZhbHNlOwogICAgICAgICAgICAgIHBhY2tUaHJvdHRsZWQoKTsKICAgICAgICAgIH0sIDApOwogICAgICB9CiAgfTsKICBzZWxmLm9ubWVzc2FnZSA9IChlKSA9PiB7CiAgICAgIGlmIChlLmRhdGEuc3BsYXQpIHsKICAgICAgICAgIGNvbnN0IHNwbGF0ID0gZS5kYXRhLnNwbGF0OwogICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIGV4aXN0aW5nXSBvZiB1cGRhdGVRdWV1ZS5lbnRyaWVzKCkpIHsKICAgICAgICAgICAgICBpZiAoZXhpc3Rpbmcub2Zmc2V0ID09PSBzcGxhdC5vZmZzZXQpIHsKICAgICAgICAgICAgICAgICAgdXBkYXRlUXVldWVbaW5kZXhdID0gc3BsYXQ7CiAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICB1cGRhdGVRdWV1ZS5wdXNoKHNwbGF0KTsKICAgICAgICAgIHBhY2tUaHJvdHRsZWQoKTsKICAgICAgfQogIH07Cgp9KSgpOwovLyMgc291cmNlTWFwcGluZ1VSTD1EYXRhV29ya2VyLmpzLm1hcAoK", null), Ul = function(G = {}) {
935
- var t, F, U = G;
936
- U.ready = new Promise((V, s) => {
937
- t = V, F = s;
938
- });
939
- var l, a = Object.assign({}, U), n = "";
940
- n = (n = self.location.href).indexOf("blob:") !== 0 ? n.substr(0, n.replace(/[?#].*/, "").lastIndexOf("/") + 1) : "", l = (V) => {
941
- var s = new XMLHttpRequest();
942
- return s.open("GET", V, !1), s.responseType = "arraybuffer", s.send(null), new Uint8Array(s.response);
943
- }, U.print || console.log.bind(console);
944
- var e, Q, d = U.printErr || console.error.bind(console);
945
- Object.assign(U, a), a = null, U.arguments && U.arguments, U.thisProgram && U.thisProgram, U.quit && U.quit, U.wasmBinary && (e = U.wasmBinary), typeof WebAssembly != "object" && E("no native wasm support detected");
946
- var A, i, r, c, B, W, J, h, C = !1;
947
- function k() {
948
- var V = Q.buffer;
949
- U.HEAP8 = A = new Int8Array(V), U.HEAP16 = r = new Int16Array(V), U.HEAPU8 = i = new Uint8Array(V), U.HEAPU16 = c = new Uint16Array(V), U.HEAP32 = B = new Int32Array(V), U.HEAPU32 = W = new Uint32Array(V), U.HEAPF32 = J = new Float32Array(V), U.HEAPF64 = h = new Float64Array(V);
950
- }
951
- var p = [], X = [], D = [], u = 0, M = null;
952
- function E(V) {
953
- U.onAbort && U.onAbort(V), d(V = "Aborted(" + V + ")"), C = !0, V += ". Build with -sASSERTIONS for more info.";
954
- var s = new WebAssembly.RuntimeError(V);
955
- throw F(s), s;
956
- }
957
- var w, Ft, Y = "data:application/octet-stream;base64,", H = (V) => V.startsWith(Y);
958
- function at(V) {
959
- if (V == w && e) return new Uint8Array(e);
960
- var s = function(R) {
961
- if (H(R)) return function(Z) {
962
- for (var m = atob(Z), b = new Uint8Array(m.length), g = 0; g < m.length; ++g) b[g] = m.charCodeAt(g);
963
- return b;
964
- }(R.slice(Y.length));
965
- }(V);
966
- if (s) return s;
967
- if (l) return l(V);
968
- throw "both async and sync fetching of the wasm failed";
969
- }
970
- function L(V, s, R) {
971
- return function(Z) {
972
- return Promise.resolve().then(() => at(Z));
973
- }(V).then((Z) => WebAssembly.instantiate(Z, s)).then((Z) => Z).then(R, (Z) => {
974
- d(`failed to asynchronously prepare wasm: ${Z}`), E(Z);
975
- });
976
- }
977
- H(w = "data:application/octet-stream;base64,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aWduZWQgc2hvcnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgaW50PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxmbG9hdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDhfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1bnNpZ25lZCBjaGFyPgBzdGQ6OmJhc2ljX3N0cmluZzx1bnNpZ25lZCBjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaWduZWQgY2hhcj4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8bG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgbG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8ZG91YmxlPgBOU3QzX18yMTJiYXNpY19zdHJpbmdJY05TXzExY2hhcl90cmFpdHNJY0VFTlNfOWFsbG9jYXRvckljRUVFRQAAAABEDAAAQgcAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0loTlNfMTFjaGFyX3RyYWl0c0loRUVOU185YWxsb2NhdG9ySWhFRUVFAABEDAAAjAcAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0l3TlNfMTFjaGFyX3RyYWl0c0l3RUVOU185YWxsb2NhdG9ySXdFRUVFAABEDAAA1AcAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0lEc05TXzExY2hhcl90cmFpdHNJRHNFRU5TXzlhbGxvY2F0b3JJRHNFRUVFAAAARAwAABwIAABOU3QzX18yMTJiYXNpY19zdHJpbmdJRGlOU18xMWNoYXJfdHJhaXRzSURpRUVOU185YWxsb2NhdG9ySURpRUVFRQAAAEQMAABoCAAATjEwZW1zY3JpcHRlbjN2YWxFAABEDAAAtAgAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWNFRQAARAwAANAIAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lhRUUAAEQMAAD4CAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJaEVFAABEDAAAIAkAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXNFRQAARAwAAEgJAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0l0RUUAAEQMAABwCQAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJaUVFAABEDAAAmAkAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWpFRQAARAwAAMAJAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lsRUUAAEQMAADoCQAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJbUVFAABEDAAAEAoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXhFRQAARAwAADgKAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0l5RUUAAEQMAABgCgAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJZkVFAABEDAAAiAoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWRFRQAARAwAALAKAABOMTBfX2N4eGFiaXYxMTZfX3NoaW1fdHlwZV9pbmZvRQAAAABsDAAA2AoAANAMAABOMTBfX2N4eGFiaXYxMTdfX2NsYXNzX3R5cGVfaW5mb0UAAABsDAAACAsAAPwKAAAAAAAAfAsAAAIAAAADAAAABAAAAAUAAAAGAAAATjEwX19jeHhhYml2MTIzX19mdW5kYW1lbnRhbF90eXBlX2luZm9FAGwMAABUCwAA/AoAAHYAAABACwAAiAsAAGIAAABACwAAlAsAAGMAAABACwAAoAsAAGgAAABACwAArAsAAGEAAABACwAAuAsAAHMAAABACwAAxAsAAHQAAABACwAA0AsAAGkAAABACwAA3AsAAGoAAABACwAA6AsAAGwAAABACwAA9AsAAG0AAABACwAAAAwAAHgAAABACwAADAwAAHkAAABACwAAGAwAAGYAAABACwAAJAwAAGQAAABACwAAMAwAAAAAAAAsCwAAAgAAAAcAAAAEAAAABQAAAAgAAAAJAAAACgAAAAsAAAAAAAAAtAwAAAIAAAAMAAAABAAAAAUAAAAIAAAADQAAAA4AAAAPAAAATjEwX19jeHhhYml2MTIwX19zaV9jbGFzc190eXBlX2luZm9FAAAAAGwMAACMDAAALAsAAFN0OXR5cGVfaW5mbwAAAABEDAAAwAwAQdgZCwPgDgE=") || (Ft = w, w = U.locateFile ? U.locateFile(Ft, n) : n + Ft);
978
- var o = (V) => {
979
- for (; V.length > 0; ) V.shift()(U);
980
- };
981
- U.noExitRuntime;
982
- var T, v, x = (V) => {
983
- for (var s = "", R = V; i[R]; ) s += T[i[R++]];
984
- return s;
985
- }, At = {}, Vt = {}, K = (V) => {
986
- throw new v(V);
987
- };
988
- function _(V, s, R = {}) {
989
- if (!("argPackAdvance" in s)) throw new TypeError("registerType registeredInstance requires argPackAdvance");
990
- return function(Z, m, b = {}) {
991
- var g = m.name;
992
- if (Z || K(`type "${g}" must have a positive integer typeid pointer`), Vt.hasOwnProperty(Z)) {
993
- if (b.ignoreDuplicateRegistrations) return;
994
- K(`Cannot register type '${g}' twice`);
995
- }
996
- if (Vt[Z] = m, At.hasOwnProperty(Z)) {
997
- var y = At[Z];
998
- delete At[Z], y.forEach((N) => N());
999
- }
1000
- }(V, s, R);
1001
- }
1002
- function et() {
1003
- this.allocated = [void 0], this.freelist = [];
1004
- }
1005
- var j = new et(), Rt = () => {
1006
- for (var V = 0, s = j.reserved; s < j.allocated.length; ++s) j.allocated[s] !== void 0 && ++V;
1007
- return V;
1008
- }, It = (V) => (V || K("Cannot use deleted val. handle = " + V), j.get(V).value), kt = (V) => {
1009
- switch (V) {
1010
- case void 0:
1011
- return 1;
1012
- case null:
1013
- return 2;
1014
- case !0:
1015
- return 3;
1016
- case !1:
1017
- return 4;
1018
- default:
1019
- return j.allocate({ refcount: 1, value: V });
1020
- }
1021
- };
1022
- function Nt(V) {
1023
- return this.fromWireType(B[V >> 2]);
1024
- }
1025
- var Tt = (V, s) => {
1026
- switch (s) {
1027
- case 4:
1028
- return function(R) {
1029
- return this.fromWireType(J[R >> 2]);
1030
- };
1031
- case 8:
1032
- return function(R) {
1033
- return this.fromWireType(h[R >> 3]);
1034
- };
1035
- default:
1036
- throw new TypeError(`invalid float width (${s}): ${V}`);
1037
- }
1038
- }, Ht = (V, s, R) => {
1039
- switch (s) {
1040
- case 1:
1041
- return R ? (Z) => A[Z >> 0] : (Z) => i[Z >> 0];
1042
- case 2:
1043
- return R ? (Z) => r[Z >> 1] : (Z) => c[Z >> 1];
1044
- case 4:
1045
- return R ? (Z) => B[Z >> 2] : (Z) => W[Z >> 2];
1046
- default:
1047
- throw new TypeError(`invalid integer width (${s}): ${V}`);
1048
- }
1049
- };
1050
- function xt(V) {
1051
- return this.fromWireType(W[V >> 2]);
1052
- }
1053
- var Gt = typeof TextDecoder < "u" ? new TextDecoder("utf8") : void 0, ft = (V, s) => V ? ((R, Z, m) => {
1054
- for (var b = Z + m, g = Z; R[g] && !(g >= b); ) ++g;
1055
- if (g - Z > 16 && R.buffer && Gt) return Gt.decode(R.subarray(Z, g));
1056
- for (var y = ""; Z < g; ) {
1057
- var N = R[Z++];
1058
- if (128 & N) {
1059
- var S = 63 & R[Z++];
1060
- if ((224 & N) != 192) {
1061
- var q = 63 & R[Z++];
1062
- if ((N = (240 & N) == 224 ? (15 & N) << 12 | S << 6 | q : (7 & N) << 18 | S << 12 | q << 6 | 63 & R[Z++]) < 65536) y += String.fromCharCode(N);
1063
- else {
1064
- var P = N - 65536;
1065
- y += String.fromCharCode(55296 | P >> 10, 56320 | 1023 & P);
1066
- }
1067
- } else y += String.fromCharCode((31 & N) << 6 | S);
1068
- } else y += String.fromCharCode(N);
1069
- }
1070
- return y;
1071
- })(i, V, s) : "", pt = typeof TextDecoder < "u" ? new TextDecoder("utf-16le") : void 0, Dt = (V, s) => {
1072
- for (var R = V, Z = R >> 1, m = Z + s / 2; !(Z >= m) && c[Z]; ) ++Z;
1073
- if ((R = Z << 1) - V > 32 && pt) return pt.decode(i.subarray(V, R));
1074
- for (var b = "", g = 0; !(g >= s / 2); ++g) {
1075
- var y = r[V + 2 * g >> 1];
1076
- if (y == 0) break;
1077
- b += String.fromCharCode(y);
1078
- }
1079
- return b;
1080
- }, wt = (V, s, R) => {
1081
- if (R === void 0 && (R = 2147483647), R < 2) return 0;
1082
- for (var Z = s, m = (R -= 2) < 2 * V.length ? R / 2 : V.length, b = 0; b < m; ++b) {
1083
- var g = V.charCodeAt(b);
1084
- r[s >> 1] = g, s += 2;
1085
- }
1086
- return r[s >> 1] = 0, s - Z;
1087
- }, vt = (V) => 2 * V.length, zt = (V, s) => {
1088
- for (var R = 0, Z = ""; !(R >= s / 4); ) {
1089
- var m = B[V + 4 * R >> 2];
1090
- if (m == 0) break;
1091
- if (++R, m >= 65536) {
1092
- var b = m - 65536;
1093
- Z += String.fromCharCode(55296 | b >> 10, 56320 | 1023 & b);
1094
- } else Z += String.fromCharCode(m);
1095
- }
1096
- return Z;
1097
- }, Mt = (V, s, R) => {
1098
- if (R === void 0 && (R = 2147483647), R < 4) return 0;
1099
- for (var Z = s, m = Z + R - 4, b = 0; b < V.length; ++b) {
1100
- var g = V.charCodeAt(b);
1101
- if (g >= 55296 && g <= 57343 && (g = 65536 + ((1023 & g) << 10) | 1023 & V.charCodeAt(++b)), B[s >> 2] = g, (s += 4) + 4 > m) break;
1102
- }
1103
- return B[s >> 2] = 0, s - Z;
1104
- }, Kt = (V) => {
1105
- for (var s = 0, R = 0; R < V.length; ++R) {
1106
- var Z = V.charCodeAt(R);
1107
- Z >= 55296 && Z <= 57343 && ++R, s += 4;
1108
- }
1109
- return s;
1110
- }, jt = (V) => {
1111
- var s = (V - Q.buffer.byteLength + 65535) / 65536;
1112
- try {
1113
- return Q.grow(s), k(), 1;
1114
- } catch {
1115
- }
1116
- };
1117
- (() => {
1118
- for (var V = new Array(256), s = 0; s < 256; ++s) V[s] = String.fromCharCode(s);
1119
- T = V;
1120
- })(), v = U.BindingError = class extends Error {
1121
- constructor(V) {
1122
- super(V), this.name = "BindingError";
1123
- }
1124
- }, U.InternalError = class extends Error {
1125
- constructor(V) {
1126
- super(V), this.name = "InternalError";
1127
- }
1128
- }, Object.assign(et.prototype, { get(V) {
1129
- return this.allocated[V];
1130
- }, has(V) {
1131
- return this.allocated[V] !== void 0;
1132
- }, allocate(V) {
1133
- var s = this.freelist.pop() || this.allocated.length;
1134
- return this.allocated[s] = V, s;
1135
- }, free(V) {
1136
- this.allocated[V] = void 0, this.freelist.push(V);
1137
- } }), j.allocated.push({ value: void 0 }, { value: null }, { value: !0 }, { value: !1 }), j.reserved = j.allocated.length, U.count_emval_handles = Rt;
1138
- var Ot = { f: (V, s, R, Z, m) => {
1139
- }, i: (V, s, R, Z) => {
1140
- _(V, { name: s = x(s), fromWireType: function(m) {
1141
- return !!m;
1142
- }, toWireType: function(m, b) {
1143
- return b ? R : Z;
1144
- }, argPackAdvance: 8, readValueFromPointer: function(m) {
1145
- return this.fromWireType(i[m]);
1146
- }, destructorFunction: null });
1147
- }, h: (V, s) => {
1148
- _(V, { name: s = x(s), fromWireType: (R) => {
1149
- var Z = It(R);
1150
- return ((m) => {
1151
- m >= j.reserved && --j.get(m).refcount == 0 && j.free(m);
1152
- })(R), Z;
1153
- }, toWireType: (R, Z) => kt(Z), argPackAdvance: 8, readValueFromPointer: Nt, destructorFunction: null });
1154
- }, e: (V, s, R) => {
1155
- _(V, { name: s = x(s), fromWireType: (Z) => Z, toWireType: (Z, m) => m, argPackAdvance: 8, readValueFromPointer: Tt(s, R), destructorFunction: null });
1156
- }, b: (V, s, R, Z, m) => {
1157
- s = x(s);
1158
- var b = (N) => N;
1159
- if (Z === 0) {
1160
- var g = 32 - 8 * R;
1161
- b = (N) => N << g >>> g;
1162
- }
1163
- var y = s.includes("unsigned");
1164
- _(V, { name: s, fromWireType: b, toWireType: y ? function(N, S) {
1165
- return this.name, S >>> 0;
1166
- } : function(N, S) {
1167
- return this.name, S;
1168
- }, argPackAdvance: 8, readValueFromPointer: Ht(s, R, Z !== 0), destructorFunction: null });
1169
- }, a: (V, s, R) => {
1170
- var Z = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array][s];
1171
- function m(b) {
1172
- var g = W[b >> 2], y = W[b + 4 >> 2];
1173
- return new Z(A.buffer, y, g);
1174
- }
1175
- _(V, { name: R = x(R), fromWireType: m, argPackAdvance: 8, readValueFromPointer: m }, { ignoreDuplicateRegistrations: !0 });
1176
- }, d: (V, s) => {
1177
- var R = (s = x(s)) === "std::string";
1178
- _(V, { name: s, fromWireType(Z) {
1179
- var m, b = W[Z >> 2], g = Z + 4;
1180
- if (R) for (var y = g, N = 0; N <= b; ++N) {
1181
- var S = g + N;
1182
- if (N == b || i[S] == 0) {
1183
- var q = ft(y, S - y);
1184
- m === void 0 ? m = q : (m += "\0", m += q), y = S + 1;
1185
- }
1186
- }
1187
- else {
1188
- var P = new Array(b);
1189
- for (N = 0; N < b; ++N) P[N] = String.fromCharCode(i[g + N]);
1190
- m = P.join("");
1191
- }
1192
- return it(Z), m;
1193
- }, toWireType(Z, m) {
1194
- var b;
1195
- m instanceof ArrayBuffer && (m = new Uint8Array(m));
1196
- var g = typeof m == "string";
1197
- g || m instanceof Uint8Array || m instanceof Uint8ClampedArray || m instanceof Int8Array || K("Cannot pass non-string to std::string"), b = R && g ? ((P) => {
1198
- for (var O = 0, f = 0; f < P.length; ++f) {
1199
- var Qt = P.charCodeAt(f);
1200
- Qt <= 127 ? O++ : Qt <= 2047 ? O += 2 : Qt >= 55296 && Qt <= 57343 ? (O += 4, ++f) : O += 3;
1201
- }
1202
- return O;
1203
- })(m) : m.length;
1204
- var y = Jt(4 + b + 1), N = y + 4;
1205
- if (W[y >> 2] = b, R && g) ((P, O, f, Qt) => {
1206
- if (!(Qt > 0)) return 0;
1207
- for (var st = f + Qt - 1, Wt = 0; Wt < P.length; ++Wt) {
1208
- var $ = P.charCodeAt(Wt);
1209
- if ($ >= 55296 && $ <= 57343 && ($ = 65536 + ((1023 & $) << 10) | 1023 & P.charCodeAt(++Wt)), $ <= 127) {
1210
- if (f >= st) break;
1211
- O[f++] = $;
1212
- } else if ($ <= 2047) {
1213
- if (f + 1 >= st) break;
1214
- O[f++] = 192 | $ >> 6, O[f++] = 128 | 63 & $;
1215
- } else if ($ <= 65535) {
1216
- if (f + 2 >= st) break;
1217
- O[f++] = 224 | $ >> 12, O[f++] = 128 | $ >> 6 & 63, O[f++] = 128 | 63 & $;
1218
- } else {
1219
- if (f + 3 >= st) break;
1220
- O[f++] = 240 | $ >> 18, O[f++] = 128 | $ >> 12 & 63, O[f++] = 128 | $ >> 6 & 63, O[f++] = 128 | 63 & $;
1221
- }
1222
- }
1223
- O[f] = 0;
1224
- })(m, i, N, b + 1);
1225
- else if (g) for (var S = 0; S < b; ++S) {
1226
- var q = m.charCodeAt(S);
1227
- q > 255 && (it(N), K("String has UTF-16 code units that do not fit in 8 bits")), i[N + S] = q;
1228
- }
1229
- else for (S = 0; S < b; ++S) i[N + S] = m[S];
1230
- return Z !== null && Z.push(it, y), y;
1231
- }, argPackAdvance: 8, readValueFromPointer: xt, destructorFunction(Z) {
1232
- it(Z);
1233
- } });
1234
- }, c: (V, s, R) => {
1235
- var Z, m, b, g, y;
1236
- R = x(R), s === 2 ? (Z = Dt, m = wt, g = vt, b = () => c, y = 1) : s === 4 && (Z = zt, m = Mt, g = Kt, b = () => W, y = 2), _(V, { name: R, fromWireType: (N) => {
1237
- for (var S, q = W[N >> 2], P = b(), O = N + 4, f = 0; f <= q; ++f) {
1238
- var Qt = N + 4 + f * s;
1239
- if (f == q || P[Qt >> y] == 0) {
1240
- var st = Z(O, Qt - O);
1241
- S === void 0 ? S = st : (S += "\0", S += st), O = Qt + s;
1242
- }
1243
- }
1244
- return it(N), S;
1245
- }, toWireType: (N, S) => {
1246
- typeof S != "string" && K(`Cannot pass non-string to C++ string type ${R}`);
1247
- var q = g(S), P = Jt(4 + q + s);
1248
- return W[P >> 2] = q >> y, m(S, P + 4, q + s), N !== null && N.push(it, P), P;
1249
- }, argPackAdvance: 8, readValueFromPointer: Nt, destructorFunction(N) {
1250
- it(N);
1251
- } });
1252
- }, j: (V, s) => {
1253
- _(V, { isVoid: !0, name: s = x(s), argPackAdvance: 0, fromWireType: () => {
1254
- }, toWireType: (R, Z) => {
1255
- } });
1256
- }, g: (V) => {
1257
- var s = i.length, R = 2147483648;
1258
- if ((V >>>= 0) > R) return !1;
1259
- for (var Z, m, b = 1; b <= 4; b *= 2) {
1260
- var g = s * (1 + 0.2 / b);
1261
- g = Math.min(g, V + 100663296);
1262
- var y = Math.min(R, (Z = Math.max(V, g)) + ((m = 65536) - Z % m) % m);
1263
- if (jt(y)) return !0;
1264
- }
1265
- return !1;
1266
- } }, Bt = function() {
1267
- var V, s, R, Z = { a: Ot };
1268
- function m(b, g) {
1269
- var y;
1270
- return Bt = b.exports, Q = Bt.k, k(), y = Bt.l, X.unshift(y), function(N) {
1271
- if (u--, U.monitorRunDependencies && U.monitorRunDependencies(u), u == 0 && M) {
1272
- var S = M;
1273
- M = null, S();
1274
- }
1275
- }(), Bt;
1276
- }
1277
- if (u++, U.monitorRunDependencies && U.monitorRunDependencies(u), U.instantiateWasm) try {
1278
- return U.instantiateWasm(Z, m);
1279
- } catch (b) {
1280
- d(`Module.instantiateWasm callback failed with error: ${b}`), F(b);
1281
- }
1282
- return (V = w, s = Z, R = function(b) {
1283
- m(b.instance);
1284
- }, L(V, s, R)).catch(F), {};
1285
- }();
1286
- U._pack = (V, s, R, Z, m, b, g, y, N, S, q) => (U._pack = Bt.m)(V, s, R, Z, m, b, g, y, N, S, q), U.__embind_initialize_bindings = () => (U.__embind_initialize_bindings = Bt.n)();
1287
- var rt, Jt = U._malloc = (V) => (Jt = U._malloc = Bt.p)(V), it = U._free = (V) => (it = U._free = Bt.q)(V);
1288
- function Xt() {
1289
- function V() {
1290
- rt || (rt = !0, U.calledRun = !0, C || (o(X), t(U), U.onRuntimeInitialized && U.onRuntimeInitialized(), function() {
1291
- if (U.postRun) for (typeof U.postRun == "function" && (U.postRun = [U.postRun]); U.postRun.length; ) s = U.postRun.shift(), D.unshift(s);
1292
- var s;
1293
- o(D);
1294
- }()));
1295
- }
1296
- u > 0 || (function() {
1297
- if (U.preRun) for (typeof U.preRun == "function" && (U.preRun = [U.preRun]); U.preRun.length; ) s = U.preRun.shift(), p.unshift(s);
1298
- var s;
1299
- o(p);
1300
- }(), u > 0 || (U.setStatus ? (U.setStatus("Running..."), setTimeout(function() {
1301
- setTimeout(function() {
1302
- U.setStatus("");
1303
- }, 1), V();
1304
- }, 1)) : V()));
1305
- }
1306
- if (M = function V() {
1307
- rt || Xt(), rt || (M = V);
1308
- }, U.preInit) for (typeof U.preInit == "function" && (U.preInit = [U.preInit]); U.preInit.length > 0; ) U.preInit.pop()();
1309
- return Xt(), G.ready;
1310
- };
1311
- class Fl {
1312
- constructor(t) {
1313
- this.dataChanged = !1, this.transformsChanged = !1, this.colorTransformsChanged = !1, this._updating = /* @__PURE__ */ new Set(), this._dirty = /* @__PURE__ */ new Set();
1314
- let F = 0, U = 0;
1315
- this._splatIndices = /* @__PURE__ */ new Map(), this._offsets = /* @__PURE__ */ new Map();
1316
- const l = /* @__PURE__ */ new Map();
1317
- for (const A of t.objects) A instanceof dt && (this._splatIndices.set(A, U), this._offsets.set(A, F), l.set(F, A), F += A.data.vertexCount, U++);
1318
- this._vertexCount = F, this._width = 2048, this._height = Math.ceil(2 * this.vertexCount / this.width), this._data = new Uint32Array(this.width * this.height * 4), this._transformsWidth = 5, this._transformsHeight = l.size, this._transforms = new Float32Array(this._transformsWidth * this._transformsHeight * 4), this._transformIndicesWidth = 1024, this._transformIndicesHeight = Math.ceil(this.vertexCount / this._transformIndicesWidth), this._transformIndices = new Uint32Array(this._transformIndicesWidth * this._transformIndicesHeight), this._colorTransformsWidth = 4, this._colorTransformsHeight = 64, this._colorTransforms = new Float32Array(this._colorTransformsWidth * this._colorTransformsHeight * 4), this._colorTransforms.fill(0), this._colorTransforms[0] = 1, this._colorTransforms[5] = 1, this._colorTransforms[10] = 1, this._colorTransforms[15] = 1, this._colorTransformIndicesWidth = 1024, this._colorTransformIndicesHeight = Math.ceil(this.vertexCount / this._colorTransformIndicesWidth), this._colorTransformIndices = new Uint32Array(this._colorTransformIndicesWidth * this._colorTransformIndicesHeight), this.colorTransformIndices.fill(0), this._positions = new Float32Array(3 * this.vertexCount), this._rotations = new Float32Array(4 * this.vertexCount), this._scales = new Float32Array(3 * this.vertexCount), this._worker = new ll();
1319
- const a = (A) => {
1320
- const i = this._splatIndices.get(A);
1321
- this._transforms.set(A.transform.buffer, 20 * i), this._transforms[20 * i + 16] = A.selected ? 1 : 0, A.positionChanged = !1, A.rotationChanged = !1, A.scaleChanged = !1, A.selectedChanged = !1, this.transformsChanged = !0;
1322
- }, n = () => {
1323
- let A = !1;
1324
- for (const c of this._splatIndices.keys()) if (c.colorTransformChanged) {
1325
- A = !0;
1326
- break;
1327
- }
1328
- if (!A) return;
1329
- const i = [new Ut()];
1330
- this._colorTransformIndices.fill(0);
1331
- let r = 1;
1332
- for (const c of this._splatIndices.keys()) {
1333
- const B = this._offsets.get(c);
1334
- for (const W of c.colorTransforms) i.includes(W) || (i.push(W), r++);
1335
- for (const W of c.colorTransformsMap.keys()) {
1336
- const J = c.colorTransformsMap.get(W);
1337
- this._colorTransformIndices[W + B] = J + r - 1;
1338
- }
1339
- c.colorTransformChanged = !1;
1340
- }
1341
- for (let c = 0; c < i.length; c++) {
1342
- const B = i[c];
1343
- this._colorTransforms.set(B.buffer, 16 * c);
1344
- }
1345
- this.colorTransformsChanged = !0;
1346
- };
1347
- let e;
1348
- this._worker.onmessage = (A) => {
1349
- if (A.data.response) {
1350
- const i = A.data.response, r = l.get(i.offset);
1351
- a(r), n();
1352
- const c = this._splatIndices.get(r);
1353
- for (let B = 0; B < r.data.vertexCount; B++) this._transformIndices[i.offset + B] = c;
1354
- this._data.set(i.data, 8 * i.offset), r.data.reattach(i.positions, i.rotations, i.scales, i.colors, i.selection), this._positions.set(i.worldPositions, 3 * i.offset), this._rotations.set(i.worldRotations, 4 * i.offset), this._scales.set(i.worldScales, 3 * i.offset), this._updating.delete(r), r.selectedChanged = !1, this.dataChanged = !0;
1355
- }
1356
- }, async function() {
1357
- e = await Ul();
1358
- }();
1359
- const Q = (A) => {
1360
- if (!e) return void async function() {
1361
- for (; !e; ) await new Promise((w) => setTimeout(w, 0));
1362
- }().then(() => {
1363
- Q(A);
1364
- });
1365
- a(A);
1366
- const i = e._malloc(3 * A.data.vertexCount * 4), r = e._malloc(4 * A.data.vertexCount * 4), c = e._malloc(3 * A.data.vertexCount * 4), B = e._malloc(4 * A.data.vertexCount), W = e._malloc(A.data.vertexCount), J = e._malloc(8 * A.data.vertexCount * 4), h = e._malloc(3 * A.data.vertexCount * 4), C = e._malloc(4 * A.data.vertexCount * 4), k = e._malloc(3 * A.data.vertexCount * 4);
1367
- e.HEAPF32.set(A.data.positions, i / 4), e.HEAPF32.set(A.data.rotations, r / 4), e.HEAPF32.set(A.data.scales, c / 4), e.HEAPU8.set(A.data.colors, B), e.HEAPU8.set(A.data.selection, W), e._pack(A.selected, A.data.vertexCount, i, r, c, B, W, J, h, C, k);
1368
- const p = new Uint32Array(e.HEAPU32.buffer, J, 8 * A.data.vertexCount), X = new Float32Array(e.HEAPF32.buffer, h, 3 * A.data.vertexCount), D = new Float32Array(e.HEAPF32.buffer, C, 4 * A.data.vertexCount), u = new Float32Array(e.HEAPF32.buffer, k, 3 * A.data.vertexCount), M = this._splatIndices.get(A), E = this._offsets.get(A);
1369
- for (let w = 0; w < A.data.vertexCount; w++) this._transformIndices[E + w] = M;
1370
- this._data.set(p, 8 * E), this._positions.set(X, 3 * E), this._rotations.set(D, 4 * E), this._scales.set(u, 3 * E), e._free(i), e._free(r), e._free(c), e._free(B), e._free(W), e._free(J), e._free(h), e._free(C), e._free(k), this.dataChanged = !0, this.colorTransformsChanged = !0;
1371
- }, d = (A) => {
1372
- if ((A.positionChanged || A.rotationChanged || A.scaleChanged || A.selectedChanged) && a(A), A.colorTransformChanged && n(), !A.data.changed || A.data.detached) return;
1373
- const i = { position: new Float32Array(A.position.flat()), rotation: new Float32Array(A.rotation.flat()), scale: new Float32Array(A.scale.flat()), selected: A.selected, vertexCount: A.data.vertexCount, positions: A.data.positions, rotations: A.data.rotations, scales: A.data.scales, colors: A.data.colors, selection: A.data.selection, offset: this._offsets.get(A) };
1374
- this._worker.postMessage({ splat: i }, [i.position.buffer, i.rotation.buffer, i.scale.buffer, i.positions.buffer, i.rotations.buffer, i.scales.buffer, i.colors.buffer, i.selection.buffer]), this._updating.add(A), A.data.detached = !0;
1375
- };
1376
- this.getSplat = (A) => {
1377
- let i = null;
1378
- for (const [r, c] of this._offsets) {
1379
- if (!(A >= c)) break;
1380
- i = r;
1381
- }
1382
- return i;
1383
- }, this.getLocalIndex = (A, i) => i - this._offsets.get(A), this.markDirty = (A) => {
1384
- this._dirty.add(A);
1385
- }, this.rebuild = () => {
1386
- for (const A of this._dirty) d(A);
1387
- this._dirty.clear();
1388
- }, this.dispose = () => {
1389
- this._worker.terminate();
1390
- };
1391
- for (const A of this._splatIndices.keys()) Q(A);
1392
- n();
1393
- }
1394
- get offsets() {
1395
- return this._offsets;
1396
- }
1397
- get data() {
1398
- return this._data;
1399
- }
1400
- get width() {
1401
- return this._width;
1402
- }
1403
- get height() {
1404
- return this._height;
1405
- }
1406
- get transforms() {
1407
- return this._transforms;
1408
- }
1409
- get transformsWidth() {
1410
- return this._transformsWidth;
1411
- }
1412
- get transformsHeight() {
1413
- return this._transformsHeight;
1414
- }
1415
- get transformIndices() {
1416
- return this._transformIndices;
1417
- }
1418
- get transformIndicesWidth() {
1419
- return this._transformIndicesWidth;
1420
- }
1421
- get transformIndicesHeight() {
1422
- return this._transformIndicesHeight;
1423
- }
1424
- get colorTransforms() {
1425
- return this._colorTransforms;
1426
- }
1427
- get colorTransformsWidth() {
1428
- return this._colorTransformsWidth;
1429
- }
1430
- get colorTransformsHeight() {
1431
- return this._colorTransformsHeight;
1432
- }
1433
- get colorTransformIndices() {
1434
- return this._colorTransformIndices;
1435
- }
1436
- get colorTransformIndicesWidth() {
1437
- return this._colorTransformIndicesWidth;
1438
- }
1439
- get colorTransformIndicesHeight() {
1440
- return this._colorTransformIndicesHeight;
1441
- }
1442
- get positions() {
1443
- return this._positions;
1444
- }
1445
- get rotations() {
1446
- return this._rotations;
1447
- }
1448
- get scales() {
1449
- return this._scales;
1450
- }
1451
- get vertexCount() {
1452
- return this._vertexCount;
1453
- }
1454
- get needsRebuild() {
1455
- return this._dirty.size > 0;
1456
- }
1457
- get updating() {
1458
- return this._updating.size > 0;
1459
- }
1460
- }
1461
- class ut {
1462
- constructor(t = 0, F = 0, U = 0, l = 255) {
1463
- this.r = t, this.g = F, this.b = U, this.a = l;
1464
- }
1465
- flat() {
1466
- return [this.r, this.g, this.b, this.a];
1467
- }
1468
- flatNorm() {
1469
- return [this.r / 255, this.g / 255, this.b / 255, this.a / 255];
1470
- }
1471
- toHexString() {
1472
- return "#" + this.flat().map((t) => t.toString(16).padStart(2, "0")).join("");
1473
- }
1474
- toString() {
1475
- return `[${this.flat().join(", ")}]`;
1476
- }
1477
- }
1478
- class Yt extends St {
1479
- constructor(t, F) {
1480
- super(t, F), this._outlineThickness = 10, this._outlineColor = new ut(255, 165, 0, 255), this._renderData = null, this._depthIndex = new Uint32Array(), this._splatTexture = null, this._worker = null;
1481
- const U = t.canvas, l = t.gl;
1482
- let a, n, e, Q, d, A, i, r, c, B, W, J, h, C, k, p, X, D, u;
1483
- this._resize = () => {
1484
- this._camera && (this._camera.data.setSize(U.width, U.height), this._camera.update(), a = l.getUniformLocation(this.program, "projection"), l.uniformMatrix4fv(a, !1, this._camera.data.projectionMatrix.buffer), n = l.getUniformLocation(this.program, "viewport"), l.uniform2fv(n, new Float32Array([U.width, U.height])));
1485
- };
1486
- const M = () => {
1487
- this._worker = new tl(), this._worker.onmessage = (Y) => {
1488
- if (Y.data.depthIndex) {
1489
- const { depthIndex: H } = Y.data;
1490
- this._depthIndex = H, l.bindBuffer(l.ARRAY_BUFFER, u), l.bufferData(l.ARRAY_BUFFER, H, l.STATIC_DRAW);
1491
- }
1492
- };
1493
- };
1494
- this._initialize = () => {
1495
- if (this._scene && this._camera) {
1496
- this._resize(), this._scene.addEventListener("objectAdded", E), this._scene.addEventListener("objectRemoved", w);
1497
- for (const Y of this._scene.objects) Y instanceof dt && Y.addEventListener("objectChanged", Ft);
1498
- this._renderData = new Fl(this._scene), e = l.getUniformLocation(this.program, "focal"), l.uniform2fv(e, new Float32Array([this._camera.data.fx, this._camera.data.fy])), Q = l.getUniformLocation(this.program, "view"), l.uniformMatrix4fv(Q, !1, this._camera.data.viewMatrix.buffer), B = l.getUniformLocation(this.program, "outlineThickness"), l.uniform1f(B, this.outlineThickness), W = l.getUniformLocation(this.program, "outlineColor"), l.uniform4fv(W, new Float32Array(this.outlineColor.flatNorm())), this._splatTexture = l.createTexture(), d = l.getUniformLocation(this.program, "u_texture"), l.uniform1i(d, 0), C = l.createTexture(), A = l.getUniformLocation(this.program, "u_transforms"), l.uniform1i(A, 1), k = l.createTexture(), i = l.getUniformLocation(this.program, "u_transformIndices"), l.uniform1i(i, 2), p = l.createTexture(), r = l.getUniformLocation(this.program, "u_colorTransforms"), l.uniform1i(r, 3), X = l.createTexture(), c = l.getUniformLocation(this.program, "u_colorTransformIndices"), l.uniform1i(c, 4), D = l.createBuffer(), l.bindBuffer(l.ARRAY_BUFFER, D), l.bufferData(l.ARRAY_BUFFER, new Float32Array([-2, -2, 2, -2, 2, 2, -2, 2]), l.STATIC_DRAW), J = l.getAttribLocation(this.program, "position"), l.enableVertexAttribArray(J), l.vertexAttribPointer(J, 2, l.FLOAT, !1, 0, 0), u = l.createBuffer(), h = l.getAttribLocation(this.program, "index"), l.enableVertexAttribArray(h), l.bindBuffer(l.ARRAY_BUFFER, u), M();
1499
- } else console.error("Cannot render without scene and camera");
1500
- };
1501
- const E = (Y) => {
1502
- const H = Y;
1503
- H.object instanceof dt && H.object.addEventListener("objectChanged", Ft), this.dispose();
1504
- }, w = (Y) => {
1505
- const H = Y;
1506
- H.object instanceof dt && H.object.removeEventListener("objectChanged", Ft), this.dispose();
1507
- }, Ft = (Y) => {
1508
- const H = Y;
1509
- H.object instanceof dt && this._renderData && this._renderData.markDirty(H.object);
1510
- };
1511
- this._render = () => {
1512
- var Y, H;
1513
- if (this._scene && this._camera && this.renderData) {
1514
- if (this.renderData.needsRebuild && this.renderData.rebuild(), this.renderData.dataChanged || this.renderData.transformsChanged || this.renderData.colorTransformsChanged) {
1515
- this.renderData.dataChanged && (l.activeTexture(l.TEXTURE0), l.bindTexture(l.TEXTURE_2D, this.splatTexture), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_S, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_T, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MIN_FILTER, l.NEAREST), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MAG_FILTER, l.NEAREST), l.texImage2D(l.TEXTURE_2D, 0, l.RGBA32UI, this.renderData.width, this.renderData.height, 0, l.RGBA_INTEGER, l.UNSIGNED_INT, this.renderData.data)), this.renderData.transformsChanged && (l.activeTexture(l.TEXTURE1), l.bindTexture(l.TEXTURE_2D, C), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_S, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_T, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MIN_FILTER, l.NEAREST), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MAG_FILTER, l.NEAREST), l.texImage2D(l.TEXTURE_2D, 0, l.RGBA32F, this.renderData.transformsWidth, this.renderData.transformsHeight, 0, l.RGBA, l.FLOAT, this.renderData.transforms), l.activeTexture(l.TEXTURE2), l.bindTexture(l.TEXTURE_2D, k), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_S, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_T, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MIN_FILTER, l.NEAREST), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MAG_FILTER, l.NEAREST), l.texImage2D(l.TEXTURE_2D, 0, l.R32UI, this.renderData.transformIndicesWidth, this.renderData.transformIndicesHeight, 0, l.RED_INTEGER, l.UNSIGNED_INT, this.renderData.transformIndices)), this.renderData.colorTransformsChanged && (l.activeTexture(l.TEXTURE3), l.bindTexture(l.TEXTURE_2D, p), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_S, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_T, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MIN_FILTER, l.NEAREST), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MAG_FILTER, l.NEAREST), l.texImage2D(l.TEXTURE_2D, 0, l.RGBA32F, this.renderData.colorTransformsWidth, this.renderData.colorTransformsHeight, 0, l.RGBA, l.FLOAT, this.renderData.colorTransforms), l.activeTexture(l.TEXTURE4), l.bindTexture(l.TEXTURE_2D, X), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_S, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_T, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MIN_FILTER, l.NEAREST), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MAG_FILTER, l.NEAREST), l.texImage2D(l.TEXTURE_2D, 0, l.R32UI, this.renderData.colorTransformIndicesWidth, this.renderData.colorTransformIndicesHeight, 0, l.RED_INTEGER, l.UNSIGNED_INT, this.renderData.colorTransformIndices));
1516
- const at = new Float32Array(this.renderData.positions.slice().buffer), L = new Float32Array(this.renderData.transforms.slice().buffer), o = new Uint32Array(this.renderData.transformIndices.slice().buffer);
1517
- (Y = this._worker) === null || Y === void 0 || Y.postMessage({ sortData: { positions: at, transforms: L, transformIndices: o, vertexCount: this.renderData.vertexCount } }, [at.buffer, L.buffer, o.buffer]), this.renderData.dataChanged = !1, this.renderData.transformsChanged = !1, this.renderData.colorTransformsChanged = !1;
1518
- }
1519
- this._camera.update(), (H = this._worker) === null || H === void 0 || H.postMessage({ viewProj: this._camera.data.viewProj.buffer }), l.viewport(0, 0, U.width, U.height), l.clearColor(0, 0, 0, 0), l.clear(l.COLOR_BUFFER_BIT), l.disable(l.DEPTH_TEST), l.enable(l.BLEND), l.blendFuncSeparate(l.ONE_MINUS_DST_ALPHA, l.ONE, l.ONE_MINUS_DST_ALPHA, l.ONE), l.blendEquationSeparate(l.FUNC_ADD, l.FUNC_ADD), l.uniformMatrix4fv(a, !1, this._camera.data.projectionMatrix.buffer), l.uniformMatrix4fv(Q, !1, this._camera.data.viewMatrix.buffer), l.bindBuffer(l.ARRAY_BUFFER, D), l.vertexAttribPointer(J, 2, l.FLOAT, !1, 0, 0), l.bindBuffer(l.ARRAY_BUFFER, u), l.bufferData(l.ARRAY_BUFFER, this.depthIndex, l.STATIC_DRAW), l.vertexAttribIPointer(h, 1, l.INT, 0, 0), l.vertexAttribDivisor(h, 1), l.drawArraysInstanced(l.TRIANGLE_FAN, 0, 4, this.renderData.vertexCount);
1520
- } else console.error("Cannot render without scene and camera");
1521
- }, this._dispose = () => {
1522
- var Y;
1523
- if (this._scene && this._camera && this.renderData) {
1524
- this._scene.removeEventListener("objectAdded", E), this._scene.removeEventListener("objectRemoved", w);
1525
- for (const H of this._scene.objects) H instanceof dt && H.removeEventListener("objectChanged", Ft);
1526
- (Y = this._worker) === null || Y === void 0 || Y.terminate(), this.renderData.dispose(), l.deleteTexture(this.splatTexture), l.deleteTexture(C), l.deleteTexture(k), l.deleteBuffer(u), l.deleteBuffer(D);
1527
- } else console.error("Cannot dispose without scene and camera");
1528
- }, this._setOutlineThickness = (Y) => {
1529
- this._outlineThickness = Y, this._initialized && l.uniform1f(B, Y);
1530
- }, this._setOutlineColor = (Y) => {
1531
- this._outlineColor = Y, this._initialized && l.uniform4fv(W, new Float32Array(Y.flatNorm()));
1532
- };
1533
- }
1534
- get renderData() {
1535
- return this._renderData;
1536
- }
1537
- get depthIndex() {
1538
- return this._depthIndex;
1539
- }
1540
- get splatTexture() {
1541
- return this._splatTexture;
1542
- }
1543
- get outlineThickness() {
1544
- return this._outlineThickness;
1545
- }
1546
- set outlineThickness(t) {
1547
- this._setOutlineThickness(t);
1548
- }
1549
- get outlineColor() {
1550
- return this._outlineColor;
1551
- }
1552
- set outlineColor(t) {
1553
- this._setOutlineColor(t);
1554
- }
1555
- get worker() {
1556
- return this._worker;
1557
- }
1558
- _getVertexSource() {
1559
- return `#version 300 es
1560
- precision highp float;
1561
- precision highp int;
1562
-
1563
- uniform highp usampler2D u_texture;
1564
- uniform highp sampler2D u_transforms;
1565
- uniform highp usampler2D u_transformIndices;
1566
- uniform highp sampler2D u_colorTransforms;
1567
- uniform highp usampler2D u_colorTransformIndices;
1568
- uniform mat4 projection, view;
1569
- uniform vec2 focal;
1570
- uniform vec2 viewport;
1571
-
1572
- uniform bool useDepthFade;
1573
- uniform float depthFade;
1574
-
1575
- in vec2 position;
1576
- in int index;
1577
-
1578
- out vec4 vColor;
1579
- out vec2 vPosition;
1580
- out float vSize;
1581
- out float vSelected;
1582
-
1583
- void main () {
1584
- uvec4 cen = texelFetch(u_texture, ivec2((uint(index) & 0x3ffu) << 1, uint(index) >> 10), 0);
1585
- float selected = float((cen.w >> 24) & 0xffu);
1586
-
1587
- uint transformIndex = texelFetch(u_transformIndices, ivec2(uint(index) & 0x3ffu, uint(index) >> 10), 0).x;
1588
- mat4 transform = mat4(
1589
- texelFetch(u_transforms, ivec2(0, transformIndex), 0),
1590
- texelFetch(u_transforms, ivec2(1, transformIndex), 0),
1591
- texelFetch(u_transforms, ivec2(2, transformIndex), 0),
1592
- texelFetch(u_transforms, ivec2(3, transformIndex), 0)
1593
- );
1594
-
1595
- if (selected < 0.5) {
1596
- selected = texelFetch(u_transforms, ivec2(4, transformIndex), 0).x;
1597
- }
1598
-
1599
- mat4 viewTransform = view * transform;
1600
-
1601
- vec4 cam = viewTransform * vec4(uintBitsToFloat(cen.xyz), 1);
1602
- vec4 pos2d = projection * cam;
1603
-
1604
- float clip = 1.2 * pos2d.w;
1605
- if (pos2d.z < -pos2d.w || pos2d.z > pos2d.w || pos2d.x < -clip || pos2d.x > clip || pos2d.y < -clip || pos2d.y > clip) {
1606
- gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
1607
- return;
1608
- }
1609
-
1610
- uvec4 cov = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 1) | 1u, uint(index) >> 10), 0);
1611
- vec2 u1 = unpackHalf2x16(cov.x), u2 = unpackHalf2x16(cov.y), u3 = unpackHalf2x16(cov.z);
1612
- mat3 Vrk = mat3(u1.x, u1.y, u2.x, u1.y, u2.y, u3.x, u2.x, u3.x, u3.y);
1613
-
1614
- mat3 J = mat3(
1615
- focal.x / cam.z, 0., -(focal.x * cam.x) / (cam.z * cam.z),
1616
- 0., -focal.y / cam.z, (focal.y * cam.y) / (cam.z * cam.z),
1617
- 0., 0., 0.
1618
- );
1619
-
1620
- mat3 T = transpose(mat3(viewTransform)) * J;
1621
- mat3 cov2d = transpose(T) * Vrk * T;
1622
-
1623
- //ref: https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/forward.cu#L110-L111
1624
- cov2d[0][0] += 0.3;
1625
- cov2d[1][1] += 0.3;
1626
-
1627
- float mid = (cov2d[0][0] + cov2d[1][1]) / 2.0;
1628
- float radius = length(vec2((cov2d[0][0] - cov2d[1][1]) / 2.0, cov2d[0][1]));
1629
- float lambda1 = mid + radius, lambda2 = mid - radius;
1630
-
1631
- if (lambda2 < 0.0) return;
1632
- vec2 diagonalVector = normalize(vec2(cov2d[0][1], lambda1 - cov2d[0][0]));
1633
- vec2 majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;
1634
- vec2 minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x);
1635
-
1636
- uint colorTransformIndex = texelFetch(u_colorTransformIndices, ivec2(uint(index) & 0x3ffu, uint(index) >> 10), 0).x;
1637
- mat4 colorTransform = mat4(
1638
- texelFetch(u_colorTransforms, ivec2(0, colorTransformIndex), 0),
1639
- texelFetch(u_colorTransforms, ivec2(1, colorTransformIndex), 0),
1640
- texelFetch(u_colorTransforms, ivec2(2, colorTransformIndex), 0),
1641
- texelFetch(u_colorTransforms, ivec2(3, colorTransformIndex), 0)
1642
- );
1643
-
1644
- vec4 color = vec4((cov.w) & 0xffu, (cov.w >> 8) & 0xffu, (cov.w >> 16) & 0xffu, (cov.w >> 24) & 0xffu) / 255.0;
1645
- vColor = colorTransform * color;
1646
-
1647
- vPosition = position;
1648
- vSize = length(majorAxis);
1649
- vSelected = selected;
1650
-
1651
- float scalingFactor = 1.0;
1652
-
1653
- if (useDepthFade) {
1654
- float depthNorm = (pos2d.z / pos2d.w + 1.0) / 2.0;
1655
- float near = 0.1; float far = 100.0;
1656
- float normalizedDepth = (2.0 * near) / (far + near - depthNorm * (far - near));
1657
- float start = max(normalizedDepth - 0.1, 0.0);
1658
- float end = min(normalizedDepth + 0.1, 1.0);
1659
- scalingFactor = clamp((depthFade - start) / (end - start), 0.0, 1.0);
1660
- }
1661
-
1662
- vec2 vCenter = vec2(pos2d) / pos2d.w;
1663
- gl_Position = vec4(
1664
- vCenter
1665
- + position.x * majorAxis * scalingFactor / viewport
1666
- + position.y * minorAxis * scalingFactor / viewport, 0.0, 1.0);
1667
- }
1668
- `;
1669
- }
1670
- _getFragmentSource() {
1671
- return `#version 300 es
1672
- precision highp float;
1673
-
1674
- uniform float outlineThickness;
1675
- uniform vec4 outlineColor;
1676
-
1677
- in vec4 vColor;
1678
- in vec2 vPosition;
1679
- in float vSize;
1680
- in float vSelected;
1681
-
1682
- out vec4 fragColor;
1683
-
1684
- void main () {
1685
- float A = -dot(vPosition, vPosition);
1686
-
1687
- if (A < -4.0) discard;
1688
-
1689
- if (vSelected < 0.5) {
1690
- float B = exp(A) * vColor.a;
1691
- fragColor = vec4(B * vColor.rgb, B);
1692
- return;
1693
- }
1694
-
1695
- float outlineThreshold = -4.0 + (outlineThickness / vSize);
1696
-
1697
- if (A < outlineThreshold) {
1698
- fragColor = outlineColor;
1699
- }
1700
- else {
1701
- float B = exp(A) * vColor.a;
1702
- fragColor = vec4(B * vColor.rgb, B);
1703
- }
1704
- }
1705
- `;
1706
- }
1707
- }
1708
- class el {
1709
- constructor(t = 1) {
1710
- let F, U, l, a, n = 0, e = !1;
1711
- this.initialize = (Q) => {
1712
- if (!(Q instanceof Yt)) throw new Error("FadeInPass requires a RenderProgram");
1713
- n = Q.started ? 1 : 0, e = !0, F = Q, U = Q.renderer.gl, l = U.getUniformLocation(F.program, "useDepthFade"), U.uniform1i(l, 1), a = U.getUniformLocation(F.program, "depthFade"), U.uniform1f(a, n);
1714
- }, this.render = () => {
1715
- var Q;
1716
- e && !(!((Q = F.renderData) === null || Q === void 0) && Q.updating) && (U.useProgram(F.program), n = Math.min(n + 0.01 * t, 1), n >= 1 && (e = !1, U.uniform1i(l, 0)), U.uniform1f(a, n));
1717
- };
1718
- }
1719
- dispose() {
1720
- }
1721
- }
1722
- class Bl {
1723
- constructor(t = null, F = null) {
1724
- this._backgroundColor = new ut();
1725
- const U = t || document.createElement("canvas");
1726
- t || (U.style.display = "block", U.style.boxSizing = "border-box", U.style.width = "100%", U.style.height = "100%", U.style.margin = "0", U.style.padding = "0", document.body.appendChild(U)), U.style.background = this._backgroundColor.toHexString(), this._canvas = U, this._gl = U.getContext("webgl2", { antialias: !1 });
1727
- const l = F || [];
1728
- F || l.push(new el()), this._renderProgram = new Yt(this, l);
1729
- const a = [this._renderProgram];
1730
- this.resize = () => {
1731
- const n = U.clientWidth, e = U.clientHeight;
1732
- U.width === n && U.height === e || this.setSize(n, e);
1733
- }, this.setSize = (n, e) => {
1734
- U.width = n, U.height = e, this._gl.viewport(0, 0, U.width, U.height);
1735
- for (const Q of a) Q.resize();
1736
- }, this.render = (n, e) => {
1737
- for (const Q of a) Q.render(n, e);
1738
- }, this.dispose = () => {
1739
- for (const n of a) n.dispose();
1740
- }, this.addProgram = (n) => {
1741
- a.push(n);
1742
- }, this.removeProgram = (n) => {
1743
- const e = a.indexOf(n);
1744
- if (e < 0) throw new Error("Program not found");
1745
- a.splice(e, 1);
1746
- }, this.resize();
1747
- }
1748
- get canvas() {
1749
- return this._canvas;
1750
- }
1751
- get gl() {
1752
- return this._gl;
1753
- }
1754
- get renderProgram() {
1755
- return this._renderProgram;
1756
- }
1757
- get backgroundColor() {
1758
- return this._backgroundColor;
1759
- }
1760
- set backgroundColor(t) {
1761
- this._backgroundColor = t, this._canvas.style.background = t.toHexString();
1762
- }
1763
- }
1764
- class il {
1765
- constructor(t, F, U = 0.5, l = 0.5, a = 5, n = !0, e = new I()) {
1766
- this.minAngle = -90, this.maxAngle = 90, this.minZoom = 0.1, this.maxZoom = 30, this.orbitSpeed = 1, this.panSpeed = 1, this.zoomSpeed = 1, this.dampening = 0.12, this.setCameraTarget = () => {
1767
- };
1768
- let Q = e.clone(), d = Q.clone(), A = U, i = l, r = a, c = !1, B = !1, W = 0, J = 0, h = 0;
1769
- const C = {};
1770
- let k = !1;
1771
- t.addEventListener("objectChanged", () => {
1772
- if (k) return;
1773
- const o = t.rotation.toEuler();
1774
- A = -o.y, i = -o.x;
1775
- const T = t.position.x - r * Math.sin(A) * Math.cos(i), v = t.position.y + r * Math.sin(i), x = t.position.z + r * Math.cos(A) * Math.cos(i);
1776
- d = new I(T, v, x);
1777
- }), this.setCameraTarget = (o) => {
1778
- const T = o.x - t.position.x, v = o.y - t.position.y, x = o.z - t.position.z;
1779
- r = Math.sqrt(T * T + v * v + x * x), i = Math.atan2(v, Math.sqrt(T * T + x * x)), A = -Math.atan2(T, x), d = new I(o.x, o.y, o.z);
1780
- };
1781
- const p = () => 0.1 + 0.9 * (r - this.minZoom) / (this.maxZoom - this.minZoom), X = (o) => {
1782
- C[o.code] = !0, o.code === "ArrowUp" && (C.KeyW = !0), o.code === "ArrowDown" && (C.KeyS = !0), o.code === "ArrowLeft" && (C.KeyA = !0), o.code === "ArrowRight" && (C.KeyD = !0);
1783
- }, D = (o) => {
1784
- C[o.code] = !1, o.code === "ArrowUp" && (C.KeyW = !1), o.code === "ArrowDown" && (C.KeyS = !1), o.code === "ArrowLeft" && (C.KeyA = !1), o.code === "ArrowRight" && (C.KeyD = !1);
1785
- }, u = (o) => {
1786
- L(o), c = !0, B = o.button === 2, J = o.clientX, h = o.clientY, window.addEventListener("mouseup", M);
1787
- }, M = (o) => {
1788
- L(o), c = !1, B = !1, window.removeEventListener("mouseup", M);
1789
- }, E = (o) => {
1790
- if (L(o), !c || !t) return;
1791
- const T = o.clientX - J, v = o.clientY - h;
1792
- if (B) {
1793
- const x = p(), At = -T * this.panSpeed * 0.01 * x, Vt = -v * this.panSpeed * 0.01 * x, K = tt.RotationFromQuaternion(t.rotation).buffer, _ = new I(K[0], K[3], K[6]), et = new I(K[1], K[4], K[7]);
1794
- d = d.add(_.multiply(At)), d = d.add(et.multiply(Vt));
1795
- } else A -= T * this.orbitSpeed * 3e-3, i += v * this.orbitSpeed * 3e-3, i = Math.min(Math.max(i, this.minAngle * Math.PI / 180), this.maxAngle * Math.PI / 180);
1796
- J = o.clientX, h = o.clientY;
1797
- }, w = (o) => {
1798
- L(o);
1799
- const T = p();
1800
- r += o.deltaY * this.zoomSpeed * 0.025 * T, r = Math.min(Math.max(r, this.minZoom), this.maxZoom);
1801
- }, Ft = (o) => {
1802
- if (L(o), o.touches.length === 1) c = !0, B = !1, J = o.touches[0].clientX, h = o.touches[0].clientY, W = 0;
1803
- else if (o.touches.length === 2) {
1804
- c = !0, B = !0, J = (o.touches[0].clientX + o.touches[1].clientX) / 2, h = (o.touches[0].clientY + o.touches[1].clientY) / 2;
1805
- const T = o.touches[0].clientX - o.touches[1].clientX, v = o.touches[0].clientY - o.touches[1].clientY;
1806
- W = Math.sqrt(T * T + v * v);
1807
- }
1808
- }, Y = (o) => {
1809
- L(o), c = !1, B = !1;
1810
- }, H = (o) => {
1811
- if (L(o), c && t) if (B) {
1812
- const T = p(), v = o.touches[0].clientX - o.touches[1].clientX, x = o.touches[0].clientY - o.touches[1].clientY, At = Math.sqrt(v * v + x * x);
1813
- r += (W - At) * this.zoomSpeed * 0.1 * T, r = Math.min(Math.max(r, this.minZoom), this.maxZoom), W = At;
1814
- const Vt = (o.touches[0].clientX + o.touches[1].clientX) / 2, K = (o.touches[0].clientY + o.touches[1].clientY) / 2, _ = Vt - J, et = K - h, j = tt.RotationFromQuaternion(t.rotation).buffer, Rt = new I(j[0], j[3], j[6]), It = new I(j[1], j[4], j[7]);
1815
- d = d.add(Rt.multiply(-_ * this.panSpeed * 0.025 * T)), d = d.add(It.multiply(-et * this.panSpeed * 0.025 * T)), J = Vt, h = K;
1816
- } else {
1817
- const T = o.touches[0].clientX - J, v = o.touches[0].clientY - h;
1818
- A -= T * this.orbitSpeed * 3e-3, i += v * this.orbitSpeed * 3e-3, i = Math.min(Math.max(i, this.minAngle * Math.PI / 180), this.maxAngle * Math.PI / 180), J = o.touches[0].clientX, h = o.touches[0].clientY;
1819
- }
1820
- }, at = (o, T, v) => (1 - v) * o + v * T;
1821
- this.update = () => {
1822
- k = !0, U = at(U, A, this.dampening), l = at(l, i, this.dampening), a = at(a, r, this.dampening), Q = Q.lerp(d, this.dampening);
1823
- const o = Q.x + a * Math.sin(U) * Math.cos(l), T = Q.y - a * Math.sin(l), v = Q.z - a * Math.cos(U) * Math.cos(l);
1824
- t.position = new I(o, T, v);
1825
- const x = Q.subtract(t.position).normalize(), At = Math.asin(-x.y), Vt = Math.atan2(x.x, x.z);
1826
- t.rotation = z.FromEuler(new I(At, Vt, 0));
1827
- const K = 0.025, _ = 0.01, et = tt.RotationFromQuaternion(t.rotation).buffer, j = new I(-et[2], -et[5], -et[8]), Rt = new I(et[0], et[3], et[6]);
1828
- C.KeyS && (d = d.add(j.multiply(K))), C.KeyW && (d = d.subtract(j.multiply(K))), C.KeyA && (d = d.subtract(Rt.multiply(K))), C.KeyD && (d = d.add(Rt.multiply(K))), C.KeyE && (A += _), C.KeyQ && (A -= _), C.KeyR && (i += _), C.KeyF && (i -= _), k = !1;
1829
- };
1830
- const L = (o) => {
1831
- o.preventDefault(), o.stopPropagation();
1832
- };
1833
- this.dispose = () => {
1834
- F.removeEventListener("dragenter", L), F.removeEventListener("dragover", L), F.removeEventListener("dragleave", L), F.removeEventListener("contextmenu", L), F.removeEventListener("mousedown", u), F.removeEventListener("mousemove", E), F.removeEventListener("wheel", w), F.removeEventListener("touchstart", Ft), F.removeEventListener("touchend", Y), F.removeEventListener("touchmove", H), n && (window.removeEventListener("keydown", X), window.removeEventListener("keyup", D));
1835
- }, n && (window.addEventListener("keydown", X), window.addEventListener("keyup", D)), F.addEventListener("dragenter", L), F.addEventListener("dragover", L), F.addEventListener("dragleave", L), F.addEventListener("contextmenu", L), F.addEventListener("mousedown", u), F.addEventListener("mousemove", E), F.addEventListener("wheel", w), F.addEventListener("touchstart", Ft), F.addEventListener("touchend", Y), F.addEventListener("touchmove", H), this.update();
1836
- }
1837
- }
1838
- class sl {
1839
- constructor(t, F) {
1840
- this.moveSpeed = 1.5, this.lookSpeed = 0.7, this.dampening = 0.5;
1841
- const U = {};
1842
- let l = t.rotation.toEuler().x, a = t.rotation.toEuler().y, n = t.position, e = !1;
1843
- const Q = () => {
1844
- F.requestPointerLock();
1845
- }, d = () => {
1846
- e = document.pointerLockElement === F, e ? F.addEventListener("mousemove", A) : F.removeEventListener("mousemove", A);
1847
- }, A = (B) => {
1848
- const W = B.movementX, J = B.movementY;
1849
- a += W * this.lookSpeed * 1e-3, l -= J * this.lookSpeed * 1e-3, l = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, l));
1850
- }, i = (B) => {
1851
- U[B.code] = !0, B.code === "ArrowUp" && (U.KeyW = !0), B.code === "ArrowDown" && (U.KeyS = !0), B.code === "ArrowLeft" && (U.KeyA = !0), B.code === "ArrowRight" && (U.KeyD = !0);
1852
- }, r = (B) => {
1853
- U[B.code] = !1, B.code === "ArrowUp" && (U.KeyW = !1), B.code === "ArrowDown" && (U.KeyS = !1), B.code === "ArrowLeft" && (U.KeyA = !1), B.code === "ArrowRight" && (U.KeyD = !1), B.code === "Escape" && document.exitPointerLock();
1854
- };
1855
- this.update = () => {
1856
- const B = tt.RotationFromQuaternion(t.rotation).buffer, W = new I(-B[2], -B[5], -B[8]), J = new I(B[0], B[3], B[6]);
1857
- let h = new I(0, 0, 0);
1858
- U.KeyS && (h = h.add(W)), U.KeyW && (h = h.subtract(W)), U.KeyA && (h = h.subtract(J)), U.KeyD && (h = h.add(J)), h = new I(h.x, 0, h.z), h.magnitude() > 0 && (h = h.normalize()), n = n.add(h.multiply(0.01 * this.moveSpeed)), t.position = t.position.add(n.subtract(t.position).multiply(this.dampening)), t.rotation = z.FromEuler(new I(l, a, 0));
1859
- };
1860
- const c = (B) => {
1861
- B.preventDefault(), B.stopPropagation();
1862
- };
1863
- this.dispose = () => {
1864
- F.removeEventListener("dragenter", c), F.removeEventListener("dragover", c), F.removeEventListener("dragleave", c), F.removeEventListener("contextmenu", c), F.removeEventListener("mousedown", Q), document.removeEventListener("pointerlockchange", d), window.removeEventListener("keydown", i), window.removeEventListener("keyup", r);
1865
- }, window.addEventListener("keydown", i), window.addEventListener("keyup", r), F.addEventListener("dragenter", c), F.addEventListener("dragover", c), F.addEventListener("dragleave", c), F.addEventListener("contextmenu", c), F.addEventListener("mousedown", Q), document.addEventListener("pointerlockchange", d), this.update();
1866
- }
1867
- }
1868
- class Zl {
1869
- constructor(t, F) {
1870
- this.normal = t, this.point = F;
1871
- }
1872
- intersect(t, F) {
1873
- const U = this.normal.dot(F);
1874
- if (Math.abs(U) < 1e-4) return null;
1875
- const l = this.normal.dot(this.point.subtract(t)) / U;
1876
- return l < 0 ? null : t.add(F.multiply(l));
1877
- }
1878
- }
1879
- class Rl {
1880
- initialize(t) {
1881
- }
1882
- render() {
1883
- }
1884
- dispose() {
1885
- }
1886
- }
1887
- class cl extends St {
1888
- constructor(t, F = []) {
1889
- super(t, F), this._renderData = null, this._depthIndex = new Uint32Array(), this._splatTexture = null;
1890
- const U = t.canvas, l = t.gl;
1891
- let a, n, e, Q, d, A, i, r, c, B, W;
1892
- this._resize = () => {
1893
- this._camera && (this._camera.data.setSize(U.width, U.height), this._camera.update(), n = l.getUniformLocation(this.program, "projection"), l.uniformMatrix4fv(n, !1, this._camera.data.projectionMatrix.buffer), e = l.getUniformLocation(this.program, "viewport"), l.uniform2fv(e, new Float32Array([U.width, U.height])));
1894
- };
1895
- const J = () => {
1896
- t.renderProgram.worker !== null ? (a = t.renderProgram.worker, a.onmessage = (p) => {
1897
- if (p.data.depthIndex) {
1898
- const { depthIndex: X } = p.data;
1899
- this._depthIndex = X, l.bindBuffer(l.ARRAY_BUFFER, W), l.bufferData(l.ARRAY_BUFFER, X, l.STATIC_DRAW);
1900
- }
1901
- }) : console.error("Render program is not initialized. Cannot render without worker");
1902
- };
1903
- this._initialize = () => {
1904
- if (!this._scene || !this._camera) return void console.error("Cannot render without scene and camera");
1905
- this._resize(), this._scene.addEventListener("objectAdded", h), this._scene.addEventListener("objectRemoved", C);
1906
- for (const u of this._scene.objects) u instanceof ct && (this._renderData === null ? (this._renderData = u.data, u.addEventListener("objectChanged", k)) : console.warn("Multiple Splatv objects are not currently supported"));
1907
- if (this._renderData === null) return void console.error("Cannot render without Splatv object");
1908
- Q = l.getUniformLocation(this.program, "focal"), l.uniform2fv(Q, new Float32Array([this._camera.data.fx, this._camera.data.fy])), d = l.getUniformLocation(this.program, "view"), l.uniformMatrix4fv(d, !1, this._camera.data.viewMatrix.buffer), this._splatTexture = l.createTexture(), A = l.getUniformLocation(this.program, "u_texture"), l.uniform1i(A, 0), i = l.getUniformLocation(this.program, "time"), l.uniform1f(i, Math.sin(Date.now() / 1e3) / 2 + 0.5), B = l.createBuffer(), l.bindBuffer(l.ARRAY_BUFFER, B), l.bufferData(l.ARRAY_BUFFER, new Float32Array([-2, -2, 2, -2, 2, 2, -2, 2]), l.STATIC_DRAW), r = l.getAttribLocation(this.program, "position"), l.enableVertexAttribArray(r), l.vertexAttribPointer(r, 2, l.FLOAT, !1, 0, 0), W = l.createBuffer(), c = l.getAttribLocation(this.program, "index"), l.enableVertexAttribArray(c), l.bindBuffer(l.ARRAY_BUFFER, W), J(), l.activeTexture(l.TEXTURE0), l.bindTexture(l.TEXTURE_2D, this._splatTexture), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_S, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_WRAP_T, l.CLAMP_TO_EDGE), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MIN_FILTER, l.NEAREST), l.texParameteri(l.TEXTURE_2D, l.TEXTURE_MAG_FILTER, l.NEAREST), l.texImage2D(l.TEXTURE_2D, 0, l.RGBA32UI, this._renderData.width, this._renderData.height, 0, l.RGBA_INTEGER, l.UNSIGNED_INT, this._renderData.data);
1909
- const p = this._renderData.positions, X = new Float32Array(new Ut().buffer), D = new Uint32Array(this._renderData.vertexCount);
1910
- D.fill(0), a.postMessage({ sortData: { positions: p, transforms: X, transformIndices: D, vertexCount: this._renderData.vertexCount } }, [p.buffer, X.buffer, D.buffer]);
1911
- };
1912
- const h = (p) => {
1913
- const X = p;
1914
- X.object instanceof ct && (this._renderData === null ? (this._renderData = X.object.data, X.object.addEventListener("objectChanged", k)) : console.warn("Splatv not supported by default RenderProgram. Use VideoRenderProgram instead.")), this.dispose();
1915
- }, C = (p) => {
1916
- const X = p;
1917
- X.object instanceof ct && this._renderData === X.object.data && (this._renderData = null, X.object.removeEventListener("objectChanged", k)), this.dispose();
1918
- }, k = (p) => {
1919
- const X = p;
1920
- X.object instanceof ct && this._renderData === X.object.data && this.dispose();
1921
- };
1922
- this._render = () => {
1923
- this._scene && this._camera ? this._renderData ? (this._camera.update(), a.postMessage({ viewProj: this._camera.data.viewProj.buffer }), l.viewport(0, 0, U.width, U.height), l.clearColor(0, 0, 0, 0), l.clear(l.COLOR_BUFFER_BIT), l.disable(l.DEPTH_TEST), l.enable(l.BLEND), l.blendFuncSeparate(l.ONE_MINUS_DST_ALPHA, l.ONE, l.ONE_MINUS_DST_ALPHA, l.ONE), l.blendEquationSeparate(l.FUNC_ADD, l.FUNC_ADD), l.uniformMatrix4fv(n, !1, this._camera.data.projectionMatrix.buffer), l.uniformMatrix4fv(d, !1, this._camera.data.viewMatrix.buffer), l.uniform1f(i, Math.sin(Date.now() / 1e3) / 2 + 0.5), l.bindBuffer(l.ARRAY_BUFFER, B), l.vertexAttribPointer(r, 2, l.FLOAT, !1, 0, 0), l.bindBuffer(l.ARRAY_BUFFER, W), l.bufferData(l.ARRAY_BUFFER, this._depthIndex, l.STATIC_DRAW), l.vertexAttribIPointer(c, 1, l.INT, 0, 0), l.vertexAttribDivisor(c, 1), l.drawArraysInstanced(l.TRIANGLE_FAN, 0, 4, this._renderData.vertexCount)) : console.warn("Cannot render without Splatv object") : console.error("Cannot render without scene and camera");
1924
- }, this._dispose = () => {
1925
- if (this._scene && this._camera) {
1926
- this._scene.removeEventListener("objectAdded", h), this._scene.removeEventListener("objectRemoved", C);
1927
- for (const p of this._scene.objects) p instanceof ct && this._renderData === p.data && (this._renderData = null, p.removeEventListener("objectChanged", k));
1928
- a == null || a.terminate(), l.deleteTexture(this._splatTexture), l.deleteBuffer(W), l.deleteBuffer(B);
1929
- } else console.error("Cannot dispose without scene and camera");
1930
- };
1931
- }
1932
- get renderData() {
1933
- return this._renderData;
1934
- }
1935
- _getVertexSource() {
1936
- return `#version 300 es
1937
- precision highp float;
1938
- precision highp int;
1939
-
1940
- uniform highp usampler2D u_texture;
1941
- uniform mat4 projection, view;
1942
- uniform vec2 focal;
1943
- uniform vec2 viewport;
1944
- uniform float time;
1945
-
1946
- in vec2 position;
1947
- in int index;
1948
-
1949
- out vec4 vColor;
1950
- out vec2 vPosition;
1951
-
1952
- void main () {
1953
- gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
1954
-
1955
- uvec4 motion1 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2) | 3u, uint(index) >> 10), 0);
1956
- vec2 trbf = unpackHalf2x16(motion1.w);
1957
- float dt = time - trbf.x;
1958
-
1959
- float topacity = exp(-1.0 * pow(dt / trbf.y, 2.0));
1960
- if(topacity < 0.02) return;
1961
-
1962
- uvec4 motion0 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2) | 2u, uint(index) >> 10), 0);
1963
- uvec4 static0 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2), uint(index) >> 10), 0);
1964
-
1965
- vec2 m0 = unpackHalf2x16(motion0.x), m1 = unpackHalf2x16(motion0.y), m2 = unpackHalf2x16(motion0.z),
1966
- m3 = unpackHalf2x16(motion0.w), m4 = unpackHalf2x16(motion1.x);
1967
-
1968
- vec4 trot = vec4(unpackHalf2x16(motion1.y).xy, unpackHalf2x16(motion1.z).xy) * dt;
1969
- vec3 tpos = (vec3(m0.xy, m1.x) * dt + vec3(m1.y, m2.xy) * dt*dt + vec3(m3.xy, m4.x) * dt*dt*dt);
1970
-
1971
- vec4 cam = view * vec4(uintBitsToFloat(static0.xyz) + tpos, 1);
1972
- vec4 pos = projection * cam;
1973
-
1974
- float clip = 1.2 * pos.w;
1975
- if (pos.z < -clip || pos.x < -clip || pos.x > clip || pos.y < -clip || pos.y > clip) return;
1976
- uvec4 static1 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2) | 1u, uint(index) >> 10), 0);
1977
-
1978
- vec4 rot = vec4(unpackHalf2x16(static0.w).xy, unpackHalf2x16(static1.x).xy) + trot;
1979
- vec3 scale = vec3(unpackHalf2x16(static1.y).xy, unpackHalf2x16(static1.z).x);
1980
- rot /= sqrt(dot(rot, rot));
1981
-
1982
- mat3 S = mat3(scale.x, 0.0, 0.0, 0.0, scale.y, 0.0, 0.0, 0.0, scale.z);
1983
- mat3 R = mat3(
1984
- 1.0 - 2.0 * (rot.z * rot.z + rot.w * rot.w), 2.0 * (rot.y * rot.z - rot.x * rot.w), 2.0 * (rot.y * rot.w + rot.x * rot.z),
1985
- 2.0 * (rot.y * rot.z + rot.x * rot.w), 1.0 - 2.0 * (rot.y * rot.y + rot.w * rot.w), 2.0 * (rot.z * rot.w - rot.x * rot.y),
1986
- 2.0 * (rot.y * rot.w - rot.x * rot.z), 2.0 * (rot.z * rot.w + rot.x * rot.y), 1.0 - 2.0 * (rot.y * rot.y + rot.z * rot.z));
1987
- mat3 M = S * R;
1988
- mat3 Vrk = 4.0 * transpose(M) * M;
1989
- mat3 J = mat3(
1990
- focal.x / cam.z, 0., -(focal.x * cam.x) / (cam.z * cam.z),
1991
- 0., -focal.y / cam.z, (focal.y * cam.y) / (cam.z * cam.z),
1992
- 0., 0., 0.
1993
- );
1994
-
1995
- mat3 T = transpose(mat3(view)) * J;
1996
- mat3 cov2d = transpose(T) * Vrk * T;
1997
-
1998
- float mid = (cov2d[0][0] + cov2d[1][1]) / 2.0;
1999
- float radius = length(vec2((cov2d[0][0] - cov2d[1][1]) / 2.0, cov2d[0][1]));
2000
- float lambda1 = mid + radius, lambda2 = mid - radius;
2001
-
2002
- if(lambda2 < 0.0) return;
2003
- vec2 diagonalVector = normalize(vec2(cov2d[0][1], lambda1 - cov2d[0][0]));
2004
- vec2 majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;
2005
- vec2 minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x);
2006
-
2007
- uint rgba = static1.w;
2008
- vColor =
2009
- clamp(pos.z/pos.w+1.0, 0.0, 1.0) *
2010
- vec4(1.0, 1.0, 1.0, topacity) *
2011
- vec4(
2012
- (rgba) & 0xffu,
2013
- (rgba >> 8) & 0xffu,
2014
- (rgba >> 16) & 0xffu,
2015
- (rgba >> 24) & 0xffu) / 255.0;
2016
-
2017
- vec2 vCenter = vec2(pos) / pos.w;
2018
- gl_Position = vec4(
2019
- vCenter
2020
- + position.x * majorAxis / viewport
2021
- + position.y * minorAxis / viewport, 0.0, 1.0);
2022
-
2023
- vPosition = position;
2024
- }
2025
- `;
2026
- }
2027
- _getFragmentSource() {
2028
- return `#version 300 es
2029
- precision highp float;
2030
-
2031
- in vec4 vColor;
2032
- in vec2 vPosition;
2033
-
2034
- out vec4 fragColor;
2035
-
2036
- void main () {
2037
- float A = -dot(vPosition, vPosition);
2038
- if (A < -4.0) discard;
2039
- float B = exp(A) * vColor.a;
2040
- fragColor = vec4(B * vColor.rgb, B);
2041
- }
2042
- `;
2043
- }
2044
- }
2045
- class ht {
2046
- constructor(t, F, U) {
2047
- this.bounds = t, this.boxes = F, this.left = null, this.right = null, this.pointIndices = [], U.length > 1 ? this.split(t, F, U) : U.length > 0 && (this.pointIndices = U);
2048
- }
2049
- split(t, F, U) {
2050
- const l = t.size().maxComponent();
2051
- U.sort((Q, d) => F[Q].center().getComponent(l) - F[d].center().getComponent(l));
2052
- const a = Math.floor(U.length / 2), n = U.slice(0, a), e = U.slice(a);
2053
- this.left = new ht(t, F, n), this.right = new ht(t, F, e);
2054
- }
2055
- queryRange(t) {
2056
- return this.bounds.intersects(t) ? this.left !== null && this.right !== null ? this.left.queryRange(t).concat(this.right.queryRange(t)) : this.pointIndices.filter((F) => t.intersects(this.boxes[F])) : [];
2057
- }
2058
- }
2059
- class nl {
2060
- constructor(t, F) {
2061
- const U = F.map((l, a) => a);
2062
- this.root = new ht(t, F, U);
2063
- }
2064
- queryRange(t) {
2065
- return this.root.queryRange(t);
2066
- }
2067
- }
2068
- class ol {
2069
- constructor(t, F = 100, U = 1) {
2070
- let l = 0, a = null, n = [];
2071
- this.testPoint = (e, Q) => {
2072
- if (t.renderData === null || t.camera === null) return console.error("IntersectionTester cannot be called before renderProgram has been initialized"), null;
2073
- if ((() => {
2074
- if (t.renderData === null) return void console.error("IntersectionTester cannot be called before renderProgram has been initialized");
2075
- n = [];
2076
- const r = t.renderData, c = new Array(r.offsets.size);
2077
- let B = 0;
2078
- const W = new ot(new I(1 / 0, 1 / 0, 1 / 0), new I(-1 / 0, -1 / 0, -1 / 0));
2079
- for (const J of r.offsets.keys()) {
2080
- const h = J.bounds;
2081
- c[B++] = h, W.expand(h.min), W.expand(h.max), n.push(J);
2082
- }
2083
- W.permute(), a = new nl(W, c), l = r.vertexCount;
2084
- })(), a === null) return console.error("Failed to build octree for IntersectionTester"), null;
2085
- const d = t.renderData, A = t.camera;
2086
- l !== d.vertexCount && console.warn("IntersectionTester has not been rebuilt since the last render");
2087
- const i = A.screenPointToRay(e, Q);
2088
- for (let r = 0; r < F; r += U) {
2089
- const c = A.position.add(i.multiply(r)), B = new I(c.x - U / 2, c.y - U / 2, c.z - U / 2), W = new I(c.x + U / 2, c.y + U / 2, c.z + U / 2), J = new ot(B, W), h = a.queryRange(J);
2090
- if (h.length > 0) return n[h[0]];
2091
- }
2092
- return null;
2093
- };
2094
- }
2095
- }
2096
- export {
2097
- Ql as Camera,
2098
- qt as CameraData,
2099
- ut as Color32,
2100
- sl as FPSControls,
2101
- el as FadeInPass,
2102
- ol as IntersectionTester,
2103
- al as Loader,
2104
- tt as Matrix3,
2105
- Ut as Matrix4,
2106
- bt as Object3D,
2107
- il as OrbitControls,
2108
- Al as PLYLoader,
2109
- Zl as Plane,
2110
- z as Quaternion,
2111
- Fl as RenderData,
2112
- Yt as RenderProgram,
2113
- dl as Scene,
2114
- Rl as ShaderPass,
2115
- St as ShaderProgram,
2116
- dt as Splat,
2117
- lt as SplatData,
2118
- ct as Splatv,
2119
- mt as SplatvData,
2120
- Vl as SplatvLoader,
2121
- I as Vector3,
2122
- nt as Vector4,
2123
- cl as VideoRenderProgram,
2124
- Bl as WebGLRenderer
2125
- };