@threepipe/plugin-gaussian-splatting 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.
- package/dist/assets/{worker-dK7pvmNj.js.map → worker-BYCkgQO3.js.map} +1 -1
- package/dist/index.js +46 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46 -35
- package/dist/index.mjs.map +1 -1
- package/dist/three-gaussian-splat/cpp-sorter/SortWorkerManager.d.ts.map +1 -1
- package/dist/three-gaussian-splat/cpp-sorter/sort.d.ts +3 -0
- package/dist/three-gaussian-splat/cpp-sorter/sort.d.ts.map +1 -0
- package/dist/three-gaussian-splat/cpp-sorter/worker.d.ts.map +1 -1
- package/package.json +7 -5
- package/src/gaussian-splats-3d/Constants.js +10 -0
- package/src/gaussian-splats-3d/Util.js +147 -0
- package/src/gaussian-splats-3d/loaders/KSplatLoader.js +238 -0
- package/src/gaussian-splats-3d/loaders/LoaderStatus.js +6 -0
- package/src/gaussian-splats-3d/loaders/PlyLoader.js +32 -0
- package/src/gaussian-splats-3d/loaders/PlyParser.js +188 -0
- package/src/gaussian-splats-3d/loaders/SceneFormat.js +5 -0
- package/src/gaussian-splats-3d/loaders/SplatBuffer.js +817 -0
- package/src/gaussian-splats-3d/loaders/SplatBufferGenerator.js +31 -0
- package/src/gaussian-splats-3d/loaders/SplatLoader.js +129 -0
- package/src/gaussian-splats-3d/loaders/SplatParser.js +88 -0
- package/src/gaussian-splats-3d/loaders/SplatPartitioner.js +99 -0
- package/src/gaussian-splats-3d/loaders/UncompressedSplatArray.js +49 -0
- package/src/gaussian-splats-3d/loaders/Utils.js +8 -0
- package/src/gaussian-splats-3d/loaders-ts/SplatLoader.ts +33 -0
- package/src/three-gaussian-splat/ThreeGaussianSplatPlugin.ts +1 -1
- package/src/three-gaussian-splat/cpp-sorter/SortWorkerManager.ts +3 -1
- package/src/three-gaussian-splat/cpp-sorter/worker.ts +0 -1
- package/dist/assets/worker-dK7pvmNj.js +0 -1569
- package/dist/gaussian-splats-3d/GaussianSplatsPlugin.d.ts +0 -1
- package/dist/gaussian-splats-3d/GaussianSplatsPlugin.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
})(this, function(exports2, threepipe, three) {
|
|
4
4
|
"use strict";/**
|
|
5
5
|
* @license
|
|
6
|
-
* @threepipe/plugin-gaussian-splatting v0.1
|
|
6
|
+
* @threepipe/plugin-gaussian-splatting v0.2.1
|
|
7
7
|
* Copyright 2022-2024 repalash <palash@shaders.app>
|
|
8
8
|
* Apache-2.0 License
|
|
9
|
+
* See ./dependencies.txt for any bundled third-party dependencies and licenses.
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
|
-
var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
|
|
12
12
|
const computeFocalLengths = (width, height, fov, aspect, dpr) => {
|
|
13
13
|
const fovRad = threepipe.MathUtils.degToRad(fov);
|
|
14
14
|
const fovXRad = 2 * Math.atan(Math.tan(fovRad / 2) * aspect);
|
|
@@ -74,8 +74,7 @@
|
|
|
74
74
|
this.isCompatible = (material) => !!material.isPhysicalMaterial || !!material.isUnlitMaterial || !!material.isGBufferMaterial || !!material.userData.isGBufferMaterial;
|
|
75
75
|
this._refresh = () => {
|
|
76
76
|
var _a, _b;
|
|
77
|
-
if (!this._currentCamera)
|
|
78
|
-
return;
|
|
77
|
+
if (!this._currentCamera) return;
|
|
79
78
|
const size = new threepipe.Vector2();
|
|
80
79
|
(_a = this._renderer) == null ? void 0 : _a.getSize(size);
|
|
81
80
|
const dpr = ((_b = this._renderer) == null ? void 0 : _b.getPixelRatio()) || 1;
|
|
@@ -98,8 +97,7 @@
|
|
|
98
97
|
window.removeEventListener("resize", this._refresh);
|
|
99
98
|
}
|
|
100
99
|
update(camera, renderer) {
|
|
101
|
-
if (this._currentCamera === camera && this._renderer === renderer)
|
|
102
|
-
return;
|
|
100
|
+
if (this._currentCamera === camera && this._renderer === renderer) return;
|
|
103
101
|
this._renderer = renderer;
|
|
104
102
|
this._currentCamera = camera;
|
|
105
103
|
this._refresh();
|
|
@@ -146,8 +144,7 @@ void main () {
|
|
|
146
144
|
this.isGaussianSplatMaterialRaw = true;
|
|
147
145
|
this._refresh = () => {
|
|
148
146
|
var _a, _b;
|
|
149
|
-
if (!this._currentCamera)
|
|
150
|
-
return;
|
|
147
|
+
if (!this._currentCamera) return;
|
|
151
148
|
const size = new threepipe.Vector2();
|
|
152
149
|
(_a = this._renderer) == null ? void 0 : _a.getSize(size);
|
|
153
150
|
const width = size.x;
|
|
@@ -537,10 +534,8 @@ void main () {
|
|
|
537
534
|
const viewProj = new Float32Array(this._viewProj);
|
|
538
535
|
const result = await this._worker.runSort(viewProj);
|
|
539
536
|
const { quat, scale, center, color } = this._extractViews(result);
|
|
540
|
-
if (this._centersBuffer.length !== center.length)
|
|
541
|
-
|
|
542
|
-
else
|
|
543
|
-
this._centersBuffer.set(center);
|
|
537
|
+
if (this._centersBuffer.length !== center.length) this._centersBuffer = new Float32Array(center);
|
|
538
|
+
else this._centersBuffer.set(center);
|
|
544
539
|
this.attributes.color.array = color;
|
|
545
540
|
this.attributes.quat.array = quat;
|
|
546
541
|
this.attributes.scale.array = scale;
|
|
@@ -595,8 +590,7 @@ void main () {
|
|
|
595
590
|
return { quat, scale, center, color };
|
|
596
591
|
}
|
|
597
592
|
computeBoundingBox() {
|
|
598
|
-
if (!this.getAttribute("center"))
|
|
599
|
-
return super.computeBoundingBox();
|
|
593
|
+
if (!this.getAttribute("center")) return super.computeBoundingBox();
|
|
600
594
|
const box = this.boundingBox ?? (this.boundingBox = new threepipe.Box3());
|
|
601
595
|
box.setFromBufferAttribute(this.getAttribute("center"));
|
|
602
596
|
if (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) {
|
|
@@ -604,8 +598,7 @@ void main () {
|
|
|
604
598
|
}
|
|
605
599
|
}
|
|
606
600
|
computeBoundingSphere() {
|
|
607
|
-
if (this.boundingSphere === null)
|
|
608
|
-
this.boundingSphere = new threepipe.Sphere();
|
|
601
|
+
if (this.boundingSphere === null) this.boundingSphere = new threepipe.Sphere();
|
|
609
602
|
const position = this.attributes.center;
|
|
610
603
|
if (position && position.isGLBufferAttribute) {
|
|
611
604
|
console.error('THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set "mesh.frustumCulled" to "false".', this);
|
|
@@ -614,8 +607,7 @@ void main () {
|
|
|
614
607
|
}
|
|
615
608
|
if (position) {
|
|
616
609
|
const center = this.boundingSphere.center;
|
|
617
|
-
if (!this.boundingBox)
|
|
618
|
-
this.computeBoundingBox();
|
|
610
|
+
if (!this.boundingBox) this.computeBoundingBox();
|
|
619
611
|
this.boundingBox.getCenter(center);
|
|
620
612
|
let maxRadiusSq = 0;
|
|
621
613
|
const vector = new threepipe.Vector3();
|
|
@@ -651,14 +643,12 @@ void main () {
|
|
|
651
643
|
const geometry = this.geometry;
|
|
652
644
|
const matrixWorld = this.matrixWorld;
|
|
653
645
|
const threshold = 0.02;
|
|
654
|
-
if (geometry.boundingSphere === null)
|
|
655
|
-
geometry.computeBoundingSphere();
|
|
646
|
+
if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
|
|
656
647
|
const sphere = new three.Sphere();
|
|
657
648
|
sphere.copy(geometry.boundingSphere);
|
|
658
649
|
sphere.applyMatrix4(matrixWorld);
|
|
659
650
|
sphere.radius += threshold;
|
|
660
|
-
if (!raycaster.ray.intersectsSphere(sphere))
|
|
661
|
-
return;
|
|
651
|
+
if (!raycaster.ray.intersectsSphere(sphere)) return;
|
|
662
652
|
const inverseMatrix = new three.Matrix4();
|
|
663
653
|
const ray = new three.Ray();
|
|
664
654
|
inverseMatrix.copy(matrixWorld).invert();
|
|
@@ -676,8 +666,7 @@ void main () {
|
|
|
676
666
|
ray.closestPointToPoint(position, intersectPoint);
|
|
677
667
|
intersectPoint.applyMatrix4(matrixWorld);
|
|
678
668
|
const distance = raycaster.ray.origin.distanceTo(intersectPoint);
|
|
679
|
-
if (distance < raycaster.near || distance > raycaster.far)
|
|
680
|
-
return;
|
|
669
|
+
if (distance < raycaster.near || distance > raycaster.far) return;
|
|
681
670
|
intersects.push({
|
|
682
671
|
distance,
|
|
683
672
|
distanceToRay: Math.sqrt(rayPointDistanceSq),
|
|
@@ -690,6 +679,32 @@ void main () {
|
|
|
690
679
|
}
|
|
691
680
|
}
|
|
692
681
|
const styles = "";
|
|
682
|
+
const encodedJs = "KGZ1bmN0aW9uKCkgewogICJ1c2Ugc3RyaWN0IjsKICAvKioKICAgKiBAbGljZW5zZQogICAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMKICAgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMAogICAqLwogIGNvbnN0IHByb3h5TWFya2VyID0gU3ltYm9sKCJDb21saW5rLnByb3h5Iik7CiAgY29uc3QgY3JlYXRlRW5kcG9pbnQgPSBTeW1ib2woIkNvbWxpbmsuZW5kcG9pbnQiKTsKICBjb25zdCByZWxlYXNlUHJveHkgPSBTeW1ib2woIkNvbWxpbmsucmVsZWFzZVByb3h5Iik7CiAgY29uc3QgZmluYWxpemVyID0gU3ltYm9sKCJDb21saW5rLmZpbmFsaXplciIpOwogIGNvbnN0IHRocm93TWFya2VyID0gU3ltYm9sKCJDb21saW5rLnRocm93biIpOwogIGNvbnN0IGlzT2JqZWN0ID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gIm9iamVjdCIgJiYgdmFsICE9PSBudWxsIHx8IHR5cGVvZiB2YWwgPT09ICJmdW5jdGlvbiI7CiAgY29uc3QgcHJveHlUcmFuc2ZlckhhbmRsZXIgPSB7CiAgICBjYW5IYW5kbGU6ICh2YWwpID0+IGlzT2JqZWN0KHZhbCkgJiYgdmFsW3Byb3h5TWFya2VyXSwKICAgIHNlcmlhbGl6ZShvYmopIHsKICAgICAgY29uc3QgeyBwb3J0MSwgcG9ydDIgfSA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpOwogICAgICBleHBvc2Uob2JqLCBwb3J0MSk7CiAgICAgIHJldHVybiBbcG9ydDIsIFtwb3J0Ml1dOwogICAgfSwKICAgIGRlc2VyaWFsaXplKHBvcnQpIHsKICAgICAgcG9ydC5zdGFydCgpOwogICAgICByZXR1cm4gd3JhcChwb3J0KTsKICAgIH0KICB9OwogIGNvbnN0IHRocm93VHJhbnNmZXJIYW5kbGVyID0gewogICAgY2FuSGFuZGxlOiAodmFsdWUpID0+IGlzT2JqZWN0KHZhbHVlKSAmJiB0aHJvd01hcmtlciBpbiB2YWx1ZSwKICAgIHNlcmlhbGl6ZSh7IHZhbHVlIH0pIHsKICAgICAgbGV0IHNlcmlhbGl6ZWQ7CiAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEVycm9yKSB7CiAgICAgICAgc2VyaWFsaXplZCA9IHsKICAgICAgICAgIGlzRXJyb3I6IHRydWUsCiAgICAgICAgICB2YWx1ZTogewogICAgICAgICAgICBtZXNzYWdlOiB2YWx1ZS5tZXNzYWdlLAogICAgICAgICAgICBuYW1lOiB2YWx1ZS5uYW1lLAogICAgICAgICAgICBzdGFjazogdmFsdWUuc3RhY2sKICAgICAgICAgIH0KICAgICAgICB9OwogICAgICB9IGVsc2UgewogICAgICAgIHNlcmlhbGl6ZWQgPSB7IGlzRXJyb3I6IGZhbHNlLCB2YWx1ZSB9OwogICAgICB9CiAgICAgIHJldHVybiBbc2VyaWFsaXplZCwgW11dOwogICAgfSwKICAgIGRlc2VyaWFsaXplKHNlcmlhbGl6ZWQpIHsKICAgICAgaWYgKHNlcmlhbGl6ZWQuaXNFcnJvcikgewogICAgICAgIHRocm93IE9iamVjdC5hc3NpZ24obmV3IEVycm9yKHNlcmlhbGl6ZWQudmFsdWUubWVzc2FnZSksIHNlcmlhbGl6ZWQudmFsdWUpOwogICAgICB9CiAgICAgIHRocm93IHNlcmlhbGl6ZWQudmFsdWU7CiAgICB9CiAgfTsKICBjb25zdCB0cmFuc2ZlckhhbmRsZXJzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoWwogICAgWyJwcm94eSIsIHByb3h5VHJhbnNmZXJIYW5kbGVyXSwKICAgIFsidGhyb3ciLCB0aHJvd1RyYW5zZmVySGFuZGxlcl0KICBdKTsKICBmdW5jdGlvbiBpc0FsbG93ZWRPcmlnaW4oYWxsb3dlZE9yaWdpbnMsIG9yaWdpbikgewogICAgZm9yIChjb25zdCBhbGxvd2VkT3JpZ2luIG9mIGFsbG93ZWRPcmlnaW5zKSB7CiAgICAgIGlmIChvcmlnaW4gPT09IGFsbG93ZWRPcmlnaW4gfHwgYWxsb3dlZE9yaWdpbiA9PT0gIioiKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKGFsbG93ZWRPcmlnaW4gaW5zdGFuY2VvZiBSZWdFeHAgJiYgYWxsb3dlZE9yaWdpbi50ZXN0KG9yaWdpbikpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH0KICBmdW5jdGlvbiBleHBvc2Uob2JqLCBlcCA9IGdsb2JhbFRoaXMsIGFsbG93ZWRPcmlnaW5zID0gWyIqIl0pIHsKICAgIGVwLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCBmdW5jdGlvbiBjYWxsYmFjayhldikgewogICAgICBpZiAoIWV2IHx8ICFldi5kYXRhKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIGlmICghaXNBbGxvd2VkT3JpZ2luKGFsbG93ZWRPcmlnaW5zLCBldi5vcmlnaW4pKSB7CiAgICAgICAgY29uc29sZS53YXJuKGBJbnZhbGlkIG9yaWdpbiAnJHtldi5vcmlnaW59JyBmb3IgY29tbGluayBwcm94eWApOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBjb25zdCB7IGlkLCB0eXBlLCBwYXRoIH0gPSBPYmplY3QuYXNzaWduKHsgcGF0aDogW10gfSwgZXYuZGF0YSk7CiAgICAgIGNvbnN0IGFyZ3VtZW50TGlzdCA9IChldi5kYXRhLmFyZ3VtZW50TGlzdCB8fCBbXSkubWFwKGZyb21XaXJlVmFsdWUpOwogICAgICBsZXQgcmV0dXJuVmFsdWU7CiAgICAgIHRyeSB7CiAgICAgICAgY29uc3QgcGFyZW50ID0gcGF0aC5zbGljZSgwLCAtMSkucmVkdWNlKChvYmoyLCBwcm9wKSA9PiBvYmoyW3Byb3BdLCBvYmopOwogICAgICAgIGNvbnN0IHJhd1ZhbHVlID0gcGF0aC5yZWR1Y2UoKG9iajIsIHByb3ApID0+IG9iajJbcHJvcF0sIG9iaik7CiAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICBjYXNlICJHRVQiOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSByYXdWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgIlNFVCI6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBwYXJlbnRbcGF0aC5zbGljZSgtMSlbMF1dID0gZnJvbVdpcmVWYWx1ZShldi5kYXRhLnZhbHVlKTsKICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlICJBUFBMWSI6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHJhd1ZhbHVlLmFwcGx5KHBhcmVudCwgYXJndW1lbnRMaXN0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgIkNPTlNUUlVDVCI6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyByYXdWYWx1ZSguLi5hcmd1bWVudExpc3QpOwogICAgICAgICAgICAgIHJldHVyblZhbHVlID0gcHJveHkodmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSAiRU5EUE9JTlQiOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgY29uc3QgeyBwb3J0MSwgcG9ydDIgfSA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpOwogICAgICAgICAgICAgIGV4cG9zZShvYmosIHBvcnQyKTsKICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRyYW5zZmVyKHBvcnQxLCBbcG9ydDFdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgIlJFTEVBU0UiOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB2b2lkIDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICB9IGNhdGNoICh2YWx1ZSkgewogICAgICAgIHJldHVyblZhbHVlID0geyB2YWx1ZSwgW3Rocm93TWFya2VyXTogMCB9OwogICAgICB9CiAgICAgIFByb21pc2UucmVzb2x2ZShyZXR1cm5WYWx1ZSkuY2F0Y2goKHZhbHVlKSA9PiB7CiAgICAgICAgcmV0dXJuIHsgdmFsdWUsIFt0aHJvd01hcmtlcl06IDAgfTsKICAgICAgfSkudGhlbigocmV0dXJuVmFsdWUyKSA9PiB7CiAgICAgICAgY29uc3QgW3dpcmVWYWx1ZSwgdHJhbnNmZXJhYmxlc10gPSB0b1dpcmVWYWx1ZShyZXR1cm5WYWx1ZTIpOwogICAgICAgIGVwLnBvc3RNZXNzYWdlKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgd2lyZVZhbHVlKSwgeyBpZCB9KSwgdHJhbnNmZXJhYmxlcyk7CiAgICAgICAgaWYgKHR5cGUgPT09ICJSRUxFQVNFIikgewogICAgICAgICAgZXAucmVtb3ZlRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsIGNhbGxiYWNrKTsKICAgICAgICAgIGNsb3NlRW5kUG9pbnQoZXApOwogICAgICAgICAgaWYgKGZpbmFsaXplciBpbiBvYmogJiYgdHlwZW9mIG9ialtmaW5hbGl6ZXJdID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgIG9ialtmaW5hbGl6ZXJdKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHsKICAgICAgICBjb25zdCBbd2lyZVZhbHVlLCB0cmFuc2ZlcmFibGVzXSA9IHRvV2lyZVZhbHVlKHsKICAgICAgICAgIHZhbHVlOiBuZXcgVHlwZUVycm9yKCJVbnNlcmlhbGl6YWJsZSByZXR1cm4gdmFsdWUiKSwKICAgICAgICAgIFt0aHJvd01hcmtlcl06IDAKICAgICAgICB9KTsKICAgICAgICBlcC5wb3N0TWVzc2FnZShPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHdpcmVWYWx1ZSksIHsgaWQgfSksIHRyYW5zZmVyYWJsZXMpOwogICAgICB9KTsKICAgIH0pOwogICAgaWYgKGVwLnN0YXJ0KSB7CiAgICAgIGVwLnN0YXJ0KCk7CiAgICB9CiAgfQogIGZ1bmN0aW9uIGlzTWVzc2FnZVBvcnQoZW5kcG9pbnQpIHsKICAgIHJldHVybiBlbmRwb2ludC5jb25zdHJ1Y3Rvci5uYW1lID09PSAiTWVzc2FnZVBvcnQiOwogIH0KICBmdW5jdGlvbiBjbG9zZUVuZFBvaW50KGVuZHBvaW50KSB7CiAgICBpZiAoaXNNZXNzYWdlUG9ydChlbmRwb2ludCkpCiAgICAgIGVuZHBvaW50LmNsb3NlKCk7CiAgfQogIGZ1bmN0aW9uIHdyYXAoZXAsIHRhcmdldCkgewogICAgcmV0dXJuIGNyZWF0ZVByb3h5KGVwLCBbXSwgdGFyZ2V0KTsKICB9CiAgZnVuY3Rpb24gdGhyb3dJZlByb3h5UmVsZWFzZWQoaXNSZWxlYXNlZCkgewogICAgaWYgKGlzUmVsZWFzZWQpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCJQcm94eSBoYXMgYmVlbiByZWxlYXNlZCBhbmQgaXMgbm90IHVzZWFibGUiKTsKICAgIH0KICB9CiAgZnVuY3Rpb24gcmVsZWFzZUVuZHBvaW50KGVwKSB7CiAgICByZXR1cm4gcmVxdWVzdFJlc3BvbnNlTWVzc2FnZShlcCwgewogICAgICB0eXBlOiAiUkVMRUFTRSIKICAgIH0pLnRoZW4oKCkgPT4gewogICAgICBjbG9zZUVuZFBvaW50KGVwKTsKICAgIH0pOwogIH0KICBjb25zdCBwcm94eUNvdW50ZXIgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTsKICBjb25zdCBwcm94eUZpbmFsaXplcnMgPSAiRmluYWxpemF0aW9uUmVnaXN0cnkiIGluIGdsb2JhbFRoaXMgJiYgbmV3IEZpbmFsaXphdGlvblJlZ2lzdHJ5KChlcCkgPT4gewogICAgY29uc3QgbmV3Q291bnQgPSAocHJveHlDb3VudGVyLmdldChlcCkgfHwgMCkgLSAxOwogICAgcHJveHlDb3VudGVyLnNldChlcCwgbmV3Q291bnQpOwogICAgaWYgKG5ld0NvdW50ID09PSAwKSB7CiAgICAgIHJlbGVhc2VFbmRwb2ludChlcCk7CiAgICB9CiAgfSk7CiAgZnVuY3Rpb24gcmVnaXN0ZXJQcm94eShwcm94eTIsIGVwKSB7CiAgICBjb25zdCBuZXdDb3VudCA9IChwcm94eUNvdW50ZXIuZ2V0KGVwKSB8fCAwKSArIDE7CiAgICBwcm94eUNvdW50ZXIuc2V0KGVwLCBuZXdDb3VudCk7CiAgICBpZiAocHJveHlGaW5hbGl6ZXJzKSB7CiAgICAgIHByb3h5RmluYWxpemVycy5yZWdpc3Rlcihwcm94eTIsIGVwLCBwcm94eTIpOwogICAgfQogIH0KICBmdW5jdGlvbiB1bnJlZ2lzdGVyUHJveHkocHJveHkyKSB7CiAgICBpZiAocHJveHlGaW5hbGl6ZXJzKSB7CiAgICAgIHByb3h5RmluYWxpemVycy51bnJlZ2lzdGVyKHByb3h5Mik7CiAgICB9CiAgfQogIGZ1bmN0aW9uIGNyZWF0ZVByb3h5KGVwLCBwYXRoID0gW10sIHRhcmdldCA9IGZ1bmN0aW9uKCkgewogIH0pIHsKICAgIGxldCBpc1Byb3h5UmVsZWFzZWQgPSBmYWxzZTsKICAgIGNvbnN0IHByb3h5MiA9IG5ldyBQcm94eSh0YXJnZXQsIHsKICAgICAgZ2V0KF90YXJnZXQsIHByb3ApIHsKICAgICAgICB0aHJvd0lmUHJveHlSZWxlYXNlZChpc1Byb3h5UmVsZWFzZWQpOwogICAgICAgIGlmIChwcm9wID09PSByZWxlYXNlUHJveHkpIHsKICAgICAgICAgIHJldHVybiAoKSA9PiB7CiAgICAgICAgICAgIHVucmVnaXN0ZXJQcm94eShwcm94eTIpOwogICAgICAgICAgICByZWxlYXNlRW5kcG9pbnQoZXApOwogICAgICAgICAgICBpc1Byb3h5UmVsZWFzZWQgPSB0cnVlOwogICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgaWYgKHByb3AgPT09ICJ0aGVuIikgewogICAgICAgICAgaWYgKHBhdGgubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgIHJldHVybiB7IHRoZW46ICgpID0+IHByb3h5MiB9OwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgciA9IHJlcXVlc3RSZXNwb25zZU1lc3NhZ2UoZXAsIHsKICAgICAgICAgICAgdHlwZTogIkdFVCIsCiAgICAgICAgICAgIHBhdGg6IHBhdGgubWFwKChwKSA9PiBwLnRvU3RyaW5nKCkpCiAgICAgICAgICB9KS50aGVuKGZyb21XaXJlVmFsdWUpOwogICAgICAgICAgcmV0dXJuIHIudGhlbi5iaW5kKHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY3JlYXRlUHJveHkoZXAsIFsuLi5wYXRoLCBwcm9wXSk7CiAgICAgIH0sCiAgICAgIHNldChfdGFyZ2V0LCBwcm9wLCByYXdWYWx1ZSkgewogICAgICAgIHRocm93SWZQcm94eVJlbGVhc2VkKGlzUHJveHlSZWxlYXNlZCk7CiAgICAgICAgY29uc3QgW3ZhbHVlLCB0cmFuc2ZlcmFibGVzXSA9IHRvV2lyZVZhbHVlKHJhd1ZhbHVlKTsKICAgICAgICByZXR1cm4gcmVxdWVzdFJlc3BvbnNlTWVzc2FnZShlcCwgewogICAgICAgICAgdHlwZTogIlNFVCIsCiAgICAgICAgICBwYXRoOiBbLi4ucGF0aCwgcHJvcF0ubWFwKChwKSA9PiBwLnRvU3RyaW5nKCkpLAogICAgICAgICAgdmFsdWUKICAgICAgICB9LCB0cmFuc2ZlcmFibGVzKS50aGVuKGZyb21XaXJlVmFsdWUpOwogICAgICB9LAogICAgICBhcHBseShfdGFyZ2V0LCBfdGhpc0FyZywgcmF3QXJndW1lbnRMaXN0KSB7CiAgICAgICAgdGhyb3dJZlByb3h5UmVsZWFzZWQoaXNQcm94eVJlbGVhc2VkKTsKICAgICAgICBjb25zdCBsYXN0ID0gcGF0aFtwYXRoLmxlbmd0aCAtIDFdOwogICAgICAgIGlmIChsYXN0ID09PSBjcmVhdGVFbmRwb2ludCkgewogICAgICAgICAgcmV0dXJuIHJlcXVlc3RSZXNwb25zZU1lc3NhZ2UoZXAsIHsKICAgICAgICAgICAgdHlwZTogIkVORFBPSU5UIgogICAgICAgICAgfSkudGhlbihmcm9tV2lyZVZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGxhc3QgPT09ICJiaW5kIikgewogICAgICAgICAgcmV0dXJuIGNyZWF0ZVByb3h5KGVwLCBwYXRoLnNsaWNlKDAsIC0xKSk7CiAgICAgICAgfQogICAgICAgIGNvbnN0IFthcmd1bWVudExpc3QsIHRyYW5zZmVyYWJsZXNdID0gcHJvY2Vzc0FyZ3VtZW50cyhyYXdBcmd1bWVudExpc3QpOwogICAgICAgIHJldHVybiByZXF1ZXN0UmVzcG9uc2VNZXNzYWdlKGVwLCB7CiAgICAgICAgICB0eXBlOiAiQVBQTFkiLAogICAgICAgICAgcGF0aDogcGF0aC5tYXAoKHApID0+IHAudG9TdHJpbmcoKSksCiAgICAgICAgICBhcmd1bWVudExpc3QKICAgICAgICB9LCB0cmFuc2ZlcmFibGVzKS50aGVuKGZyb21XaXJlVmFsdWUpOwogICAgICB9LAogICAgICBjb25zdHJ1Y3QoX3RhcmdldCwgcmF3QXJndW1lbnRMaXN0KSB7CiAgICAgICAgdGhyb3dJZlByb3h5UmVsZWFzZWQoaXNQcm94eVJlbGVhc2VkKTsKICAgICAgICBjb25zdCBbYXJndW1lbnRMaXN0LCB0cmFuc2ZlcmFibGVzXSA9IHByb2Nlc3NBcmd1bWVudHMocmF3QXJndW1lbnRMaXN0KTsKICAgICAgICByZXR1cm4gcmVxdWVzdFJlc3BvbnNlTWVzc2FnZShlcCwgewogICAgICAgICAgdHlwZTogIkNPTlNUUlVDVCIsCiAgICAgICAgICBwYXRoOiBwYXRoLm1hcCgocCkgPT4gcC50b1N0cmluZygpKSwKICAgICAgICAgIGFyZ3VtZW50TGlzdAogICAgICAgIH0sIHRyYW5zZmVyYWJsZXMpLnRoZW4oZnJvbVdpcmVWYWx1ZSk7CiAgICAgIH0KICAgIH0pOwogICAgcmVnaXN0ZXJQcm94eShwcm94eTIsIGVwKTsKICAgIHJldHVybiBwcm94eTI7CiAgfQogIGZ1bmN0aW9uIG15RmxhdChhcnIpIHsKICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFtdLCBhcnIpOwogIH0KICBmdW5jdGlvbiBwcm9jZXNzQXJndW1lbnRzKGFyZ3VtZW50TGlzdCkgewogICAgY29uc3QgcHJvY2Vzc2VkID0gYXJndW1lbnRMaXN0Lm1hcCh0b1dpcmVWYWx1ZSk7CiAgICByZXR1cm4gW3Byb2Nlc3NlZC5tYXAoKHYpID0+IHZbMF0pLCBteUZsYXQocHJvY2Vzc2VkLm1hcCgodikgPT4gdlsxXSkpXTsKICB9CiAgY29uc3QgdHJhbnNmZXJDYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOwogIGZ1bmN0aW9uIHRyYW5zZmVyKG9iaiwgdHJhbnNmZXJzKSB7CiAgICB0cmFuc2ZlckNhY2hlLnNldChvYmosIHRyYW5zZmVycyk7CiAgICByZXR1cm4gb2JqOwogIH0KICBmdW5jdGlvbiBwcm94eShvYmopIHsKICAgIHJldHVybiBPYmplY3QuYXNzaWduKG9iaiwgeyBbcHJveHlNYXJrZXJdOiB0cnVlIH0pOwogIH0KICBmdW5jdGlvbiB0b1dpcmVWYWx1ZSh2YWx1ZSkgewogICAgZm9yIChjb25zdCBbbmFtZSwgaGFuZGxlcl0gb2YgdHJhbnNmZXJIYW5kbGVycykgewogICAgICBpZiAoaGFuZGxlci5jYW5IYW5kbGUodmFsdWUpKSB7CiAgICAgICAgY29uc3QgW3NlcmlhbGl6ZWRWYWx1ZSwgdHJhbnNmZXJhYmxlc10gPSBoYW5kbGVyLnNlcmlhbGl6ZSh2YWx1ZSk7CiAgICAgICAgcmV0dXJuIFsKICAgICAgICAgIHsKICAgICAgICAgICAgdHlwZTogIkhBTkRMRVIiLAogICAgICAgICAgICBuYW1lLAogICAgICAgICAgICB2YWx1ZTogc2VyaWFsaXplZFZhbHVlCiAgICAgICAgICB9LAogICAgICAgICAgdHJhbnNmZXJhYmxlcwogICAgICAgIF07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBbCiAgICAgIHsKICAgICAgICB0eXBlOiAiUkFXIiwKICAgICAgICB2YWx1ZQogICAgICB9LAogICAgICB0cmFuc2ZlckNhY2hlLmdldCh2YWx1ZSkgfHwgW10KICAgIF07CiAgfQogIGZ1bmN0aW9uIGZyb21XaXJlVmFsdWUodmFsdWUpIHsKICAgIHN3aXRjaCAodmFsdWUudHlwZSkgewogICAgICBjYXNlICJIQU5ETEVSIjoKICAgICAgICByZXR1cm4gdHJhbnNmZXJIYW5kbGVycy5nZXQodmFsdWUubmFtZSkuZGVzZXJpYWxpemUodmFsdWUudmFsdWUpOwogICAgICBjYXNlICJSQVciOgogICAgICAgIHJldHVybiB2YWx1ZS52YWx1ZTsKICAgIH0KICB9CiAgZnVuY3Rpb24gcmVxdWVzdFJlc3BvbnNlTWVzc2FnZShlcCwgbXNnLCB0cmFuc2ZlcnMpIHsKICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewogICAgICBjb25zdCBpZCA9IGdlbmVyYXRlVVVJRCgpOwogICAgICBlcC5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwgZnVuY3Rpb24gbChldikgewogICAgICAgIGlmICghZXYuZGF0YSB8fCAhZXYuZGF0YS5pZCB8fCBldi5kYXRhLmlkICE9PSBpZCkgewogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBlcC5yZW1vdmVFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwgbCk7CiAgICAgICAgcmVzb2x2ZShldi5kYXRhKTsKICAgICAgfSk7CiAgICAgIGlmIChlcC5zdGFydCkgewogICAgICAgIGVwLnN0YXJ0KCk7CiAgICAgIH0KICAgICAgZXAucG9zdE1lc3NhZ2UoT2JqZWN0LmFzc2lnbih7IGlkIH0sIG1zZyksIHRyYW5zZmVycyk7CiAgICB9KTsKICB9CiAgZnVuY3Rpb24gZ2VuZXJhdGVVVUlEKCkgewogICAgcmV0dXJuIG5ldyBBcnJheSg0KS5maWxsKDApLm1hcCgoKSA9PiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUikudG9TdHJpbmcoMTYpKS5qb2luKCItIik7CiAgfQogIHZhciBNb2R1bGUgPSAoKCkgPT4gewogICAgdmFyIF9zY3JpcHREaXIgPSBzZWxmLmxvY2F0aW9uLmhyZWY7CiAgICByZXR1cm4gZnVuY3Rpb24obW9kdWxlQXJnID0ge30pIHsKICAgICAgdmFyIE1vZHVsZTIgPSBtb2R1bGVBcmc7CiAgICAgIHZhciByZWFkeVByb21pc2VSZXNvbHZlLCByZWFkeVByb21pc2VSZWplY3Q7CiAgICAgIE1vZHVsZTJbInJlYWR5Il0gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAgICAgcmVhZHlQcm9taXNlUmVzb2x2ZSA9IHJlc29sdmU7CiAgICAgICAgcmVhZHlQcm9taXNlUmVqZWN0ID0gcmVqZWN0OwogICAgICB9KTsKICAgICAgdmFyIG1vZHVsZU92ZXJyaWRlcyA9IE9iamVjdC5hc3NpZ24oe30sIE1vZHVsZTIpOwogICAgICB2YXIgRU5WSVJPTk1FTlRfSVNfV0VCID0gdHlwZW9mIHdpbmRvdyA9PSAib2JqZWN0IjsKICAgICAgdmFyIEVOVklST05NRU5UX0lTX1dPUktFUiA9IHR5cGVvZiBpbXBvcnRTY3JpcHRzID09ICJmdW5jdGlvbiI7CiAgICAgIHR5cGVvZiBwcm9jZXNzID09ICJvYmplY3QiICYmIHR5cGVvZiBwcm9jZXNzLnZlcnNpb25zID09ICJvYmplY3QiICYmIHR5cGVvZiBwcm9jZXNzLnZlcnNpb25zLm5vZGUgPT0gInN0cmluZyI7CiAgICAgIHZhciBzY3JpcHREaXJlY3RvcnkgPSAiIjsKICAgICAgZnVuY3Rpb24gbG9jYXRlRmlsZShwYXRoKSB7CiAgICAgICAgaWYgKE1vZHVsZTJbImxvY2F0ZUZpbGUiXSkgewogICAgICAgICAgcmV0dXJuIE1vZHVsZTJbImxvY2F0ZUZpbGUiXShwYXRoLCBzY3JpcHREaXJlY3RvcnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2NyaXB0RGlyZWN0b3J5ICsgcGF0aDsKICAgICAgfQogICAgICB2YXIgcmVhZEJpbmFyeTsKICAgICAgaWYgKEVOVklST05NRU5UX0lTX1dFQiB8fCBFTlZJUk9OTUVOVF9JU19XT1JLRVIpIHsKICAgICAgICBpZiAoRU5WSVJPTk1FTlRfSVNfV09SS0VSKSB7CiAgICAgICAgICBzY3JpcHREaXJlY3RvcnkgPSBzZWxmLmxvY2F0aW9uLmhyZWY7CiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZG9jdW1lbnQgIT0gInVuZGVmaW5lZCIgJiYgZG9jdW1lbnQuY3VycmVudFNjcmlwdCkgewogICAgICAgICAgc2NyaXB0RGlyZWN0b3J5ID0gZG9jdW1lbnQuY3VycmVudFNjcmlwdC5zcmM7CiAgICAgICAgfQogICAgICAgIGlmIChfc2NyaXB0RGlyKSB7CiAgICAgICAgICBzY3JpcHREaXJlY3RvcnkgPSBfc2NyaXB0RGlyOwogICAgICAgIH0KICAgICAgICBpZiAoc2NyaXB0RGlyZWN0b3J5LmluZGV4T2YoImJsb2I6IikgIT09IDApIHsKICAgICAgICAgIHNjcmlwdERpcmVjdG9yeSA9IHNjcmlwdERpcmVjdG9yeS5zdWJzdHIoMCwgc2NyaXB0RGlyZWN0b3J5LnJlcGxhY2UoL1s/I10uKi8sICIiKS5sYXN0SW5kZXhPZigiLyIpICsgMSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHNjcmlwdERpcmVjdG9yeSA9ICIiOwogICAgICAgIH0KICAgICAgICB7CiAgICAgICAgICBpZiAoRU5WSVJPTk1FTlRfSVNfV09SS0VSKSB7CiAgICAgICAgICAgIHJlYWRCaW5hcnkgPSAodXJsKSA9PiB7CiAgICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOwogICAgICAgICAgICAgIHhoci5vcGVuKCJHRVQiLCB1cmwsIGZhbHNlKTsKICAgICAgICAgICAgICB4aHIucmVzcG9uc2VUeXBlID0gImFycmF5YnVmZmVyIjsKICAgICAgICAgICAgICB4aHIuc2VuZChudWxsKTsKICAgICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoeGhyLnJlc3BvbnNlKTsKICAgICAgICAgICAgfTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgTW9kdWxlMlsicHJpbnQiXSB8fCBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpOwogICAgICB2YXIgZXJyID0gTW9kdWxlMlsicHJpbnRFcnIiXSB8fCBjb25zb2xlLmVycm9yLmJpbmQoY29uc29sZSk7CiAgICAgIE9iamVjdC5hc3NpZ24oTW9kdWxlMiwgbW9kdWxlT3ZlcnJpZGVzKTsKICAgICAgbW9kdWxlT3ZlcnJpZGVzID0gbnVsbDsKICAgICAgaWYgKE1vZHVsZTJbImFyZ3VtZW50cyJdKSBNb2R1bGUyWyJhcmd1bWVudHMiXTsKICAgICAgaWYgKE1vZHVsZTJbInRoaXNQcm9ncmFtIl0pIE1vZHVsZTJbInRoaXNQcm9ncmFtIl07CiAgICAgIGlmIChNb2R1bGUyWyJxdWl0Il0pIE1vZHVsZTJbInF1aXQiXTsKICAgICAgdmFyIHdhc21CaW5hcnk7CiAgICAgIGlmIChNb2R1bGUyWyJ3YXNtQmluYXJ5Il0pIHdhc21CaW5hcnkgPSBNb2R1bGUyWyJ3YXNtQmluYXJ5Il07CiAgICAgIGlmICh0eXBlb2YgV2ViQXNzZW1ibHkgIT0gIm9iamVjdCIpIHsKICAgICAgICBhYm9ydCgibm8gbmF0aXZlIHdhc20gc3VwcG9ydCBkZXRlY3RlZCIpOwogICAgICB9CiAgICAgIHZhciB3YXNtTWVtb3J5OwogICAgICB2YXIgQUJPUlQgPSBmYWxzZTsKICAgICAgdmFyIEhFQVA4LCBIRUFQVTgsIEhFQVAxNiwgSEVBUFUxNiwgSEVBUDMyLCBIRUFQVTMyLCBIRUFQRjMyLCBIRUFQRjY0OwogICAgICBmdW5jdGlvbiB1cGRhdGVNZW1vcnlWaWV3cygpIHsKICAgICAgICB2YXIgYiA9IHdhc21NZW1vcnkuYnVmZmVyOwogICAgICAgIE1vZHVsZTJbIkhFQVA4Il0gPSBIRUFQOCA9IG5ldyBJbnQ4QXJyYXkoYik7CiAgICAgICAgTW9kdWxlMlsiSEVBUDE2Il0gPSBIRUFQMTYgPSBuZXcgSW50MTZBcnJheShiKTsKICAgICAgICBNb2R1bGUyWyJIRUFQVTgiXSA9IEhFQVBVOCA9IG5ldyBVaW50OEFycmF5KGIpOwogICAgICAgIE1vZHVsZTJbIkhFQVBVMTYiXSA9IEhFQVBVMTYgPSBuZXcgVWludDE2QXJyYXkoYik7CiAgICAgICAgTW9kdWxlMlsiSEVBUDMyIl0gPSBIRUFQMzIgPSBuZXcgSW50MzJBcnJheShiKTsKICAgICAgICBNb2R1bGUyWyJIRUFQVTMyIl0gPSBIRUFQVTMyID0gbmV3IFVpbnQzMkFycmF5KGIpOwogICAgICAgIE1vZHVsZTJbIkhFQVBGMzIiXSA9IEhFQVBGMzIgPSBuZXcgRmxvYXQzMkFycmF5KGIpOwogICAgICAgIE1vZHVsZTJbIkhFQVBGNjQiXSA9IEhFQVBGNjQgPSBuZXcgRmxvYXQ2NEFycmF5KGIpOwogICAgICB9CiAgICAgIHZhciBfX0FUUFJFUlVOX18gPSBbXTsKICAgICAgdmFyIF9fQVRJTklUX18gPSBbXTsKICAgICAgdmFyIF9fQVRQT1NUUlVOX18gPSBbXTsKICAgICAgZnVuY3Rpb24gcHJlUnVuKCkgewogICAgICAgIGlmIChNb2R1bGUyWyJwcmVSdW4iXSkgewogICAgICAgICAgaWYgKHR5cGVvZiBNb2R1bGUyWyJwcmVSdW4iXSA9PSAiZnVuY3Rpb24iKSBNb2R1bGUyWyJwcmVSdW4iXSA9IFtNb2R1bGUyWyJwcmVSdW4iXV07CiAgICAgICAgICB3aGlsZSAoTW9kdWxlMlsicHJlUnVuIl0ubGVuZ3RoKSB7CiAgICAgICAgICAgIGFkZE9uUHJlUnVuKE1vZHVsZTJbInByZVJ1biJdLnNoaWZ0KCkpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjYWxsUnVudGltZUNhbGxiYWNrcyhfX0FUUFJFUlVOX18pOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIGluaXRSdW50aW1lKCkgewogICAgICAgIGNhbGxSdW50aW1lQ2FsbGJhY2tzKF9fQVRJTklUX18pOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIHBvc3RSdW4oKSB7CiAgICAgICAgaWYgKE1vZHVsZTJbInBvc3RSdW4iXSkgewogICAgICAgICAgaWYgKHR5cGVvZiBNb2R1bGUyWyJwb3N0UnVuIl0gPT0gImZ1bmN0aW9uIikgTW9kdWxlMlsicG9zdFJ1biJdID0gW01vZHVsZTJbInBvc3RSdW4iXV07CiAgICAgICAgICB3aGlsZSAoTW9kdWxlMlsicG9zdFJ1biJdLmxlbmd0aCkgewogICAgICAgICAgICBhZGRPblBvc3RSdW4oTW9kdWxlMlsicG9zdFJ1biJdLnNoaWZ0KCkpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjYWxsUnVudGltZUNhbGxiYWNrcyhfX0FUUE9TVFJVTl9fKTsKICAgICAgfQogICAgICBmdW5jdGlvbiBhZGRPblByZVJ1bihjYikgewogICAgICAgIF9fQVRQUkVSVU5fXy51bnNoaWZ0KGNiKTsKICAgICAgfQogICAgICBmdW5jdGlvbiBhZGRPbkluaXQoY2IpIHsKICAgICAgICBfX0FUSU5JVF9fLnVuc2hpZnQoY2IpOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIGFkZE9uUG9zdFJ1bihjYikgewogICAgICAgIF9fQVRQT1NUUlVOX18udW5zaGlmdChjYik7CiAgICAgIH0KICAgICAgdmFyIHJ1bkRlcGVuZGVuY2llcyA9IDA7CiAgICAgIHZhciBkZXBlbmRlbmNpZXNGdWxmaWxsZWQgPSBudWxsOwogICAgICBmdW5jdGlvbiBhZGRSdW5EZXBlbmRlbmN5KGlkKSB7CiAgICAgICAgcnVuRGVwZW5kZW5jaWVzKys7CiAgICAgICAgaWYgKE1vZHVsZTJbIm1vbml0b3JSdW5EZXBlbmRlbmNpZXMiXSkgewogICAgICAgICAgTW9kdWxlMlsibW9uaXRvclJ1bkRlcGVuZGVuY2llcyJdKHJ1bkRlcGVuZGVuY2llcyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZ1bmN0aW9uIHJlbW92ZVJ1bkRlcGVuZGVuY3koaWQpIHsKICAgICAgICBydW5EZXBlbmRlbmNpZXMtLTsKICAgICAgICBpZiAoTW9kdWxlMlsibW9uaXRvclJ1bkRlcGVuZGVuY2llcyJdKSB7CiAgICAgICAgICBNb2R1bGUyWyJtb25pdG9yUnVuRGVwZW5kZW5jaWVzIl0ocnVuRGVwZW5kZW5jaWVzKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJ1bkRlcGVuZGVuY2llcyA9PSAwKSB7CiAgICAgICAgICBpZiAoZGVwZW5kZW5jaWVzRnVsZmlsbGVkKSB7CiAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IGRlcGVuZGVuY2llc0Z1bGZpbGxlZDsKICAgICAgICAgICAgZGVwZW5kZW5jaWVzRnVsZmlsbGVkID0gbnVsbDsKICAgICAgICAgICAgY2FsbGJhY2soKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgZnVuY3Rpb24gYWJvcnQod2hhdCkgewogICAgICAgIGlmIChNb2R1bGUyWyJvbkFib3J0Il0pIHsKICAgICAgICAgIE1vZHVsZTJbIm9uQWJvcnQiXSh3aGF0KTsKICAgICAgICB9CiAgICAgICAgd2hhdCA9ICJBYm9ydGVkKCIgKyB3aGF0ICsgIikiOwogICAgICAgIGVycih3aGF0KTsKICAgICAgICBBQk9SVCA9IHRydWU7CiAgICAgICAgd2hhdCArPSAiLiBCdWlsZCB3aXRoIC1zQVNTRVJUSU9OUyBmb3IgbW9yZSBpbmZvLiI7CiAgICAgICAgdmFyIGUgPSBuZXcgV2ViQXNzZW1ibHkuUnVudGltZUVycm9yKHdoYXQpOwogICAgICAgIHJlYWR5UHJvbWlzZVJlamVjdChlKTsKICAgICAgICB0aHJvdyBlOwogICAgICB9CiAgICAgIHZhciBkYXRhVVJJUHJlZml4ID0gImRhdGE6YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtO2Jhc2U2NCwiOwogICAgICB2YXIgaXNEYXRhVVJJID0gKGZpbGVuYW1lKSA9PiBmaWxlbmFtZS5zdGFydHNXaXRoKGRhdGFVUklQcmVmaXgpOwogICAgICB2YXIgd2FzbUJpbmFyeUZpbGU7CiAgICAgIGlmIChNb2R1bGUyWyJsb2NhdGVGaWxlIl0pIHsKICAgICAgICB3YXNtQmluYXJ5RmlsZSA9ICJzb3J0Lndhc20iOwogICAgICAgIGlmICghaXNEYXRhVVJJKHdhc21CaW5hcnlGaWxlKSkgewogICAgICAgICAgd2FzbUJpbmFyeUZpbGUgPSBsb2NhdGVGaWxlKHdhc21CaW5hcnlGaWxlKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgd2FzbUJpbmFyeUZpbGUgPSBuZXcgVVJMKCJkYXRhOmFwcGxpY2F0aW9uL3dhc207YmFzZTY0LEFHRnpiUUVBQUFBQlRneGdBWDhCZjJBQUFHQUVmMzkvZndCZ0EzOS9md0JnQlg5L2YzOS9BR0FCZndCZ0JuOS9mMzkvZndCZ0FuOS9BR0FEZjM5L0FYOWdCMzkvZjM5L2YzOEFZQUovZndGL1lBUi9mMzUrQUFKVkRnRmhBV0VBQXdGaEFXSUFCQUZoQVdNQUF3RmhBV1FBQXdGaEFXVUFCd0ZoQVdZQUFRRmhBV2NBQ1FGaEFXZ0FCd0ZoQVdrQUFnRmhBV29BQndGaEFXc0FDUUZoQVd3QUFBRmhBVzBBQXdGaEFXNEFBd01sSkFnS0JRQUFCUUFCQ3dVREFnb0ZBQUVBQVFVQkFBQUFCZ1FDQWdRR0NBZ0JBUUFDQkFRRkFYQUJHeHNGQndFQmdBS0FnQUlHQ0FGL0FVR2dvQVFMQngwSEFXOENBQUZ3QUJVQmNRQXZBWElBRWdGekFRQUJkQUFRQVhVQUpBa2dBUUJCQVFzYUlURXdIaDB0SEJNYkd5d1hJaGNUS3lVbUp4TXFLU2djRXlNSy9sMGtkQUVCZnlBQ1JRUkFJQUFvQWdRZ0FTZ0NCRVlQQ3lBQUlBRkdCRUJCQVE4TElBRW9BZ1FpQWkwQUFDRUJBa0FnQUNnQ0JDSURMUUFBSWdCRkRRQWdBQ0FCUncwQUEwQWdBaTBBQVNFQklBTXRBQUVpQUVVTkFTQUNRUUZxSVFJZ0EwRUJhaUVESUFBZ0FVWU5BQXNMSUFBZ0FVWUwyQUlCQW44Q1FDQUJSUTBBSUFCQkFEb0FBQ0FBSUFGcUlnSkJBV3RCQURvQUFDQUJRUU5KRFFBZ0FFRUFPZ0FDSUFCQkFEb0FBU0FDUVFOclFRQTZBQUFnQWtFQ2EwRUFPZ0FBSUFGQkIwa05BQ0FBUVFBNkFBTWdBa0VFYTBFQU9nQUFJQUZCQ1VrTkFDQUFRUUFnQUd0QkEzRWlBMm9pQWtFQU5nSUFJQUlnQVNBRGEwRjhjU0lEYWlJQlFRUnJRUUEyQWdBZ0EwRUpTUTBBSUFKQkFEWUNDQ0FDUVFBMkFnUWdBVUVJYTBFQU5nSUFJQUZCREd0QkFEWUNBQ0FEUVJsSkRRQWdBa0VBTmdJWUlBSkJBRFlDRkNBQ1FRQTJBaEFnQWtFQU5nSU1JQUZCRUd0QkFEWUNBQ0FCUVJSclFRQTJBZ0FnQVVFWWEwRUFOZ0lBSUFGQkhHdEJBRFlDQUNBRElBSkJCSEZCR0hJaUEyc2lBVUVnU1EwQUlBSWdBMm9oQWdOQUlBSkNBRGNER0NBQ1FnQTNBeEFnQWtJQU53TUlJQUpDQURjREFDQUNRU0JxSVFJZ0FVRWdheUlCUVI5TERRQUxDeUFBQzlJTEFRZC9Ba0FnQUVVTkFDQUFRUWhySWdJZ0FFRUVheWdDQUNJQlFYaHhJZ0JxSVFVQ1FDQUJRUUZ4RFFBZ0FVRURjVVVOQVNBQ0lBSW9BZ0FpQVdzaUFrR2NIQ2dDQUVrTkFTQUFJQUZxSVFBQ1FBSkFRYUFjS0FJQUlBSkhCRUFnQVVIL0FVMEVRQ0FCUVFOMklRUWdBaWdDRENJQklBSW9BZ2dpQTBZRVFFR01IRUdNSENnQ0FFRitJQVIzY1RZQ0FBd0ZDeUFESUFFMkFnd2dBU0FETmdJSURBUUxJQUlvQWhnaEJpQUNJQUlvQWd3aUFVY0VRQ0FDS0FJSUlnTWdBVFlDRENBQklBTTJBZ2dNQXdzZ0FrRVVhaUlFS0FJQUlnTkZCRUFnQWlnQ0VDSURSUTBDSUFKQkVHb2hCQXNEUUNBRUlRY2dBeUlCUVJScUlnUW9BZ0FpQXcwQUlBRkJFR29oQkNBQktBSVFJZ01OQUFzZ0IwRUFOZ0lBREFJTElBVW9BZ1FpQVVFRGNVRURSdzBDUVpRY0lBQTJBZ0FnQlNBQlFYNXhOZ0lFSUFJZ0FFRUJjallDQkNBRklBQTJBZ0FQQzBFQUlRRUxJQVpGRFFBQ1FDQUNLQUljSWdOQkFuUkJ2QjVxSWdRb0FnQWdBa1lFUUNBRUlBRTJBZ0FnQVEwQlFaQWNRWkFjS0FJQVFYNGdBM2R4TmdJQURBSUxJQVpCRUVFVUlBWW9BaEFnQWtZYmFpQUJOZ0lBSUFGRkRRRUxJQUVnQmpZQ0dDQUNLQUlRSWdNRVFDQUJJQU0yQWhBZ0F5QUJOZ0lZQ3lBQ0tBSVVJZ05GRFFBZ0FTQUROZ0lVSUFNZ0FUWUNHQXNnQWlBRlR3MEFJQVVvQWdRaUFVRUJjVVVOQUFKQUFrQUNRQUpBSUFGQkFuRkZCRUJCcEJ3b0FnQWdCVVlFUUVHa0hDQUNOZ0lBUVpnY1FaZ2NLQUlBSUFCcUlnQTJBZ0FnQWlBQVFRRnlOZ0lFSUFKQm9Cd29BZ0JIRFFaQmxCeEJBRFlDQUVHZ0hFRUFOZ0lBRHd0Qm9Cd29BZ0FnQlVZRVFFR2dIQ0FDTmdJQVFaUWNRWlFjS0FJQUlBQnFJZ0EyQWdBZ0FpQUFRUUZ5TmdJRUlBQWdBbW9nQURZQ0FBOExJQUZCZUhFZ0FHb2hBQ0FCUWY4QlRRUkFJQUZCQTNZaEJDQUZLQUlNSWdFZ0JTZ0NDQ0lEUmdSQVFZd2NRWXdjS0FJQVFYNGdCSGR4TmdJQURBVUxJQU1nQVRZQ0RDQUJJQU0yQWdnTUJBc2dCU2dDR0NFR0lBVWdCU2dDRENJQlJ3UkFRWndjS0FJQUdpQUZLQUlJSWdNZ0FUWUNEQ0FCSUFNMkFnZ01Bd3NnQlVFVWFpSUVLQUlBSWdORkJFQWdCU2dDRUNJRFJRMENJQVZCRUdvaEJBc0RRQ0FFSVFjZ0F5SUJRUlJxSWdRb0FnQWlBdzBBSUFGQkVHb2hCQ0FCS0FJUUlnTU5BQXNnQjBFQU5nSUFEQUlMSUFVZ0FVRitjVFlDQkNBQ0lBQkJBWEkyQWdRZ0FDQUNhaUFBTmdJQURBTUxRUUFoQVFzZ0JrVU5BQUpBSUFVb0Fod2lBMEVDZEVHOEhtb2lCQ2dDQUNBRlJnUkFJQVFnQVRZQ0FDQUJEUUZCa0J4QmtCd29BZ0JCZmlBRGQzRTJBZ0FNQWdzZ0JrRVFRUlFnQmlnQ0VDQUZSaHRxSUFFMkFnQWdBVVVOQVFzZ0FTQUdOZ0lZSUFVb0FoQWlBd1JBSUFFZ0F6WUNFQ0FESUFFMkFoZ0xJQVVvQWhRaUEwVU5BQ0FCSUFNMkFoUWdBeUFCTmdJWUN5QUNJQUJCQVhJMkFnUWdBQ0FDYWlBQU5nSUFJQUpCb0J3b0FnQkhEUUJCbEJ3Z0FEWUNBQThMSUFCQi93Rk5CRUFnQUVGNGNVRzBIR29oQVFKL1FZd2NLQUlBSWdOQkFTQUFRUU4yZENJQWNVVUVRRUdNSENBQUlBTnlOZ0lBSUFFTUFRc2dBU2dDQ0FzaEFDQUJJQUkyQWdnZ0FDQUNOZ0lNSUFJZ0FUWUNEQ0FDSUFBMkFnZ1BDMEVmSVFNZ0FFSC8vLzhIVFFSQUlBQkJKaUFBUVFoMlp5SUJhM1pCQVhFZ0FVRUJkR3RCUG1vaEF3c2dBaUFETmdJY0lBSkNBRGNDRUNBRFFRSjBRYndlYWlFQkFrQUNRQUpBUVpBY0tBSUFJZ1JCQVNBRGRDSUhjVVVFUUVHUUhDQUVJQWR5TmdJQUlBRWdBallDQUNBQ0lBRTJBaGdNQVFzZ0FFRVpJQU5CQVhaclFRQWdBMEVmUnh0MElRTWdBU2dDQUNFQkEwQWdBU0lFS0FJRVFYaHhJQUJHRFFJZ0EwRWRkaUVCSUFOQkFYUWhBeUFFSUFGQkJIRnFJZ2RCRUdvb0FnQWlBUTBBQ3lBSElBSTJBaEFnQWlBRU5nSVlDeUFDSUFJMkFnd2dBaUFDTmdJSURBRUxJQVFvQWdnaUFDQUNOZ0lNSUFRZ0FqWUNDQ0FDUVFBMkFoZ2dBaUFFTmdJTUlBSWdBRFlDQ0F0QnJCeEJyQndvQWdCQkFXc2lBRUYvSUFBYk5nSUFDd3RQQVFKL1FZQWNLQUlBSWdFZ0FFRUhha0Y0Y1NJQ2FpRUFBa0FnQWtFQUlBQWdBVTBiUlFSQUlBQS9BRUVRZEUwTkFTQUFFQXNOQVF0QmlCeEJNRFlDQUVGL0R3dEJnQndnQURZQ0FDQUJDODRuQVF4L0l3QkJFR3NpQ2lRQUFrQUNRQUpBQWtBQ1FBSkFBa0FDUUFKQUlBQkI5QUZOQkVCQmpCd29BZ0FpQmtFUUlBQkJDMnBCZUhFZ0FFRUxTUnNpQlVFRGRpSUFkaUlCUVFOeEJFQUNRQ0FCUVg5elFRRnhJQUJxSWdKQkEzUWlBVUcwSEdvaUFDQUJRYndjYWlnQ0FDSUJLQUlJSWdOR0JFQkJqQndnQmtGK0lBSjNjVFlDQUF3QkN5QURJQUEyQWd3Z0FDQUROZ0lJQ3lBQlFRaHFJUUFnQVNBQ1FRTjBJZ0pCQTNJMkFnUWdBU0FDYWlJQklBRW9BZ1JCQVhJMkFnUU1DZ3NnQlVHVUhDZ0NBQ0lIVFEwQklBRUVRQUpBUVFJZ0FIUWlBa0VBSUFKcmNpQUJJQUIwY1dnaUFVRURkQ0lBUWJRY2FpSUNJQUJCdkJ4cUtBSUFJZ0FvQWdnaUEwWUVRRUdNSENBR1FYNGdBWGR4SWdZMkFnQU1BUXNnQXlBQ05nSU1JQUlnQXpZQ0NBc2dBQ0FGUVFOeU5nSUVJQUFnQldvaUJDQUJRUU4wSWdFZ0JXc2lBMEVCY2pZQ0JDQUFJQUZxSUFNMkFnQWdCd1JBSUFkQmVIRkJ0QnhxSVFGQm9Cd29BZ0FoQWdKL0lBWkJBU0FIUVFOMmRDSUZjVVVFUUVHTUhDQUZJQVp5TmdJQUlBRU1BUXNnQVNnQ0NBc2hCU0FCSUFJMkFnZ2dCU0FDTmdJTUlBSWdBVFlDRENBQ0lBVTJBZ2dMSUFCQkNHb2hBRUdnSENBRU5nSUFRWlFjSUFNMkFnQU1DZ3RCa0J3b0FnQWlDMFVOQVNBTGFFRUNkRUc4SG1vb0FnQWlBaWdDQkVGNGNTQUZheUVFSUFJaEFRTkFBa0FnQVNnQ0VDSUFSUVJBSUFFb0FoUWlBRVVOQVFzZ0FDZ0NCRUY0Y1NBRmF5SUJJQVFnQVNBRVNTSUJHeUVFSUFBZ0FpQUJHeUVDSUFBaEFRd0JDd3NnQWlnQ0dDRUpJQUlnQWlnQ0RDSURSd1JBUVp3Y0tBSUFHaUFDS0FJSUlnQWdBellDRENBRElBQTJBZ2dNQ1FzZ0FrRVVhaUlCS0FJQUlnQkZCRUFnQWlnQ0VDSUFSUTBESUFKQkVHb2hBUXNEUUNBQklRZ2dBQ0lEUVJScUlnRW9BZ0FpQUEwQUlBTkJFR29oQVNBREtBSVFJZ0FOQUFzZ0NFRUFOZ0lBREFnTFFYOGhCU0FBUWI5L1N3MEFJQUJCQzJvaUFFRjRjU0VGUVpBY0tBSUFJZ2hGRFFCQkFDQUZheUVFQWtBQ1FBSkFBbjlCQUNBRlFZQUNTUTBBR2tFZklBVkIvLy8vQjBzTkFCb2dCVUVtSUFCQkNIWm5JZ0JyZGtFQmNTQUFRUUYwYTBFK2Fnc2lCMEVDZEVHOEhtb29BZ0FpQVVVRVFFRUFJUUFNQVF0QkFDRUFJQVZCR1NBSFFRRjJhMEVBSUFkQkgwY2JkQ0VDQTBBQ1FDQUJLQUlFUVhoeElBVnJJZ1lnQkU4TkFDQUJJUU1nQmlJRURRQkJBQ0VFSUFFaEFBd0RDeUFBSUFFb0FoUWlCaUFHSUFFZ0FrRWRka0VFY1dvb0FoQWlBVVliSUFBZ0Joc2hBQ0FDUVFGMElRSWdBUTBBQ3dzZ0FDQURja1VFUUVFQUlRTkJBaUFIZENJQVFRQWdBR3R5SUFoeElnQkZEUU1nQUdoQkFuUkJ2QjVxS0FJQUlRQUxJQUJGRFFFTEEwQWdBQ2dDQkVGNGNTQUZheUlDSUFSSklRRWdBaUFFSUFFYklRUWdBQ0FESUFFYklRTWdBQ2dDRUNJQkJIOGdBUVVnQUNnQ0ZBc2lBQTBBQ3dzZ0EwVU5BQ0FFUVpRY0tBSUFJQVZyVHcwQUlBTW9BaGdoQnlBRElBTW9BZ3dpQWtjRVFFR2NIQ2dDQUJvZ0F5Z0NDQ0lBSUFJMkFnd2dBaUFBTmdJSURBY0xJQU5CRkdvaUFTZ0NBQ0lBUlFSQUlBTW9BaEFpQUVVTkF5QURRUkJxSVFFTEEwQWdBU0VHSUFBaUFrRVVhaUlCS0FJQUlnQU5BQ0FDUVJCcUlRRWdBaWdDRUNJQURRQUxJQVpCQURZQ0FBd0dDeUFGUVpRY0tBSUFJZ05OQkVCQm9Cd29BZ0FoQUFKQUlBTWdCV3NpQVVFUVR3UkFJQUFnQldvaUFpQUJRUUZ5TmdJRUlBQWdBMm9nQVRZQ0FDQUFJQVZCQTNJMkFnUU1BUXNnQUNBRFFRTnlOZ0lFSUFBZ0Eyb2lBU0FCS0FJRVFRRnlOZ0lFUVFBaEFrRUFJUUVMUVpRY0lBRTJBZ0JCb0J3Z0FqWUNBQ0FBUVFocUlRQU1DQXNnQlVHWUhDZ0NBQ0lDU1FSQVFaZ2NJQUlnQldzaUFUWUNBRUdrSEVHa0hDZ0NBQ0lBSUFWcUlnSTJBZ0FnQWlBQlFRRnlOZ0lFSUFBZ0JVRURjallDQkNBQVFRaHFJUUFNQ0F0QkFDRUFJQVZCTDJvaUJBSi9RZVFmS0FJQUJFQkI3QjhvQWdBTUFRdEI4QjlDZnpjQ0FFSG9IMEtBb0lDQWdJQUVOd0lBUWVRZklBcEJER3BCY0hGQjJLclZxZ1Z6TmdJQVFmZ2ZRUUEyQWdCQnlCOUJBRFlDQUVHQUlBc2lBV29pQmtFQUlBRnJJZ2h4SWdFZ0JVME5CMEhFSHlnQ0FDSURCRUJCdkI4b0FnQWlCeUFCYWlJSklBZE5EUWdnQXlBSlNRMElDd0pBUWNnZkxRQUFRUVJ4UlFSQUFrQUNRQUpBQWtCQnBCd29BZ0FpQXdSQVFjd2ZJUUFEUUNBRElBQW9BZ0FpQjA4RVFDQUhJQUFvQWdScUlBTkxEUU1MSUFBb0FnZ2lBQTBBQ3d0QkFCQVJJZ0pCZjBZTkF5QUJJUVpCNkI4b0FnQWlBRUVCYXlJRElBSnhCRUFnQVNBQ2F5QUNJQU5xUVFBZ0FHdHhhaUVHQ3lBRklBWlBEUU5CeEI4b0FnQWlBQVJBUWJ3ZktBSUFJZ01nQm1vaUNDQURUUTBFSUFBZ0NFa05CQXNnQmhBUklnQWdBa2NOQVF3RkN5QUdJQUpySUFoeElnWVFFU0lDSUFBb0FnQWdBQ2dDQkdwR0RRRWdBaUVBQ3lBQVFYOUdEUUVnQlVFd2FpQUdUUVJBSUFBaEFnd0VDMEhzSHlnQ0FDSUNJQVFnQm10cVFRQWdBbXR4SWdJUUVVRi9SZzBCSUFJZ0Jtb2hCaUFBSVFJTUF3c2dBa0YvUncwQ0MwSElIMEhJSHlnQ0FFRUVjallDQUFzZ0FSQVJJUUpCQUJBUklRQWdBa0YvUmcwRklBQkJmMFlOQlNBQUlBSk5EUVVnQUNBQ2F5SUdJQVZCS0dwTkRRVUxRYndmUWJ3ZktBSUFJQVpxSWdBMkFnQkJ3QjhvQWdBZ0FFa0VRRUhBSHlBQU5nSUFDd0pBUWFRY0tBSUFJZ1FFUUVITUh5RUFBMEFnQWlBQUtBSUFJZ0VnQUNnQ0JDSURha1lOQWlBQUtBSUlJZ0FOQUFzTUJBdEJuQndvQWdBaUFFRUFJQUFnQWswYlJRUkFRWndjSUFJMkFnQUxRUUFoQUVIUUh5QUdOZ0lBUWN3ZklBSTJBZ0JCckJ4QmZ6WUNBRUd3SEVIa0h5Z0NBRFlDQUVIWUgwRUFOZ0lBQTBBZ0FFRURkQ0lCUWJ3Y2FpQUJRYlFjYWlJRE5nSUFJQUZCd0J4cUlBTTJBZ0FnQUVFQmFpSUFRU0JIRFFBTFFaZ2NJQVpCS0dzaUFFRjRJQUpyUVFkeElnRnJJZ00yQWdCQnBCd2dBU0FDYWlJQk5nSUFJQUVnQTBFQmNqWUNCQ0FBSUFKcVFTZzJBZ1JCcUJ4QjlCOG9BZ0EyQWdBTUJBc2dBaUFFVFEwQ0lBRWdCRXNOQWlBQUtBSU1RUWh4RFFJZ0FDQURJQVpxTmdJRVFhUWNJQVJCZUNBRWEwRUhjU0lBYWlJQk5nSUFRWmdjUVpnY0tBSUFJQVpxSWdJZ0FHc2lBRFlDQUNBQklBQkJBWEkyQWdRZ0FpQUVha0VvTmdJRVFhZ2NRZlFmS0FJQU5nSUFEQU1MUVFBaEF3d0ZDMEVBSVFJTUF3dEJuQndvQWdBZ0Frc0VRRUdjSENBQ05nSUFDeUFDSUFacUlRRkJ6QjhoQUFKQUFrQUNRQU5BSUFFZ0FDZ0NBRWNFUUNBQUtBSUlJZ0FOQVF3Q0N3c2dBQzBBREVFSWNVVU5BUXRCekI4aEFBTkFBa0FnQkNBQUtBSUFJZ0ZQQkVBZ0FTQUFLQUlFYWlJRElBUkxEUUVMSUFBb0FnZ2hBQXdCQ3d0Qm1Cd2dCa0VvYXlJQVFYZ2dBbXRCQjNFaUFXc2lDRFlDQUVHa0hDQUJJQUpxSWdFMkFnQWdBU0FJUVFGeU5nSUVJQUFnQW1wQktEWUNCRUdvSEVIMEh5Z0NBRFlDQUNBRUlBTkJKeUFEYTBFSGNXcEJMMnNpQUNBQUlBUkJFR3BKR3lJQlFSczJBZ1FnQVVIVUh5a0NBRGNDRUNBQlFjd2ZLUUlBTndJSVFkUWZJQUZCQ0dvMkFnQkIwQjhnQmpZQ0FFSE1IeUFDTmdJQVFkZ2ZRUUEyQWdBZ0FVRVlhaUVBQTBBZ0FFRUhOZ0lFSUFCQkNHb2hEQ0FBUVFScUlRQWdEQ0FEU1EwQUN5QUJJQVJHRFFJZ0FTQUJLQUlFUVg1eE5nSUVJQVFnQVNBRWF5SUNRUUZ5TmdJRUlBRWdBallDQUNBQ1FmOEJUUVJBSUFKQmVIRkJ0QnhxSVFBQ2YwR01IQ2dDQUNJQlFRRWdBa0VEZG5RaUFuRkZCRUJCakJ3Z0FTQUNjallDQUNBQURBRUxJQUFvQWdnTElRRWdBQ0FFTmdJSUlBRWdCRFlDRENBRUlBQTJBZ3dnQkNBQk5nSUlEQU1MUVI4aEFDQUNRZi8vL3dkTkJFQWdBa0VtSUFKQkNIWm5JZ0JyZGtFQmNTQUFRUUYwYTBFK2FpRUFDeUFFSUFBMkFod2dCRUlBTndJUUlBQkJBblJCdkI1cUlRRUNRRUdRSENnQ0FDSURRUUVnQUhRaUJuRkZCRUJCa0J3Z0F5QUdjallDQUNBQklBUTJBZ0FNQVFzZ0FrRVpJQUJCQVhaclFRQWdBRUVmUnh0MElRQWdBU2dDQUNFREEwQWdBeUlCS0FJRVFYaHhJQUpHRFFNZ0FFRWRkaUVESUFCQkFYUWhBQ0FCSUFOQkJIRnFJZ1lvQWhBaUF3MEFDeUFHSUFRMkFoQUxJQVFnQVRZQ0dDQUVJQVEyQWd3Z0JDQUVOZ0lJREFJTElBQWdBallDQUNBQUlBQW9BZ1FnQm1vMkFnUWdBa0Y0SUFKclFRZHhhaUlISUFWQkEzSTJBZ1FnQVVGNElBRnJRUWR4YWlJRUlBVWdCMm9pQldzaEJnSkFRYVFjS0FJQUlBUkdCRUJCcEJ3Z0JUWUNBRUdZSEVHWUhDZ0NBQ0FHYWlJQU5nSUFJQVVnQUVFQmNqWUNCQXdCQzBHZ0hDZ0NBQ0FFUmdSQVFhQWNJQVUyQWdCQmxCeEJsQndvQWdBZ0Jtb2lBRFlDQUNBRklBQkJBWEkyQWdRZ0FDQUZhaUFBTmdJQURBRUxJQVFvQWdRaUFrRURjVUVCUmdSQUlBSkJlSEVoQ1FKQUlBSkIvd0ZOQkVBZ0JDZ0NEQ0lBSUFRb0FnZ2lBVVlFUUVHTUhFR01IQ2dDQUVGK0lBSkJBM1ozY1RZQ0FBd0NDeUFCSUFBMkFnd2dBQ0FCTmdJSURBRUxJQVFvQWhnaENBSkFJQVFnQkNnQ0RDSUFSd1JBUVp3Y0tBSUFHaUFFS0FJSUlnRWdBRFlDRENBQUlBRTJBZ2dNQVFzQ1FDQUVRUlJxSWdFb0FnQWlBa1VFUUNBRUtBSVFJZ0pGRFFFZ0JFRVFhaUVCQ3dOQUlBRWhBeUFDSWdCQkZHb2lBU2dDQUNJQ0RRQWdBRUVRYWlFQklBQW9BaEFpQWcwQUN5QURRUUEyQWdBTUFRdEJBQ0VBQ3lBSVJRMEFBa0FnQkNnQ0hDSUJRUUowUWJ3ZWFpSUNLQUlBSUFSR0JFQWdBaUFBTmdJQUlBQU5BVUdRSEVHUUhDZ0NBRUYrSUFGM2NUWUNBQXdDQ3lBSVFSQkJGQ0FJS0FJUUlBUkdHMm9nQURZQ0FDQUFSUTBCQ3lBQUlBZzJBaGdnQkNnQ0VDSUJCRUFnQUNBQk5nSVFJQUVnQURZQ0dBc2dCQ2dDRkNJQlJRMEFJQUFnQVRZQ0ZDQUJJQUEyQWhnTElBWWdDV29oQmlBRUlBbHFJZ1FvQWdRaEFnc2dCQ0FDUVg1eE5nSUVJQVVnQmtFQmNqWUNCQ0FGSUFacUlBWTJBZ0FnQmtIL0FVMEVRQ0FHUVhoeFFiUWNhaUVBQW45QmpCd29BZ0FpQVVFQklBWkJBM1owSWdKeFJRUkFRWXdjSUFFZ0FuSTJBZ0FnQUF3QkN5QUFLQUlJQ3lFQklBQWdCVFlDQ0NBQklBVTJBZ3dnQlNBQU5nSU1JQVVnQVRZQ0NBd0JDMEVmSVFJZ0JrSC8vLzhIVFFSQUlBWkJKaUFHUVFoMlp5SUFhM1pCQVhFZ0FFRUJkR3RCUG1vaEFnc2dCU0FDTmdJY0lBVkNBRGNDRUNBQ1FRSjBRYndlYWlFQkFrQUNRRUdRSENnQ0FDSUFRUUVnQW5RaUEzRkZCRUJCa0J3Z0FDQURjallDQUNBQklBVTJBZ0FNQVFzZ0JrRVpJQUpCQVhaclFRQWdBa0VmUnh0MElRSWdBU2dDQUNFQUEwQWdBQ0lCS0FJRVFYaHhJQVpHRFFJZ0FrRWRkaUVBSUFKQkFYUWhBaUFCSUFCQkJIRnFJZ01vQWhBaUFBMEFDeUFESUFVMkFoQUxJQVVnQVRZQ0dDQUZJQVUyQWd3Z0JTQUZOZ0lJREFFTElBRW9BZ2dpQUNBRk5nSU1JQUVnQlRZQ0NDQUZRUUEyQWhnZ0JTQUJOZ0lNSUFVZ0FEWUNDQXNnQjBFSWFpRUFEQVVMSUFFb0FnZ2lBQ0FFTmdJTUlBRWdCRFlDQ0NBRVFRQTJBaGdnQkNBQk5nSU1JQVFnQURZQ0NBdEJtQndvQWdBaUFDQUZUUTBBUVpnY0lBQWdCV3NpQVRZQ0FFR2tIRUdrSENnQ0FDSUFJQVZxSWdJMkFnQWdBaUFCUVFGeU5nSUVJQUFnQlVFRGNqWUNCQ0FBUVFocUlRQU1Bd3RCaUJ4Qk1EWUNBRUVBSVFBTUFnc0NRQ0FIUlEwQUFrQWdBeWdDSENJQVFRSjBRYndlYWlJQktBSUFJQU5HQkVBZ0FTQUNOZ0lBSUFJTkFVR1FIQ0FJUVg0Z0FIZHhJZ2cyQWdBTUFnc2dCMEVRUVJRZ0J5Z0NFQ0FEUmh0cUlBSTJBZ0FnQWtVTkFRc2dBaUFITmdJWUlBTW9BaEFpQUFSQUlBSWdBRFlDRUNBQUlBSTJBaGdMSUFNb0FoUWlBRVVOQUNBQ0lBQTJBaFFnQUNBQ05nSVlDd0pBSUFSQkQwMEVRQ0FESUFRZ0JXb2lBRUVEY2pZQ0JDQUFJQU5xSWdBZ0FDZ0NCRUVCY2pZQ0JBd0JDeUFESUFWQkEzSTJBZ1FnQXlBRmFpSUNJQVJCQVhJMkFnUWdBaUFFYWlBRU5nSUFJQVJCL3dGTkJFQWdCRUY0Y1VHMEhHb2hBQUovUVl3Y0tBSUFJZ0ZCQVNBRVFRTjJkQ0lGY1VVRVFFR01IQ0FCSUFWeU5nSUFJQUFNQVFzZ0FDZ0NDQXNoQVNBQUlBSTJBZ2dnQVNBQ05nSU1JQUlnQURZQ0RDQUNJQUUyQWdnTUFRdEJIeUVBSUFSQi8vLy9CMDBFUUNBRVFTWWdCRUVJZG1jaUFHdDJRUUZ4SUFCQkFYUnJRVDVxSVFBTElBSWdBRFlDSENBQ1FnQTNBaEFnQUVFQ2RFRzhIbW9oQVFKQUFrQWdDRUVCSUFCMElnVnhSUVJBUVpBY0lBVWdDSEkyQWdBZ0FTQUNOZ0lBREFFTElBUkJHU0FBUVFGMmEwRUFJQUJCSDBjYmRDRUFJQUVvQWdBaEJRTkFJQVVpQVNnQ0JFRjRjU0FFUmcwQ0lBQkJIWFloQlNBQVFRRjBJUUFnQVNBRlFRUnhhaUlHS0FJUUlnVU5BQXNnQmlBQ05nSVFDeUFDSUFFMkFoZ2dBaUFDTmdJTUlBSWdBallDQ0F3QkN5QUJLQUlJSWdBZ0FqWUNEQ0FCSUFJMkFnZ2dBa0VBTmdJWUlBSWdBVFlDRENBQ0lBQTJBZ2dMSUFOQkNHb2hBQXdCQ3dKQUlBbEZEUUFDUUNBQ0tBSWNJZ0JCQW5SQnZCNXFJZ0VvQWdBZ0FrWUVRQ0FCSUFNMkFnQWdBdzBCUVpBY0lBdEJmaUFBZDNFMkFnQU1BZ3NnQ1VFUVFSUWdDU2dDRUNBQ1JodHFJQU0yQWdBZ0EwVU5BUXNnQXlBSk5nSVlJQUlvQWhBaUFBUkFJQU1nQURZQ0VDQUFJQU0yQWhnTElBSW9BaFFpQUVVTkFDQURJQUEyQWhRZ0FDQUROZ0lZQ3dKQUlBUkJEMDBFUUNBQ0lBUWdCV29pQUVFRGNqWUNCQ0FBSUFKcUlnQWdBQ2dDQkVFQmNqWUNCQXdCQ3lBQ0lBVkJBM0kyQWdRZ0FpQUZhaUlESUFSQkFYSTJBZ1FnQXlBRWFpQUVOZ0lBSUFjRVFDQUhRWGh4UWJRY2FpRUFRYUFjS0FJQUlRRUNmMEVCSUFkQkEzWjBJZ1VnQm5GRkJFQkJqQndnQlNBR2NqWUNBQ0FBREFFTElBQW9BZ2dMSVFVZ0FDQUJOZ0lJSUFVZ0FUWUNEQ0FCSUFBMkFnd2dBU0FGTmdJSUMwR2dIQ0FETmdJQVFaUWNJQVEyQWdBTElBSkJDR29oQUFzZ0NrRVFhaVFBSUFBTEJnQWdBQkFRQ3pVQkFYOUJBU0FBSUFCQkFVMGJJUUFDUUFOQUlBQVFFaUlCRFFGQmtDQW9BZ0FpQVFSQUlBRVJBUUFNQVFzTEVBVUFDeUFCQzJFQVFmd2ZRUUUyQWdCQmdDQkJBRFlDQUVHUENFRUZRZUFPUWZRT1FRSkJBMEVBRUFaQmdDQkJoQ0FvQWdBMkFnQkJoQ0JCL0I4MkFnQkJpQ0JCQlRZQ0FFR01JRUVBTmdJQUVCMUJqQ0JCaENBb0FnQTJBZ0JCaENCQmlDQTJBZ0FMSEFBZ0FDQUJRUWdnQXFjZ0FrSWdpS2NnQTZjZ0EwSWdpS2NRQ2dzSUFDQUFFQjRRRUF0ZEFRRi9JQUFvQWhBaUEwVUVRQ0FBUVFFMkFpUWdBQ0FDTmdJWUlBQWdBVFlDRUE4TEFrQWdBU0FEUmdSQUlBQW9BaGhCQWtjTkFTQUFJQUkyQWhnUEN5QUFRUUU2QURZZ0FFRUNOZ0lZSUFBZ0FDZ0NKRUVCYWpZQ0pBc0xtZ0VBSUFCQkFUb0FOUUpBSUFBb0FnUWdBa2NOQUNBQVFRRTZBRFFDUUNBQUtBSVFJZ0pGQkVBZ0FFRUJOZ0lrSUFBZ0F6WUNHQ0FBSUFFMkFoQWdBMEVCUncwQ0lBQW9BakJCQVVZTkFRd0NDeUFCSUFKR0JFQWdBQ2dDR0NJQ1FRSkdCRUFnQUNBRE5nSVlJQU1oQWdzZ0FDZ0NNRUVCUncwQ0lBSkJBVVlOQVF3Q0N5QUFJQUFvQWlSQkFXbzJBaVFMSUFCQkFUb0FOZ3NML2dJQkEzOGpBRUh3QUdzaUFpUUFJQUFvQWdBaUEwRUVheWdDQUNFRUlBTkJDR3NvQWdBaEF5QUNRZ0EzQWt3Z0FrSUFOd0pVSUFKQ0FEY0NYQ0FDUWdBM0FtUWdBa0VBTmdCcklBSkNBRGNDUkNBQ1FiUVdOZ0pBSUFJZ0FEWUNQQ0FDSUFFMkFqZ0NRQ0FFSUFGQkFCQU9CRUJCQUNBQUlBTWJJUUFNQVFzZ0FDQUFJQU5xSWdOT0JFQWdBa0lBTndJc0lBSkJBRFlBTXlBQ1FnQTNBaFFnQWtJQU53SWNJQUpDQURjQ0pDQUNRZ0EzQWd3Z0FpQUJOZ0lJSUFJZ0FEWUNCQ0FDSUFRMkFnQWdBa0VCTmdJd0lBUWdBaUFESUFOQkFVRUFJQVFvQWdBb0FoUVJCZ0FnQWlnQ0dBMEJDMEVBSVFBZ0JDQUNRVGhxSUFOQkFVRUFJQVFvQWdBb0FoZ1JCQUFDUUFKQUlBSW9BbHdPQWdBQkFnc2dBaWdDVEVFQUlBSW9BbGhCQVVZYlFRQWdBaWdDVkVFQlJodEJBQ0FDS0FKZ1FRRkdHeUVBREFFTElBSW9BbEJCQVVjRVFDQUNLQUpnRFFFZ0FpZ0NWRUVCUncwQklBSW9BbGhCQVVjTkFRc2dBaWdDU0NFQUN5QUNRZkFBYWlRQUlBQUxBZ0FMQkFBZ0FBdmhBd0JCcEJoQnVBa1FDVUd3R0VIWENFRUJRUUFRQ0VHOEdFSERDRUVCUVlCL1FmOEFFQUZCMUJoQnZBaEJBVUdBZjBIL0FCQUJRY2dZUWJvSVFRRkJBRUgvQVJBQlFlQVlRWWtJUVFKQmdJQitRZi8vQVJBQlFld1lRWUFJUVFKQkFFSC8vd01RQVVINEdFR2dDRUVFUVlDQWdJQjRRZi8vLy84SEVBRkJoQmxCbHdoQkJFRUFRWDhRQVVHUUdVSDFDRUVFUVlDQWdJQjRRZi8vLy84SEVBRkJuQmxCN0FoQkJFRUFRWDhRQVVHb0dVR3JDRUtBZ0lDQWdJQ0FnSUIvUXYvLy8vLy8vLy8vL3dBUUZrRzBHVUdxQ0VJQVFuOFFGa0hBR1VHa0NFRUVFQU5CekJsQnNRbEJDQkFEUWJ3UFFZY0pFQVJCaEJCQnRRMFFCRUhNRUVFRVFmb0lFQUpCbUJGQkFrR1RDUkFDUWVRUlFRUkJvZ2tRQWtHQUVrSGNDQkFIUWFnU1FRQkI4QXdRQUVIUUVrRUFRZFlORUFCQitCSkJBVUdPRFJBQVFhQVRRUUpCdlFrUUFFSElFMEVEUWR3SkVBQkI4Qk5CQkVHRUNoQUFRWmdVUVFWQm9Rb1FBRUhBRkVFRVFmc05FQUJCNkJSQkJVR1pEaEFBUWRBU1FRQkJod3NRQUVINEVrRUJRZVlLRUFCQm9CTkJBa0hKQ3hBQVFjZ1RRUU5CcHdzUUFFSHdFMEVFUWM4TUVBQkJtQlJCQlVHdERCQUFRWkFWUVFoQmpBd1FBRUc0RlVFSlFlb0xFQUJCNEJWQkJrSEhDaEFBUVlnV1FRZEJ3QTRRQUFzeEFRSi9JQUJCb0JvMkFnQWdBQ2dDQkVFTWF5SUJJQUVvQWdoQkFXc2lBallDQ0NBQ1FRQklCRUFnQVJBUUN5QUFDMmdCQTM5QjJBQVFFa0hRQUdvaUFFSDBHellDQUNBQVFhQWFOZ0lBUVJNUUZDSUJRUUEyQWdnZ0FVS0dnSUNBNEFBM0FnQWdBVUVNYWlJQ1FiWUlLQUFBTmdBRElBRkJzd2dvQUFBMkFBd2dBQ0FDTmdJRUlBQkIwQm8yQWdBZ0FFSHdHa0VFRUEwQUM4a0tBUTUvSXdCQmdCQnJJZ01rQUFKL0lBQW9BZ1FpQ2lBQUtBSUFJZ1JHQkVBZ0EwR0FDR3BCZ0FnUUR4cEJBQXdCQ3lBS0lBUnJJZ1ZCQTNVaUNFR0FnSUNBQWs4RVFCQWZBQXNnQlJBVUlnY2dCUkFQSVFFZ0EwR0FDR3BCZ0FnUUR4b2dCQ0VDQTBBZ0EwR0FDR29nQWlnQ0FDSUpRUjkxSUFselFmOEJjVUVDZEdvaUNTQUpLQUlBUVFGcU5nSUFJQUpCQ0dvaUFpQUtSdzBBQ3lBQklBaEJBM1JxSVFnZ0FTQUZhZ3NoQlVFQUlRRWdBMEVBTmdJQVFRRWhBZ05BSUFNZ0FrRUNkQ0lKYWlJTElBRWdBMEdBQ0dvZ0NXb2lCa0VFYXlnQ0FHb2lBVFlDQUNBRElBbEJCR29pQ1dvZ0JpZ0NBQ0FCYWlJQk5nSUFJQXNnQTBHQUNHb2dDV29vQWdBZ0FXb2lBVFlDQ0NBQ1FRTnFJZ0pCZ0FKSERRQUxJQVFnQ2tZaUMwVUVRQ0FFSVFJRFFDQURJQUlvQWdBaUFVRWZkU0FCYzBIL0FYRkJBblJxSWdFZ0FTZ0NBQ0lCUVFGcU5nSUFJQWNnQVVFRGRHb2dBaWtDQURjQ0FDQUNRUWhxSWdJZ0NrY05BQXNMSUFBZ0JUWUNCQ0FBSUFjMkFnQWdBQ2dDQ0NFSklBQWdDRFlDQ0VFQUlRRWdBMEdBQ0dwQmdBZ1FEeG9nQlNBSFJpSU1SUVJBSUFjaEFnTkFJQU5CZ0FocUlBSW9BZ0FpQmtFZmRTQUdjMEVHZGtIOEIzRnFJZ1lnQmlnQ0FFRUJhallDQUNBQ1FRaHFJZ0lnQlVjTkFBc0xJQU5CQURZQ0FFRUJJUUlEUUNBRElBSkJBblFpQm1vaURTQUJJQU5CZ0FocUlBWnFJZzVCQkdzb0FnQnFJZ0UyQWdBZ0F5QUdRUVJxSWdacUlBNG9BZ0FnQVdvaUFUWUNBQ0FOSUFOQmdBaHFJQVpxS0FJQUlBRnFJZ0UyQWdnZ0FrRURhaUlDUVlBQ1J3MEFDeUFNQkg4Z0J3VURRQ0FESUFjb0FnQWlBa0VmZFNBQ2MwRUdka0g4QjNGcUlnSWdBaWdDQUNJQ1FRRnFOZ0lBSUFRZ0FrRURkR29nQnlrQ0FEY0NBQ0FIUVFocUlnY2dCVWNOQUFzZ0FDZ0NDQ0VJSUFBb0FnUWhCeUFBS0FJQUN5RUNJQUFnQ1RZQ0NDQUFJQW8yQWdRZ0FDQUVOZ0lBUVFBaEFTQURRWUFJYWtHQUNCQVBHaUFMUlFSQUlBUWhCUU5BSUFOQmdBaHFJQVVvQWdBaUJrRWZkU0FHYzBFT2RrSDhCM0ZxSWdZZ0JpZ0NBRUVCYWpZQ0FDQUZRUWhxSWdVZ0NrY05BQXNMSUFOQkFEWUNBRUVCSVFVRFFDQURJQVZCQW5RaUJtb2lEQ0FCSUFOQmdBaHFJQVpxSWcxQkJHc29BZ0JxSWdFMkFnQWdBeUFHUVFScUlnWnFJQTBvQWdBZ0FXb2lBVFlDQUNBTUlBTkJnQWhxSUFacUtBSUFJQUZxSWdFMkFnZ2dCVUVEYWlJRlFZQUNSdzBBQ3lBTEJIOGdDZ1VEUUNBRElBUW9BZ0FpQlVFZmRTQUZjMEVPZGtIOEIzRnFJZ1VnQlNnQ0FDSUZRUUZxTmdJQUlBSWdCVUVEZEdvZ0JDa0NBRGNDQUNBRVFRaHFJZ1FnQ2tjTkFBc2dBQ2dDQ0NFSklBQW9BZ1FoQ2lBQUtBSUFDeUVGSUFBZ0NEWUNDQ0FBSUFjMkFnUWdBQ0FDTmdJQVFRQWhBU0FEUVlBSWFrR0FDQkFQR2lBQ0lBZEdJZ3RGQkVBZ0FpRUVBMEFnQTBHQUNHb2dCQ2dDQUNJSVFSOTFRWUNBZ0lCNGNpQUljMEVXZGtIOEIzRnFJZ2dnQ0NnQ0FFRUJhallDQUNBRVFRaHFJZ1FnQjBjTkFBc0xJQU5CQURZQ0FFRUJJUVFEUUNBRElBUkJBblFpQ0dvaUJpQUJJQU5CZ0FocUlBaHFJZ3hCQkdzb0FnQnFJZ0UyQWdBZ0F5QUlRUVJxSWdocUlBd29BZ0FnQVdvaUFUWUNBQ0FHSUFOQmdBaHFJQWhxS0FJQUlBRnFJZ0UyQWdnZ0JFRURhaUlFUVlBQ1J3MEFDeUFMUlFSQUEwQWdBeUFDS0FJQUlnUkJIM1ZCZ0lDQWdIaHlJQVJ6UVJaMlFmd0hjV29pQkNBRUtBSUFJZ1JCQVdvMkFnQWdCU0FFUVFOMGFpQUNLUUlBTndJQUlBSkJDR29pQWlBSFJ3MEFDeUFBS0FJQUlRY0xJQUFnQ1RZQ0NDQUFJQW8yQWdRZ0FDQUZOZ0lBSUFjRVFDQUhFQkFMSUFOQmdCQnFKQUFMRlFCQmp3aEJCVUhnRGtIMERrRUNRUU5CQUJBR0N3Y0FJQUFvQWdRTEJRQkJ5QWdMRlFBZ0FFVUVRRUVBRHdzZ0FFSEVGeEFhUVFCSEN4b0FJQUFnQVNnQ0NDQUZFQTRFUUNBQklBSWdBeUFFRUJrTEM2Y0JBQ0FBSUFFb0FnZ2dCQkFPQkVBQ1FDQUJLQUlFSUFKSERRQWdBU2dDSEVFQlJnMEFJQUVnQXpZQ0hBc1BDd0pBSUFBZ0FTZ0NBQ0FFRUE1RkRRQUNRQ0FDSUFFb0FoQkhCRUFnQVNnQ0ZDQUNSdzBCQ3lBRFFRRkhEUUVnQVVFQk5nSWdEd3NnQVNBQ05nSVVJQUVnQXpZQ0lDQUJJQUVvQWloQkFXbzJBaWdDUUNBQktBSWtRUUZIRFFBZ0FTZ0NHRUVDUncwQUlBRkJBVG9BTmdzZ0FVRUVOZ0lzQ3dzWUFDQUFJQUVvQWdoQkFCQU9CRUFnQVNBQ0lBTVFHQXNMTVFBZ0FDQUJLQUlJUVFBUURnUkFJQUVnQWlBREVCZ1BDeUFBS0FJSUlnQWdBU0FDSUFNZ0FDZ0NBQ2dDSEJFQ0FBdUlBZ0FnQUNBQktBSUlJQVFRRGdSQUFrQWdBU2dDQkNBQ1J3MEFJQUVvQWh4QkFVWU5BQ0FCSUFNMkFod0xEd3NDUUNBQUlBRW9BZ0FnQkJBT0JFQUNRQ0FDSUFFb0FoQkhCRUFnQVNnQ0ZDQUNSdzBCQ3lBRFFRRkhEUUlnQVVFQk5nSWdEd3NnQVNBRE5nSWdBa0FnQVNnQ0xFRUVSZzBBSUFGQkFEc0JOQ0FBS0FJSUlnQWdBU0FDSUFKQkFTQUVJQUFvQWdBb0FoUVJCZ0FnQVMwQU5RUkFJQUZCQXpZQ0xDQUJMUUEwUlEwQkRBTUxJQUZCQkRZQ0xBc2dBU0FDTmdJVUlBRWdBU2dDS0VFQmFqWUNLQ0FCS0FJa1FRRkhEUUVnQVNnQ0dFRUNSdzBCSUFGQkFUb0FOZzhMSUFBb0FnZ2lBQ0FCSUFJZ0F5QUVJQUFvQWdBb0FoZ1JCQUFMQ3pjQUlBQWdBU2dDQ0NBRkVBNEVRQ0FCSUFJZ0F5QUVFQmtQQ3lBQUtBSUlJZ0FnQVNBQ0lBTWdCQ0FGSUFBb0FnQW9BaFFSQmdBTG1nRUJBbjhqQUVGQWFpSURKQUFDZjBFQklBQWdBVUVBRUE0TkFCcEJBQ0FCUlEwQUdrRUFJQUZCNUJZUUdpSUJSUTBBR2lBRFFReHFRVFFRRHhvZ0EwRUJOZ0k0SUFOQmZ6WUNGQ0FESUFBMkFoQWdBeUFCTmdJSUlBRWdBMEVJYWlBQ0tBSUFRUUVnQVNnQ0FDZ0NIQkVDQUNBREtBSWdJZ0JCQVVZRVFDQUNJQU1vQWhnMkFnQUxJQUJCQVVZTElRUWdBMEZBYXlRQUlBUUxDZ0FnQUNBQlFRQVFEZ3NGQUJBdUFBc0ZBQkFGQUF1UUJRRUZmd0ovQWtBQ1FDQUFLQUlFSWdJaUFVRURjVVVOQUVFQUlBRXRBQUJGRFFJYUEwQWdBVUVCYWlJQlFRTnhSUTBCSUFFdEFBQU5BQXNNQVFzRFFDQUJJZ0JCQkdvaEFTQUFLQUlBSWdSQmYzTWdCRUdCZ29RSWEzRkJnSUdDaEhoeFJRMEFDd05BSUFBaUFVRUJhaUVBSUFFdEFBQU5BQXNMSUFFZ0Ftc0xRUUZxSWdFUUVpSUFCSDhDZnlBQlFZQUVUd1JBSUFBZ0FpQUJFQXdnQUF3QkN5QUFJQUZxSVFNQ1FDQUFJQUp6UVFOeFJRUkFBa0FnQUVFRGNVVUVRQ0FBSVFFTUFRc2dBVVVFUUNBQUlRRU1BUXNnQUNFQkEwQWdBU0FDTFFBQU9nQUFJQUpCQVdvaEFpQUJRUUZxSWdGQkEzRkZEUUVnQVNBRFNRMEFDd3NDUUNBRFFYeHhJZ1ZCd0FCSkRRQWdBU0FGUVVCcUlnUkxEUUFEUUNBQklBSW9BZ0EyQWdBZ0FTQUNLQUlFTmdJRUlBRWdBaWdDQ0RZQ0NDQUJJQUlvQWd3MkFnd2dBU0FDS0FJUU5nSVFJQUVnQWlnQ0ZEWUNGQ0FCSUFJb0FoZzJBaGdnQVNBQ0tBSWNOZ0ljSUFFZ0FpZ0NJRFlDSUNBQklBSW9BaVEyQWlRZ0FTQUNLQUlvTmdJb0lBRWdBaWdDTERZQ0xDQUJJQUlvQWpBMkFqQWdBU0FDS0FJME5nSTBJQUVnQWlnQ09EWUNPQ0FCSUFJb0FqdzJBandnQWtGQWF5RUNJQUZCUUdzaUFTQUVUUTBBQ3dzZ0FTQUZUdzBCQTBBZ0FTQUNLQUlBTmdJQUlBSkJCR29oQWlBQlFRUnFJZ0VnQlVrTkFBc01BUXNnQTBFRVNRUkFJQUFoQVF3QkN5QUFJQU5CQkdzaUJFc0VRQ0FBSVFFTUFRc2dBQ0VCQTBBZ0FTQUNMUUFBT2dBQUlBRWdBaTBBQVRvQUFTQUJJQUl0QUFJNkFBSWdBU0FDTFFBRE9nQURJQUpCQkdvaEFpQUJRUVJxSWdFZ0JFME5BQXNMSUFFZ0Ewa0VRQU5BSUFFZ0FpMEFBRG9BQUNBQ1FRRnFJUUlnQVVFQmFpSUJJQU5IRFFBTEN5QUFDd1ZCQUFzTHlBUUNDWDhHZlNNQVFSQnJJZ1lrQUNBR1FRQTJBZ3dnQmtJQU53SUVBa0FnQWtVRVFDQUdRUVJxRUNBTUFRc2dBa0dBZ0lDQUFra0VRQ0FDUVFwc0lRc2dBa0VIYkNFSUlBSkJBblFoQ1NBR0lBSkJBM1FpQlJBVUlnYzJBZ1FnQmlBRklBZHFJZ28yQWd3Z0J5QUZFQThoQlNBR0lBbzJBZ2dnQUNvQ0tDRU5JQUFxQWhnaERpQUFLZ0lJSVE4RFFDQUJJQVJCQlhScUlnQXFBZ2doRUNBQUtnSUFJUkVnQUNvQ0JDRVNJQVVnQkVFRGRHb2lBQ0FFTmdJRUlBQkRBRUFjUmlBTklCQ1VJQThnRVpRZ0RpQVNsSktTa3pnQ0FDQUVRUUZxSWdRZ0FrY05BQXNnQXlBSlFRSjBhaUVISUFNZ0NFRUNkR29oQ0NBR1FRUnFFQ0JCQUNFQUlBWW9BZ1FoQ1FOQUlBTWdBRUVFZEdvaUJTQUJJQWtnQUVFRGRHb29BZ1JCQlhScUlnUXRBQnhCZ0FGcnNrTUFBQUE4bERnQ0FDQUZJQVF0QUIxQmdBRnJza01BQUFBOGxEZ0NCQ0FGSUFRdEFCNUJnQUZyc2tNQUFBQThsRGdDQ0NBRklBUXRBQjlCZ0FGcnNrTUFBQUE4bERnQ0RDQUlJQUJCREd3aUNtb2lCU0FFS2dJQU9BSUFJQVVnQkNvQ0JEZ0NCQ0FGSUFRcUFnZzRBZ2dnQXlBQVFRSjBJQXRxUVFKMElneHFJZ1VnQkMwQUdMTkRBQUIvUTVVNEFnQWdBeUFNUVFSeWFpQUVMUUFaczBNQUFIOURsVGdDQUNBRklBUXRBQnF6UXdBQWYwT1ZPQUlJSUFVZ0JDMEFHN05EQUFCL1E1VTRBZ3dnQnlBS2FpSUZJQVFxQWd3NEFnQWdCU0FFS2dJUU9BSUVJQVVnQkNvQ0ZEZ0NDQ0FBUVFGcUlnQWdBa2NOQUFzTUFRc1FId0FMSUFZb0FnUWlBQVJBSUFBUUVBc2dCa0VRYWlRQUN3OEFJQUVnQWlBRElBUWdBQkVDQUFzTGtCUUNBRUdBQ0F2OUUzVnVjMmxuYm1Wa0lITm9iM0owQUhKMWJsTnZjblFBZFc1emFXZHVaV1FnYVc1MEFHWnNiMkYwQUhWcGJuUTJORjkwQUhabFkzUnZjZ0IxYm5OcFoyNWxaQ0JqYUdGeUFITjBaRG82WlhoalpYQjBhVzl1QUdKdmIyd0FaVzF6WTNKcGNIUmxiam82ZG1Gc0FIVnVjMmxuYm1Wa0lHeHZibWNBYzNSa09qcDNjM1J5YVc1bkFITjBaRG82YzNSeWFXNW5BSE4wWkRvNmRURTJjM1J5YVc1bkFITjBaRG82ZFRNeWMzUnlhVzVuQUdSdmRXSnNaUUIyYjJsa0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEhOb2IzSjBQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eDFibk5wWjI1bFpDQnphRzl5ZEQ0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4YVc1MFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4MWJuTnBaMjVsWkNCcGJuUStBR1Z0YzJOeWFYQjBaVzQ2T20xbGJXOXllVjkyYVdWM1BHWnNiMkYwUGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkengxYVc1ME9GOTBQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eHBiblE0WDNRK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEhWcGJuUXhObDkwUGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkenhwYm5ReE5sOTBQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eDFhVzUwTmpSZmRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGFXNTBOalJmZEQ0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4ZFdsdWRETXlYM1ErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQR2x1ZERNeVgzUStBR1Z0YzJOeWFYQjBaVzQ2T20xbGJXOXllVjkyYVdWM1BHTm9ZWEkrQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQSFZ1YzJsbmJtVmtJR05vWVhJK0FITjBaRG82WW1GemFXTmZjM1J5YVc1blBIVnVjMmxuYm1Wa0lHTm9ZWEkrQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQSE5wWjI1bFpDQmphR0Z5UGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkenhzYjI1blBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4MWJuTnBaMjVsWkNCc2IyNW5QZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eGtiM1ZpYkdVK0FDUU1BQUI0REFBQWVBd0FBSGdNQUFCNERBQUFkbWxwYVdscEFFNVRkRE5mWHpJeE1tSmhjMmxqWDNOMGNtbHVaMGxqVGxOZk1URmphR0Z5WDNSeVlXbDBjMGxqUlVWT1UxODVZV3hzYjJOaGRHOXlTV05GUlVWRkFBQUFoQTBBQUhzSEFBQk9VM1F6WDE4eU1USmlZWE5wWTE5emRISnBibWRKYUU1VFh6RXhZMmhoY2w5MGNtRnBkSE5KYUVWRlRsTmZPV0ZzYkc5allYUnZja2xvUlVWRlJRQUFoQTBBQU1RSEFBQk9VM1F6WDE4eU1USmlZWE5wWTE5emRISnBibWRKZDA1VFh6RXhZMmhoY2w5MGNtRnBkSE5KZDBWRlRsTmZPV0ZzYkc5allYUnZja2wzUlVWRlJRQUFoQTBBQUF3SUFBQk9VM1F6WDE4eU1USmlZWE5wWTE5emRISnBibWRKUkhOT1UxOHhNV05vWVhKZmRISmhhWFJ6U1VSelJVVk9VMTg1WVd4c2IyTmhkRzl5U1VSelJVVkZSUUFBQUlRTkFBQlVDQUFBVGxOME0xOWZNakV5WW1GemFXTmZjM1J5YVc1blNVUnBUbE5mTVRGamFHRnlYM1J5WVdsMGMwbEVhVVZGVGxOZk9XRnNiRzlqWVhSdmNrbEVhVVZGUlVVQUFBQ0VEUUFBb0FnQUFFNHhNR1Z0YzJOeWFYQjBaVzR6ZG1Gc1JRQUFoQTBBQU93SUFBQk9NVEJsYlhOamNtbHdkR1Z1TVRGdFpXMXZjbmxmZG1sbGQwbGpSVVVBQUlRTkFBQUlDUUFBVGpFd1pXMXpZM0pwY0hSbGJqRXhiV1Z0YjNKNVgzWnBaWGRKWVVWRkFBQ0VEUUFBTUFrQUFFNHhNR1Z0YzJOeWFYQjBaVzR4TVcxbGJXOXllVjkyYVdWM1NXaEZSUUFBaEEwQUFGZ0pBQUJPTVRCbGJYTmpjbWx3ZEdWdU1URnRaVzF2Y25sZmRtbGxkMGx6UlVVQUFJUU5BQUNBQ1FBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSmRFVkZBQUNFRFFBQXFBa0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTV2xGUlFBQWhBMEFBTkFKQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBscVJVVUFBSVFOQUFENENRQUFUakV3WlcxelkzSnBjSFJsYmpFeGJXVnRiM0o1WDNacFpYZEpiRVZGQUFDRURRQUFJQW9BQUU0eE1HVnRjMk55YVhCMFpXNHhNVzFsYlc5eWVWOTJhV1YzU1cxRlJRQUFoQTBBQUVnS0FBQk9NVEJsYlhOamNtbHdkR1Z1TVRGdFpXMXZjbmxmZG1sbGQwbDRSVVVBQUlRTkFBQndDZ0FBVGpFd1pXMXpZM0pwY0hSbGJqRXhiV1Z0YjNKNVgzWnBaWGRKZVVWRkFBQ0VEUUFBbUFvQUFFNHhNR1Z0YzJOeWFYQjBaVzR4TVcxbGJXOXllVjkyYVdWM1NXWkZSUUFBaEEwQUFNQUtBQUJPTVRCbGJYTmpjbWx3ZEdWdU1URnRaVzF2Y25sZmRtbGxkMGxrUlVVQUFJUU5BQURvQ2dBQVRqRXdYMTlqZUhoaFltbDJNVEUyWDE5emFHbHRYM1I1Y0dWZmFXNW1iMFVBQUFBQXhBMEFBQkFMQUFDMERRQUFUakV3WDE5amVIaGhZbWwyTVRFM1gxOWpiR0Z6YzE5MGVYQmxYMmx1Wm05RkFBQUF4QTBBQUVBTEFBQTBDd0FBVGpFd1gxOWplSGhoWW1sMk1URTNYMTl3WW1GelpWOTBlWEJsWDJsdVptOUZBQUFBeEEwQUFIQUxBQUEwQ3dBQVRqRXdYMTlqZUhoaFltbDJNVEU1WDE5d2IybHVkR1Z5WDNSNWNHVmZhVzVtYjBVQXhBMEFBS0FMQUFDVUN3QUFBQUFBQUJRTUFBQUhBQUFBQ0FBQUFBa0FBQUFLQUFBQUN3QUFBRTR4TUY5ZlkzaDRZV0pwZGpFeU0xOWZablZ1WkdGdFpXNTBZV3hmZEhsd1pWOXBibVp2UlFERURRQUE3QXNBQURRTEFBQjJBQUFBMkFzQUFDQU1BQUJpQUFBQTJBc0FBQ3dNQUFCakFBQUEyQXNBQURnTUFBQm9BQUFBMkFzQUFFUU1BQUJoQUFBQTJBc0FBRkFNQUFCekFBQUEyQXNBQUZ3TUFBQjBBQUFBMkFzQUFHZ01BQUJwQUFBQTJBc0FBSFFNQUFCcUFBQUEyQXNBQUlBTUFBQnNBQUFBMkFzQUFJd01BQUJ0QUFBQTJBc0FBSmdNQUFCNEFBQUEyQXNBQUtRTUFBQjVBQUFBMkFzQUFMQU1BQUJtQUFBQTJBc0FBTHdNQUFCa0FBQUEyQXNBQU1nTUFBQk9NVEJmWDJONGVHRmlhWFl4TWpCZlgzTnBYMk5zWVhOelgzUjVjR1ZmYVc1bWIwVUFBQUFBeEEwQUFOUU1BQUJrQ3dBQVUzUTVaWGhqWlhCMGFXOXVBQUFBQUFBQUFBQThEUUFBQkFBQUFBd0FBQUFOQUFBQVUzUXhNV3h2WjJsalgyVnljbTl5QU1RTkFBQXNEUUFBNUEwQUFBQUFBQUJ3RFFBQUJBQUFBQTRBQUFBTkFBQUFVM1F4TW14bGJtZDBhRjlsY25KdmNnQUFBQURFRFFBQVhBMEFBRHdOQUFBQUFBQUFaQXNBQUFjQUFBQVBBQUFBQ1FBQUFBb0FBQUFRQUFBQUVRQUFBQklBQUFBVEFBQUFVM1E1ZEhsd1pWOXBibVp2QUFBQUFJUU5BQUNrRFFBQUFBQUFBUHdNQUFBSEFBQUFGQUFBQUFrQUFBQUtBQUFBRUFBQUFCVUFBQUFXQUFBQUZ3QUFBSVFOQUFBSURRQUFBQUFBQU9RTkFBQVlBQUFBR1FBQUFCb0FRWUFjQ3dVZ0VBRUFCZz09Iiwgc2VsZi5sb2NhdGlvbi5ocmVmKS5ocmVmOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIGdldEJpbmFyeVN5bmMoZmlsZSkgewogICAgICAgIGlmIChmaWxlID09IHdhc21CaW5hcnlGaWxlICYmIHdhc21CaW5hcnkpIHsKICAgICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheSh3YXNtQmluYXJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlYWRCaW5hcnkpIHsKICAgICAgICAgIHJldHVybiByZWFkQmluYXJ5KGZpbGUpOwogICAgICAgIH0KICAgICAgICB0aHJvdyAiYm90aCBhc3luYyBhbmQgc3luYyBmZXRjaGluZyBvZiB0aGUgd2FzbSBmYWlsZWQiOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIGdldEJpbmFyeVByb21pc2UoYmluYXJ5RmlsZSkgewogICAgICAgIGlmICghd2FzbUJpbmFyeSAmJiAoRU5WSVJPTk1FTlRfSVNfV0VCIHx8IEVOVklST05NRU5UX0lTX1dPUktFUikpIHsKICAgICAgICAgIGlmICh0eXBlb2YgZmV0Y2ggPT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICByZXR1cm4gZmV0Y2goYmluYXJ5RmlsZSwgeyBjcmVkZW50aWFsczogInNhbWUtb3JpZ2luIiB9KS50aGVuKChyZXNwb25zZSkgPT4gewogICAgICAgICAgICAgIGlmICghcmVzcG9uc2VbIm9rIl0pIHsKICAgICAgICAgICAgICAgIHRocm93ICJmYWlsZWQgdG8gbG9hZCB3YXNtIGJpbmFyeSBmaWxlIGF0ICciICsgYmluYXJ5RmlsZSArICInIjsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlWyJhcnJheUJ1ZmZlciJdKCk7CiAgICAgICAgICAgIH0pLmNhdGNoKCgpID0+IGdldEJpbmFyeVN5bmMoYmluYXJ5RmlsZSkpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiBnZXRCaW5hcnlTeW5jKGJpbmFyeUZpbGUpKTsKICAgICAgfQogICAgICBmdW5jdGlvbiBpbnN0YW50aWF0ZUFycmF5QnVmZmVyKGJpbmFyeUZpbGUsIGltcG9ydHMsIHJlY2VpdmVyKSB7CiAgICAgICAgcmV0dXJuIGdldEJpbmFyeVByb21pc2UoYmluYXJ5RmlsZSkudGhlbigoYmluYXJ5KSA9PiBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShiaW5hcnksIGltcG9ydHMpKS50aGVuKChpbnN0YW5jZSkgPT4gaW5zdGFuY2UpLnRoZW4ocmVjZWl2ZXIsIChyZWFzb24pID0+IHsKICAgICAgICAgIGVycihgZmFpbGVkIHRvIGFzeW5jaHJvbm91c2x5IHByZXBhcmUgd2FzbTogJHtyZWFzb259YCk7CiAgICAgICAgICBhYm9ydChyZWFzb24pOwogICAgICAgIH0pOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIGluc3RhbnRpYXRlQXN5bmMoYmluYXJ5LCBiaW5hcnlGaWxlLCBpbXBvcnRzLCBjYWxsYmFjaykgewogICAgICAgIGlmICghYmluYXJ5ICYmIHR5cGVvZiBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZVN0cmVhbWluZyA9PSAiZnVuY3Rpb24iICYmICFpc0RhdGFVUkkoYmluYXJ5RmlsZSkgJiYgdHlwZW9mIGZldGNoID09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgIHJldHVybiBmZXRjaChiaW5hcnlGaWxlLCB7IGNyZWRlbnRpYWxzOiAic2FtZS1vcmlnaW4iIH0pLnRoZW4oKHJlc3BvbnNlKSA9PiB7CiAgICAgICAgICAgIHZhciByZXN1bHQgPSBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZVN0cmVhbWluZyhyZXNwb25zZSwgaW1wb3J0cyk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbihjYWxsYmFjaywgZnVuY3Rpb24ocmVhc29uKSB7CiAgICAgICAgICAgICAgZXJyKGB3YXNtIHN0cmVhbWluZyBjb21waWxlIGZhaWxlZDogJHtyZWFzb259YCk7CiAgICAgICAgICAgICAgZXJyKCJmYWxsaW5nIGJhY2sgdG8gQXJyYXlCdWZmZXIgaW5zdGFudGlhdGlvbiIpOwogICAgICAgICAgICAgIHJldHVybiBpbnN0YW50aWF0ZUFycmF5QnVmZmVyKGJpbmFyeUZpbGUsIGltcG9ydHMsIGNhbGxiYWNrKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGluc3RhbnRpYXRlQXJyYXlCdWZmZXIoYmluYXJ5RmlsZSwgaW1wb3J0cywgY2FsbGJhY2spOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIGNyZWF0ZVdhc20oKSB7CiAgICAgICAgdmFyIGluZm8gPSB7ICJhIjogd2FzbUltcG9ydHMgfTsKICAgICAgICBmdW5jdGlvbiByZWNlaXZlSW5zdGFuY2UoaW5zdGFuY2UsIG1vZHVsZSkgewogICAgICAgICAgd2FzbUV4cG9ydHMgPSBpbnN0YW5jZS5leHBvcnRzOwogICAgICAgICAgd2FzbU1lbW9yeSA9IHdhc21FeHBvcnRzWyJvIl07CiAgICAgICAgICB1cGRhdGVNZW1vcnlWaWV3cygpOwogICAgICAgICAgd2FzbVRhYmxlID0gd2FzbUV4cG9ydHNbInMiXTsKICAgICAgICAgIGFkZE9uSW5pdCh3YXNtRXhwb3J0c1sicCJdKTsKICAgICAgICAgIHJlbW92ZVJ1bkRlcGVuZGVuY3koKTsKICAgICAgICAgIHJldHVybiB3YXNtRXhwb3J0czsKICAgICAgICB9CiAgICAgICAgYWRkUnVuRGVwZW5kZW5jeSgpOwogICAgICAgIGZ1bmN0aW9uIHJlY2VpdmVJbnN0YW50aWF0aW9uUmVzdWx0KHJlc3VsdCkgewogICAgICAgICAgcmVjZWl2ZUluc3RhbmNlKHJlc3VsdFsiaW5zdGFuY2UiXSk7CiAgICAgICAgfQogICAgICAgIGlmIChNb2R1bGUyWyJpbnN0YW50aWF0ZVdhc20iXSkgewogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIE1vZHVsZTJbImluc3RhbnRpYXRlV2FzbSJdKGluZm8sIHJlY2VpdmVJbnN0YW5jZSk7CiAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIGVycihgTW9kdWxlLmluc3RhbnRpYXRlV2FzbSBjYWxsYmFjayBmYWlsZWQgd2l0aCBlcnJvcjogJHtlfWApOwogICAgICAgICAgICByZWFkeVByb21pc2VSZWplY3QoZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGluc3RhbnRpYXRlQXN5bmMod2FzbUJpbmFyeSwgd2FzbUJpbmFyeUZpbGUsIGluZm8sIHJlY2VpdmVJbnN0YW50aWF0aW9uUmVzdWx0KS5jYXRjaChyZWFkeVByb21pc2VSZWplY3QpOwogICAgICAgIHJldHVybiB7fTsKICAgICAgfQogICAgICB2YXIgY2FsbFJ1bnRpbWVDYWxsYmFja3MgPSAoY2FsbGJhY2tzKSA9PiB7CiAgICAgICAgd2hpbGUgKGNhbGxiYWNrcy5sZW5ndGggPiAwKSB7CiAgICAgICAgICBjYWxsYmFja3Muc2hpZnQoKShNb2R1bGUyKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIE1vZHVsZTJbIm5vRXhpdFJ1bnRpbWUiXSB8fCB0cnVlOwogICAgICBmdW5jdGlvbiBFeGNlcHRpb25JbmZvKGV4Y1B0cikgewogICAgICAgIHRoaXMuZXhjUHRyID0gZXhjUHRyOwogICAgICAgIHRoaXMucHRyID0gZXhjUHRyIC0gMjQ7CiAgICAgICAgdGhpcy5zZXRfdHlwZSA9IGZ1bmN0aW9uKHR5cGUpIHsKICAgICAgICAgIEhFQVBVMzJbdGhpcy5wdHIgKyA0ID4+IDJdID0gdHlwZTsKICAgICAgICB9OwogICAgICAgIHRoaXMuZ2V0X3R5cGUgPSBmdW5jdGlvbigpIHsKICAgICAgICAgIHJldHVybiBIRUFQVTMyW3RoaXMucHRyICsgNCA+PiAyXTsKICAgICAgICB9OwogICAgICAgIHRoaXMuc2V0X2Rlc3RydWN0b3IgPSBmdW5jdGlvbihkZXN0cnVjdG9yKSB7CiAgICAgICAgICBIRUFQVTMyW3RoaXMucHRyICsgOCA+PiAyXSA9IGRlc3RydWN0b3I7CiAgICAgICAgfTsKICAgICAgICB0aGlzLmdldF9kZXN0cnVjdG9yID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICByZXR1cm4gSEVBUFUzMlt0aGlzLnB0ciArIDggPj4gMl07CiAgICAgICAgfTsKICAgICAgICB0aGlzLnNldF9jYXVnaHQgPSBmdW5jdGlvbihjYXVnaHQpIHsKICAgICAgICAgIGNhdWdodCA9IGNhdWdodCA/IDEgOiAwOwogICAgICAgICAgSEVBUDhbdGhpcy5wdHIgKyAxMiA+PiAwXSA9IGNhdWdodDsKICAgICAgICB9OwogICAgICAgIHRoaXMuZ2V0X2NhdWdodCA9IGZ1bmN0aW9uKCkgewogICAgICAgICAgcmV0dXJuIEhFQVA4W3RoaXMucHRyICsgMTIgPj4gMF0gIT0gMDsKICAgICAgICB9OwogICAgICAgIHRoaXMuc2V0X3JldGhyb3duID0gZnVuY3Rpb24ocmV0aHJvd24pIHsKICAgICAgICAgIHJldGhyb3duID0gcmV0aHJvd24gPyAxIDogMDsKICAgICAgICAgIEhFQVA4W3RoaXMucHRyICsgMTMgPj4gMF0gPSByZXRocm93bjsKICAgICAgICB9OwogICAgICAgIHRoaXMuZ2V0X3JldGhyb3duID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICByZXR1cm4gSEVBUDhbdGhpcy5wdHIgKyAxMyA+PiAwXSAhPSAwOwogICAgICAgIH07CiAgICAgICAgdGhpcy5pbml0ID0gZnVuY3Rpb24odHlwZSwgZGVzdHJ1Y3RvcikgewogICAgICAgICAgdGhpcy5zZXRfYWRqdXN0ZWRfcHRyKDApOwogICAgICAgICAgdGhpcy5zZXRfdHlwZSh0eXBlKTsKICAgICAgICAgIHRoaXMuc2V0X2Rlc3RydWN0b3IoZGVzdHJ1Y3Rvcik7CiAgICAgICAgfTsKICAgICAgICB0aGlzLnNldF9hZGp1c3RlZF9wdHIgPSBmdW5jdGlvbihhZGp1c3RlZFB0cikgewogICAgICAgICAgSEVBUFUzMlt0aGlzLnB0ciArIDE2ID4+IDJdID0gYWRqdXN0ZWRQdHI7CiAgICAgICAgfTsKICAgICAgICB0aGlzLmdldF9hZGp1c3RlZF9wdHIgPSBmdW5jdGlvbigpIHsKICAgICAgICAgIHJldHVybiBIRUFQVTMyW3RoaXMucHRyICsgMTYgPj4gMl07CiAgICAgICAgfTsKICAgICAgICB0aGlzLmdldF9leGNlcHRpb25fcHRyID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICB2YXIgaXNQb2ludGVyID0gX19fY3hhX2lzX3BvaW50ZXJfdHlwZSh0aGlzLmdldF90eXBlKCkpOwogICAgICAgICAgaWYgKGlzUG9pbnRlcikgewogICAgICAgICAgICByZXR1cm4gSEVBUFUzMlt0aGlzLmV4Y1B0ciA+PiAyXTsKICAgICAgICAgIH0KICAgICAgICAgIHZhciBhZGp1c3RlZCA9IHRoaXMuZ2V0X2FkanVzdGVkX3B0cigpOwogICAgICAgICAgaWYgKGFkanVzdGVkICE9PSAwKSByZXR1cm4gYWRqdXN0ZWQ7CiAgICAgICAgICByZXR1cm4gdGhpcy5leGNQdHI7CiAgICAgICAgfTsKICAgICAgfQogICAgICB2YXIgZXhjZXB0aW9uTGFzdCA9IDA7CiAgICAgIHZhciBfX19jeGFfdGhyb3cgPSAocHRyLCB0eXBlLCBkZXN0cnVjdG9yKSA9PiB7CiAgICAgICAgdmFyIGluZm8gPSBuZXcgRXhjZXB0aW9uSW5mbyhwdHIpOwogICAgICAgIGluZm8uaW5pdCh0eXBlLCBkZXN0cnVjdG9yKTsKICAgICAgICBleGNlcHRpb25MYXN0ID0gcHRyOwogICAgICAgIHRocm93IGV4Y2VwdGlvbkxhc3Q7CiAgICAgIH07CiAgICAgIHZhciBfX2VtYmluZF9yZWdpc3Rlcl9iaWdpbnQgPSAocHJpbWl0aXZlVHlwZSwgbmFtZSwgc2l6ZSwgbWluUmFuZ2UsIG1heFJhbmdlKSA9PiB7CiAgICAgIH07CiAgICAgIHZhciBlbWJpbmRfaW5pdF9jaGFyQ29kZXMgPSAoKSA9PiB7CiAgICAgICAgdmFyIGNvZGVzID0gbmV3IEFycmF5KDI1Nik7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkgewogICAgICAgICAgY29kZXNbaV0gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpOwogICAgICAgIH0KICAgICAgICBlbWJpbmRfY2hhckNvZGVzID0gY29kZXM7CiAgICAgIH07CiAgICAgIHZhciBlbWJpbmRfY2hhckNvZGVzOwogICAgICB2YXIgcmVhZExhdGluMVN0cmluZyA9IChwdHIpID0+IHsKICAgICAgICB2YXIgcmV0ID0gIiI7CiAgICAgICAgdmFyIGMgPSBwdHI7CiAgICAgICAgd2hpbGUgKEhFQVBVOFtjXSkgewogICAgICAgICAgcmV0ICs9IGVtYmluZF9jaGFyQ29kZXNbSEVBUFU4W2MrK11dOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9OwogICAgICB2YXIgYXdhaXRpbmdEZXBlbmRlbmNpZXMgPSB7fTsKICAgICAgdmFyIHJlZ2lzdGVyZWRUeXBlcyA9IHt9OwogICAgICB2YXIgdHlwZURlcGVuZGVuY2llcyA9IHt9OwogICAgICB2YXIgQmluZGluZ0Vycm9yOwogICAgICB2YXIgdGhyb3dCaW5kaW5nRXJyb3IgPSAobWVzc2FnZSkgPT4gewogICAgICAgIHRocm93IG5ldyBCaW5kaW5nRXJyb3IobWVzc2FnZSk7CiAgICAgIH07CiAgICAgIHZhciBJbnRlcm5hbEVycm9yOwogICAgICB2YXIgdGhyb3dJbnRlcm5hbEVycm9yID0gKG1lc3NhZ2UpID0+IHsKICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihtZXNzYWdlKTsKICAgICAgfTsKICAgICAgdmFyIHdoZW5EZXBlbmRlbnRUeXBlc0FyZVJlc29sdmVkID0gKG15VHlwZXMsIGRlcGVuZGVudFR5cGVzLCBnZXRUeXBlQ29udmVydGVycykgPT4gewogICAgICAgIG15VHlwZXMuZm9yRWFjaChmdW5jdGlvbih0eXBlKSB7CiAgICAgICAgICB0eXBlRGVwZW5kZW5jaWVzW3R5cGVdID0gZGVwZW5kZW50VHlwZXM7CiAgICAgICAgfSk7CiAgICAgICAgZnVuY3Rpb24gb25Db21wbGV0ZSh0eXBlQ29udmVydGVyczIpIHsKICAgICAgICAgIHZhciBteVR5cGVDb252ZXJ0ZXJzID0gZ2V0VHlwZUNvbnZlcnRlcnModHlwZUNvbnZlcnRlcnMyKTsKICAgICAgICAgIGlmIChteVR5cGVDb252ZXJ0ZXJzLmxlbmd0aCAhPT0gbXlUeXBlcy5sZW5ndGgpIHsKICAgICAgICAgICAgdGhyb3dJbnRlcm5hbEVycm9yKCJNaXNtYXRjaGVkIHR5cGUgY29udmVydGVyIGNvdW50Iik7CiAgICAgICAgICB9CiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG15VHlwZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVnaXN0ZXJUeXBlKG15VHlwZXNbaV0sIG15VHlwZUNvbnZlcnRlcnNbaV0pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB2YXIgdHlwZUNvbnZlcnRlcnMgPSBuZXcgQXJyYXkoZGVwZW5kZW50VHlwZXMubGVuZ3RoKTsKICAgICAgICB2YXIgdW5yZWdpc3RlcmVkVHlwZXMgPSBbXTsKICAgICAgICB2YXIgcmVnaXN0ZXJlZCA9IDA7CiAgICAgICAgZGVwZW5kZW50VHlwZXMuZm9yRWFjaCgoZHQsIGkpID0+IHsKICAgICAgICAgIGlmIChyZWdpc3RlcmVkVHlwZXMuaGFzT3duUHJvcGVydHkoZHQpKSB7CiAgICAgICAgICAgIHR5cGVDb252ZXJ0ZXJzW2ldID0gcmVnaXN0ZXJlZFR5cGVzW2R0XTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHVucmVnaXN0ZXJlZFR5cGVzLnB1c2goZHQpOwogICAgICAgICAgICBpZiAoIWF3YWl0aW5nRGVwZW5kZW5jaWVzLmhhc093blByb3BlcnR5KGR0KSkgewogICAgICAgICAgICAgIGF3YWl0aW5nRGVwZW5kZW5jaWVzW2R0XSA9IFtdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGF3YWl0aW5nRGVwZW5kZW5jaWVzW2R0XS5wdXNoKCgpID0+IHsKICAgICAgICAgICAgICB0eXBlQ29udmVydGVyc1tpXSA9IHJlZ2lzdGVyZWRUeXBlc1tkdF07CiAgICAgICAgICAgICAgKytyZWdpc3RlcmVkOwogICAgICAgICAgICAgIGlmIChyZWdpc3RlcmVkID09PSB1bnJlZ2lzdGVyZWRUeXBlcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIG9uQ29tcGxldGUodHlwZUNvbnZlcnRlcnMpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgaWYgKDAgPT09IHVucmVnaXN0ZXJlZFR5cGVzLmxlbmd0aCkgewogICAgICAgICAgb25Db21wbGV0ZSh0eXBlQ29udmVydGVycyk7CiAgICAgICAgfQogICAgICB9OwogICAgICBmdW5jdGlvbiBzaGFyZWRSZWdpc3RlclR5cGUocmF3VHlwZSwgcmVnaXN0ZXJlZEluc3RhbmNlLCBvcHRpb25zID0ge30pIHsKICAgICAgICB2YXIgbmFtZSA9IHJlZ2lzdGVyZWRJbnN0YW5jZS5uYW1lOwogICAgICAgIGlmICghcmF3VHlwZSkgewogICAgICAgICAgdGhyb3dCaW5kaW5nRXJyb3IoYHR5cGUgIiR7bmFtZX0iIG11c3QgaGF2ZSBhIHBvc2l0aXZlIGludGVnZXIgdHlwZWlkIHBvaW50ZXJgKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlZ2lzdGVyZWRUeXBlcy5oYXNPd25Qcm9wZXJ0eShyYXdUeXBlKSkgewogICAgICAgICAgaWYgKG9wdGlvbnMuaWdub3JlRHVwbGljYXRlUmVnaXN0cmF0aW9ucykgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvd0JpbmRpbmdFcnJvcihgQ2Fubm90IHJlZ2lzdGVyIHR5cGUgJyR7bmFtZX0nIHR3aWNlYCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJlZ2lzdGVyZWRUeXBlc1tyYXdUeXBlXSA9IHJlZ2lzdGVyZWRJbnN0YW5jZTsKICAgICAgICBkZWxldGUgdHlwZURlcGVuZGVuY2llc1tyYXdUeXBlXTsKICAgICAgICBpZiAoYXdhaXRpbmdEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocmF3VHlwZSkpIHsKICAgICAgICAgIHZhciBjYWxsYmFja3MgPSBhd2FpdGluZ0RlcGVuZGVuY2llc1tyYXdUeXBlXTsKICAgICAgICAgIGRlbGV0ZSBhd2FpdGluZ0RlcGVuZGVuY2llc1tyYXdUeXBlXTsKICAgICAgICAgIGNhbGxiYWNrcy5mb3JFYWNoKChjYikgPT4gY2IoKSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZ1bmN0aW9uIHJlZ2lzdGVyVHlwZShyYXdUeXBlLCByZWdpc3RlcmVkSW5zdGFuY2UsIG9wdGlvbnMgPSB7fSkgewogICAgICAgIGlmICghKCJhcmdQYWNrQWR2YW5jZSIgaW4gcmVnaXN0ZXJlZEluc3RhbmNlKSkgewogICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigicmVnaXN0ZXJUeXBlIHJlZ2lzdGVyZWRJbnN0YW5jZSByZXF1aXJlcyBhcmdQYWNrQWR2YW5jZSIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2hhcmVkUmVnaXN0ZXJUeXBlKHJhd1R5cGUsIHJlZ2lzdGVyZWRJbnN0YW5jZSwgb3B0aW9ucyk7CiAgICAgIH0KICAgICAgdmFyIEdlbmVyaWNXaXJlVHlwZVNpemUgPSA4OwogICAgICB2YXIgX19lbWJpbmRfcmVnaXN0ZXJfYm9vbCA9IChyYXdUeXBlLCBuYW1lLCB0cnVlVmFsdWUsIGZhbHNlVmFsdWUpID0+IHsKICAgICAgICBuYW1lID0gcmVhZExhdGluMVN0cmluZyhuYW1lKTsKICAgICAgICByZWdpc3RlclR5cGUocmF3VHlwZSwgeyBuYW1lLCAiZnJvbVdpcmVUeXBlIjogZnVuY3Rpb24od3QpIHsKICAgICAgICAgIHJldHVybiAhIXd0OwogICAgICAgIH0sICJ0b1dpcmVUeXBlIjogZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsIG8pIHsKICAgICAgICAgIHJldHVybiBvID8gdHJ1ZVZhbHVlIDogZmFsc2VWYWx1ZTsKICAgICAgICB9LCAiYXJnUGFja0FkdmFuY2UiOiBHZW5lcmljV2lyZVR5cGVTaXplLCAicmVhZFZhbHVlRnJvbVBvaW50ZXIiOiBmdW5jdGlvbihwb2ludGVyKSB7CiAgICAgICAgICByZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUFU4W3BvaW50ZXJdKTsKICAgICAgICB9LCBkZXN0cnVjdG9yRnVuY3Rpb246IG51bGwgfSk7CiAgICAgIH07CiAgICAgIGZ1bmN0aW9uIGhhbmRsZUFsbG9jYXRvckluaXQoKSB7CiAgICAgICAgT2JqZWN0LmFzc2lnbihIYW5kbGVBbGxvY2F0b3IucHJvdG90eXBlLCB7IGdldChpZCkgewogICAgICAgICAgcmV0dXJuIHRoaXMuYWxsb2NhdGVkW2lkXTsKICAgICAgICB9LCBoYXMoaWQpIHsKICAgICAgICAgIHJldHVybiB0aGlzLmFsbG9jYXRlZFtpZF0gIT09IHZvaWQgMDsKICAgICAgICB9LCBhbGxvY2F0ZShoYW5kbGUpIHsKICAgICAgICAgIHZhciBpZCA9IHRoaXMuZnJlZWxpc3QucG9wKCkgfHwgdGhpcy5hbGxvY2F0ZWQubGVuZ3RoOwogICAgICAgICAgdGhpcy5hbGxvY2F0ZWRbaWRdID0gaGFuZGxlOwogICAgICAgICAgcmV0dXJuIGlkOwogICAgICAgIH0sIGZyZWUoaWQpIHsKICAgICAgICAgIHRoaXMuYWxsb2NhdGVkW2lkXSA9IHZvaWQgMDsKICAgICAgICAgIHRoaXMuZnJlZWxpc3QucHVzaChpZCk7CiAgICAgICAgfSB9KTsKICAgICAgfQogICAgICBmdW5jdGlvbiBIYW5kbGVBbGxvY2F0b3IoKSB7CiAgICAgICAgdGhpcy5hbGxvY2F0ZWQgPSBbdm9pZCAwXTsKICAgICAgICB0aGlzLmZyZWVsaXN0ID0gW107CiAgICAgIH0KICAgICAgdmFyIGVtdmFsX2hhbmRsZXMgPSBuZXcgSGFuZGxlQWxsb2NhdG9yKCk7CiAgICAgIHZhciBfX2VtdmFsX2RlY3JlZiA9IChoYW5kbGUpID0+IHsKICAgICAgICBpZiAoaGFuZGxlID49IGVtdmFsX2hhbmRsZXMucmVzZXJ2ZWQgJiYgMCA9PT0gLS1lbXZhbF9oYW5kbGVzLmdldChoYW5kbGUpLnJlZmNvdW50KSB7CiAgICAgICAgICBlbXZhbF9oYW5kbGVzLmZyZWUoaGFuZGxlKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHZhciBjb3VudF9lbXZhbF9oYW5kbGVzID0gKCkgPT4gewogICAgICAgIHZhciBjb3VudCA9IDA7CiAgICAgICAgZm9yICh2YXIgaSA9IGVtdmFsX2hhbmRsZXMucmVzZXJ2ZWQ7IGkgPCBlbXZhbF9oYW5kbGVzLmFsbG9jYXRlZC5sZW5ndGg7ICsraSkgewogICAgICAgICAgaWYgKGVtdmFsX2hhbmRsZXMuYWxsb2NhdGVkW2ldICE9PSB2b2lkIDApIHsKICAgICAgICAgICAgKytjb3VudDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgICB9OwogICAgICB2YXIgaW5pdF9lbXZhbCA9ICgpID0+IHsKICAgICAgICBlbXZhbF9oYW5kbGVzLmFsbG9jYXRlZC5wdXNoKHsgdmFsdWU6IHZvaWQgMCB9LCB7IHZhbHVlOiBudWxsIH0sIHsgdmFsdWU6IHRydWUgfSwgeyB2YWx1ZTogZmFsc2UgfSk7CiAgICAgICAgZW12YWxfaGFuZGxlcy5yZXNlcnZlZCA9IGVtdmFsX2hhbmRsZXMuYWxsb2NhdGVkLmxlbmd0aDsKICAgICAgICBNb2R1bGUyWyJjb3VudF9lbXZhbF9oYW5kbGVzIl0gPSBjb3VudF9lbXZhbF9oYW5kbGVzOwogICAgICB9OwogICAgICB2YXIgRW12YWwgPSB7IHRvVmFsdWU6IChoYW5kbGUpID0+IHsKICAgICAgICBpZiAoIWhhbmRsZSkgewogICAgICAgICAgdGhyb3dCaW5kaW5nRXJyb3IoIkNhbm5vdCB1c2UgZGVsZXRlZCB2YWwuIGhhbmRsZSA9ICIgKyBoYW5kbGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZW12YWxfaGFuZGxlcy5nZXQoaGFuZGxlKS52YWx1ZTsKICAgICAgfSwgdG9IYW5kbGU6ICh2YWx1ZSkgPT4gewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2Ugdm9pZCAwOgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgIGNhc2UgbnVsbDoKICAgICAgICAgICAgcmV0dXJuIDI7CiAgICAgICAgICBjYXNlIHRydWU6CiAgICAgICAgICAgIHJldHVybiAzOwogICAgICAgICAgY2FzZSBmYWxzZToKICAgICAgICAgICAgcmV0dXJuIDQ7CiAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgIHJldHVybiBlbXZhbF9oYW5kbGVzLmFsbG9jYXRlKHsgcmVmY291bnQ6IDEsIHZhbHVlIH0pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSB9OwogICAgICBmdW5jdGlvbiBzaW1wbGVSZWFkVmFsdWVGcm9tUG9pbnRlcihwb2ludGVyKSB7CiAgICAgICAgcmV0dXJuIHRoaXNbImZyb21XaXJlVHlwZSJdKEhFQVAzMltwb2ludGVyID4+IDJdKTsKICAgICAgfQogICAgICB2YXIgX19lbWJpbmRfcmVnaXN0ZXJfZW12YWwgPSAocmF3VHlwZSwgbmFtZSkgPT4gewogICAgICAgIG5hbWUgPSByZWFkTGF0aW4xU3RyaW5nKG5hbWUpOwogICAgICAgIHJlZ2lzdGVyVHlwZShyYXdUeXBlLCB7IG5hbWUsICJmcm9tV2lyZVR5cGUiOiAoaGFuZGxlKSA9PiB7CiAgICAgICAgICB2YXIgcnYgPSBFbXZhbC50b1ZhbHVlKGhhbmRsZSk7CiAgICAgICAgICBfX2VtdmFsX2RlY3JlZihoYW5kbGUpOwogICAgICAgICAgcmV0dXJuIHJ2OwogICAgICAgIH0sICJ0b1dpcmVUeXBlIjogKGRlc3RydWN0b3JzLCB2YWx1ZSkgPT4gRW12YWwudG9IYW5kbGUodmFsdWUpLCAiYXJnUGFja0FkdmFuY2UiOiBHZW5lcmljV2lyZVR5cGVTaXplLCAicmVhZFZhbHVlRnJvbVBvaW50ZXIiOiBzaW1wbGVSZWFkVmFsdWVGcm9tUG9pbnRlciwgZGVzdHJ1Y3RvckZ1bmN0aW9uOiBudWxsIH0pOwogICAgICB9OwogICAgICB2YXIgZmxvYXRSZWFkVmFsdWVGcm9tUG9pbnRlciA9IChuYW1lLCB3aWR0aCkgPT4gewogICAgICAgIHN3aXRjaCAod2lkdGgpIHsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHBvaW50ZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUEYzMltwb2ludGVyID4+IDJdKTsKICAgICAgICAgICAgfTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHBvaW50ZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUEY2NFtwb2ludGVyID4+IDNdKTsKICAgICAgICAgICAgfTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGludmFsaWQgZmxvYXQgd2lkdGggKCR7d2lkdGh9KTogJHtuYW1lfWApOwogICAgICAgIH0KICAgICAgfTsKICAgICAgdmFyIF9fZW1iaW5kX3JlZ2lzdGVyX2Zsb2F0ID0gKHJhd1R5cGUsIG5hbWUsIHNpemUpID0+IHsKICAgICAgICBuYW1lID0gcmVhZExhdGluMVN0cmluZyhuYW1lKTsKICAgICAgICByZWdpc3RlclR5cGUocmF3VHlwZSwgeyBuYW1lLCAiZnJvbVdpcmVUeXBlIjogKHZhbHVlKSA9PiB2YWx1ZSwgInRvV2lyZVR5cGUiOiAoZGVzdHJ1Y3RvcnMsIHZhbHVlKSA9PiB2YWx1ZSwgImFyZ1BhY2tBZHZhbmNlIjogR2VuZXJpY1dpcmVUeXBlU2l6ZSwgInJlYWRWYWx1ZUZyb21Qb2ludGVyIjogZmxvYXRSZWFkVmFsdWVGcm9tUG9pbnRlcihuYW1lLCBzaXplKSwgZGVzdHJ1Y3RvckZ1bmN0aW9uOiBudWxsIH0pOwogICAgICB9OwogICAgICB2YXIgY3JlYXRlTmFtZWRGdW5jdGlvbiA9IChuYW1lLCBib2R5KSA9PiBPYmplY3QuZGVmaW5lUHJvcGVydHkoYm9keSwgIm5hbWUiLCB7IHZhbHVlOiBuYW1lIH0pOwogICAgICB2YXIgcnVuRGVzdHJ1Y3RvcnMgPSAoZGVzdHJ1Y3RvcnMpID0+IHsKICAgICAgICB3aGlsZSAoZGVzdHJ1Y3RvcnMubGVuZ3RoKSB7CiAgICAgICAgICB2YXIgcHRyID0gZGVzdHJ1Y3RvcnMucG9wKCk7CiAgICAgICAgICB2YXIgZGVsID0gZGVzdHJ1Y3RvcnMucG9wKCk7CiAgICAgICAgICBkZWwocHRyKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGZ1bmN0aW9uIG5ld0Z1bmMoY29uc3RydWN0b3IsIGFyZ3VtZW50TGlzdCkgewogICAgICAgIGlmICghKGNvbnN0cnVjdG9yIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7CiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBuZXdfIGNhbGxlZCB3aXRoIGNvbnN0cnVjdG9yIHR5cGUgJHt0eXBlb2YgY29uc3RydWN0b3J9IHdoaWNoIGlzIG5vdCBhIGZ1bmN0aW9uYCk7CiAgICAgICAgfQogICAgICAgIHZhciBkdW1teSA9IGNyZWF0ZU5hbWVkRnVuY3Rpb24oY29uc3RydWN0b3IubmFtZSB8fCAidW5rbm93bkZ1bmN0aW9uTmFtZSIsIGZ1bmN0aW9uKCkgewogICAgICAgIH0pOwogICAgICAgIGR1bW15LnByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICAgICAgICB2YXIgb2JqID0gbmV3IGR1bW15KCk7CiAgICAgICAgdmFyIHIgPSBjb25zdHJ1Y3Rvci5hcHBseShvYmosIGFyZ3VtZW50TGlzdCk7CiAgICAgICAgcmV0dXJuIHIgaW5zdGFuY2VvZiBPYmplY3QgPyByIDogb2JqOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIGNyYWZ0SW52b2tlckZ1bmN0aW9uKGh1bWFuTmFtZSwgYXJnVHlwZXMsIGNsYXNzVHlwZSwgY3BwSW52b2tlckZ1bmMsIGNwcFRhcmdldEZ1bmMsIGlzQXN5bmMpIHsKICAgICAgICB2YXIgYXJnQ291bnQgPSBhcmdUeXBlcy5sZW5ndGg7CiAgICAgICAgaWYgKGFyZ0NvdW50IDwgMikgewogICAgICAgICAgdGhyb3dCaW5kaW5nRXJyb3IoImFyZ1R5cGVzIGFycmF5IHNpemUgbWlzbWF0Y2ghIE11c3QgYXQgbGVhc3QgZ2V0IHJldHVybiB2YWx1ZSBhbmQgJ3RoaXMnIHR5cGVzISIpOwogICAgICAgIH0KICAgICAgICB2YXIgaXNDbGFzc01ldGhvZEZ1bmMgPSBhcmdUeXBlc1sxXSAhPT0gbnVsbCAmJiBjbGFzc1R5cGUgIT09IG51bGw7CiAgICAgICAgdmFyIG5lZWRzRGVzdHJ1Y3RvclN0YWNrID0gZmFsc2U7CiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmdUeXBlcy5sZW5ndGg7ICsraSkgewogICAgICAgICAgaWYgKGFyZ1R5cGVzW2ldICE9PSBudWxsICYmIGFyZ1R5cGVzW2ldLmRlc3RydWN0b3JGdW5jdGlvbiA9PT0gdm9pZCAwKSB7CiAgICAgICAgICAgIG5lZWRzRGVzdHJ1Y3RvclN0YWNrID0gdHJ1ZTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHZhciByZXR1cm5zID0gYXJnVHlwZXNbMF0ubmFtZSAhPT0gInZvaWQiOwogICAgICAgIHZhciBhcmdzTGlzdCA9ICIiOwogICAgICAgIHZhciBhcmdzTGlzdFdpcmVkID0gIiI7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdDb3VudCAtIDI7ICsraSkgewogICAgICAgICAgYXJnc0xpc3QgKz0gKGkgIT09IDAgPyAiLCAiIDogIiIpICsgImFyZyIgKyBpOwogICAgICAgICAgYXJnc0xpc3RXaXJlZCArPSAoaSAhPT0gMCA/ICIsICIgOiAiIikgKyAiYXJnIiArIGkgKyAiV2lyZWQiOwogICAgICAgIH0KICAgICAgICB2YXIgaW52b2tlckZuQm9keSA9IGAKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCR7YXJnc0xpc3R9KSB7CiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggIT09ICR7YXJnQ291bnQgLSAyfSkgewogICAgICAgICAgdGhyb3dCaW5kaW5nRXJyb3IoJ2Z1bmN0aW9uICR7aHVtYW5OYW1lfSBjYWxsZWQgd2l0aCAnICsgYXJndW1lbnRzLmxlbmd0aCArICcgYXJndW1lbnRzLCBleHBlY3RlZCAke2FyZ0NvdW50IC0gMn0nKTsKICAgICAgICB9YDsKICAgICAgICBpZiAobmVlZHNEZXN0cnVjdG9yU3RhY2spIHsKICAgICAgICAgIGludm9rZXJGbkJvZHkgKz0gInZhciBkZXN0cnVjdG9ycyA9IFtdO1xuIjsKICAgICAgICB9CiAgICAgICAgdmFyIGR0b3JTdGFjayA9IG5lZWRzRGVzdHJ1Y3RvclN0YWNrID8gImRlc3RydWN0b3JzIiA6ICJudWxsIjsKICAgICAgICB2YXIgYXJnczEgPSBbInRocm93QmluZGluZ0Vycm9yIiwgImludm9rZXIiLCAiZm4iLCAicnVuRGVzdHJ1Y3RvcnMiLCAicmV0VHlwZSIsICJjbGFzc1BhcmFtIl07CiAgICAgICAgdmFyIGFyZ3MyID0gW3Rocm93QmluZGluZ0Vycm9yLCBjcHBJbnZva2VyRnVuYywgY3BwVGFyZ2V0RnVuYywgcnVuRGVzdHJ1Y3RvcnMsIGFyZ1R5cGVzWzBdLCBhcmdUeXBlc1sxXV07CiAgICAgICAgaWYgKGlzQ2xhc3NNZXRob2RGdW5jKSB7CiAgICAgICAgICBpbnZva2VyRm5Cb2R5ICs9ICJ2YXIgdGhpc1dpcmVkID0gY2xhc3NQYXJhbS50b1dpcmVUeXBlKCIgKyBkdG9yU3RhY2sgKyAiLCB0aGlzKTtcbiI7CiAgICAgICAgfQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJnQ291bnQgLSAyOyArK2kpIHsKICAgICAgICAgIGludm9rZXJGbkJvZHkgKz0gInZhciBhcmciICsgaSArICJXaXJlZCA9IGFyZ1R5cGUiICsgaSArICIudG9XaXJlVHlwZSgiICsgZHRvclN0YWNrICsgIiwgYXJnIiArIGkgKyAiKTsgLy8gIiArIGFyZ1R5cGVzW2kgKyAyXS5uYW1lICsgIlxuIjsKICAgICAgICAgIGFyZ3MxLnB1c2goImFyZ1R5cGUiICsgaSk7CiAgICAgICAgICBhcmdzMi5wdXNoKGFyZ1R5cGVzW2kgKyAyXSk7CiAgICAgICAgfQogICAgICAgIGlmIChpc0NsYXNzTWV0aG9kRnVuYykgewogICAgICAgICAgYXJnc0xpc3RXaXJlZCA9ICJ0aGlzV2lyZWQiICsgKGFyZ3NMaXN0V2lyZWQubGVuZ3RoID4gMCA/ICIsICIgOiAiIikgKyBhcmdzTGlzdFdpcmVkOwogICAgICAgIH0KICAgICAgICBpbnZva2VyRm5Cb2R5ICs9IChyZXR1cm5zIHx8IGlzQXN5bmMgPyAidmFyIHJ2ID0gIiA6ICIiKSArICJpbnZva2VyKGZuIiArIChhcmdzTGlzdFdpcmVkLmxlbmd0aCA+IDAgPyAiLCAiIDogIiIpICsgYXJnc0xpc3RXaXJlZCArICIpO1xuIjsKICAgICAgICBpZiAobmVlZHNEZXN0cnVjdG9yU3RhY2spIHsKICAgICAgICAgIGludm9rZXJGbkJvZHkgKz0gInJ1bkRlc3RydWN0b3JzKGRlc3RydWN0b3JzKTtcbiI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvciAodmFyIGkgPSBpc0NsYXNzTWV0aG9kRnVuYyA/IDEgOiAyOyBpIDwgYXJnVHlwZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgdmFyIHBhcmFtTmFtZSA9IGkgPT09IDEgPyAidGhpc1dpcmVkIiA6ICJhcmciICsgKGkgLSAyKSArICJXaXJlZCI7CiAgICAgICAgICAgIGlmIChhcmdUeXBlc1tpXS5kZXN0cnVjdG9yRnVuY3Rpb24gIT09IG51bGwpIHsKICAgICAgICAgICAgICBpbnZva2VyRm5Cb2R5ICs9IHBhcmFtTmFtZSArICJfZHRvcigiICsgcGFyYW1OYW1lICsgIik7IC8vICIgKyBhcmdUeXBlc1tpXS5uYW1lICsgIlxuIjsKICAgICAgICAgICAgICBhcmdzMS5wdXNoKHBhcmFtTmFtZSArICJfZHRvciIpOwogICAgICAgICAgICAgIGFyZ3MyLnB1c2goYXJnVHlwZXNbaV0uZGVzdHJ1Y3RvckZ1bmN0aW9uKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmV0dXJucykgewogICAgICAgICAgaW52b2tlckZuQm9keSArPSAidmFyIHJldCA9IHJldFR5cGUuZnJvbVdpcmVUeXBlKHJ2KTtcbnJldHVybiByZXQ7XG4iOwogICAgICAgIH0KICAgICAgICBpbnZva2VyRm5Cb2R5ICs9ICJ9XG4iOwogICAgICAgIGFyZ3MxLnB1c2goaW52b2tlckZuQm9keSk7CiAgICAgICAgdmFyIGludm9rZXJGbiA9IG5ld0Z1bmMoRnVuY3Rpb24sIGFyZ3MxKS5hcHBseShudWxsLCBhcmdzMik7CiAgICAgICAgcmV0dXJuIGNyZWF0ZU5hbWVkRnVuY3Rpb24oaHVtYW5OYW1lLCBpbnZva2VyRm4pOwogICAgICB9CiAgICAgIHZhciBlbnN1cmVPdmVybG9hZFRhYmxlID0gKHByb3RvLCBtZXRob2ROYW1lLCBodW1hbk5hbWUpID0+IHsKICAgICAgICBpZiAodm9pZCAwID09PSBwcm90b1ttZXRob2ROYW1lXS5vdmVybG9hZFRhYmxlKSB7CiAgICAgICAgICB2YXIgcHJldkZ1bmMgPSBwcm90b1ttZXRob2ROYW1lXTsKICAgICAgICAgIHByb3RvW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICghcHJvdG9bbWV0aG9kTmFtZV0ub3ZlcmxvYWRUYWJsZS5oYXNPd25Qcm9wZXJ0eShhcmd1bWVudHMubGVuZ3RoKSkgewogICAgICAgICAgICAgIHRocm93QmluZGluZ0Vycm9yKGBGdW5jdGlvbiAnJHtodW1hbk5hbWV9JyBjYWxsZWQgd2l0aCBhbiBpbnZhbGlkIG51bWJlciBvZiBhcmd1bWVudHMgKCR7YXJndW1lbnRzLmxlbmd0aH0pIC0gZXhwZWN0cyBvbmUgb2YgKCR7cHJvdG9bbWV0aG9kTmFtZV0ub3ZlcmxvYWRUYWJsZX0pIWApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBwcm90b1ttZXRob2ROYW1lXS5vdmVybG9hZFRhYmxlW2FyZ3VtZW50cy5sZW5ndGhdLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICB9OwogICAgICAgICAgcHJvdG9bbWV0aG9kTmFtZV0ub3ZlcmxvYWRUYWJsZSA9IFtdOwogICAgICAgICAgcHJvdG9bbWV0aG9kTmFtZV0ub3ZlcmxvYWRUYWJsZVtwcmV2RnVuYy5hcmdDb3VudF0gPSBwcmV2RnVuYzsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHZhciBleHBvc2VQdWJsaWNTeW1ib2wgPSAobmFtZSwgdmFsdWUsIG51bUFyZ3VtZW50cykgPT4gewogICAgICAgIGlmIChNb2R1bGUyLmhhc093blByb3BlcnR5KG5hbWUpKSB7CiAgICAgICAgICBpZiAodm9pZCAwID09PSBudW1Bcmd1bWVudHMgfHwgdm9pZCAwICE9PSBNb2R1bGUyW25hbWVdLm92ZXJsb2FkVGFibGUgJiYgdm9pZCAwICE9PSBNb2R1bGUyW25hbWVdLm92ZXJsb2FkVGFibGVbbnVtQXJndW1lbnRzXSkgewogICAgICAgICAgICB0aHJvd0JpbmRpbmdFcnJvcihgQ2Fubm90IHJlZ2lzdGVyIHB1YmxpYyBuYW1lICcke25hbWV9JyB0d2ljZWApOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlT3ZlcmxvYWRUYWJsZShNb2R1bGUyLCBuYW1lLCBuYW1lKTsKICAgICAgICAgIGlmIChNb2R1bGUyLmhhc093blByb3BlcnR5KG51bUFyZ3VtZW50cykpIHsKICAgICAgICAgICAgdGhyb3dCaW5kaW5nRXJyb3IoYENhbm5vdCByZWdpc3RlciBtdWx0aXBsZSBvdmVybG9hZHMgb2YgYSBmdW5jdGlvbiB3aXRoIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgKCR7bnVtQXJndW1lbnRzfSkhYCk7CiAgICAgICAgICB9CiAgICAgICAgICBNb2R1bGUyW25hbWVdLm92ZXJsb2FkVGFibGVbbnVtQXJndW1lbnRzXSA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBNb2R1bGUyW25hbWVdID0gdmFsdWU7CiAgICAgICAgICBpZiAodm9pZCAwICE9PSBudW1Bcmd1bWVudHMpIHsKICAgICAgICAgICAgTW9kdWxlMltuYW1lXS5udW1Bcmd1bWVudHMgPSBudW1Bcmd1bWVudHM7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9OwogICAgICB2YXIgaGVhcDMyVmVjdG9yVG9BcnJheSA9IChjb3VudCwgZmlyc3RFbGVtZW50KSA9PiB7CiAgICAgICAgdmFyIGFycmF5ID0gW107CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CiAgICAgICAgICBhcnJheS5wdXNoKEhFQVBVMzJbZmlyc3RFbGVtZW50ICsgaSAqIDQgPj4gMl0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYXJyYXk7CiAgICAgIH07CiAgICAgIHZhciByZXBsYWNlUHVibGljU3ltYm9sID0gKG5hbWUsIHZhbHVlLCBudW1Bcmd1bWVudHMpID0+IHsKICAgICAgICBpZiAoIU1vZHVsZTIuaGFzT3duUHJvcGVydHkobmFtZSkpIHsKICAgICAgICAgIHRocm93SW50ZXJuYWxFcnJvcigiUmVwbGFjaW5nIG5vbmV4aXN0YW50IHB1YmxpYyBzeW1ib2wiKTsKICAgICAgICB9CiAgICAgICAgaWYgKHZvaWQgMCAhPT0gTW9kdWxlMltuYW1lXS5vdmVybG9hZFRhYmxlICYmIHZvaWQgMCAhPT0gbnVtQXJndW1lbnRzKSB7CiAgICAgICAgICBNb2R1bGUyW25hbWVdLm92ZXJsb2FkVGFibGVbbnVtQXJndW1lbnRzXSA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBNb2R1bGUyW25hbWVdID0gdmFsdWU7CiAgICAgICAgICBNb2R1bGUyW25hbWVdLmFyZ0NvdW50ID0gbnVtQXJndW1lbnRzOwogICAgICAgIH0KICAgICAgfTsKICAgICAgdmFyIGR5bkNhbGxMZWdhY3kgPSAoc2lnLCBwdHIsIGFyZ3MpID0+IHsKICAgICAgICB2YXIgZiA9IE1vZHVsZTJbImR5bkNhbGxfIiArIHNpZ107CiAgICAgICAgcmV0dXJuIGFyZ3MgJiYgYXJncy5sZW5ndGggPyBmLmFwcGx5KG51bGwsIFtwdHJdLmNvbmNhdChhcmdzKSkgOiBmLmNhbGwobnVsbCwgcHRyKTsKICAgICAgfTsKICAgICAgdmFyIHdhc21UYWJsZU1pcnJvciA9IFtdOwogICAgICB2YXIgd2FzbVRhYmxlOwogICAgICB2YXIgZ2V0V2FzbVRhYmxlRW50cnkgPSAoZnVuY1B0cikgPT4gewogICAgICAgIHZhciBmdW5jID0gd2FzbVRhYmxlTWlycm9yW2Z1bmNQdHJdOwogICAgICAgIGlmICghZnVuYykgewogICAgICAgICAgaWYgKGZ1bmNQdHIgPj0gd2FzbVRhYmxlTWlycm9yLmxlbmd0aCkgd2FzbVRhYmxlTWlycm9yLmxlbmd0aCA9IGZ1bmNQdHIgKyAxOwogICAgICAgICAgd2FzbVRhYmxlTWlycm9yW2Z1bmNQdHJdID0gZnVuYyA9IHdhc21UYWJsZS5nZXQoZnVuY1B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmdW5jOwogICAgICB9OwogICAgICB2YXIgZHluQ2FsbCA9IChzaWcsIHB0ciwgYXJncykgPT4gewogICAgICAgIGlmIChzaWcuaW5jbHVkZXMoImoiKSkgewogICAgICAgICAgcmV0dXJuIGR5bkNhbGxMZWdhY3koc2lnLCBwdHIsIGFyZ3MpOwogICAgICAgIH0KICAgICAgICB2YXIgcnRuID0gZ2V0V2FzbVRhYmxlRW50cnkocHRyKS5hcHBseShudWxsLCBhcmdzKTsKICAgICAgICByZXR1cm4gcnRuOwogICAgICB9OwogICAgICB2YXIgZ2V0RHluQ2FsbGVyID0gKHNpZywgcHRyKSA9PiB7CiAgICAgICAgdmFyIGFyZ0NhY2hlID0gW107CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICAgICAgYXJnQ2FjaGUubGVuZ3RoID0gMDsKICAgICAgICAgIE9iamVjdC5hc3NpZ24oYXJnQ2FjaGUsIGFyZ3VtZW50cyk7CiAgICAgICAgICByZXR1cm4gZHluQ2FsbChzaWcsIHB0ciwgYXJnQ2FjaGUpOwogICAgICAgIH07CiAgICAgIH07CiAgICAgIHZhciBlbWJpbmRfX3JlcXVpcmVGdW5jdGlvbiA9IChzaWduYXR1cmUsIHJhd0Z1bmN0aW9uKSA9PiB7CiAgICAgICAgc2lnbmF0dXJlID0gcmVhZExhdGluMVN0cmluZyhzaWduYXR1cmUpOwogICAgICAgIGZ1bmN0aW9uIG1ha2VEeW5DYWxsZXIoKSB7CiAgICAgICAgICBpZiAoc2lnbmF0dXJlLmluY2x1ZGVzKCJqIikpIHsKICAgICAgICAgICAgcmV0dXJuIGdldER5bkNhbGxlcihzaWduYXR1cmUsIHJhd0Z1bmN0aW9uKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBnZXRXYXNtVGFibGVFbnRyeShyYXdGdW5jdGlvbik7CiAgICAgICAgfQogICAgICAgIHZhciBmcCA9IG1ha2VEeW5DYWxsZXIoKTsKICAgICAgICBpZiAodHlwZW9mIGZwICE9ICJmdW5jdGlvbiIpIHsKICAgICAgICAgIHRocm93QmluZGluZ0Vycm9yKGB1bmtub3duIGZ1bmN0aW9uIHBvaW50ZXIgd2l0aCBzaWduYXR1cmUgJHtzaWduYXR1cmV9OiAke3Jhd0Z1bmN0aW9ufWApOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZnA7CiAgICAgIH07CiAgICAgIHZhciBleHRlbmRFcnJvciA9IChiYXNlRXJyb3JUeXBlLCBlcnJvck5hbWUpID0+IHsKICAgICAgICB2YXIgZXJyb3JDbGFzcyA9IGNyZWF0ZU5hbWVkRnVuY3Rpb24oZXJyb3JOYW1lLCBmdW5jdGlvbihtZXNzYWdlKSB7CiAgICAgICAgICB0aGlzLm5hbWUgPSBlcnJvck5hbWU7CiAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlOwogICAgICAgICAgdmFyIHN0YWNrID0gbmV3IEVycm9yKG1lc3NhZ2UpLnN0YWNrOwogICAgICAgICAgaWYgKHN0YWNrICE9PSB2b2lkIDApIHsKICAgICAgICAgICAgdGhpcy5zdGFjayA9IHRoaXMudG9TdHJpbmcoKSArICJcbiIgKyBzdGFjay5yZXBsYWNlKC9eRXJyb3IoOlteXG5dKik/XG4vLCAiIik7CiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgZXJyb3JDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKGJhc2VFcnJvclR5cGUucHJvdG90eXBlKTsKICAgICAgICBlcnJvckNsYXNzLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGVycm9yQ2xhc3M7CiAgICAgICAgZXJyb3JDbGFzcy5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHsKICAgICAgICAgIGlmICh0aGlzLm1lc3NhZ2UgPT09IHZvaWQgMCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5uYW1lOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGAke3RoaXMubmFtZX06ICR7dGhpcy5tZXNzYWdlfWA7CiAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gZXJyb3JDbGFzczsKICAgICAgfTsKICAgICAgdmFyIFVuYm91bmRUeXBlRXJyb3I7CiAgICAgIHZhciBnZXRUeXBlTmFtZSA9ICh0eXBlKSA9PiB7CiAgICAgICAgdmFyIHB0ciA9IF9fX2dldFR5cGVOYW1lKHR5cGUpOwogICAgICAgIHZhciBydiA9IHJlYWRMYXRpbjFTdHJpbmcocHRyKTsKICAgICAgICBfZnJlZShwdHIpOwogICAgICAgIHJldHVybiBydjsKICAgICAgfTsKICAgICAgdmFyIHRocm93VW5ib3VuZFR5cGVFcnJvciA9IChtZXNzYWdlLCB0eXBlcykgPT4gewogICAgICAgIHZhciB1bmJvdW5kVHlwZXMgPSBbXTsKICAgICAgICB2YXIgc2VlbiA9IHt9OwogICAgICAgIGZ1bmN0aW9uIHZpc2l0KHR5cGUpIHsKICAgICAgICAgIGlmIChzZWVuW3R5cGVdKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChyZWdpc3RlcmVkVHlwZXNbdHlwZV0pIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHR5cGVEZXBlbmRlbmNpZXNbdHlwZV0pIHsKICAgICAgICAgICAgdHlwZURlcGVuZGVuY2llc1t0eXBlXS5mb3JFYWNoKHZpc2l0KTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgdW5ib3VuZFR5cGVzLnB1c2godHlwZSk7CiAgICAgICAgICBzZWVuW3R5cGVdID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgdHlwZXMuZm9yRWFjaCh2aXNpdCk7CiAgICAgICAgdGhyb3cgbmV3IFVuYm91bmRUeXBlRXJyb3IoYCR7bWVzc2FnZX06IGAgKyB1bmJvdW5kVHlwZXMubWFwKGdldFR5cGVOYW1lKS5qb2luKFsiLCAiXSkpOwogICAgICB9OwogICAgICB2YXIgZ2V0RnVuY3Rpb25OYW1lID0gKHNpZ25hdHVyZSkgPT4gewogICAgICAgIHNpZ25hdHVyZSA9IHNpZ25hdHVyZS50cmltKCk7CiAgICAgICAgY29uc3QgYXJnc0luZGV4ID0gc2lnbmF0dXJlLmluZGV4T2YoIigiKTsKICAgICAgICBpZiAoYXJnc0luZGV4ICE9PSAtMSkgewogICAgICAgICAgcmV0dXJuIHNpZ25hdHVyZS5zdWJzdHIoMCwgYXJnc0luZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHNpZ25hdHVyZTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHZhciBfX2VtYmluZF9yZWdpc3Rlcl9mdW5jdGlvbiA9IChuYW1lLCBhcmdDb3VudCwgcmF3QXJnVHlwZXNBZGRyLCBzaWduYXR1cmUsIHJhd0ludm9rZXIsIGZuLCBpc0FzeW5jKSA9PiB7CiAgICAgICAgdmFyIGFyZ1R5cGVzID0gaGVhcDMyVmVjdG9yVG9BcnJheShhcmdDb3VudCwgcmF3QXJnVHlwZXNBZGRyKTsKICAgICAgICBuYW1lID0gcmVhZExhdGluMVN0cmluZyhuYW1lKTsKICAgICAgICBuYW1lID0gZ2V0RnVuY3Rpb25OYW1lKG5hbWUpOwogICAgICAgIHJhd0ludm9rZXIgPSBlbWJpbmRfX3JlcXVpcmVGdW5jdGlvbihzaWduYXR1cmUsIHJhd0ludm9rZXIpOwogICAgICAgIGV4cG9zZVB1YmxpY1N5bWJvbChuYW1lLCBmdW5jdGlvbigpIHsKICAgICAgICAgIHRocm93VW5ib3VuZFR5cGVFcnJvcihgQ2Fubm90IGNhbGwgJHtuYW1lfSBkdWUgdG8gdW5ib3VuZCB0eXBlc2AsIGFyZ1R5cGVzKTsKICAgICAgICB9LCBhcmdDb3VudCAtIDEpOwogICAgICAgIHdoZW5EZXBlbmRlbnRUeXBlc0FyZVJlc29sdmVkKFtdLCBhcmdUeXBlcywgZnVuY3Rpb24oYXJnVHlwZXMyKSB7CiAgICAgICAgICB2YXIgaW52b2tlckFyZ3NBcnJheSA9IFthcmdUeXBlczJbMF0sIG51bGxdLmNvbmNhdChhcmdUeXBlczIuc2xpY2UoMSkpOwogICAgICAgICAgcmVwbGFjZVB1YmxpY1N5bWJvbChuYW1lLCBjcmFmdEludm9rZXJGdW5jdGlvbihuYW1lLCBpbnZva2VyQXJnc0FycmF5LCBudWxsLCByYXdJbnZva2VyLCBmbiwgaXNBc3luYyksIGFyZ0NvdW50IC0gMSk7CiAgICAgICAgICByZXR1cm4gW107CiAgICAgICAgfSk7CiAgICAgIH07CiAgICAgIHZhciBpbnRlZ2VyUmVhZFZhbHVlRnJvbVBvaW50ZXIgPSAobmFtZSwgd2lkdGgsIHNpZ25lZCkgPT4gewogICAgICAgIHN3aXRjaCAod2lkdGgpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIHNpZ25lZCA/IChwb2ludGVyKSA9PiBIRUFQOFtwb2ludGVyID4+IDBdIDogKHBvaW50ZXIpID0+IEhFQVBVOFtwb2ludGVyID4+IDBdOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gc2lnbmVkID8gKHBvaW50ZXIpID0+IEhFQVAxNltwb2ludGVyID4+IDFdIDogKHBvaW50ZXIpID0+IEhFQVBVMTZbcG9pbnRlciA+PiAxXTsKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgcmV0dXJuIHNpZ25lZCA/IChwb2ludGVyKSA9PiBIRUFQMzJbcG9pbnRlciA+PiAyXSA6IChwb2ludGVyKSA9PiBIRUFQVTMyW3BvaW50ZXIgPj4gMl07CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnZhbGlkIGludGVnZXIgd2lkdGggKCR7d2lkdGh9KTogJHtuYW1lfWApOwogICAgICAgIH0KICAgICAgfTsKICAgICAgdmFyIF9fZW1iaW5kX3JlZ2lzdGVyX2ludGVnZXIgPSAocHJpbWl0aXZlVHlwZSwgbmFtZSwgc2l6ZSwgbWluUmFuZ2UsIG1heFJhbmdlKSA9PiB7CiAgICAgICAgbmFtZSA9IHJlYWRMYXRpbjFTdHJpbmcobmFtZSk7CiAgICAgICAgdmFyIGZyb21XaXJlVHlwZSA9ICh2YWx1ZSkgPT4gdmFsdWU7CiAgICAgICAgaWYgKG1pblJhbmdlID09PSAwKSB7CiAgICAgICAgICB2YXIgYml0c2hpZnQgPSAzMiAtIDggKiBzaXplOwogICAgICAgICAgZnJvbVdpcmVUeXBlID0gKHZhbHVlKSA9PiB2YWx1ZSA8PCBiaXRzaGlmdCA+Pj4gYml0c2hpZnQ7CiAgICAgICAgfQogICAgICAgIHZhciBpc1Vuc2lnbmVkVHlwZSA9IG5hbWUuaW5jbHVkZXMoInVuc2lnbmVkIik7CiAgICAgICAgdmFyIGNoZWNrQXNzZXJ0aW9ucyA9ICh2YWx1ZSwgdG9UeXBlTmFtZSkgPT4gewogICAgICAgIH07CiAgICAgICAgdmFyIHRvV2lyZVR5cGU7CiAgICAgICAgaWYgKGlzVW5zaWduZWRUeXBlKSB7CiAgICAgICAgICB0b1dpcmVUeXBlID0gZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsIHZhbHVlKSB7CiAgICAgICAgICAgIGNoZWNrQXNzZXJ0aW9ucyh2YWx1ZSwgdGhpcy5uYW1lKTsKICAgICAgICAgICAgcmV0dXJuIHZhbHVlID4+PiAwOwogICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdG9XaXJlVHlwZSA9IGZ1bmN0aW9uKGRlc3RydWN0b3JzLCB2YWx1ZSkgewogICAgICAgICAgICBjaGVja0Fzc2VydGlvbnModmFsdWUsIHRoaXMubmFtZSk7CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIHJlZ2lzdGVyVHlwZShwcmltaXRpdmVUeXBlLCB7IG5hbWUsICJmcm9tV2lyZVR5cGUiOiBmcm9tV2lyZVR5cGUsICJ0b1dpcmVUeXBlIjogdG9XaXJlVHlwZSwgImFyZ1BhY2tBZHZhbmNlIjogR2VuZXJpY1dpcmVUeXBlU2l6ZSwgInJlYWRWYWx1ZUZyb21Qb2ludGVyIjogaW50ZWdlclJlYWRWYWx1ZUZyb21Qb2ludGVyKG5hbWUsIHNpemUsIG1pblJhbmdlICE9PSAwKSwgZGVzdHJ1Y3RvckZ1bmN0aW9uOiBudWxsIH0pOwogICAgICB9OwogICAgICB2YXIgX19lbWJpbmRfcmVnaXN0ZXJfbWVtb3J5X3ZpZXcgPSAocmF3VHlwZSwgZGF0YVR5cGVJbmRleCwgbmFtZSkgPT4gewogICAgICAgIHZhciB0eXBlTWFwcGluZyA9IFtJbnQ4QXJyYXksIFVpbnQ4QXJyYXksIEludDE2QXJyYXksIFVpbnQxNkFycmF5LCBJbnQzMkFycmF5LCBVaW50MzJBcnJheSwgRmxvYXQzMkFycmF5LCBGbG9hdDY0QXJyYXldOwogICAgICAgIHZhciBUQSA9IHR5cGVNYXBwaW5nW2RhdGFUeXBlSW5kZXhdOwogICAgICAgIGZ1bmN0aW9uIGRlY29kZU1lbW9yeVZpZXcoaGFuZGxlKSB7CiAgICAgICAgICB2YXIgc2l6ZSA9IEhFQVBVMzJbaGFuZGxlID4+IDJdOwogICAgICAgICAgdmFyIGRhdGEgPSBIRUFQVTMyW2hhbmRsZSArIDQgPj4gMl07CiAgICAgICAgICByZXR1cm4gbmV3IFRBKEhFQVA4LmJ1ZmZlciwgZGF0YSwgc2l6ZSk7CiAgICAgICAgfQogICAgICAgIG5hbWUgPSByZWFkTGF0aW4xU3RyaW5nKG5hbWUpOwogICAgICAgIHJlZ2lzdGVyVHlwZShyYXdUeXBlLCB7IG5hbWUsICJmcm9tV2lyZVR5cGUiOiBkZWNvZGVNZW1vcnlWaWV3LCAiYXJnUGFja0FkdmFuY2UiOiBHZW5lcmljV2lyZVR5cGVTaXplLCAicmVhZFZhbHVlRnJvbVBvaW50ZXIiOiBkZWNvZGVNZW1vcnlWaWV3IH0sIHsgaWdub3JlRHVwbGljYXRlUmVnaXN0cmF0aW9uczogdHJ1ZSB9KTsKICAgICAgfTsKICAgICAgZnVuY3Rpb24gcmVhZFBvaW50ZXIocG9pbnRlcikgewogICAgICAgIHJldHVybiB0aGlzWyJmcm9tV2lyZVR5cGUiXShIRUFQVTMyW3BvaW50ZXIgPj4gMl0pOwogICAgICB9CiAgICAgIHZhciBzdHJpbmdUb1VURjhBcnJheSA9IChzdHIsIGhlYXAsIG91dElkeCwgbWF4Qnl0ZXNUb1dyaXRlKSA9PiB7CiAgICAgICAgaWYgKCEobWF4Qnl0ZXNUb1dyaXRlID4gMCkpIHJldHVybiAwOwogICAgICAgIHZhciBzdGFydElkeCA9IG91dElkeDsKICAgICAgICB2YXIgZW5kSWR4ID0gb3V0SWR4ICsgbWF4Qnl0ZXNUb1dyaXRlIC0gMTsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkgewogICAgICAgICAgdmFyIHUgPSBzdHIuY2hhckNvZGVBdChpKTsKICAgICAgICAgIGlmICh1ID49IDU1Mjk2ICYmIHUgPD0gNTczNDMpIHsKICAgICAgICAgICAgdmFyIHUxID0gc3RyLmNoYXJDb2RlQXQoKytpKTsKICAgICAgICAgICAgdSA9IDY1NTM2ICsgKCh1ICYgMTAyMykgPDwgMTApIHwgdTEgJiAxMDIzOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHUgPD0gMTI3KSB7CiAgICAgICAgICAgIGlmIChvdXRJZHggPj0gZW5kSWR4KSBicmVhazsKICAgICAgICAgICAgaGVhcFtvdXRJZHgrK10gPSB1OwogICAgICAgICAgfSBlbHNlIGlmICh1IDw9IDIwNDcpIHsKICAgICAgICAgICAgaWYgKG91dElkeCArIDEgPj0gZW5kSWR4KSBicmVhazsKICAgICAgICAgICAgaGVhcFtvdXRJZHgrK10gPSAxOTIgfCB1ID4+IDY7CiAgICAgICAgICAgIGhlYXBbb3V0SWR4KytdID0gMTI4IHwgdSAmIDYzOwogICAgICAgICAgfSBlbHNlIGlmICh1IDw9IDY1NTM1KSB7CiAgICAgICAgICAgIGlmIChvdXRJZHggKyAyID49IGVuZElkeCkgYnJlYWs7CiAgICAgICAgICAgIGhlYXBbb3V0SWR4KytdID0gMjI0IHwgdSA+PiAxMjsKICAgICAgICAgICAgaGVhcFtvdXRJZHgrK10gPSAxMjggfCB1ID4+IDYgJiA2MzsKICAgICAgICAgICAgaGVhcFtvdXRJZHgrK10gPSAxMjggfCB1ICYgNjM7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAob3V0SWR4ICsgMyA+PSBlbmRJZHgpIGJyZWFrOwogICAgICAgICAgICBoZWFwW291dElkeCsrXSA9IDI0MCB8IHUgPj4gMTg7CiAgICAgICAgICAgIGhlYXBbb3V0SWR4KytdID0gMTI4IHwgdSA+PiAxMiAmIDYzOwogICAgICAgICAgICBoZWFwW291dElkeCsrXSA9IDEyOCB8IHUgPj4gNiAmIDYzOwogICAgICAgICAgICBoZWFwW291dElkeCsrXSA9IDEyOCB8IHUgJiA2MzsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaGVhcFtvdXRJZHhdID0gMDsKICAgICAgICByZXR1cm4gb3V0SWR4IC0gc3RhcnRJZHg7CiAgICAgIH07CiAgICAgIHZhciBzdHJpbmdUb1VURjggPSAoc3RyLCBvdXRQdHIsIG1heEJ5dGVzVG9Xcml0ZSkgPT4gc3RyaW5nVG9VVEY4QXJyYXkoc3RyLCBIRUFQVTgsIG91dFB0ciwgbWF4Qnl0ZXNUb1dyaXRlKTsKICAgICAgdmFyIGxlbmd0aEJ5dGVzVVRGOCA9IChzdHIpID0+IHsKICAgICAgICB2YXIgbGVuID0gMDsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkgewogICAgICAgICAgdmFyIGMgPSBzdHIuY2hhckNvZGVBdChpKTsKICAgICAgICAgIGlmIChjIDw9IDEyNykgewogICAgICAgICAgICBsZW4rKzsKICAgICAgICAgIH0gZWxzZSBpZiAoYyA8PSAyMDQ3KSB7CiAgICAgICAgICAgIGxlbiArPSAyOwogICAgICAgICAgfSBlbHNlIGlmIChjID49IDU1Mjk2ICYmIGMgPD0gNTczNDMpIHsKICAgICAgICAgICAgbGVuICs9IDQ7CiAgICAgICAgICAgICsraTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxlbiArPSAzOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbGVuOwogICAgICB9OwogICAgICB2YXIgVVRGOERlY29kZXIgPSB0eXBlb2YgVGV4dERlY29kZXIgIT0gInVuZGVmaW5lZCIgPyBuZXcgVGV4dERlY29kZXIoInV0ZjgiKSA6IHZvaWQgMDsKICAgICAgdmFyIFVURjhBcnJheVRvU3RyaW5nID0gKGhlYXBPckFycmF5LCBpZHgsIG1heEJ5dGVzVG9SZWFkKSA9PiB7CiAgICAgICAgdmFyIGVuZElkeCA9IGlkeCArIG1heEJ5dGVzVG9SZWFkOwogICAgICAgIHZhciBlbmRQdHIgPSBpZHg7CiAgICAgICAgd2hpbGUgKGhlYXBPckFycmF5W2VuZFB0cl0gJiYgIShlbmRQdHIgPj0gZW5kSWR4KSkgKytlbmRQdHI7CiAgICAgICAgaWYgKGVuZFB0ciAtIGlkeCA+IDE2ICYmIGhlYXBPckFycmF5LmJ1ZmZlciAmJiBVVEY4RGVjb2RlcikgewogICAgICAgICAgcmV0dXJuIFVURjhEZWNvZGVyLmRlY29kZShoZWFwT3JBcnJheS5zdWJhcnJheShpZHgsIGVuZFB0cikpOwogICAgICAgIH0KICAgICAgICB2YXIgc3RyID0gIiI7CiAgICAgICAgd2hpbGUgKGlkeCA8IGVuZFB0cikgewogICAgICAgICAgdmFyIHUwID0gaGVhcE9yQXJyYXlbaWR4KytdOwogICAgICAgICAgaWYgKCEodTAgJiAxMjgpKSB7CiAgICAgICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHUwKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CiAgICAgICAgICB2YXIgdTEgPSBoZWFwT3JBcnJheVtpZHgrK10gJiA2MzsKICAgICAgICAgIGlmICgodTAgJiAyMjQpID09IDE5MikgewogICAgICAgICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgodTAgJiAzMSkgPDwgNiB8IHUxKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICB9CiAgICAgICAgICB2YXIgdTIgPSBoZWFwT3JBcnJheVtpZHgrK10gJiA2MzsKICAgICAgICAgIGlmICgodTAgJiAyNDApID09IDIyNCkgewogICAgICAgICAgICB1MCA9ICh1MCAmIDE1KSA8PCAxMiB8IHUxIDw8IDYgfCB1MjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHUwID0gKHUwICYgNykgPDwgMTggfCB1MSA8PCAxMiB8IHUyIDw8IDYgfCBoZWFwT3JBcnJheVtpZHgrK10gJiA2MzsKICAgICAgICAgIH0KICAgICAgICAgIGlmICh1MCA8IDY1NTM2KSB7CiAgICAgICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHUwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciBjaCA9IHUwIC0gNjU1MzY7CiAgICAgICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2IHwgY2ggPj4gMTAsIDU2MzIwIHwgY2ggJiAxMDIzKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cjsKICAgICAgfTsKICAgICAgdmFyIFVURjhUb1N0cmluZyA9IChwdHIsIG1heEJ5dGVzVG9SZWFkKSA9PiBwdHIgPyBVVEY4QXJyYXlUb1N0cmluZyhIRUFQVTgsIHB0ciwgbWF4Qnl0ZXNUb1JlYWQpIDogIiI7CiAgICAgIHZhciBfX2VtYmluZF9yZWdpc3Rlcl9zdGRfc3RyaW5nID0gKHJhd1R5cGUsIG5hbWUpID0+IHsKICAgICAgICBuYW1lID0gcmVhZExhdGluMVN0cmluZyhuYW1lKTsKICAgICAgICB2YXIgc3RkU3RyaW5nSXNVVEY4ID0gbmFtZSA9PT0gInN0ZDo6c3RyaW5nIjsKICAgICAgICByZWdpc3RlclR5cGUocmF3VHlwZSwgeyBuYW1lLCAiZnJvbVdpcmVUeXBlIih2YWx1ZSkgewogICAgICAgICAgdmFyIGxlbmd0aCA9IEhFQVBVMzJbdmFsdWUgPj4gMl07CiAgICAgICAgICB2YXIgcGF5bG9hZCA9IHZhbHVlICsgNDsKICAgICAgICAgIHZhciBzdHI7CiAgICAgICAgICBpZiAoc3RkU3RyaW5nSXNVVEY4KSB7CiAgICAgICAgICAgIHZhciBkZWNvZGVTdGFydFB0ciA9IHBheWxvYWQ7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IGxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgdmFyIGN1cnJlbnRCeXRlUHRyID0gcGF5bG9hZCArIGk7CiAgICAgICAgICAgICAgaWYgKGkgPT0gbGVuZ3RoIHx8IEhFQVBVOFtjdXJyZW50Qnl0ZVB0cl0gPT0gMCkgewogICAgICAgICAgICAgICAgdmFyIG1heFJlYWQgPSBjdXJyZW50Qnl0ZVB0ciAtIGRlY29kZVN0YXJ0UHRyOwogICAgICAgICAgICAgICAgdmFyIHN0cmluZ1NlZ21lbnQgPSBVVEY4VG9TdHJpbmcoZGVjb2RlU3RhcnRQdHIsIG1heFJlYWQpOwogICAgICAgICAgICAgICAgaWYgKHN0ciA9PT0gdm9pZCAwKSB7CiAgICAgICAgICAgICAgICAgIHN0ciA9IHN0cmluZ1NlZ21lbnQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTsKICAgICAgICAgICAgICAgICAgc3RyICs9IHN0cmluZ1NlZ21lbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkZWNvZGVTdGFydFB0ciA9IGN1cnJlbnRCeXRlUHRyICsgMTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciBhID0gbmV3IEFycmF5KGxlbmd0aCk7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICBhW2ldID0gU3RyaW5nLmZyb21DaGFyQ29kZShIRUFQVThbcGF5bG9hZCArIGldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdHIgPSBhLmpvaW4oIiIpOwogICAgICAgICAgfQogICAgICAgICAgX2ZyZWUodmFsdWUpOwogICAgICAgICAgcmV0dXJuIHN0cjsKICAgICAgICB9LCAidG9XaXJlVHlwZSIoZGVzdHJ1Y3RvcnMsIHZhbHVlKSB7CiAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgICAgICAgICB2YWx1ZSA9IG5ldyBVaW50OEFycmF5KHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHZhciBsZW5ndGg7CiAgICAgICAgICB2YXIgdmFsdWVJc09mVHlwZVN0cmluZyA9IHR5cGVvZiB2YWx1ZSA9PSAic3RyaW5nIjsKICAgICAgICAgIGlmICghKHZhbHVlSXNPZlR5cGVTdHJpbmcgfHwgdmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5IHx8IHZhbHVlIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXkgfHwgdmFsdWUgaW5zdGFuY2VvZiBJbnQ4QXJyYXkpKSB7CiAgICAgICAgICAgIHRocm93QmluZGluZ0Vycm9yKCJDYW5ub3QgcGFzcyBub24tc3RyaW5nIHRvIHN0ZDo6c3RyaW5nIik7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoc3RkU3RyaW5nSXNVVEY4ICYmIHZhbHVlSXNPZlR5cGVTdHJpbmcpIHsKICAgICAgICAgICAgbGVuZ3RoID0gbGVuZ3RoQnl0ZXNVVEY4KHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxlbmd0aCA9IHZhbHVlLmxlbmd0aDsKICAgICAgICAgIH0KICAgICAgICAgIHZhciBiYXNlID0gX21hbGxvYyg0ICsgbGVuZ3RoICsgMSk7CiAgICAgICAgICB2YXIgcHRyID0gYmFzZSArIDQ7CiAgICAgICAgICBIRUFQVTMyW2Jhc2UgPj4gMl0gPSBsZW5ndGg7CiAgICAgICAgICBpZiAoc3RkU3RyaW5nSXNVVEY4ICYmIHZhbHVlSXNPZlR5cGVTdHJpbmcpIHsKICAgICAgICAgICAgc3RyaW5nVG9VVEY4KHZhbHVlLCBwdHIsIGxlbmd0aCArIDEpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHZhbHVlSXNPZlR5cGVTdHJpbmcpIHsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICB2YXIgY2hhckNvZGUgPSB2YWx1ZS5jaGFyQ29kZUF0KGkpOwogICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID4gMjU1KSB7CiAgICAgICAgICAgICAgICAgIF9mcmVlKHB0cik7CiAgICAgICAgICAgICAgICAgIHRocm93QmluZGluZ0Vycm9yKCJTdHJpbmcgaGFzIFVURi0xNiBjb2RlIHVuaXRzIHRoYXQgZG8gbm90IGZpdCBpbiA4IGJpdHMiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEhFQVBVOFtwdHIgKyBpXSA9IGNoYXJDb2RlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICBIRUFQVThbcHRyICsgaV0gPSB2YWx1ZVtpXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmIChkZXN0cnVjdG9ycyAhPT0gbnVsbCkgewogICAgICAgICAgICBkZXN0cnVjdG9ycy5wdXNoKF9mcmVlLCBiYXNlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBiYXNlOwogICAgICAgIH0sICJhcmdQYWNrQWR2YW5jZSI6IEdlbmVyaWNXaXJlVHlwZVNpemUsICJyZWFkVmFsdWVGcm9tUG9pbnRlciI6IHJlYWRQb2ludGVyLCBkZXN0cnVjdG9yRnVuY3Rpb24ocHRyKSB7CiAgICAgICAgICBfZnJlZShwdHIpOwogICAgICAgIH0gfSk7CiAgICAgIH07CiAgICAgIHZhciBVVEYxNkRlY29kZXIgPSB0eXBlb2YgVGV4dERlY29kZXIgIT0gInVuZGVmaW5lZCIgPyBuZXcgVGV4dERlY29kZXIoInV0Zi0xNmxlIikgOiB2b2lkIDA7CiAgICAgIHZhciBVVEYxNlRvU3RyaW5nID0gKHB0ciwgbWF4Qnl0ZXNUb1JlYWQpID0+IHsKICAgICAgICB2YXIgZW5kUHRyID0gcHRyOwogICAgICAgIHZhciBpZHggPSBlbmRQdHIgPj4gMTsKICAgICAgICB2YXIgbWF4SWR4ID0gaWR4ICsgbWF4Qnl0ZXNUb1JlYWQgLyAyOwogICAgICAgIHdoaWxlICghKGlkeCA+PSBtYXhJZHgpICYmIEhFQVBVMTZbaWR4XSkgKytpZHg7CiAgICAgICAgZW5kUHRyID0gaWR4IDw8IDE7CiAgICAgICAgaWYgKGVuZFB0ciAtIHB0ciA+IDMyICYmIFVURjE2RGVjb2RlcikgcmV0dXJuIFVURjE2RGVjb2Rlci5kZWNvZGUoSEVBUFU4LnN1YmFycmF5KHB0ciwgZW5kUHRyKSk7CiAgICAgICAgdmFyIHN0ciA9ICIiOwogICAgICAgIGZvciAodmFyIGkgPSAwOyAhKGkgPj0gbWF4Qnl0ZXNUb1JlYWQgLyAyKTsgKytpKSB7CiAgICAgICAgICB2YXIgY29kZVVuaXQgPSBIRUFQMTZbcHRyICsgaSAqIDIgPj4gMV07CiAgICAgICAgICBpZiAoY29kZVVuaXQgPT0gMCkgYnJlYWs7CiAgICAgICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlVW5pdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHI7CiAgICAgIH07CiAgICAgIHZhciBzdHJpbmdUb1VURjE2ID0gKHN0ciwgb3V0UHRyLCBtYXhCeXRlc1RvV3JpdGUpID0+IHsKICAgICAgICBpZiAobWF4Qnl0ZXNUb1dyaXRlID09PSB2b2lkIDApIHsKICAgICAgICAgIG1heEJ5dGVzVG9Xcml0ZSA9IDIxNDc0ODM2NDc7CiAgICAgICAgfQogICAgICAgIGlmIChtYXhCeXRlc1RvV3JpdGUgPCAyKSByZXR1cm4gMDsKICAgICAgICBtYXhCeXRlc1RvV3JpdGUgLT0gMjsKICAgICAgICB2YXIgc3RhcnRQdHIgPSBvdXRQdHI7CiAgICAgICAgdmFyIG51bUNoYXJzVG9Xcml0ZSA9IG1heEJ5dGVzVG9Xcml0ZSA8IHN0ci5sZW5ndGggKiAyID8gbWF4Qnl0ZXNUb1dyaXRlIC8gMiA6IHN0ci5sZW5ndGg7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1DaGFyc1RvV3JpdGU7ICsraSkgewogICAgICAgICAgdmFyIGNvZGVVbml0ID0gc3RyLmNoYXJDb2RlQXQoaSk7CiAgICAgICAgICBIRUFQMTZbb3V0UHRyID4+IDFdID0gY29kZVVuaXQ7CiAgICAgICAgICBvdXRQdHIgKz0gMjsKICAgICAgICB9CiAgICAgICAgSEVBUDE2W291dFB0ciA+PiAxXSA9IDA7CiAgICAgICAgcmV0dXJuIG91dFB0ciAtIHN0YXJ0UHRyOwogICAgICB9OwogICAgICB2YXIgbGVuZ3RoQnl0ZXNVVEYxNiA9IChzdHIpID0+IHN0ci5sZW5ndGggKiAyOwogICAgICB2YXIgVVRGMzJUb1N0cmluZyA9IChwdHIsIG1heEJ5dGVzVG9SZWFkKSA9PiB7CiAgICAgICAgdmFyIGkgPSAwOwogICAgICAgIHZhciBzdHIgPSAiIjsKICAgICAgICB3aGlsZSAoIShpID49IG1heEJ5dGVzVG9SZWFkIC8gNCkpIHsKICAgICAgICAgIHZhciB1dGYzMiA9IEhFQVAzMltwdHIgKyBpICogNCA+PiAyXTsKICAgICAgICAgIGlmICh1dGYzMiA9PSAwKSBicmVhazsKICAgICAgICAgICsraTsKICAgICAgICAgIGlmICh1dGYzMiA+PSA2NTUzNikgewogICAgICAgICAgICB2YXIgY2ggPSB1dGYzMiAtIDY1NTM2OwogICAgICAgICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSg1NTI5NiB8IGNoID4+IDEwLCA1NjMyMCB8IGNoICYgMTAyMyk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh1dGYzMik7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHI7CiAgICAgIH07CiAgICAgIHZhciBzdHJpbmdUb1VURjMyID0gKHN0ciwgb3V0UHRyLCBtYXhCeXRlc1RvV3JpdGUpID0+IHsKICAgICAgICBpZiAobWF4Qnl0ZXNUb1dyaXRlID09PSB2b2lkIDApIHsKICAgICAgICAgIG1heEJ5dGVzVG9Xcml0ZSA9IDIxNDc0ODM2NDc7CiAgICAgICAgfQogICAgICAgIGlmIChtYXhCeXRlc1RvV3JpdGUgPCA0KSByZXR1cm4gMDsKICAgICAgICB2YXIgc3RhcnRQdHIgPSBvdXRQdHI7CiAgICAgICAgdmFyIGVuZFB0ciA9IHN0YXJ0UHRyICsgbWF4Qnl0ZXNUb1dyaXRlIC0gNDsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkgewogICAgICAgICAgdmFyIGNvZGVVbml0ID0gc3RyLmNoYXJDb2RlQXQoaSk7CiAgICAgICAgICBpZiAoY29kZVVuaXQgPj0gNTUyOTYgJiYgY29kZVVuaXQgPD0gNTczNDMpIHsKICAgICAgICAgICAgdmFyIHRyYWlsU3Vycm9nYXRlID0gc3RyLmNoYXJDb2RlQXQoKytpKTsKICAgICAgICAgICAgY29kZVVuaXQgPSA2NTUzNiArICgoY29kZVVuaXQgJiAxMDIzKSA8PCAxMCkgfCB0cmFpbFN1cnJvZ2F0ZSAmIDEwMjM7CiAgICAgICAgICB9CiAgICAgICAgICBIRUFQMzJbb3V0UHRyID4+IDJdID0gY29kZVVuaXQ7CiAgICAgICAgICBvdXRQdHIgKz0gNDsKICAgICAgICAgIGlmIChvdXRQdHIgKyA0ID4gZW5kUHRyKSBicmVhazsKICAgICAgICB9CiAgICAgICAgSEVBUDMyW291dFB0ciA+PiAyXSA9IDA7CiAgICAgICAgcmV0dXJuIG91dFB0ciAtIHN0YXJ0UHRyOwogICAgICB9OwogICAgICB2YXIgbGVuZ3RoQnl0ZXNVVEYzMiA9IChzdHIpID0+IHsKICAgICAgICB2YXIgbGVuID0gMDsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkgewogICAgICAgICAgdmFyIGNvZGVVbml0ID0gc3RyLmNoYXJDb2RlQXQoaSk7CiAgICAgICAgICBpZiAoY29kZVVuaXQgPj0gNTUyOTYgJiYgY29kZVVuaXQgPD0gNTczNDMpICsraTsKICAgICAgICAgIGxlbiArPSA0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGVuOwogICAgICB9OwogICAgICB2YXIgX19lbWJpbmRfcmVnaXN0ZXJfc3RkX3dzdHJpbmcgPSAocmF3VHlwZSwgY2hhclNpemUsIG5hbWUpID0+IHsKICAgICAgICBuYW1lID0gcmVhZExhdGluMVN0cmluZyhuYW1lKTsKICAgICAgICB2YXIgZGVjb2RlU3RyaW5nLCBlbmNvZGVTdHJpbmcsIGdldEhlYXAsIGxlbmd0aEJ5dGVzVVRGLCBzaGlmdDsKICAgICAgICBpZiAoY2hhclNpemUgPT09IDIpIHsKICAgICAgICAgIGRlY29kZVN0cmluZyA9IFVURjE2VG9TdHJpbmc7CiAgICAgICAgICBlbmNvZGVTdHJpbmcgPSBzdHJpbmdUb1VURjE2OwogICAgICAgICAgbGVuZ3RoQnl0ZXNVVEYgPSBsZW5ndGhCeXRlc1VURjE2OwogICAgICAgICAgZ2V0SGVhcCA9ICgpID0+IEhFQVBVMTY7CiAgICAgICAgICBzaGlmdCA9IDE7CiAgICAgICAgfSBlbHNlIGlmIChjaGFyU2l6ZSA9PT0gNCkgewogICAgICAgICAgZGVjb2RlU3RyaW5nID0gVVRGMzJUb1N0cmluZzsKICAgICAgICAgIGVuY29kZVN0cmluZyA9IHN0cmluZ1RvVVRGMzI7CiAgICAgICAgICBsZW5ndGhCeXRlc1VURiA9IGxlbmd0aEJ5dGVzVVRGMzI7CiAgICAgICAgICBnZXRIZWFwID0gKCkgPT4gSEVBUFUzMjsKICAgICAgICAgIHNoaWZ0ID0gMjsKICAgICAgICB9CiAgICAgICAgcmVnaXN0ZXJUeXBlKHJhd1R5cGUsIHsgbmFtZSwgImZyb21XaXJlVHlwZSI6ICh2YWx1ZSkgPT4gewogICAgICAgICAgdmFyIGxlbmd0aCA9IEhFQVBVMzJbdmFsdWUgPj4gMl07CiAgICAgICAgICB2YXIgSEVBUCA9IGdldEhlYXAoKTsKICAgICAgICAgIHZhciBzdHI7CiAgICAgICAgICB2YXIgZGVjb2RlU3RhcnRQdHIgPSB2YWx1ZSArIDQ7CiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBsZW5ndGg7ICsraSkgewogICAgICAgICAgICB2YXIgY3VycmVudEJ5dGVQdHIgPSB2YWx1ZSArIDQgKyBpICogY2hhclNpemU7CiAgICAgICAgICAgIGlmIChpID09IGxlbmd0aCB8fCBIRUFQW2N1cnJlbnRCeXRlUHRyID4+IHNoaWZ0XSA9PSAwKSB7CiAgICAgICAgICAgICAgdmFyIG1heFJlYWRCeXRlcyA9IGN1cnJlbnRCeXRlUHRyIC0gZGVjb2RlU3RhcnRQdHI7CiAgICAgICAgICAgICAgdmFyIHN0cmluZ1NlZ21lbnQgPSBkZWNvZGVTdHJpbmcoZGVjb2RlU3RhcnRQdHIsIG1heFJlYWRCeXRlcyk7CiAgICAgICAgICAgICAgaWYgKHN0ciA9PT0gdm9pZCAwKSB7CiAgICAgICAgICAgICAgICBzdHIgPSBzdHJpbmdTZWdtZW50OwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTsKICAgICAgICAgICAgICAgIHN0ciArPSBzdHJpbmdTZWdtZW50OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBkZWNvZGVTdGFydFB0ciA9IGN1cnJlbnRCeXRlUHRyICsgY2hhclNpemU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIF9mcmVlKHZhbHVlKTsKICAgICAgICAgIHJldHVybiBzdHI7CiAgICAgICAgfSwgInRvV2lyZVR5cGUiOiAoZGVzdHJ1Y3RvcnMsIHZhbHVlKSA9PiB7CiAgICAgICAgICBpZiAoISh0eXBlb2YgdmFsdWUgPT0gInN0cmluZyIpKSB7CiAgICAgICAgICAgIHRocm93QmluZGluZ0Vycm9yKGBDYW5ub3QgcGFzcyBub24tc3RyaW5nIHRvIEMrKyBzdHJpbmcgdHlwZSAke25hbWV9YCk7CiAgICAgICAgICB9CiAgICAgICAgICB2YXIgbGVuZ3RoID0gbGVuZ3RoQnl0ZXNVVEYodmFsdWUpOwogICAgICAgICAgdmFyIHB0ciA9IF9tYWxsb2MoNCArIGxlbmd0aCArIGNoYXJTaXplKTsKICAgICAgICAgIEhFQVBVMzJbcHRyID4+IDJdID0gbGVuZ3RoID4+IHNoaWZ0OwogICAgICAgICAgZW5jb2RlU3RyaW5nKHZhbHVlLCBwdHIgKyA0LCBsZW5ndGggKyBjaGFyU2l6ZSk7CiAgICAgICAgICBpZiAoZGVzdHJ1Y3RvcnMgIT09IG51bGwpIHsKICAgICAgICAgICAgZGVzdHJ1Y3RvcnMucHVzaChfZnJlZSwgcHRyKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwdHI7CiAgICAgICAgfSwgImFyZ1BhY2tBZHZhbmNlIjogR2VuZXJpY1dpcmVUeXBlU2l6ZSwgInJlYWRWYWx1ZUZyb21Qb2ludGVyIjogc2ltcGxlUmVhZFZhbHVlRnJvbVBvaW50ZXIsIGRlc3RydWN0b3JGdW5jdGlvbihwdHIpIHsKICAgICAgICAgIF9mcmVlKHB0cik7CiAgICAgICAgfSB9KTsKICAgICAgfTsKICAgICAgdmFyIF9fZW1iaW5kX3JlZ2lzdGVyX3ZvaWQgPSAocmF3VHlwZSwgbmFtZSkgPT4gewogICAgICAgIG5hbWUgPSByZWFkTGF0aW4xU3RyaW5nKG5hbWUpOwogICAgICAgIHJlZ2lzdGVyVHlwZShyYXdUeXBlLCB7IGlzVm9pZDogdHJ1ZSwgbmFtZSwgImFyZ1BhY2tBZHZhbmNlIjogMCwgImZyb21XaXJlVHlwZSI6ICgpID0+IHZvaWQgMCwgInRvV2lyZVR5cGUiOiAoZGVzdHJ1Y3RvcnMsIG8pID0+IHZvaWQgMCB9KTsKICAgICAgfTsKICAgICAgdmFyIF9hYm9ydCA9ICgpID0+IHsKICAgICAgICBhYm9ydCgiIik7CiAgICAgIH07CiAgICAgIHZhciBfZW1zY3JpcHRlbl9tZW1jcHlfanMgPSAoZGVzdCwgc3JjLCBudW0pID0+IEhFQVBVOC5jb3B5V2l0aGluKGRlc3QsIHNyYywgc3JjICsgbnVtKTsKICAgICAgdmFyIGdldEhlYXBNYXggPSAoKSA9PiAyMTQ3NDgzNjQ4OwogICAgICB2YXIgZ3Jvd01lbW9yeSA9IChzaXplKSA9PiB7CiAgICAgICAgdmFyIGIgPSB3YXNtTWVtb3J5LmJ1ZmZlcjsKICAgICAgICB2YXIgcGFnZXMgPSAoc2l6ZSAtIGIuYnl0ZUxlbmd0aCArIDY1NTM1KSAvIDY1NTM2OwogICAgICAgIHRyeSB7CiAgICAgICAgICB3YXNtTWVtb3J5Lmdyb3cocGFnZXMpOwogICAgICAgICAgdXBkYXRlTWVtb3J5Vmlld3MoKTsKICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHZhciBfZW1zY3JpcHRlbl9yZXNpemVfaGVhcCA9IChyZXF1ZXN0ZWRTaXplKSA9PiB7CiAgICAgICAgdmFyIG9sZFNpemUgPSBIRUFQVTgubGVuZ3RoOwogICAgICAgIHJlcXVlc3RlZFNpemUgPj4+PSAwOwogICAgICAgIHZhciBtYXhIZWFwU2l6ZSA9IGdldEhlYXBNYXgoKTsKICAgICAgICBpZiAocmVxdWVzdGVkU2l6ZSA+IG1heEhlYXBTaXplKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHZhciBhbGlnblVwID0gKHgsIG11bHRpcGxlKSA9PiB4ICsgKG11bHRpcGxlIC0geCAlIG11bHRpcGxlKSAlIG11bHRpcGxlOwogICAgICAgIGZvciAodmFyIGN1dERvd24gPSAxOyBjdXREb3duIDw9IDQ7IGN1dERvd24gKj0gMikgewogICAgICAgICAgdmFyIG92ZXJHcm93bkhlYXBTaXplID0gb2xkU2l6ZSAqICgxICsgMC4yIC8gY3V0RG93bik7CiAgICAgICAgICBvdmVyR3Jvd25IZWFwU2l6ZSA9IE1hdGgubWluKG92ZXJHcm93bkhlYXBTaXplLCByZXF1ZXN0ZWRTaXplICsgMTAwNjYzMjk2KTsKICAgICAgICAgIHZhciBuZXdTaXplID0gTWF0aC5taW4obWF4SGVhcFNpemUsIGFsaWduVXAoTWF0aC5tYXgocmVxdWVzdGVkU2l6ZSwgb3Zlckdyb3duSGVhcFNpemUpLCA2NTUzNikpOwogICAgICAgICAgdmFyIHJlcGxhY2VtZW50ID0gZ3Jvd01lbW9yeShuZXdTaXplKTsKICAgICAgICAgIGlmIChyZXBsYWNlbWVudCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9OwogICAgICBlbWJpbmRfaW5pdF9jaGFyQ29kZXMoKTsKICAgICAgQmluZGluZ0Vycm9yID0gTW9kdWxlMlsiQmluZGluZ0Vycm9yIl0gPSBjbGFzcyBCaW5kaW5nRXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgICAgICAgY29uc3RydWN0b3IobWVzc2FnZSkgewogICAgICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICAgICAgICB0aGlzLm5hbWUgPSAiQmluZGluZ0Vycm9yIjsKICAgICAgICB9CiAgICAgIH07CiAgICAgIEludGVybmFsRXJyb3IgPSBNb2R1bGUyWyJJbnRlcm5hbEVycm9yIl0gPSBjbGFzcyBJbnRlcm5hbEVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UpIHsKICAgICAgICAgIHN1cGVyKG1lc3NhZ2UpOwogICAgICAgICAgdGhpcy5uYW1lID0gIkludGVybmFsRXJyb3IiOwogICAgICAgIH0KICAgICAgfTsKICAgICAgaGFuZGxlQWxsb2NhdG9ySW5pdCgpOwogICAgICBpbml0X2VtdmFsKCk7CiAgICAgIFVuYm91bmRUeXBlRXJyb3IgPSBNb2R1bGUyWyJVbmJvdW5kVHlwZUVycm9yIl0gPSBleHRlbmRFcnJvcihFcnJvciwgIlVuYm91bmRUeXBlRXJyb3IiKTsKICAgICAgdmFyIHdhc21JbXBvcnRzID0geyBuOiBfX19jeGFfdGhyb3csIGs6IF9fZW1iaW5kX3JlZ2lzdGVyX2JpZ2ludCwgaTogX19lbWJpbmRfcmVnaXN0ZXJfYm9vbCwgaDogX19lbWJpbmRfcmVnaXN0ZXJfZW12YWwsIGQ6IF9fZW1iaW5kX3JlZ2lzdGVyX2Zsb2F0LCBnOiBfX2VtYmluZF9yZWdpc3Rlcl9mdW5jdGlvbiwgYjogX19lbWJpbmRfcmVnaXN0ZXJfaW50ZWdlciwgYTogX19lbWJpbmRfcmVnaXN0ZXJfbWVtb3J5X3ZpZXcsIGU6IF9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF9zdHJpbmcsIGM6IF9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF93c3RyaW5nLCBqOiBfX2VtYmluZF9yZWdpc3Rlcl92b2lkLCBmOiBfYWJvcnQsIG06IF9lbXNjcmlwdGVuX21lbWNweV9qcywgbDogX2Vtc2NyaXB0ZW5fcmVzaXplX2hlYXAgfTsKICAgICAgdmFyIHdhc21FeHBvcnRzID0gY3JlYXRlV2FzbSgpOwogICAgICB2YXIgX19fZ2V0VHlwZU5hbWUgPSAoYTApID0+IChfX19nZXRUeXBlTmFtZSA9IHdhc21FeHBvcnRzWyJxIl0pKGEwKTsKICAgICAgdmFyIF9tYWxsb2MgPSBNb2R1bGUyWyJfbWFsbG9jIl0gPSAoYTApID0+IChfbWFsbG9jID0gTW9kdWxlMlsiX21hbGxvYyJdID0gd2FzbUV4cG9ydHNbInIiXSkoYTApOwogICAgICB2YXIgX2ZyZWUgPSBNb2R1bGUyWyJfZnJlZSJdID0gKGEwKSA9PiAoX2ZyZWUgPSBNb2R1bGUyWyJfZnJlZSJdID0gd2FzbUV4cG9ydHNbInQiXSkoYTApOwogICAgICB2YXIgX19fY3hhX2lzX3BvaW50ZXJfdHlwZSA9IChhMCkgPT4gKF9fX2N4YV9pc19wb2ludGVyX3R5cGUgPSB3YXNtRXhwb3J0c1sidSJdKShhMCk7CiAgICAgIHZhciBjYWxsZWRSdW47CiAgICAgIGRlcGVuZGVuY2llc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uIHJ1bkNhbGxlcigpIHsKICAgICAgICBpZiAoIWNhbGxlZFJ1bikgcnVuKCk7CiAgICAgICAgaWYgKCFjYWxsZWRSdW4pIGRlcGVuZGVuY2llc0Z1bGZpbGxlZCA9IHJ1bkNhbGxlcjsKICAgICAgfTsKICAgICAgZnVuY3Rpb24gcnVuKCkgewogICAgICAgIGlmIChydW5EZXBlbmRlbmNpZXMgPiAwKSB7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHByZVJ1bigpOwogICAgICAgIGlmIChydW5EZXBlbmRlbmNpZXMgPiAwKSB7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGZ1bmN0aW9uIGRvUnVuKCkgewogICAgICAgICAgaWYgKGNhbGxlZFJ1bikgcmV0dXJuOwogICAgICAgICAgY2FsbGVkUnVuID0gdHJ1ZTsKICAgICAgICAgIE1vZHVsZTJbImNhbGxlZFJ1biJdID0gdHJ1ZTsKICAgICAgICAgIGlmIChBQk9SVCkgcmV0dXJuOwogICAgICAgICAgaW5pdFJ1bnRpbWUoKTsKICAgICAgICAgIHJlYWR5UHJvbWlzZVJlc29sdmUoTW9kdWxlMik7CiAgICAgICAgICBpZiAoTW9kdWxlMlsib25SdW50aW1lSW5pdGlhbGl6ZWQiXSkgTW9kdWxlMlsib25SdW50aW1lSW5pdGlhbGl6ZWQiXSgpOwogICAgICAgICAgcG9zdFJ1bigpOwogICAgICAgIH0KICAgICAgICBpZiAoTW9kdWxlMlsic2V0U3RhdHVzIl0pIHsKICAgICAgICAgIE1vZHVsZTJbInNldFN0YXR1cyJdKCJSdW5uaW5nLi4uIik7CiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgIE1vZHVsZTJbInNldFN0YXR1cyJdKCIiKTsKICAgICAgICAgICAgfSwgMSk7CiAgICAgICAgICAgIGRvUnVuKCk7CiAgICAgICAgICB9LCAxKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZG9SdW4oKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKE1vZHVsZTJbInByZUluaXQiXSkgewogICAgICAgIGlmICh0eXBlb2YgTW9kdWxlMlsicHJlSW5pdCJdID09ICJmdW5jdGlvbiIpIE1vZHVsZTJbInByZUluaXQiXSA9IFtNb2R1bGUyWyJwcmVJbml0Il1dOwogICAgICAgIHdoaWxlIChNb2R1bGUyWyJwcmVJbml0Il0ubGVuZ3RoID4gMCkgewogICAgICAgICAgTW9kdWxlMlsicHJlSW5pdCJdLnBvcCgpKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJ1bigpOwogICAgICByZXR1cm4gbW9kdWxlQXJnLnJlYWR5OwogICAgfTsKICB9KSgpOwogIGNsYXNzIEJ1ZmZlclBvb2wgewogICAgY29uc3RydWN0b3IoYnVmZmVyU2l6ZSwgaW5pdGlhbFBvb2xTaXplID0gMCkgewogICAgICB0aGlzLmJ1ZmZlclNpemUgPSBidWZmZXJTaXplOwogICAgICB0aGlzLnBvb2wgPSBbXTsKICAgICAgdGhpcy5pbml0UG9vbChpbml0aWFsUG9vbFNpemUpOwogICAgfQogICAgaW5pdFBvb2woaW5pdGlhbFBvb2xTaXplKSB7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5pdGlhbFBvb2xTaXplOyBpKyspIHsKICAgICAgICB0aGlzLnBvb2wucHVzaChuZXcgQXJyYXlCdWZmZXIodGhpcy5idWZmZXJTaXplKSk7CiAgICAgIH0KICAgIH0KICAgIGdldEJ1ZmZlcigpIHsKICAgICAgaWYgKHRoaXMucG9vbC5sZW5ndGggPiAwKSB7CiAgICAgICAgcmV0dXJuIHRoaXMucG9vbC5wb3AoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKHRoaXMuYnVmZmVyU2l6ZSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybkJ1ZmZlcihidWZmZXIpIHsKICAgICAgaWYgKGJ1ZmZlci5ieXRlTGVuZ3RoID09PSB0aGlzLmJ1ZmZlclNpemUpIHsKICAgICAgICB0aGlzLnBvb2wucHVzaChidWZmZXIpOwogICAgICB9CiAgICB9CiAgfQogIGNsYXNzIFdhc21Tb3J0ZXIgewogICAgY29uc3RydWN0b3IoX3ZlcnRleENvdW50LCBfZ2xvYmFsQnVmZmVyKSB7CiAgICAgIHRoaXMuX3ZlcnRleENvdW50ID0gX3ZlcnRleENvdW50OwogICAgICB0aGlzLl9nbG9iYWxCdWZmZXIgPSBfZ2xvYmFsQnVmZmVyOwogICAgICBjb25zdCBjb21iaW5lZExlbmd0aCA9IHRoaXMuX2NhbGN1bGF0ZUNvbWJpbmVkTGVuZ3RoKCk7CiAgICAgIHRoaXMuX2J1ZmZlclBvb2wgPSBuZXcgQnVmZmVyUG9vbChjb21iaW5lZExlbmd0aCwgMik7CiAgICB9CiAgICBhc3luYyBsb2FkKCkgewogICAgICB0aGlzLm1vZHVsZSA9IGF3YWl0IE1vZHVsZSgpOwogICAgICB0aGlzLl92aWV3UHJvalB0ciA9IHRoaXMubW9kdWxlLl9tYWxsb2MoMTYgKiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgICB0aGlzLl9nbG9iYWxCdWZmZXJQdHIgPSB0aGlzLm1vZHVsZS5fbWFsbG9jKHRoaXMuX3ZlcnRleENvdW50ICogMzIpOwogICAgICB0aGlzLl9jb21iaW5lZFB0ciA9IHRoaXMubW9kdWxlLl9tYWxsb2ModGhpcy5fY2FsY3VsYXRlQ29tYmluZWRMZW5ndGgoKSk7CiAgICAgIHRoaXMubW9kdWxlLkhFQVBVOC5zZXQodGhpcy5fZ2xvYmFsQnVmZmVyLCB0aGlzLl9nbG9iYWxCdWZmZXJQdHIpOwogICAgfQogICAgcnVuU29ydCh2aWV3UHJvaikgewogICAgICB0aGlzLm1vZHVsZS5IRUFQRjMyLnNldCh2aWV3UHJvaiwgdGhpcy5fdmlld1Byb2pQdHIgLyBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgICB0aGlzLm1vZHVsZS5ydW5Tb3J0KHRoaXMuX3ZpZXdQcm9qUHRyLCB0aGlzLl9nbG9iYWxCdWZmZXJQdHIsIHRoaXMuX3ZlcnRleENvdW50LCB0aGlzLl9jb21iaW5lZFB0cik7CiAgICAgIGNvbnN0IGJ5dGVTdGFydCA9IHRoaXMuX2NvbWJpbmVkUHRyOwogICAgICBjb25zdCBieXRlTGVuZ3RoID0gdGhpcy5fY2FsY3VsYXRlQ29tYmluZWRMZW5ndGgoKTsKICAgICAgY29uc3QgYnVmZmVyVG9UcmFuc2ZlciA9IHRoaXMuX2J1ZmZlclBvb2wuZ2V0QnVmZmVyKCk7CiAgICAgIG5ldyBVaW50OEFycmF5KGJ1ZmZlclRvVHJhbnNmZXIpLnNldChuZXcgVWludDhBcnJheSh0aGlzLm1vZHVsZS5IRUFQVTguYnVmZmVyLCBieXRlU3RhcnQsIGJ5dGVMZW5ndGgpKTsKICAgICAgcmV0dXJuIHRyYW5zZmVyKGJ1ZmZlclRvVHJhbnNmZXIsIFtidWZmZXJUb1RyYW5zZmVyXSk7CiAgICB9CiAgICByZXR1cm5CdWZmZXIoYnVmZmVyKSB7CiAgICAgIHRoaXMuX2J1ZmZlclBvb2wucmV0dXJuQnVmZmVyKGJ1ZmZlcik7CiAgICB9CiAgICBfY2FsY3VsYXRlQ29tYmluZWRMZW5ndGgoKSB7CiAgICAgIHJldHVybiA0ICogNCAqIHRoaXMuX3ZlcnRleENvdW50ICsgMyAqIDQgKiB0aGlzLl92ZXJ0ZXhDb3VudCArIDMgKiA0ICogdGhpcy5fdmVydGV4Q291bnQgKyA0ICogNCAqIHRoaXMuX3ZlcnRleENvdW50ICogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UOwogICAgfQogICAgZGlzcG9zZSgpIHsKICAgICAgaWYgKHRoaXMubW9kdWxlKSB7CiAgICAgICAgdGhpcy5tb2R1bGUuX2ZyZWUodGhpcy5fdmlld1Byb2pQdHIpOwogICAgICAgIHRoaXMubW9kdWxlLl9mcmVlKHRoaXMuX2dsb2JhbEJ1ZmZlclB0cik7CiAgICAgICAgdGhpcy5tb2R1bGUuX2ZyZWUodGhpcy5fY29tYmluZWRQdHIpOwogICAgICB9CiAgICB9CiAgfQogIGV4cG9zZShXYXNtU29ydGVyKTsKfSkoKTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9d29ya2VyLUJZQ2tnUU8zLmpzLm1hcAo=";
|
|
683
|
+
const decodeBase64 = (base64) => Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
|
|
684
|
+
const blob = typeof self !== "undefined" && self.Blob && new Blob([decodeBase64(encodedJs)], { type: "text/javascript;charset=utf-8" });
|
|
685
|
+
function WorkerWrapper(options) {
|
|
686
|
+
let objURL;
|
|
687
|
+
try {
|
|
688
|
+
objURL = blob && (self.URL || self.webkitURL).createObjectURL(blob);
|
|
689
|
+
if (!objURL) throw "";
|
|
690
|
+
const worker = new Worker(objURL, {
|
|
691
|
+
name: options == null ? void 0 : options.name
|
|
692
|
+
});
|
|
693
|
+
worker.addEventListener("error", () => {
|
|
694
|
+
(self.URL || self.webkitURL).revokeObjectURL(objURL);
|
|
695
|
+
});
|
|
696
|
+
return worker;
|
|
697
|
+
} catch (e) {
|
|
698
|
+
return new Worker(
|
|
699
|
+
"data:text/javascript;base64," + encodedJs,
|
|
700
|
+
{
|
|
701
|
+
name: options == null ? void 0 : options.name
|
|
702
|
+
}
|
|
703
|
+
);
|
|
704
|
+
} finally {
|
|
705
|
+
objURL && (self.URL || self.webkitURL).revokeObjectURL(objURL);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
693
708
|
const SPLAT_ROW_LENGTH = 3 * 4 + 3 * 4 + 4 + 4;
|
|
694
709
|
function trimBuffer(_buffer, _maxSplats, _vertexCount) {
|
|
695
710
|
const actualVertexCount = Math.min(_vertexCount, _maxSplats);
|
|
@@ -712,7 +727,7 @@ void main () {
|
|
|
712
727
|
e.message
|
|
713
728
|
);
|
|
714
729
|
};
|
|
715
|
-
const worker = new
|
|
730
|
+
const worker = new WorkerWrapper();
|
|
716
731
|
worker.addEventListener("error", this.onError, false);
|
|
717
732
|
this._workerCtor = wrap(worker);
|
|
718
733
|
}
|
|
@@ -764,10 +779,8 @@ void main () {
|
|
|
764
779
|
mesh.name = url.split("/").pop().split("?")[0];
|
|
765
780
|
onLoad && onLoad(mesh);
|
|
766
781
|
} catch (e) {
|
|
767
|
-
if (onError)
|
|
768
|
-
|
|
769
|
-
else
|
|
770
|
-
console.error(e);
|
|
782
|
+
if (onError) onError(e);
|
|
783
|
+
else console.error(e);
|
|
771
784
|
this.manager.itemError(url);
|
|
772
785
|
}
|
|
773
786
|
}, onProgress, onError);
|
|
@@ -785,14 +798,12 @@ void main () {
|
|
|
785
798
|
this.splats = [];
|
|
786
799
|
this._ready = false;
|
|
787
800
|
this._activeCameraUpdate = () => {
|
|
788
|
-
if (!this._ready || this.isDisabled())
|
|
789
|
-
return;
|
|
801
|
+
if (!this._ready || this.isDisabled()) return;
|
|
790
802
|
this.splats.forEach(async (splat) => splat.update(this._viewer.scene.mainCamera, this._viewer.renderManager.webglRenderer));
|
|
791
803
|
};
|
|
792
804
|
this._geometryUpdate = (event) => {
|
|
793
805
|
var _a;
|
|
794
|
-
if (!this._ready || this.isDisabled() || !((_a = event.geometry) == null ? void 0 : _a.isGaussianSplatGeometry))
|
|
795
|
-
return;
|
|
806
|
+
if (!this._ready || this.isDisabled() || !((_a = event.geometry) == null ? void 0 : _a.isGaussianSplatGeometry)) return;
|
|
796
807
|
event.geometry.appliedMeshes.forEach(async (splat) => splat.update ? splat.update(this._viewer.scene.mainCamera, this._viewer.renderManager.webglRenderer) : void 0);
|
|
797
808
|
};
|
|
798
809
|
this._sortWorkerManager = new SortWorkerManager();
|
|
@@ -812,8 +823,7 @@ void main () {
|
|
|
812
823
|
return res;
|
|
813
824
|
}
|
|
814
825
|
}, ["splat"], [], true, (l) => {
|
|
815
|
-
if (!l)
|
|
816
|
-
return l;
|
|
826
|
+
if (!l) return l;
|
|
817
827
|
l.sortWorkerManager = this._sortWorkerManager;
|
|
818
828
|
l.onDispose = (mesh) => {
|
|
819
829
|
this.splats = this.splats.filter((splat) => splat !== mesh);
|
|
@@ -830,7 +840,7 @@ void main () {
|
|
|
830
840
|
}
|
|
831
841
|
onAdded(viewer) {
|
|
832
842
|
super.onAdded(viewer);
|
|
833
|
-
threepipe.createStyles(styles);
|
|
843
|
+
threepipe.createStyles(styles, viewer.container);
|
|
834
844
|
viewer.assetManager.importer.addImporter(this._importer);
|
|
835
845
|
viewer.scene.addEventListener("mainCameraUpdate", this._activeCameraUpdate);
|
|
836
846
|
viewer.scene.addEventListener("geometryUpdate", this._geometryUpdate);
|