From 66534c191ac3ddaf36e3bd87a77d93a2e60dec5c Mon Sep 17 00:00:00 2001 From: Aaron Boman Date: Fri, 1 Nov 2019 10:12:24 -0500 Subject: [PATCH] Prepare for v2.0.6 --- dist/layout.d.ts | 10 ++++----- dist/mesh.d.ts | 1 + dist/webgl-obj-loader.js | 40 +++++++++++++++++++++++++++--------- dist/webgl-obj-loader.min.js | 8 ++++---- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/dist/layout.d.ts b/dist/layout.d.ts index da3f6f4..57854f7 100644 --- a/dist/layout.d.ts +++ b/dist/layout.d.ts @@ -1,9 +1,9 @@ export declare enum TYPES { - "BYTE" = 1, - "UNSIGNED_BYTE" = 1, - "SHORT" = 2, - "UNSIGNED_SHORT" = 2, - "FLOAT" = 4 + "BYTE" = "BYTE", + "UNSIGNED_BYTE" = "UNSIGNED_BYTE", + "SHORT" = "SHORT", + "UNSIGNED_SHORT" = "UNSIGNED_SHORT", + "FLOAT" = "FLOAT" } export interface AttributeInfo { attribute: Attribute; diff --git a/dist/mesh.d.ts b/dist/mesh.d.ts index abca2ae..b2bd0d9 100644 --- a/dist/mesh.d.ts +++ b/dist/mesh.d.ts @@ -76,5 +76,6 @@ export default class Mesh { */ makeBufferData(layout: Layout): ArrayBufferWithItemSize; makeIndexBufferData(): Uint16ArrayWithItemSize; + makeIndexBufferDataForMaterials(...materialIndices: Array): Uint16ArrayWithItemSize; addMaterialLibrary(mtl: MaterialLibrary): void; } diff --git a/dist/webgl-obj-loader.js b/dist/webgl-obj-loader.js index 07bb35e..b4b2691 100644 --- a/dist/webgl-obj-loader.js +++ b/dist/webgl-obj-loader.js @@ -160,11 +160,11 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Layout", function() { return Layout; }); var TYPES; (function (TYPES) { - TYPES[TYPES["BYTE"] = 1] = "BYTE"; - TYPES[TYPES["UNSIGNED_BYTE"] = 1] = "UNSIGNED_BYTE"; - TYPES[TYPES["SHORT"] = 2] = "SHORT"; - TYPES[TYPES["UNSIGNED_SHORT"] = 2] = "UNSIGNED_SHORT"; - TYPES[TYPES["FLOAT"] = 4] = "FLOAT"; + TYPES["BYTE"] = "BYTE"; + TYPES["UNSIGNED_BYTE"] = "UNSIGNED_BYTE"; + TYPES["SHORT"] = "SHORT"; + TYPES["UNSIGNED_SHORT"] = "UNSIGNED_SHORT"; + TYPES["FLOAT"] = "FLOAT"; })(TYPES || (TYPES = {})); /** * An exception for when two or more of the same attributes are found in the @@ -215,7 +215,21 @@ class Attribute { this.size = size; this.type = type; this.normalized = normalized; - this.sizeOfType = this.type; + switch (type) { + case "BYTE": + case "UNSIGNED_BYTE": + this.sizeOfType = 1; + break; + case "SHORT": + case "UNSIGNED_SHORT": + this.sizeOfType = 2; + break; + case "FLOAT": + this.sizeOfType = 4; + break; + default: + throw new Error(`Unknown gl type: ${type}`); + } this.sizeInBytes = this.sizeOfType * size; } } @@ -1310,7 +1324,7 @@ class Mesh { Think of faces having Vertices which are comprised of the attributes location (v), texture (vt), and normal (vn). */ - const vertex = elements[j].split("/"); + const vertex = triangle[j].split("/"); // it's possible for faces to only specify the vertex // and the normal. In this case, vertex will only have // a length of 2 and not 3 and the normal will be the @@ -1699,6 +1713,12 @@ class Mesh { buffer.numItems = this.indices.length; return buffer; } + makeIndexBufferDataForMaterials(...materialIndices) { + const indices = new Array().concat(...materialIndices.map(mtlIdx => this.indicesPerMaterial[mtlIdx])); + const buffer = new Uint16Array(indices); + buffer.numItems = indices.length; + return buffer; + } addMaterialLibrary(mtl) { for (const name in mtl.materials) { if (!(name in this.materialIndices)) { @@ -1771,7 +1791,7 @@ function downloadMtlTextures(mtl, root) { const material = mtl.materials[materialName]; for (const attr of mapAttributes) { const mapData = material[attr]; - if (!mapData) { + if (!mapData || !mapData.filename) { continue; } const url = root + mapData.filename; @@ -2059,11 +2079,11 @@ function deleteMeshBuffers(gl, mesh) { /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -module.exports = __webpack_require__(/*! /Users/aaron/git/webgl-obj-loader/src/index.ts */"./src/index.ts"); +module.exports = __webpack_require__(/*! /home/aaron/google_drive/projects/webgl-obj-loader/src/index.ts */"./src/index.ts"); /***/ }) /******/ }); }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9PQkovd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovL09CSi93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9PQkovLi9zcmMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vT0JKLy4vc3JjL2xheW91dC50cyIsIndlYnBhY2s6Ly9PQkovLi9zcmMvbWF0ZXJpYWwudHMiLCJ3ZWJwYWNrOi8vT0JKLy4vc3JjL21lc2gudHMiLCJ3ZWJwYWNrOi8vT0JKLy4vc3JjL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxPO1FDVkE7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7OztRQUdBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSwwQ0FBMEMsZ0NBQWdDO1FBQzFFO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0Esd0RBQXdELGtCQUFrQjtRQUMxRTtRQUNBLGlEQUFpRCxjQUFjO1FBQy9EOztRQUVBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQSx5Q0FBeUMsaUNBQWlDO1FBQzFFLGdIQUFnSCxtQkFBbUIsRUFBRTtRQUNySTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBLDJCQUEyQiwwQkFBMEIsRUFBRTtRQUN2RCxpQ0FBaUMsZUFBZTtRQUNoRDtRQUNBO1FBQ0E7O1FBRUE7UUFDQSxzREFBc0QsK0RBQStEOztRQUVySDtRQUNBOzs7UUFHQTtRQUNBOzs7Ozs7Ozs7Ozs7O0FDbEZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFB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Q0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzFCLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFMUIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFbEMsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDOUIsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFOUIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFbEMsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDOUIsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFOUIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxD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QUcsQ0FBQyxDQUFDLENBQUM7WUFDakMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFakMsVUFBVTtZQUNWLE1BQU0sUUFBUSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBQ3hFLE1BQU0sUUFBUSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBQ3hFLE1BQU0sUUFBUSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBRXhFLE1BQU0sYUFBYSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDO1lBQ2xELE1BQU0sYUFBYSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDO1lBQ2xELE1BQU0sYUFBYSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDO1lBRWxELE1BQU0sYUFBYSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDO1lBQ2xELE1BQU0sYUFBYSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDO1lBQ2xELE1BQU0sYUFBYSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDO1lBRWxELE1BQU0sYUFBYSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDO1lBQ2xELE1BQU0sYUFBYSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDO1lBQ2xELE1BQU0sYUFBYSxHQUFHLFNBQVMsR0FBRyxJQUFJLEdBQUcsUUFBUSxDQUFDO1lBRWxELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQ3pCLGFBQWEsR0FBRyxhQUFhLEdBQUcsYUFBYSxHQUFHLGFBQWEsR0FBRyxhQUFhLEdBQUcsYUFBYSxDQUNoRyxDQUFDO1lBQ0YsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FDekIsYUFBYSxHQUFHLGFBQWEsR0FBRyxhQUFhLEdBQUcsYUFBYSxHQUFHLGFBQWEsR0FBRyxhQUFhLENBQ2hHLENBQUM7WUFDRixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUN6QixhQUFhLEdBQUcsYUFBYSxHQUFHLGFBQWEsR0FBRyxhQUFhLEdBQUcsYUFBYSxHQUFHLGFBQWEsQ0FDaEcsQ0FBQztZQUVGLFlBQVk7WUFDWixNQUFNLFNBQVMsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFdBQVcsR0FBRyxJQUFJLEdBQUcsV0FBVyxHQUFHLElBQUksQ0FBQztZQUMvRSxNQUFNLFNBQVMsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFdBQVcsR0FBRyxJQUFJLEdBQUcsV0FBVyxHQUFHLElBQUksQ0FBQztZQUMvRSxNQUFNLFNBQVMsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFdBQVcsR0FBRyxJQUFJLEdBQUcsV0FBVyxHQUFHLElBQUksQ0FBQztZQUUvRSxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUN2RCxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUN2RCxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUV2RCxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUN2RCxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUN2RCxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUV2RCxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUN2RCxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUN2RCxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxHQUFHLFNBQVMsQ0FBQztZQUV2RCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUMzQixlQUFlLEdBQUcsZUFBZTtnQkFDN0IsZUFBZSxHQUFHLGVBQWU7Z0JBQ2pDLGVBQWUsR0FBRyxlQUFlLENBQ3hDLENBQUM7WUFDRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUMzQixlQUFlLEdBQUcsZUFBZTtnQkFDN0IsZUFBZSxHQUFHLGVBQWU7Z0JBQ2pDLGVBQWUsR0FBRyxlQUFlLENBQ3hDLENBQUM7WUFDRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUMzQixlQUFlLEdBQUcsZUFBZTtnQkFDN0IsZUFBZSxHQUFHLGVBQWU7Z0JBQ2pDLGVBQWUsR0FBRyxlQUFlLENBQ3hDLENBQUM7WUFFRixRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUM3RCxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUM3RCxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUU3RCxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUM3RCxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUM3RCxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUU3RCxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUM3RCxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUM3RCxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztZQUU3RCxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZUFBZSxHQUFHLGFBQWEsQ0FBQztZQUNuRSxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZUFBZSxHQUFHLGFBQWEsQ0FBQztZQUNuRSxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZUFBZSxHQUFHLGFBQWEsQ0FBQztZQUVuRSxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZUFBZSxHQUFHLGFBQWEsQ0FBQztZQUNuRSxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZUFBZSxHQUFHLGFBQWEsQ0FBQztZQUNuRSxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZUFBZSxHQUFHLGFBQWEsQ0FBQztZQUVuRSxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZUFBZSxHQUFHLGFBQWEsQ0FBQztZQUNuRSxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZUFBZSxHQUFHLGFBQWEsQ0FBQztZQUNuRSxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZUFBZSxHQUFHLGFBQWEsQ0FBQztZQUVuRSx5QkFBeUI7U0FDNUI7UUFFRCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFDbEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDO0lBQzFDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsY0FBYyxDQUFDLE1BQWM7UUFDekIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sTUFBTSxHQUE0QixJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxDQUFDO1FBQ2xGLE1BQU0sQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQzNCLE1BQU0sUUFBUSxHQUFHLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFlBQVksR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNqRCxZQUFZLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7WUFDakMsK0RBQStEO1lBQy9ELGVBQWU7WUFDZixLQUFLLE1BQU0sU0FBUyxJQUFJLE1BQU0sQ0FBQyxVQUFVLEVBQUU7Z0JBQ3ZDLE1BQU0sTUFBTSxHQUFHLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7Z0JBQ3hFLFFBQVEsU0FBUyxDQUFDLEdBQUcsRUFBRTtvQkFDbkIsS0FBSyw4Q0FBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHO3dCQUNwQixRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDeEQsUUFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDaEUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDaEUsTUFBTTtvQkFDVixLQUFLLDhDQUFNLENBQUMsRUFBRSxDQUFDLEdBQUc7d0JBQ2QsUUFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7d0JBQ3hELFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7d0JBQ2hFLE1BQU07b0JBQ1YsS0FBSyw4Q0FBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHO3dCQUNsQixRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDN0QsUUFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDckUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDckUsTUFBTTtvQkFDVixLQUFLLDhDQUFNLENBQUMsY0FBYyxDQUFDLEdBQUc7d0JBQzFCLFFBQVEsQ0FBQyxRQUFR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Z2wtb2JqLWxvYWRlci5qcyIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFwiT0JKXCIsIFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcIk9CSlwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJPQkpcIl0gPSBmYWN0b3J5KCk7XG59KSh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDogdGhpcywgZnVuY3Rpb24oKSB7XG5yZXR1cm4gIiwiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZ2V0dGVyIH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4gXHRcdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuIFx0XHR9XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG4gXHR9O1xuXG4gXHQvLyBjcmVhdGUgYSBmYWtlIG5hbWVzcGFjZSBvYmplY3RcbiBcdC8vIG1vZGUgJiAxOiB2YWx1ZSBpcyBhIG1vZHVsZSBpZCwgcmVxdWlyZSBpdFxuIFx0Ly8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXG4gXHQvLyBtb2RlICYgNDogcmV0dXJuIHZhbHVlIHdoZW4gYWxyZWFkeSBucyBvYmplY3RcbiBcdC8vIG1vZGUgJiA4fDE6IGJlaGF2ZSBsaWtlIHJlcXVpcmVcbiBcdF9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XG4gXHRcdGlmKG1vZGUgJiAxKSB2YWx1ZSA9IF9fd2VicGFja19yZXF1aXJlX18odmFsdWUpO1xuIFx0XHRpZihtb2RlICYgOCkgcmV0dXJuIHZhbHVlO1xuIFx0XHRpZigobW9kZSAmIDQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgdmFsdWUuX19lc01vZHVsZSkgcmV0dXJuIHZhbHVlO1xuIFx0XHR2YXIgbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIobnMpO1xuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobnMsICdkZWZhdWx0JywgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XG4gXHRcdGlmKG1vZGUgJiAyICYmIHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgZm9yKHZhciBrZXkgaW4gdmFsdWUpIF9fd2VicGFja19yZXF1aXJlX18uZChucywga2V5LCBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHZhbHVlW2tleV07IH0uYmluZChudWxsLCBrZXkpKTtcbiBcdFx0cmV0dXJuIG5zO1xuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCIvXCI7XG5cblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSAwKTtcbiIsImltcG9ydCBNZXNoLCB7XG4gICAgTWVzaE9wdGlvbnMsXG4gICAgTWF0ZXJpYWxOYW1lVG9JbmRleCxcbiAgICBJbmRleFRvTWF0ZXJpYWwsXG4gICAgQXJyYXlCdWZmZXJXaXRoSXRlbVNpemUsXG4gICAgVWludDE2QXJyYXlXaXRoSXRlbVNpemUsXG59IGZyb20gXCIuL21lc2hcIjtcbmltcG9ydCB7IE1hdGVyaWFsLCBNYXRlcmlhbExpYnJhcnksIFZlYzMsIFVWVywgVGV4dHVyZU1hcERhdGEgfSBmcm9tIFwiLi9tYXRlcmlhbFwiO1xuaW1wb3J0IHsgTGF5b3V0LCBUWVBFUywgQXR0cmlidXRlSW5mbywgRHVwbGljYXRlQXR0cmlidXRlRXhjZXB0aW9uLCBBdHRyaWJ1dGUgfSBmcm9tIFwiLi9sYXlvdXRcIjtcbmltcG9ydCB7XG4gICAgZG93bmxvYWRNb2RlbHMsXG4gICAgZG93bmxvYWRNZXNoZXMsXG4gICAgaW5pdE1lc2hCdWZmZXJzLFxuICAgIGRlbGV0ZU1lc2hCdWZmZXJzLFxuICAgIERvd25sb2FkTW9kZWxzT3B0aW9ucyxcbiAgICBNZXNoTWFwLFxuICAgIE5hbWVBbmRVcmxzLFxuICAgIEV4dGVuZGVkR0xCdWZmZXIsXG4gICAgTWVzaFdpdGhCdWZmZXJzLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuXG5jb25zdCB2ZXJzaW9uID0gXCIyLjAuM1wiO1xuXG4vKipcbiAqIEBuYW1lc3BhY2VcbiAqL1xuZXhwb3J0IHtcbiAgICBBcnJheUJ1ZmZlcldpdGhJdGVtU2l6ZSxcbiAgICBBdHRyaWJ1dGUsXG4gICAgQXR0cmlidXRlSW5mbyxcbiAgICBEb3dubG9hZE1vZGVsc09wdGlvbnMsXG4gICAgRHVwbGljYXRlQXR0cmlidXRlRXhjZXB0aW9uLFxuICAgIEV4dGVuZGVkR0xCdWZmZXIsXG4gICAgSW5kZXhUb01hdGVyaWFsLFxuICAgIExheW91dCxcbiAgICBNYXRlcmlhbCxcbiAgICBNYXRlcmlhbExpYnJhcnksXG4gICAgTWF0ZXJpYWxOYW1lVG9JbmRleCxcbiAgICBNZXNoLFxuICAgIE1lc2hNYXAsXG4gICAgTWVzaE9wdGlvbnMsXG4gICAgTWVzaFdpdGhCdWZmZXJzLFxuICAgIE5hbWVBbmRVcmxzLFxuICAgIFRleHR1cmVNYXBEYXRhLFxuICAgIFRZUEVTLFxuICAgIFVpbnQxNkFycmF5V2l0aEl0ZW1TaXplLFxuICAgIFVWVyxcbiAgICBWZWMzLFxuICAgIGRvd25sb2FkTW9kZWxzLFxuICAgIGRvd25sb2FkTWVzaGVzLFxuICAgIGluaXRNZXNoQnVmZmVycyxcbiAgICBkZWxldGVNZXNoQnVmZmVycyxcbiAgICB2ZXJzaW9uLFxufTtcbiIsImV4cG9ydCBlbnVtIFRZUEVTIHtcbiAgICBcIkJZVEVcIiA9IDEsXG4gICAgXCJVTlNJR05FRF9CWVRFXCIgPSAxLFxuICAgIFwiU0hPUlRcIiA9IDIsXG4gICAgXCJVTlNJR05FRF9TSE9SVFwiID0gMixcbiAgICBcIkZMT0FUXCIgPSA0LFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEF0dHJpYnV0ZUluZm8ge1xuICAgIGF0dHJpYnV0ZTogQXR0cmlidXRlO1xuICAgIHNpemU6IEF0dHJpYnV0ZVtcInNpemVcIl07XG4gICAgdHlwZTogQXR0cmlidXRlW1widHlwZVwiXTtcbiAgICBub3JtYWxpemVkOiBBdHRyaWJ1dGVbXCJub3JtYWxpemVkXCJdO1xuICAgIG9mZnNldDogbnVtYmVyO1xuICAgIHN0cmlkZTogbnVtYmVyO1xufVxuXG4vKipcbiAqIEFuIGV4Y2VwdGlvbiBmb3Igd2hlbiB0d28gb3IgbW9yZSBvZiB0aGUgc2FtZSBhdHRyaWJ1dGVzIGFyZSBmb3VuZCBpbiB0aGVcbiAqIHNhbWUgbGF5b3V0LlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIER1cGxpY2F0ZUF0dHJpYnV0ZUV4Y2VwdGlvbiBleHRlbmRzIEVycm9yIHtcbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBEdXBsaWNhdGVBdHRyaWJ1dGVFeGNlcHRpb25cbiAgICAgKiBAcGFyYW0ge0F0dHJpYnV0ZX0gYXR0cmlidXRlIC0gVGhlIGF0dHJpYnV0ZSB0aGF0IHdhcyBmb3VuZCBtb3JlIHRoYW5cbiAgICAgKiAgICAgICAgb25jZSBpbiB0aGUge0BsaW5rIExheW91dH1cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihhdHRyaWJ1dGU6IEF0dHJpYnV0ZSkge1xuICAgICAgICBzdXBlcihgZm91bmQgZHVwbGljYXRlIGF0dHJpYnV0ZTogJHthdHRyaWJ1dGUua2V5fWApO1xuICAgIH1cbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGhvdyBhIHZlcnRleCBhdHRyaWJ1dGUgc2hvdWxkIGJlIHBhY2tlZCBpbnRvIGFuIGJ1ZmZlci5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBBdHRyaWJ1dGUge1xuICAgIHB1YmxpYyBzaXplT2ZUeXBlOiBudW1iZXI7XG4gICAgcHVibGljIHNpemVJbkJ5dGVzOiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIGF0dHJpYnV0ZS4gRG8gbm90IGNhbGwgdGhpcyBkaXJlY3RseSwgdXNlIHRoZSBwcmVkZWZpbmVkXG4gICAgICogY29uc3RhbnRzLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUgbmFtZSBvZiB0aGlzIGF0dHJpYnV0ZSBhcyBpZiBpdCB3ZXJlIGEga2V5IGluXG4gICAgICogICAgICAgIGFuIE9iamVjdC4gVXNlIHRoZSBjYW1lbCBjYXNlIHZlcnNpb24gb2YgdGhlIHVwcGVyIHNuYWtlIGNhc2VcbiAgICAgKiAgICAgICAgY29uc3QgbmFtZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSAtIFRoZSBudW1iZXIgb2YgY29tcG9uZW50cyBwZXIgdmVydGV4IGF0dHJpYnV0ZS5cbiAgICAgKiAgICAgICAgTXVzdCBiZSAxLCAyLCAzLCBvciA0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIGRhdGEgdHlwZSBvZiBlYWNoIGNvbXBvbmVudCBmb3IgdGhpc1xuICAgICAqICAgICAgICBhdHRyaWJ1dGUuIFBvc3NpYmxlIHZhbHVlczo8YnIvPlxuICAgICAqICAgICAgICBcIkJZVEVcIjogc2lnbmVkIDgtYml0IGludGVnZXIsIHdpdGggdmFsdWVzIGluIFstMTI4LCAxMjddPGJyLz5cbiAgICAgKiAgICAgICAgXCJTSE9SVFwiOiBzaWduZWQgMTYtYml0IGludGVnZXIsIHdpdGggdmFsdWVzIGluXG4gICAgICogICAgICAgICAgICBbLTMyNzY4LCAzMjc2N108YnIvPlxuICAgICAqICAgICAgICBcIlVOU0lHTkVEX0JZVEVcIjogdW5zaWduZWQgOC1iaXQgaW50ZWdlciwgd2l0aCB2YWx1ZXMgaW5cbiAgICAgKiAgICAgICAgICAgIFswLCAyNTVdPGJyLz5cbiAgICAgKiAgICAgICAgXCJVTlNJR05FRF9TSE9SVFwiOiB1bnNpZ25lZCAxNi1iaXQgaW50ZWdlciwgd2l0aCB2YWx1ZXMgaW5cbiAgICAgKiAgICAgICAgICAgIFswLCA2NTUzNV08YnIvPlxuICAgICAqICAgICAgICBcIkZMT0FUXCI6IDMyLWJpdCBmbG9hdGluZyBwb2ludCBudW1iZXJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG5vcm1hbGl6ZWQgLSBXaGV0aGVyIGludGVnZXIgZGF0YSB2YWx1ZXMgc2hvdWxkIGJlXG4gICAgICogICAgICAgIG5vcm1hbGl6ZWQgd2hlbiBiZWluZyBjYXN0ZWQgdG8gYSBmbG9hdC48YnIvPlxuICAgICAqICAgICAgICBJZiB0cnVlLCBzaWduZWQgaW50ZWdlcnMgYXJlIG5vcm1hbGl6ZWQgdG8gWy0xLCAxXS48YnIvPlxuICAgICAqICAgICAgICBJZiB0cnVlLCB1bnNpZ25lZCBpbnRlZ2VycyBhcmUgbm9ybWFsaXplZCB0byBbMCwgMV0uPGJyLz5cbiAgICAgKiAgICAgICAgRm9yIHR5cGUgXCJGTE9BVFwiLCB0aGlzIHBhcmFtZXRlciBoYXMgbm8gZWZmZWN0LlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBrZXk6IHN0cmluZywgcHVibGljIHNpemU6IG51bWJlciwgcHVibGljIHR5cGU6IFRZUEVTLCBwdWJsaWMgbm9ybWFsaXplZDogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgICAgIHRoaXMuc2l6ZU9mVHlwZSA9IHRoaXMudHlwZTtcbiAgICAgICAgdGhpcy5zaXplSW5CeXRlcyA9IHRoaXMuc2l6ZU9mVHlwZSAqIHNpemU7XG4gICAgfVxufVxuXG4vKipcbiAqIEEgY2xhc3MgdG8gcmVwcmVzZW50IHRoZSBtZW1vcnkgbGF5b3V0IGZvciBhIHZlcnRleCBhdHRyaWJ1dGUgYXJyYXkuIFVzZWQgYnlcbiAqIHtAbGluayBNZXNofSdzIFRCRCguLi4pIG1ldGhvZCB0byBnZW5lcmF0ZSBhIHBhY2tlZCBhcnJheSBmcm9tIG1lc2ggZGF0YS5cbiAqIDxwPlxuICogTGF5b3V0IGNhbiBzb3J0IG9mIGJlIHRob3VnaHQgb2YgYXMgYSBDLXN0eWxlIHN0cnVjdCBkZWNsYXJhdGlvbi5cbiAqIHtAbGluayBNZXNofSdzIFRCRCguLi4pIG1ldGhvZCB3aWxsIHVzZSB0aGUge0BsaW5rIExheW91dH0gaW5zdGFuY2UgdG9cbiAqIHBhY2sgYW4gYXJyYXkgaW4gdGhlIGdpdmVuIGF0dHJpYnV0ZSBvcmRlci5cbiAqIDxwPlxuICogTGF5b3V0IGFsc28gaXMgdmVyeSBoZWxwZnVsIHdoZW4gY2FsbGluZyBhIFdlYkdMIGNvbnRleHQnc1xuICogPGNvZGU+dmVydGV4QXR0cmliUG9pbnRlcjwvY29kZT4gbWV0aG9kLiBJZiB5b3UndmUgY3JlYXRlZCBhIGJ1ZmZlciB1c2luZ1xuICogYSBMYXlvdXQgaW5zdGFuY2UsIHRoZW4gdGhlIHNhbWUgTGF5b3V0IGluc3RhbmNlIGNhbiBiZSB1c2VkIHRvIGRldGVybWluZVxuICogdGhlIHNpemUsIHR5cGUsIG5vcm1hbGl6ZWQsIHN0cmlkZSwgYW5kIG9mZnNldCBwYXJhbWV0ZXJzIGZvclxuICogPGNvZGU+dmVydGV4QXR0cmliUG9pbnRlcjwvY29kZT4uXG4gKiA8cD5cbiAqIEZvciBleGFtcGxlOlxuICogPHByZT48Y29kZT5cbiAqXG4gKiBjb25zdCBpbmRleCA9IGdsY3R4LmdldEF0dHJpYkxvY2F0aW9uKHNoYWRlclByb2dyYW0sIFwicG9zXCIpO1xuICogZ2xjdHgudmVydGV4QXR0cmliUG9pbnRlcihcbiAqICAgbGF5b3V0LnBvc2l0aW9uLnNpemUsXG4gKiAgIGdsY3R4W2xheW91dC5wb3NpdGlvbi50eXBlXSxcbiAqICAgbGF5b3V0LnBvc2l0aW9uLm5vcm1hbGl6ZWQsXG4gKiAgIGxheW91dC5wb3NpdGlvbi5zdHJpZGUsXG4gKiAgIGxheW91dC5wb3NpdGlvbi5vZmZzZXQpO1xuICogPC9jb2RlPjwvcHJlPlxuICogQHNlZSB7QGxpbmsgTWVzaH1cbiAqL1xuZXhwb3J0IGNsYXNzIExheW91dCB7XG4gICAgLy8gR2VvbWV0cnkgYXR0cmlidXRlc1xuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZSBsYXlvdXQgdG8gcGFjayBhIHZlcnRleCdzIHgsIHksICYgeiBhcyBmbG9hdHNcbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIExheW91dH1cbiAgICAgKi9cbiAgICBzdGF0aWMgUE9TSVRJT04gPSBuZXcgQXR0cmlidXRlKFwicG9zaXRpb25cIiwgMywgVFlQRVMuRkxPQVQpO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlIGxheW91dCB0byBwYWNrIGEgdmVydGV4J3Mgbm9ybWFsJ3MgeCwgeSwgJiB6IGFzIGZsb2F0c1xuICAgICAqXG4gICAgICogQHNlZSB7QGxpbmsgTGF5b3V0fVxuICAgICAqL1xuICAgIHN0YXRpYyBOT1JNQUwgPSBuZXcgQXR0cmlidXRlKFwibm9ybWFsXCIsIDMsIFRZUEVTLkZMT0FUKTtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZSBsYXlvdXQgdG8gcGFjayBhIHZlcnRleCdzIG5vcm1hbCdzIHgsIHksICYgeiBhcyBmbG9hdHMuXG4gICAgICogPHA+XG4gICAgICogVGhpcyB2YWx1ZSB3aWxsIGJlIGNvbXB1dGVkIG9uLXRoZS1mbHkgYmFzZWQgb24gdGhlIHRleHR1cmUgY29vcmRpbmF0ZXMuXG4gICAgICogSWYgbm8gdGV4dHVyZSBjb29yZGluYXRlcyBhcmUgYXZhaWxhYmxlLCB0aGUgZ2VuZXJhdGVkIHZhbHVlIHdpbGwgZGVmYXVsdCB0b1xuICAgICAqIDAsIDAsIDAuXG4gICAgICpcbiAgICAgKiBAc2VlIHtAbGluayBMYXlvdXR9XG4gICAgICovXG4gICAgc3RhdGljIFRBTkdFTlQgPSBuZXcgQXR0cmlidXRlKFwidGFuZ2VudFwiLCAzLCBUWVBFUy5GTE9BVCk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGUgbGF5b3V0IHRvIHBhY2sgYSB2ZXJ0ZXgncyBub3JtYWwncyBiaXRhbmdlbnQgeCwgeSwgJiB6IGFzIGZsb2F0cy5cbiAgICAgKiA8cD5cbiAgICAgKiBUaGlzIHZhbHVlIHdpbGwgYmUgY29tcHV0ZWQgb24tdGhlLWZseSBiYXNlZCBvbiB0aGUgdGV4dHVyZSBjb29yZGluYXRlcy5cbiAgICAgKiBJZiBubyB0ZXh0dXJlIGNvb3JkaW5hdGVzIGFyZSBhdmFpbGFibGUsIHRoZSBnZW5lcmF0ZWQgdmFsdWUgd2lsbCBkZWZhdWx0IHRvXG4gICAgICogMCwgMCwgMC5cbiAgICAgKiBAc2VlIHtAbGluayBMYXlvdXR9XG4gICAgICovXG4gICAgc3RhdGljIEJJVEFOR0VOVCA9IG5ldyBBdHRyaWJ1dGUoXCJiaXRhbmdlbnRcIiwgMywgVFlQRVMuRkxPQVQpO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlIGxheW91dCB0byBwYWNrIGEgdmVydGV4J3MgdGV4dHVyZSBjb29yZGluYXRlcycgdSAmIHYgYXMgZmxvYXRzXG4gICAgICpcbiAgICAgKiBAc2VlIHtAbGluayBMYXlvdXR9XG4gICAgICovXG4gICAgc3RhdGljIFVWID0gbmV3IEF0dHJpYnV0ZShcInV2XCIsIDIsIFRZUEVTLkZMT0FUKTtcblxuICAgIC8vIE1hdGVyaWFsIGF0dHJpYnV0ZXNcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZSBsYXlvdXQgdG8gcGFjayBhbiB1bnNpZ25lZCBzaG9ydCB0byBiZSBpbnRlcnByZXRlZCBhcyBhIHRoZSBpbmRleFxuICAgICAqIGludG8gYSB7QGxpbmsgTWVzaH0ncyBtYXRlcmlhbHMgbGlzdC5cbiAgICAgKiA8cD5cbiAgICAgKiBUaGUgaW50ZW50aW9uIG9mIHRoaXMgdmFsdWUgaXMgdG8gc2VuZCBhbGwgb2YgdGhlIHtAbGluayBNZXNofSdzIG1hdGVyaWFsc1xuICAgICAqIGludG8gbXVsdGlwbGUgc2hhZGVyIHVuaWZvcm1zIGFuZCB0aGVuIHJlZmVyZW5jZSB0aGUgY3VycmVudCBvbmUgYnkgdGhpc1xuICAgICAqIHZlcnRleCBhdHRyaWJ1dGUuXG4gICAgICogPHA+XG4gICAgICogZXhhbXBsZSBnbHNsIGNvZGU6XG4gICAgICpcbiAgICAgKiA8cHJlPjxjb2RlPlxuICAgICAqICAvLyB0aGlzIGlzIGJvdW5kIHVzaW5nIE1BVEVSSUFMX0lOREVYXG4gICAgICogIGF0dHJpYnV0ZSBpbnQgbWF0ZXJpYWxJbmRleDtcbiAgICAgKlxuICAgICAqICBzdHJ1Y3QgTWF0ZXJpYWwge1xuICAgICAqICAgIHZlYzMgZGlmZnVzZTtcbiAgICAgKiAgICB2ZWMzIHNwZWN1bGFyO1xuICAgICAqICAgIHZlYzMgc3BlY3VsYXJFeHBvbmVudDtcbiAgICAgKiAgfTtcbiAgICAgKlxuICAgICAqICB1bmlmb3JtIE1hdGVyaWFsIG1hdGVyaWFsc1tNQVhfTUFURVJJQUxTXTtcbiAgICAgKlxuICAgICAqICAvLyAuLi5cbiAgICAgKlxuICAgICAqICB2ZWMzIGRpZmZ1c2UgPSBtYXRlcmlhbHNbbWF0ZXJpYWxJbmRleF07XG4gICAgICpcbiAgICAgKiA8L2NvZGU+PC9wcmU+XG4gICAgICogVE9ETzogTW9yZSBkZXNjcmlwdGlvbiAmIHRlc3QgdG8gbWFrZSBzdXJlIHN1YnNjcmlwdGluZyBieSBhdHRyaWJ1dGVzIGV2ZW5cbiAgICAgKiB3b3JrcyBmb3Igd2ViZ2xcbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIExheW91dH1cbiAgICAgKi9cbiAgICBzdGF0aWMgTUFURVJJQUxfSU5ERVggPSBuZXcgQXR0cmlidXRlKFwibWF0ZXJpYWxJbmRleFwiLCAxLCBUWVBFUy5TSE9SVCk7XG4gICAgc3RhdGljIE1BVEVSSUFMX0VOQUJMRUQgPSBuZXcgQXR0cmlidXRlKFwibWF0ZXJpYWxFbmFibGVkXCIsIDEsIFRZUEVTLlVOU0lHTkVEX1NIT1JUKTtcbiAgICBzdGF0aWMgQU1CSUVOVCA9IG5ldyBBdHRyaWJ1dGUoXCJhbWJpZW50XCIsIDMsIFRZUEVTLkZMT0FUKTtcbiAgICBzdGF0aWMgRElGRlVTRSA9IG5ldyBBdHRyaWJ1dGUoXCJkaWZmdXNlXCIsIDMsIFRZUEVTLkZMT0FUKTtcbiAgICBzdGF0aWMgU1BFQ1VMQVIgPSBuZXcgQXR0cmlidXRlKFwic3BlY3VsYXJcIiwgMywgVFlQRVMuRkxPQVQpO1xuICAgIHN0YXRpYyBTUEVDVUxBUl9FWFBPTkVOVCA9IG5ldyBBdHRyaWJ1dGUoXCJzcGVjdWxhckV4cG9uZW50XCIsIDMsIFRZUEVTLkZMT0FUKTtcbiAgICBzdGF0aWMgRU1JU1NJVkUgPSBuZXcgQXR0cmlidXRlKFwiZW1pc3NpdmVcIiwgMywgVFlQRVMuRkxPQVQpO1xuICAgIHN0YXRpYyBUUkFOU01JU1NJT05fRklMVEVSID0gbmV3IEF0dHJpYnV0ZShcInRyYW5zbWlzc2lvbkZpbHRlclwiLCAzLCBUWVBFUy5GTE9BVCk7XG4gICAgc3RhdGljIERJU1NPTFZFID0gbmV3IEF0dHJpYnV0ZShcImRpc3NvbHZlXCIsIDEsIFRZUEVTLkZMT0FUKTtcbiAgICBzdGF0aWMgSUxMVU1JTkFUSU9OID0gbmV3IEF0dHJpYnV0ZShcImlsbHVtaW5hdGlvblwiLCAxLCBUWVBFUy5VTlNJR05FRF9TSE9SVCk7XG4gICAgc3RhdGljIFJFRlJBQ1RJT05fSU5ERVggPSBuZXcgQXR0cmlidXRlKFwicmVmcmFjdGlvbkluZGV4XCIsIDEsIFRZUEVTLkZMT0FUKTtcbiAgICBzdGF0aWMgU0hBUlBORVNTID0gbmV3IEF0dHJpYnV0ZShcInNoYXJwbmVzc1wiLCAxLCBUWVBFUy5GTE9BVCk7XG4gICAgc3RhdGljIE1BUF9ESUZGVVNFID0gbmV3IEF0dHJpYnV0ZShcIm1hcERpZmZ1c2VcIiwgMSwgVFlQRVMuU0hPUlQpO1xuICAgIHN0YXRpYyBNQVBfQU1CSUVOVCA9IG5ldyBBdHRyaWJ1dGUoXCJtYXBBbWJpZW50XCIsIDEsIFRZUEVTLlNIT1JUKTtcbiAgICBzdGF0aWMgTUFQX1NQRUNVTEFSID0gbmV3IEF0dHJpYnV0ZShcIm1hcFNwZWN1bGFyXCIsIDEsIFRZUEVTLlNIT1JUKTtcbiAgICBzdGF0aWMgTUFQX1NQRUNVTEFSX0VYUE9ORU5UID0gbmV3IEF0dHJpYnV0ZShcIm1hcFNwZWN1bGFyRXhwb25lbnRcIiwgMSwgVFlQRVMuU0hPUlQpO1xuICAgIHN0YXRpYyBNQVBfRElTU09MVkUgPSBuZXcgQXR0cmlidXRlKFwibWFwRGlzc29sdmVcIiwgMSwgVFlQRVMuU0hPUlQpO1xuICAgIHN0YXRpYyBBTlRJX0FMSUFTSU5HID0gbmV3IEF0dHJpYnV0ZShcImFudGlBbGlhc2luZ1wiLCAxLCBUWVBFUy5VTlNJR05FRF9TSE9SVCk7XG4gICAgc3RhdGljIE1BUF9CVU1QID0gbmV3IEF0dHJpYnV0ZShcIm1hcEJ1bXBcIiwgMSwgVFlQRVMuU0hPUlQpO1xuICAgIHN0YXRpYyBNQVBfRElTUExBQ0VNRU5UID0gbmV3IEF0dHJpYnV0ZShcIm1hcERpc3BsYWNlbWVudFwiLCAxLCBUWVBFUy5TSE9SVCk7XG4gICAgc3RhdGljIE1BUF9ERUNBTCA9IG5ldyBBdHRyaWJ1dGUoXCJtYXBEZWNhbFwiLCAxLCBUWVBFUy5TSE9SVCk7XG4gICAgc3RhdGljIE1BUF9FTUlTU0lWRSA9IG5ldyBBdHRyaWJ1dGUoXCJtYXBFbWlzc2l2ZVwiLCAxLCBUWVBFUy5TSE9SVCk7XG5cbiAgICBwdWJsaWMgc3RyaWRlOiBudW1iZXI7XG4gICAgcHVibGljIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZVtdO1xuICAgIHB1YmxpYyBhdHRyaWJ1dGVNYXA6IHsgW2lkeDogc3RyaW5nXTogQXR0cmlidXRlSW5mbyB9O1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIExheW91dCBvYmplY3QuIFRoaXMgY29uc3RydWN0b3Igd2lsbCB0aHJvdyBpZiBhbnkgZHVwbGljYXRlXG4gICAgICogYXR0cmlidXRlcyBhcmUgZ2l2ZW4uXG4gICAgICogQHBhcmFtIHtBcnJheX0gLi4uYXR0cmlidXRlcyAtIEFuIG9yZGVyZWQgbGlzdCBvZiBhdHRyaWJ1dGVzIHRoYXRcbiAgICAgKiAgICAgICAgZGVzY3JpYmUgdGhlIGRlc2lyZWQgbWVtb3J5IGxheW91dCBmb3IgZWFjaCB2ZXJ0ZXggYXR0cmlidXRlLlxuICAgICAqICAgICAgICA8cD5cbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIE1lc2h9XG4gICAgICovXG4gICAgY29uc3RydWN0b3IoLi4uYXR0cmlidXRlczogQXR0cmlidXRlW10pIHtcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gYXR0cmlidXRlcztcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVNYXAgPSB7fTtcbiAgICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICAgIGxldCBtYXhTdHJpZGVNdWx0aXBsZSA9IDA7XG4gICAgICAgIGZvciAoY29uc3QgYXR0cmlidXRlIG9mIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmF0dHJpYnV0ZU1hcFthdHRyaWJ1dGUua2V5XSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBEdXBsaWNhdGVBdHRyaWJ1dGVFeGNlcHRpb24oYXR0cmlidXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nIHRvIHNhdGlzZnkgV2ViR0wncyByZXF1aXJlbWVudCB0aGF0IGFsbFxuICAgICAgICAgICAgLy8gdmVydGV4QXR0cmliUG9pbnRlciBjYWxscyBoYXZlIGFuIG9mZnNldCB0aGF0IGlzIGEgbXVsdGlwbGUgb2ZcbiAgICAgICAgICAgIC8vIHRoZSB0eXBlIHNpemUuXG4gICAgICAgICAgICBpZiAob2Zmc2V0ICUgYXR0cmlidXRlLnNpemVPZlR5cGUgIT09IDApIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gYXR0cmlidXRlLnNpemVPZlR5cGUgLSAob2Zmc2V0ICUgYXR0cmlidXRlLnNpemVPZlR5cGUpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIkxheW91dCByZXF1aXJlcyBwYWRkaW5nIGJlZm9yZSBcIiArIGF0dHJpYnV0ZS5rZXkgKyBcIiBhdHRyaWJ1dGVcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmF0dHJpYnV0ZU1hcFthdHRyaWJ1dGUua2V5XSA9IHtcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6IGF0dHJpYnV0ZSxcbiAgICAgICAgICAgICAgICBzaXplOiBhdHRyaWJ1dGUuc2l6ZSxcbiAgICAgICAgICAgICAgICB0eXBlOiBhdHRyaWJ1dGUudHlwZSxcbiAgICAgICAgICAgICAgICBub3JtYWxpemVkOiBhdHRyaWJ1dGUubm9ybWFsaXplZCxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgICAgICAgIH0gYXMgQXR0cmlidXRlSW5mbztcbiAgICAgICAgICAgIG9mZnNldCArPSBhdHRyaWJ1dGUuc2l6ZUluQnl0ZXM7XG4gICAgICAgICAgICBtYXhTdHJpZGVNdWx0aXBsZSA9IE1hdGgubWF4KG1heFN0cmlkZU11bHRpcGxlLCBhdHRyaWJ1dGUuc2l6ZU9mVHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQWRkIHBhZGRpbmcgdG8gdGhlIGVuZCB0byBzYXRpc2Z5IFdlYkdMJ3MgcmVxdWlyZW1lbnQgdGhhdCBhbGxcbiAgICAgICAgLy8gdmVydGV4QXR0cmliUG9pbnRlciBjYWxscyBoYXZlIGEgc3RyaWRlIHRoYXQgaXMgYSBtdWx0aXBsZSBvZiB0aGVcbiAgICAgICAgLy8gdHlwZSBzaXplLiBCZWNhdXNlIHdlJ3JlIHB1dHRpbmcgZGlmZmVyZW50bHkgc2l6ZWQgYXR0cmlidXRlcyBpbnRvXG4gICAgICAgIC8vIHRoZSBzYW1lIGJ1ZmZlciwgaXQgbXVzdCBiZSBwYWRkZWQgdG8gYSBtdWx0aXBsZSBvZiB0aGUgbGFyZ2VzdFxuICAgICAgICAvLyB0eXBlIHNpemUuXG4gICAgICAgIGlmIChvZmZzZXQgJSBtYXhTdHJpZGVNdWx0aXBsZSAhPT0gMCkge1xuICAgICAgICAgICAgb2Zmc2V0ICs9IG1heFN0cmlkZU11bHRpcGxlIC0gKG9mZnNldCAlIG1heFN0cmlkZU11bHRpcGxlKTtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIkxheW91dCByZXF1aXJlcyBwYWRkaW5nIGF0IHRoZSBiYWNrXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyaWRlID0gb2Zmc2V0O1xuICAgICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZSBvZiBhdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgICB0aGlzLmF0dHJpYnV0ZU1hcFthdHRyaWJ1dGUua2V5XS5zdHJpZGUgPSB0aGlzLnN0cmlkZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImV4cG9ydCB0eXBlIFZlYzMgPSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgVVZXIHtcbiAgICB1OiBudW1iZXI7XG4gICAgdjogbnVtYmVyO1xuICAgIHc6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTWFwRGF0YSB7XG4gICAgY29sb3JDb3JyZWN0aW9uOiBib29sZWFuO1xuICAgIGhvcml6b250YWxCbGVuZGluZzogYm9vbGVhbjtcbiAgICB2ZXJ0aWNhbEJsZW5kaW5nOiBib29sZWFuO1xuICAgIGJvb3N0TWlwTWFwU2hhcnBuZXNzOiBudW1iZXI7XG4gICAgbW9kaWZ5VGV4dHVyZU1hcDoge1xuICAgICAgICBicmlnaHRuZXNzOiBudW1iZXI7XG4gICAgICAgIGNvbnRyYXN0OiBudW1iZXI7XG4gICAgfTtcbiAgICBvZmZzZXQ6IFVWVztcbiAgICBzY2FsZTogVVZXO1xuICAgIHR1cmJ1bGVuY2U6IFVWVztcbiAgICBjbGFtcDogYm9vbGVhbjtcbiAgICB0ZXh0dXJlUmVzb2x1dGlvbjogbnVtYmVyIHwgbnVsbDtcbiAgICBidW1wTXVsdGlwbGllcjogbnVtYmVyO1xuICAgIGltZkNoYW46IHN0cmluZyB8IG51bGw7XG4gICAgZmlsZW5hbWU6IHN0cmluZztcbiAgICByZWZsZWN0aW9uVHlwZT86IHN0cmluZztcbiAgICB0ZXh0dXJlPzogSFRNTEltYWdlRWxlbWVudDtcbn1cblxuLyoqXG4gKiBUaGUgTWF0ZXJpYWwgY2xhc3MuXG4gKi9cbmV4cG9ydCBjbGFzcyBNYXRlcmlhbCB7XG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSB0aGUgdW5pcXVlIG5hbWUgb2YgdGhlIG1hdGVyaWFsXG4gICAgICovXG4gICAgLy8gVGhlIHZhbHVlcyBmb3IgdGhlIGZvbGxvd2luZyBhdHRpYnV0ZXNcbiAgICAvLyBhcmUgYW4gYXJyYXkgb2YgUiwgRywgQiBub3JtYWxpemVkIHZhbHVlcy5cbiAgICAvLyBLYSAtIEFtYmllbnQgUmVmbGVjdGl2aXR5XG4gICAgYW1iaWVudDogVmVjMyA9IFswLCAwLCAwXTtcbiAgICAvLyBLZCAtIERlZnVzZSBSZWZsZWN0aXZpdHlcbiAgICBkaWZmdXNlOiBWZWMzID0gWzAsIDAsIDBdO1xuICAgIC8vIEtzXG4gICAgc3BlY3VsYXI6IFZlYzMgPSBbMCwgMCwgMF07XG4gICAgLy8gS2VcbiAgICBlbWlzc2l2ZTogVmVjMyA9IFswLCAwLCAwXTtcbiAgICAvLyBUZlxuICAgIHRyYW5zbWlzc2lvbkZpbHRlcjogVmVjMyA9IFswLCAwLCAwXTtcbiAgICAvLyBkXG4gICAgZGlzc29sdmU6IG51bWJlciA9IDA7XG4gICAgLy8gdmFsaWQgcmFuZ2UgaXMgYmV0d2VlbiAwIGFuZCAxMDAwXG4gICAgc3BlY3VsYXJFeHBvbmVudDogbnVtYmVyID0gMDtcbiAgICAvLyBlaXRoZXIgZCBvciBUcjsgdmFsaWQgdmFsdWVzIGFyZSBub3JtYWxpemVkXG4gICAgdHJhbnNwYXJlbmN5OiBudW1iZXIgPSAwO1xuICAgIC8vIGlsbHVtIC0gdGhlIGVudW0gb2YgdGhlIGlsbHVtaW5hdGlvbiBtb2RlbCB0byB1c2VcbiAgICBpbGx1bWluYXRpb246IG51bWJlciA9IDA7XG4gICAgLy8gTmkgLSBTZXQgdG8gXCJub3JtYWxcIiAoYWlyKS5cbiAgICByZWZyYWN0aW9uSW5kZXg6IG51bWJlciA9IDE7XG4gICAgLy8gc2hhcnBuZXNzXG4gICAgc2hhcnBuZXNzOiBudW1iZXIgPSAwO1xuICAgIC8vIG1hcF9LZFxuICAgIG1hcERpZmZ1c2U6IFRleHR1cmVNYXBEYXRhID0gZW1wdHlUZXh0dXJlT3B0aW9ucygpO1xuICAgIC8vIG1hcF9LYVxuICAgIG1hcEFtYmllbnQ6IFRleHR1cmVNYXBEYXRhID0gZW1wdHlUZXh0dXJlT3B0aW9ucygpO1xuICAgIC8vIG1hcF9Lc1xuICAgIG1hcFNwZWN1bGFyOiBUZXh0dXJlTWFwRGF0YSA9IGVtcHR5VGV4dHVyZU9wdGlvbnMoKTtcbiAgICAvLyBtYXBfTnNcbiAgICBtYXBTcGVjdWxhckV4cG9uZW50OiBUZXh0dXJlTWFwRGF0YSA9IGVtcHR5VGV4dHVyZU9wdGlvbnMoKTtcbiAgICAvLyBtYXBfZFxuICAgIG1hcERpc3NvbHZlOiBUZXh0dXJlTWFwRGF0YSA9IGVtcHR5VGV4dHVyZU9wdGlvbnMoKTtcbiAgICAvLyBtYXBfYWF0XG4gICAgYW50aUFsaWFzaW5nOiBib29sZWFuID0gZmFsc2U7XG4gICAgLy8gbWFwX2J1bXAgb3IgYnVtcFxuICAgIG1hcEJ1bXA6IFRleHR1cmVNYXBEYXRhID0gZW1wdHlUZXh0dXJlT3B0aW9ucygpO1xuICAgIC8vIGRpc3BcbiAgICBtYXBEaXNwbGFjZW1lbnQ6IFRleHR1cmVNYXBEYXRhID0gZW1wdHlUZXh0dXJlT3B0aW9ucygpO1xuICAgIC8vIGRlY2FsXG4gICAgbWFwRGVjYWw6IFRleHR1cmVNYXBEYXRhID0gZW1wdHlUZXh0dXJlT3B0aW9ucygpO1xuICAgIC8vIG1hcF9LZVxuICAgIG1hcEVtaXNzaXZlOiBUZXh0dXJlTWFwRGF0YSA9IGVtcHR5VGV4dHVyZU9wdGlvbnMoKTtcbiAgICAvLyByZWZsIC0gd2hlbiB0aGUgcmVmbGVjdGlvbiB0eXBlIGlzIGEgY3ViZSwgdGhlcmUgd2lsbCBiZSBtdWx0aXBsZSByZWZsXG4gICAgLy8gICAgICAgIHN0YXRlbWVudHMgZm9yIGVhY2ggc2lkZSBvZiB0aGUgY3ViZS4gSWYgaXQncyBhIHNwaGVyaWNhbFxuICAgIC8vICAgICAgICByZWZsZWN0aW9uLCB0aGVyZSBzaG91bGQgb25seSBldmVyIGJlIG9uZS5cbiAgICBtYXBSZWZsZWN0aW9uczogVGV4dHVyZU1hcERhdGFbXSA9IFtdO1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBuYW1lOiBzdHJpbmcpIHt9XG59XG5cbmNvbnN0IFNFTlRJTkVMX01BVEVSSUFMID0gbmV3IE1hdGVyaWFsKFwic2VudGluZWxcIik7XG5cbi8qKlxuICogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvV2F2ZWZyb250Xy5vYmpfZmlsZVxuICogaHR0cDovL3BhdWxib3Vya2UubmV0L2RhdGFmb3JtYXRzL210bC9cbiAqL1xuZXhwb3J0IGNsYXNzIE1hdGVyaWFsTGlicmFyeSB7XG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyB0aGUgTWF0ZXJpYWwgUGFyc2VyXG4gICAgICogQHBhcmFtIG10bERhdGEgdGhlIE1UTCBmaWxlIGNvbnRlbnRzXG4gICAgICovXG4gICAgcHVibGljIGN1cnJlbnRNYXRlcmlhbDogTWF0ZXJpYWwgPSBTRU5USU5FTF9NQVRFUklBTDtcbiAgICBwdWJsaWMgbWF0ZXJpYWxzOiB7IFtrOiBzdHJpbmddOiBNYXRlcmlhbCB9ID0ge307XG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgZGF0YTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMucGFyc2UoKTtcbiAgICB9XG5cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbiAgICAvKiB0aGUgZnVuY3Rpb24gbmFtZXMgaGVyZSBkaXNvYmV5IGNhbWVsQ2FzZSBjb252ZW50aW9uc1xuICAgICB0byBtYWtlIHBhcnNpbmcvcm91dGluZyBlYXNpZXIuIHNlZSB0aGUgcGFyc2UgZnVuY3Rpb25cbiAgICAgZG9jdW1lbnRhdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4gKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgTWF0ZXJpYWwgb2JqZWN0IGFuZCBhZGRzIHRvIHRoZSByZWdpc3RyeS5cbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9uZXdtdGwodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICBjb25zdCBuYW1lID0gdG9rZW5zWzBdO1xuICAgICAgICAvLyBjb25zb2xlLmluZm8oJ1BhcnNpbmcgbmV3IE1hdGVyaWFsOicsIG5hbWUpO1xuXG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsID0gbmV3IE1hdGVyaWFsKG5hbWUpO1xuICAgICAgICB0aGlzLm1hdGVyaWFsc1tuYW1lXSA9IHRoaXMuY3VycmVudE1hdGVyaWFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSB0aGUgZG9jdW1lbmF0aW9uIGZvciBwYXJzZV9LYSBiZWxvdyBmb3IgYSBiZXR0ZXIgdW5kZXJzdGFuZGluZy5cbiAgICAgKlxuICAgICAqIEdpdmVuIGEgbGlzdCBvZiBwb3NzaWJsZSBjb2xvciB0b2tlbnMsIHJldHVybnMgYW4gYXJyYXkgb2YgUiwgRywgYW5kIEJcbiAgICAgKiBjb2xvciB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKiBAcmV0dXJuIHsqfSBhIDMgZWxlbWVudCBhcnJheSBjb250YWluaW5nIHRoZSBSLCBHLCBhbmQgQiB2YWx1ZXNcbiAgICAgKiBvZiB0aGUgY29sb3IuXG4gICAgICovXG4gICAgcGFyc2VDb2xvcih0b2tlbnM6IHN0cmluZ1tdKTogVmVjMyB7XG4gICAgICAgIGlmICh0b2tlbnNbMF0gPT0gXCJzcGVjdHJhbFwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJUaGUgTVRMIHBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHNwZWN0cmFsIGN1cnZlIGZpbGVzLiBZb3Ugd2lsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwibmVlZCB0byBjb252ZXJ0IHRoZSBNVEwgY29sb3JzIHRvIGVpdGhlciBSR0Igb3IgQ0lFWFlaLlwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0b2tlbnNbMF0gPT0gXCJ4eXpcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiVGhlIE1UTCBwYXJzZXIgZG9lcyBub3QgY3VycmVudGx5IHN1cHBvcnQgWFlaIGNvbG9ycy4gRWl0aGVyIGNvbnZlcnQgdGhlIFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJYWVogdmFsdWVzIHRvIFJHQiBvciBjcmVhdGUgYW4gaXNzdWUgdG8gYWRkIHN1cHBvcnQgZm9yIFhZWlwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZyb20gbXkgdW5kZXJzdGFuZGluZyBvZiB0aGUgc3BlYywgUkdCIHZhbHVlcyBhdCB0aGlzIHBvaW50XG4gICAgICAgIC8vIHdpbGwgZWl0aGVyIGJlIDMgZmxvYXRzIG9yIGV4YWN0bHkgMSBmbG9hdCwgc28gdGhhdCdzIHRoZSBjaGVja1xuICAgICAgICAvLyB0aGF0IGknbSBnb2luZyB0byBwZXJmb3JtIGhlcmVcbiAgICAgICAgaWYgKHRva2Vucy5sZW5ndGggPT0gMykge1xuICAgICAgICAgICAgY29uc3QgW3gsIHksIHpdID0gdG9rZW5zO1xuICAgICAgICAgICAgcmV0dXJuIFtwYXJzZUZsb2F0KHgpLCBwYXJzZUZsb2F0KHkpLCBwYXJzZUZsb2F0KHopXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNpbmNlIHRva2VucyBhdCB0aGlzIHBvaW50IGhhcyBhIGxlbmd0aCBvZiAzLCB3ZSdyZSBnb2luZyB0byBhc3N1bWVcbiAgICAgICAgLy8gaXQncyBleGFjdGx5IDEsIHNraXBwaW5nIHRoZSBjaGVjayBmb3IgMi5cbiAgICAgICAgY29uc3QgdmFsdWUgPSBwYXJzZUZsb2F0KHRva2Vuc1swXSk7XG4gICAgICAgIC8vIGluIHRoaXMgY2FzZSwgYWxsIHZhbHVlcyBhcmUgZXF1aXZhbGVudFxuICAgICAgICByZXR1cm4gW3ZhbHVlLCB2YWx1ZSwgdmFsdWVdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlIHRoZSBhbWJpZW50IHJlZmxlY3Rpdml0eVxuICAgICAqXG4gICAgICogQSBLYSBkaXJlY3RpdmUgY2FuIHRha2Ugb25lIG9mIHRocmVlIGZvcm1zOlxuICAgICAqICAgLSBLYSByIGcgYlxuICAgICAqICAgLSBLYSBzcGVjdHJhbCBmaWxlLnJmbFxuICAgICAqICAgLSBLYSB4eXogeCB5IHpcbiAgICAgKiBUaGVzZSB0aHJlZSBmb3JtcyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIGluIHRoYXQgb25seSBvbmVcbiAgICAgKiBkZWNsYXJhdGlvbiBjYW4gZXhpc3QgcGVyIG1hdGVyaWFsLiBJdCBpcyBjb25zaWRlcmVkIGEgc3ludGF4XG4gICAgICogZXJyb3Igb3RoZXJ3aXNlLlxuICAgICAqXG4gICAgICogVGhlIFwiS2FcIiBmb3JtIHNwZWNpZmllcyB0aGUgYW1iaWVudCByZWZsZWN0aXZpdHkgdXNpbmcgUkdCIHZhbHVlcy5cbiAgICAgKiBUaGUgXCJnXCIgYW5kIFwiYlwiIHZhbHVlcyBhcmUgb3B0aW9uYWwuIElmIG9ubHkgdGhlIFwiclwiIHZhbHVlIGlzXG4gICAgICogc3BlY2lmaWVkLCB0aGVuIHRoZSBcImdcIiBhbmQgXCJiXCIgdmFsdWVzIGFyZSBhc3NpZ25lZCB0aGUgdmFsdWUgb2ZcbiAgICAgKiBcInJcIi4gVmFsdWVzIGFyZSBub3JtYWxseSBpbiB0aGUgcmFuZ2UgMC4wIHRvIDEuMC4gVmFsdWVzIG91dHNpZGVcbiAgICAgKiBvZiB0aGlzIHJhbmdlIGluY3JlYXNlIG9yIGRlY3JlYXNlIHRoZSByZWZsZWN0aXZpdHkgYWNjb3JkaW5nbHkuXG4gICAgICpcbiAgICAgKiBUaGUgXCJLYSBzcGVjdHJhbFwiIGZvcm0gc3BlY2lmaWVzIHRoZSBhbWJpZW50IHJlZmxlY3Rpdml0eSB1c2luZyBhXG4gICAgICogc3BlY3RyYWwgY3VydmUuIFwiZmlsZS5yZmxcIiBpcyB0aGUgbmFtZSBvZiB0aGUgXCIucmZsXCIgZmlsZSBjb250YWluaW5nXG4gICAgICogdGhlIGN1cnZlIGRhdGEuIFwiZmFjdG9yXCIgaXMgYW4gb3B0aW9uYWwgYXJndW1lbnQgd2hpY2ggaXMgYSBtdWx0aXBsaWVyXG4gICAgICogZm9yIHRoZSB2YWx1ZXMgaW4gdGhlIC5yZmwgZmlsZSBhbmQgZGVmYXVsdHMgdG8gMS4wIGlmIG5vdCBzcGVjaWZpZWQuXG4gICAgICpcbiAgICAgKiBUaGUgXCJLYSB4eXpcIiBmb3JtIHNwZWNpZmllcyB0aGUgYW1iaWVudCByZWZsZWN0aXZpdHkgdXNpbmcgQ0lFWFlaIHZhbHVlcy5cbiAgICAgKiBcInggeSB6XCIgYXJlIHRoZSB2YWx1ZXMgb2YgdGhlIENJRVhZWiBjb2xvciBzcGFjZS4gVGhlIFwieVwiIGFuZCBcInpcIiBhcmd1bWVudHNcbiAgICAgKiBhcmUgb3B0aW9uYWwgYW5kIHRha2Ugb24gdGhlIHZhbHVlIG9mIHRoZSBcInhcIiBjb21wb25lbnQgaWYgb25seSBcInhcIiBpc1xuICAgICAqIHNwZWNpZmllZC4gVGhlIFwieCB5IHpcIiB2YWx1ZXMgYXJlIG5vcm1hbGx5IGluIHRoZSByYW5nZSBvZiAwLjAgdG8gMS4wIGFuZFxuICAgICAqIGluY3JlYXNlIG9yIGRlY3JlYXNlIGFtYmllbnQgcmVmbGVjdGl2aXR5IGFjY29yZGluZ2x5IG91dHNpZGUgb2YgdGhhdFxuICAgICAqIHJhbmdlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyB0aGUgdG9rZW5zIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGlyZWN0aXZlXG4gICAgICovXG4gICAgcGFyc2VfS2EodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5hbWJpZW50ID0gdGhpcy5wYXJzZUNvbG9yKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGlmZnVzZSBSZWZsZWN0aXZpdHlcbiAgICAgKlxuICAgICAqIFNpbWlsYXIgdG8gdGhlIEthIGRpcmVjdGl2ZS4gU2ltcGx5IHJlcGxhY2UgXCJLYVwiIHdpdGggXCJLZFwiIGFuZCB0aGUgcnVsZXNcbiAgICAgKiBhcmUgdGhlIHNhbWVcbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgdGhlIHRva2VucyBhc3NvY2lhdGVkIHdpdGggdGhlIGRpcmVjdGl2ZVxuICAgICAqL1xuICAgIHBhcnNlX0tkKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwuZGlmZnVzZSA9IHRoaXMucGFyc2VDb2xvcih0b2tlbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNwZWN0cmFsIFJlZmxlY3Rpdml0eVxuICAgICAqXG4gICAgICogU2ltaWxhciB0byB0aGUgS2EgZGlyZWN0aXZlLiBTaW1wbHkgcmVwbGFjZSBcIktzXCIgd2l0aCBcIktkXCIgYW5kIHRoZSBydWxlc1xuICAgICAqIGFyZSB0aGUgc2FtZVxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyB0aGUgdG9rZW5zIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGlyZWN0aXZlXG4gICAgICovXG4gICAgcGFyc2VfS3ModG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5zcGVjdWxhciA9IHRoaXMucGFyc2VDb2xvcih0b2tlbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVtaXNzaXZlXG4gICAgICpcbiAgICAgKiBUaGUgYW1vdW50IGFuZCBjb2xvciBvZiBsaWdodCBlbWl0dGVkIGJ5IHRoZSBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9LZSh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLmVtaXNzaXZlID0gdGhpcy5wYXJzZUNvbG9yKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJhbnNtaXNzaW9uIEZpbHRlclxuICAgICAqXG4gICAgICogQW55IGxpZ2h0IHBhc3NpbmcgdGhyb3VnaCB0aGUgb2JqZWN0IGlzIGZpbHRlcmVkIGJ5IHRoZSB0cmFuc21pc3Npb25cbiAgICAgKiBmaWx0ZXIsIHdoaWNoIG9ubHkgYWxsb3dzIHNwZWNpZmljIGNvbG9ycyB0byBwYXNzIHRocm91Z2guIEZvciBleGFtcGxlLCBUZlxuICAgICAqIDAgMSAwIGFsbG93cyBhbGwgb2YgdGhlIGdyZWVuIHRvIHBhc3MgdGhyb3VnaCBhbmQgZmlsdGVycyBvdXQgYWxsIG9mIHRoZVxuICAgICAqIHJlZCBhbmQgYmx1ZS5cbiAgICAgKlxuICAgICAqIFNpbWlsYXIgdG8gdGhlIEthIGRpcmVjdGl2ZS4gU2ltcGx5IHJlcGxhY2UgXCJLc1wiIHdpdGggXCJUZlwiIGFuZCB0aGUgcnVsZXNcbiAgICAgKiBhcmUgdGhlIHNhbWVcbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgdGhlIHRva2VucyBhc3NvY2lhdGVkIHdpdGggdGhlIGRpcmVjdGl2ZVxuICAgICAqL1xuICAgIHBhcnNlX1RmKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwudHJhbnNtaXNzaW9uRmlsdGVyID0gdGhpcy5wYXJzZUNvbG9yKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3BlY2lmaWVzIHRoZSBkaXNzb2x2ZSBmb3IgdGhlIGN1cnJlbnQgbWF0ZXJpYWwuXG4gICAgICpcbiAgICAgKiBTdGF0ZW1lbnQ6IGQgWy1oYWxvXSBgZmFjdG9yYFxuICAgICAqXG4gICAgICogRXhhbXBsZTogXCJkIDAuNVwiXG4gICAgICpcbiAgICAgKiBUaGUgZmFjdG9yIGlzIHRoZSBhbW91bnQgdGhpcyBtYXRlcmlhbCBkaXNzb2x2ZXMgaW50byB0aGUgYmFja2dyb3VuZC4gQVxuICAgICAqIGZhY3RvciBvZiAxLjAgaXMgZnVsbHkgb3BhcXVlLiBUaGlzIGlzIHRoZSBkZWZhdWx0IHdoZW4gYSBuZXcgbWF0ZXJpYWwgaXNcbiAgICAgKiBjcmVhdGVkLiBBIGZhY3RvciBvZiAwLjAgaXMgZnVsbHkgZGlzc29sdmVkIChjb21wbGV0ZWx5IHRyYW5zcGFyZW50KS5cbiAgICAgKlxuICAgICAqIFVubGlrZSBhIHJlYWwgdHJhbnNwYXJlbnQgbWF0ZXJpYWwsIHRoZSBkaXNzb2x2ZSBkb2VzIG5vdCBkZXBlbmQgdXBvblxuICAgICAqIG1hdGVyaWFsIHRoaWNrbmVzcyBub3IgZG9lcyBpdCBoYXZlIGFueSBzcGVjdHJhbCBjaGFyYWN0ZXIuIERpc3NvbHZlIHdvcmtzXG4gICAgICogb24gYWxsIGlsbHVtaW5hdGlvbiBtb2RlbHMuXG4gICAgICpcbiAgICAgKiBUaGUgZGlzc29sdmUgc3RhdGVtZW50IGFsbG93cyBmb3IgYW4gb3B0aW9uYWwgXCItaGFsb1wiIGZsYWcgd2hpY2ggaW5kaWNhdGVzXG4gICAgICogdGhhdCBhIGRpc3NvbHZlIGlzIGRlcGVuZGVudCBvbiB0aGUgc3VyZmFjZSBvcmllbnRhdGlvbiByZWxhdGl2ZSB0byB0aGVcbiAgICAgKiB2aWV3ZXIuIEZvciBleGFtcGxlLCBhIHNwaGVyZSB3aXRoIHRoZSBmb2xsb3dpbmcgZGlzc29sdmUsIFwiZCAtaGFsbyAwLjBcIixcbiAgICAgKiB3aWxsIGJlIGZ1bGx5IGRpc3NvbHZlZCBhdCBpdHMgY2VudGVyIGFuZCB3aWxsIGFwcGVhciBncmFkdWFsbHkgbW9yZSBvcGFxdWVcbiAgICAgKiB0b3dhcmQgaXRzIGVkZ2UuXG4gICAgICpcbiAgICAgKiBcImZhY3RvclwiIGlzIHRoZSBtaW5pbXVtIGFtb3VudCBvZiBkaXNzb2x2ZSBhcHBsaWVkIHRvIHRoZSBtYXRlcmlhbC4gVGhlXG4gICAgICogYW1vdW50IG9mIGRpc3NvbHZlIHdpbGwgdmFyeSBiZXR3ZWVuIDEuMCAoZnVsbHkgb3BhcXVlKSBhbmQgdGhlIHNwZWNpZmllZFxuICAgICAqIFwiZmFjdG9yXCIuIFRoZSBmb3JtdWxhIGlzOlxuICAgICAqXG4gICAgICogICAgZGlzc29sdmUgPSAxLjAgLSAoTip2KSgxLjAtZmFjdG9yKVxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyB0aGUgdG9rZW5zIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGlyZWN0aXZlXG4gICAgICovXG4gICAgcGFyc2VfZCh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIC8vIHRoaXMgaWdub3JlcyB0aGUgLWhhbG8gb3B0aW9uIGFzIEkgY2FuJ3QgZmluZCBhbnkgZG9jdW1lbnRhdGlvbiBvbiB3aGF0XG4gICAgICAgIC8vIGl0J3Mgc3VwcG9zZWQgdG8gYmUuXG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLmRpc3NvbHZlID0gcGFyc2VGbG9hdCh0b2tlbnMucG9wKCkgfHwgXCIwXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBcImlsbHVtXCIgc3RhdGVtZW50IHNwZWNpZmllcyB0aGUgaWxsdW1pbmF0aW9uIG1vZGVsIHRvIHVzZSBpbiB0aGVcbiAgICAgKiBtYXRlcmlhbC4gSWxsdW1pbmF0aW9uIG1vZGVscyBhcmUgbWF0aGVtYXRpY2FsIGVxdWF0aW9ucyB0aGF0IHJlcHJlc2VudFxuICAgICAqIHZhcmlvdXMgbWF0ZXJpYWwgbGlnaHRpbmcgYW5kIHNoYWRpbmcgZWZmZWN0cy5cbiAgICAgKlxuICAgICAqIFRoZSBpbGx1bWluYXRpb24gbnVtYmVyIGNhbiBiZSBhIG51bWJlciBmcm9tIDAgdG8gMTAuIFRoZSBmb2xsb3dpbmcgYXJlXG4gICAgICogdGhlIGxpc3Qgb2YgaWxsdW1pbmF0aW9uIGVudW1lcmF0aW9ucyBhbmQgdGhlaXIgc3VtbWFyaWVzOlxuICAgICAqIDAuIENvbG9yIG9uIGFuZCBBbWJpZW50IG9mZlxuICAgICAqIDEuIENvbG9yIG9uIGFuZCBBbWJpZW50IG9uXG4gICAgICogMi4gSGlnaGxpZ2h0IG9uXG4gICAgICogMy4gUmVmbGVjdGlvbiBvbiBhbmQgUmF5IHRyYWNlIG9uXG4gICAgICogNC4gVHJhbnNwYXJlbmN5OiBHbGFzcyBvbiwgUmVmbGVjdGlvbjogUmF5IHRyYWNlIG9uXG4gICAgICogNS4gUmVmbGVjdGlvbjogRnJlc25lbCBvbiBhbmQgUmF5IHRyYWNlIG9uXG4gICAgICogNi4gVHJhbnNwYXJlbmN5OiBSZWZyYWN0aW9uIG9uLCBSZWZsZWN0aW9uOiBGcmVzbmVsIG9mZiBhbmQgUmF5IHRyYWNlIG9uXG4gICAgICogNy4gVHJhbnNwYXJlbmN5OiBSZWZyYWN0aW9uIG9uLCBSZWZsZWN0aW9uOiBGcmVzbmVsIG9uIGFuZCBSYXkgdHJhY2Ugb25cbiAgICAgKiA4LiBSZWZsZWN0aW9uIG9uIGFuZCBSYXkgdHJhY2Ugb2ZmXG4gICAgICogOS4gVHJhbnNwYXJlbmN5OiBHbGFzcyBvbiwgUmVmbGVjdGlvbjogUmF5IHRyYWNlIG9mZlxuICAgICAqIDEwLiBDYXN0cyBzaGFkb3dzIG9udG8gaW52aXNpYmxlIHN1cmZhY2VzXG4gICAgICpcbiAgICAgKiBFeGFtcGxlOiBcImlsbHVtIDJcIiB0byBzcGVjaWZ5IHRoZSBcIkhpZ2hsaWdodCBvblwiIG1vZGVsXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9pbGx1bSh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLmlsbHVtaW5hdGlvbiA9IHBhcnNlSW50KHRva2Vuc1swXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3B0aWNhbCBEZW5zaXR5IChBS0EgSW5kZXggb2YgUmVmcmFjdGlvbilcbiAgICAgKlxuICAgICAqIFN0YXRlbWVudDogTmkgYGluZGV4YFxuICAgICAqXG4gICAgICogRXhhbXBsZTogTmkgMS4wXG4gICAgICpcbiAgICAgKiBTcGVjaWZpZXMgdGhlIG9wdGljYWwgZGVuc2l0eSBmb3IgdGhlIHN1cmZhY2UuIGBpbmRleGAgaXMgdGhlIHZhbHVlXG4gICAgICogZm9yIHRoZSBvcHRpY2FsIGRlbnNpdHkuIFRoZSB2YWx1ZXMgY2FuIHJhbmdlIGZyb20gMC4wMDEgdG8gMTAuICBBIHZhbHVlIG9mXG4gICAgICogMS4wIG1lYW5zIHRoYXQgbGlnaHQgZG9lcyBub3QgYmVuZCBhcyBpdCBwYXNzZXMgdGhyb3VnaCBhbiBvYmplY3QuXG4gICAgICogSW5jcmVhc2luZyB0aGUgb3B0aWNhbF9kZW5zaXR5IGluY3JlYXNlcyB0aGUgYW1vdW50IG9mIGJlbmRpbmcuIEdsYXNzIGhhc1xuICAgICAqIGFuIGluZGV4IG9mIHJlZnJhY3Rpb24gb2YgYWJvdXQgMS41LiBWYWx1ZXMgb2YgbGVzcyB0aGFuIDEuMCBwcm9kdWNlXG4gICAgICogYml6YXJyZSByZXN1bHRzIGFuZCBhcmUgbm90IHJlY29tbWVuZGVkXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9OaSh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLnJlZnJhY3Rpb25JbmRleCA9IHBhcnNlRmxvYXQodG9rZW5zWzBdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZpZXMgdGhlIHNwZWN1bGFyIGV4cG9uZW50IGZvciB0aGUgY3VycmVudCBtYXRlcmlhbC4gVGhpcyBkZWZpbmVzIHRoZVxuICAgICAqIGZvY3VzIG9mIHRoZSBzcGVjdWxhciBoaWdobGlnaHQuXG4gICAgICpcbiAgICAgKiBTdGF0ZW1lbnQ6IE5zIGBleHBvbmVudGBcbiAgICAgKlxuICAgICAqIEV4YW1wbGU6IFwiTnMgMjUwXCJcbiAgICAgKlxuICAgICAqIGBleHBvbmVudGAgaXMgdGhlIHZhbHVlIGZvciB0aGUgc3BlY3VsYXIgZXhwb25lbnQuIEEgaGlnaCBleHBvbmVudCByZXN1bHRzXG4gICAgICogaW4gYSB0aWdodCwgY29uY2VudHJhdGVkIGhpZ2hsaWdodC4gTnMgVmFsdWVzIG5vcm1hbGx5IHJhbmdlIGZyb20gMCB0b1xuICAgICAqIDEwMDAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9Ocyh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLnNwZWN1bGFyRXhwb25lbnQgPSBwYXJzZUludCh0b2tlbnNbMF0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNwZWNpZmllcyB0aGUgc2hhcnBuZXNzIG9mIHRoZSByZWZsZWN0aW9ucyBmcm9tIHRoZSBsb2NhbCByZWZsZWN0aW9uIG1hcC5cbiAgICAgKlxuICAgICAqIFN0YXRlbWVudDogc2hhcnBuZXNzIGB2YWx1ZWBcbiAgICAgKlxuICAgICAqIEV4YW1wbGU6IFwic2hhcnBuZXNzIDEwMFwiXG4gICAgICpcbiAgICAgKiBJZiBhIG1hdGVyaWFsIGRvZXMgbm90IGhhdmUgYSBsb2NhbCByZWZsZWN0aW9uIG1hcCBkZWZpbmVkIGluIGl0cyBtYXRlcmlhbFxuICAgICAqIGRlZmludGlvbnMsIHNoYXJwbmVzcyB3aWxsIGFwcGx5IHRvIHRoZSBnbG9iYWwgcmVmbGVjdGlvbiBtYXAgZGVmaW5lZCBpblxuICAgICAqIFByZVZpZXcuXG4gICAgICpcbiAgICAgKiBgdmFsdWVgIGNhbiBiZSBhIG51bWJlciBmcm9tIDAgdG8gMTAwMC4gVGhlIGRlZmF1bHQgaXMgNjAuIEEgaGlnaCB2YWx1ZVxuICAgICAqIHJlc3VsdHMgaW4gYSBjbGVhciByZWZsZWN0aW9uIG9mIG9iamVjdHMgaW4gdGhlIHJlZmxlY3Rpb24gbWFwLlxuICAgICAqXG4gICAgICogVGlwOiBzaGFycG5lc3MgdmFsdWVzIGdyZWF0ZXIgdGhhbiAxMDAgaW50cm9kdWNlIGFsaWFzaW5nIGVmZmVjdHMgaW5cbiAgICAgKiBmbGF0IHN1cmZhY2VzIHRoYXQgYXJlIHZpZXdlZCBhdCBhIHNoYXJwIGFuZ2xlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyB0aGUgdG9rZW5zIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGlyZWN0aXZlXG4gICAgICovXG4gICAgcGFyc2Vfc2hhcnBuZXNzKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwuc2hhcnBuZXNzID0gcGFyc2VJbnQodG9rZW5zWzBdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC1jYyBmbGFnIGFuZCB1cGRhdGVzIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtY2MgZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV9jYyh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICBvcHRpb25zLmNvbG9yQ29ycmVjdGlvbiA9IHZhbHVlc1swXSA9PSBcIm9uXCI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSAtYmxlbmR1IGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC1ibGVuZHUgZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV9ibGVuZHUodmFsdWVzOiBzdHJpbmdbXSwgb3B0aW9uczogVGV4dHVyZU1hcERhdGEpIHtcbiAgICAgICAgb3B0aW9ucy5ob3Jpem9udGFsQmxlbmRpbmcgPSB2YWx1ZXNbMF0gPT0gXCJvblwiO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgLWJsZW5kdiBmbGFnIGFuZCB1cGRhdGVzIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtYmxlbmR2IGZsYWdcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgT2JqZWN0IG9mIGFsbCBpbWFnZSBvcHRpb25zXG4gICAgICovXG4gICAgcGFyc2VfYmxlbmR2KHZhbHVlczogc3RyaW5nW10sIG9wdGlvbnM6IFRleHR1cmVNYXBEYXRhKSB7XG4gICAgICAgIG9wdGlvbnMudmVydGljYWxCbGVuZGluZyA9IHZhbHVlc1swXSA9PSBcIm9uXCI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSAtYm9vc3QgZmxhZyBhbmQgdXBkYXRlcyB0aGUgb3B0aW9ucyBvYmplY3Qgd2l0aCB0aGUgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlcyB0aGUgdmFsdWVzIHBhc3NlZCB0byB0aGUgLWJvb3N0IGZsYWdcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgT2JqZWN0IG9mIGFsbCBpbWFnZSBvcHRpb25zXG4gICAgICovXG4gICAgcGFyc2VfYm9vc3QodmFsdWVzOiBzdHJpbmdbXSwgb3B0aW9uczogVGV4dHVyZU1hcERhdGEpIHtcbiAgICAgICAgb3B0aW9ucy5ib29zdE1pcE1hcFNoYXJwbmVzcyA9IHBhcnNlRmxvYXQodmFsdWVzWzBdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC1tbSBmbGFnIGFuZCB1cGRhdGVzIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtbW0gZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV9tbSh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICBvcHRpb25zLm1vZGlmeVRleHR1cmVNYXAuYnJpZ2h0bmVzcyA9IHBhcnNlRmxvYXQodmFsdWVzWzBdKTtcbiAgICAgICAgb3B0aW9ucy5tb2RpZnlUZXh0dXJlTWFwLmNvbnRyYXN0ID0gcGFyc2VGbG9hdCh2YWx1ZXNbMV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyBhbmQgc2V0cyB0aGUgLW8sIC1zLCBhbmQgLXQgIHUsIHYsIGFuZCB3IHZhbHVlc1xuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlcyB0aGUgdmFsdWVzIHBhc3NlZCB0byB0aGUgLW8sIC1zLCAtdCBmbGFnXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbiB0aGUgT2JqZWN0IG9mIGVpdGhlciB0aGUgLW8sIC1zLCAtdCBvcHRpb25cbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGRlZmF1bHRWYWx1ZSB0aGUgT2JqZWN0IG9mIGFsbCBpbWFnZSBvcHRpb25zXG4gICAgICovXG4gICAgcGFyc2Vfb3N0KHZhbHVlczogc3RyaW5nW10sIG9wdGlvbjogVVZXLCBkZWZhdWx0VmFsdWU6IG51bWJlcikge1xuICAgICAgICB3aGlsZSAodmFsdWVzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKGRlZmF1bHRWYWx1ZS50b1N0cmluZygpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdGlvbi51ID0gcGFyc2VGbG9hdCh2YWx1ZXNbMF0pO1xuICAgICAgICBvcHRpb24udiA9IHBhcnNlRmxvYXQodmFsdWVzWzFdKTtcbiAgICAgICAgb3B0aW9uLncgPSBwYXJzZUZsb2F0KHZhbHVlc1syXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSAtbyBmbGFnIGFuZCB1cGRhdGVzIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtbyBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX28odmFsdWVzOiBzdHJpbmdbXSwgb3B0aW9uczogVGV4dHVyZU1hcERhdGEpIHtcbiAgICAgICAgdGhpcy5wYXJzZV9vc3QodmFsdWVzLCBvcHRpb25zLm9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSAtcyBmbGFnIGFuZCB1cGRhdGVzIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtcyBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX3ModmFsdWVzOiBzdHJpbmdbXSwgb3B0aW9uczogVGV4dHVyZU1hcERhdGEpIHtcbiAgICAgICAgdGhpcy5wYXJzZV9vc3QodmFsdWVzLCBvcHRpb25zLnNjYWxlLCAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC10IGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC10IGZsYWdcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgT2JqZWN0IG9mIGFsbCBpbWFnZSBvcHRpb25zXG4gICAgICovXG4gICAgcGFyc2VfdCh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICB0aGlzLnBhcnNlX29zdCh2YWx1ZXMsIG9wdGlvbnMudHVyYnVsZW5jZSwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSAtdGV4cmVzIGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC10ZXhyZXMgZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV90ZXhyZXModmFsdWVzOiBzdHJpbmdbXSwgb3B0aW9uczogVGV4dHVyZU1hcERhdGEpIHtcbiAgICAgICAgb3B0aW9ucy50ZXh0dXJlUmVzb2x1dGlvbiA9IHBhcnNlRmxvYXQodmFsdWVzWzBdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC1jbGFtcCBmbGFnIGFuZCB1cGRhdGVzIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtY2xhbXAgZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV9jbGFtcCh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICBvcHRpb25zLmNsYW1wID0gdmFsdWVzWzBdID09IFwib25cIjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC1ibSBmbGFnIGFuZCB1cGRhdGVzIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtYm0gZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV9ibSh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICBvcHRpb25zLmJ1bXBNdWx0aXBsaWVyID0gcGFyc2VGbG9hdCh2YWx1ZXNbMF0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgLWltZmNoYW4gZmxhZyBhbmQgdXBkYXRlcyB0aGUgb3B0aW9ucyBvYmplY3Qgd2l0aCB0aGUgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlcyB0aGUgdmFsdWVzIHBhc3NlZCB0byB0aGUgLWltZmNoYW4gZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV9pbWZjaGFuKHZhbHVlczogc3RyaW5nW10sIG9wdGlvbnM6IFRleHR1cmVNYXBEYXRhKSB7XG4gICAgICAgIG9wdGlvbnMuaW1mQ2hhbiA9IHZhbHVlc1swXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG9ubHkgZXhpc3RzIGZvciByZWxlY3Rpb24gbWFwcyBhbmQgZGVub3RlcyB0aGUgdHlwZSBvZiByZWZsZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlcyB0aGUgdmFsdWVzIHBhc3NlZCB0byB0aGUgLXR5cGUgZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV90eXBlKHZhbHVlczogc3RyaW5nW10sIG9wdGlvbnM6IFRleHR1cmVNYXBEYXRhKSB7XG4gICAgICAgIG9wdGlvbnMucmVmbGVjdGlvblR5cGUgPSB2YWx1ZXNbMF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSB0ZXh0dXJlJ3Mgb3B0aW9ucyBhbmQgcmV0dXJucyBhbiBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSBpbmZvXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGFsbCBvZiB0aGUgb3B0aW9uIHRva2VucyB0byBwYXNzIHRvIHRoZSB0ZXh0dXJlXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBhIGNvbXBsZXRlIG9iamVjdCBvZiBvYmplY3RzIHRvIGFwcGx5IHRvIHRoZSB0ZXh0dXJlXG4gICAgICovXG4gICAgcGFyc2VPcHRpb25zKHRva2Vuczogc3RyaW5nW10pOiBUZXh0dXJlTWFwRGF0YSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBlbXB0eVRleHR1cmVPcHRpb25zKCk7XG5cbiAgICAgICAgbGV0IG9wdGlvbjtcbiAgICAgICAgbGV0IHZhbHVlcztcbiAgICAgICAgY29uc3Qgb3B0aW9uc1RvVmFsdWVzOiB7IFtrOiBzdHJpbmddOiBzdHJpbmdbXSB9ID0ge307XG5cbiAgICAgICAgdG9rZW5zLnJldmVyc2UoKTtcblxuICAgICAgICB3aGlsZSAodG9rZW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gdG9rZW4gaXMgZ3VhcmFudGVlZCB0byBleGlzdHMgaGVyZSwgaGVuY2UgdGhlIGV4cGxpY2l0IFwiYXNcIlxuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSB0b2tlbnMucG9wKCkgYXMgc3RyaW5nO1xuXG4gICAgICAgICAgICBpZiAodG9rZW4uc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgICAgICAgICAgICBvcHRpb24gPSB0b2tlbi5zdWJzdHIoMSk7XG4gICAgICAgICAgICAgICAgb3B0aW9uc1RvVmFsdWVzW29wdGlvbl0gPSBbXTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAob3B0aW9uKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9uc1RvVmFsdWVzW29wdGlvbl0ucHVzaCh0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKG9wdGlvbiBpbiBvcHRpb25zVG9WYWx1ZXMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9uc1RvVmFsdWVzLmhhc093blByb3BlcnR5KG9wdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbHVlcyA9IG9wdGlvbnNUb1ZhbHVlc1tvcHRpb25dO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9uTWV0aG9kID0gKHRoaXMgYXMgYW55KVtgcGFyc2VfJHtvcHRpb259YF07XG4gICAgICAgICAgICBpZiAob3B0aW9uTWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9uTWV0aG9kLmJpbmQodGhpcykodmFsdWVzLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBvcHRpb25zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgZ2l2ZW4gdGV4dHVyZSBtYXAgbGluZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgYWxsIG9mIHRoZSB0b2tlbnMgcmVwcmVzZW50aW5nIHRoZSB0ZXh0dXJlXG4gICAgICogQHJldHVybiBhIGNvbXBsZXRlIG9iamVjdCBvZiBvYmplY3RzIHRvIGFwcGx5IHRvIHRoZSB0ZXh0dXJlXG4gICAgICovXG4gICAgcGFyc2VNYXAodG9rZW5zOiBzdHJpbmdbXSk6IFRleHR1cmVNYXBEYXRhIHtcbiAgICAgICAgLy8gYWNjb3JkaW5nIHRvIHdpa2lwZWRpYTpcbiAgICAgICAgLy8gKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1dhdmVmcm9udF8ub2JqX2ZpbGUjVmVuZG9yX3NwZWNpZmljX2FsdGVyYXRpb25zKVxuICAgICAgICAvLyB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgdmVuZG9yIHRoYXQgcGxhY2VzIHRoZSBmaWxlbmFtZSBiZWZvcmUgdGhlIG9wdGlvbnNcbiAgICAgICAgLy8gcmF0aGVyIHRoYW4gYWZ0ZXIgKHdoaWNoIGlzIHRvIHNwZWMpLiBBbGwgb3B0aW9ucyBzdGFydCB3aXRoIGEgJy0nXG4gICAgICAgIC8vIHNvIGlmIHRoZSBmaXJzdCB0b2tlbiBkb2Vzbid0IHN0YXJ0IHdpdGggYSAnLScsIHdlJ3JlIGdvaW5nIHRvIGFzc3VtZVxuICAgICAgICAvLyBpdCdzIHRoZSBuYW1lIG9mIHRoZSBtYXAgZmlsZS5cbiAgICAgICAgbGV0IG9wdGlvbnNTdHJpbmc7XG4gICAgICAgIGxldCBmaWxlbmFtZSA9IFwiXCI7XG4gICAgICAgIGlmICghdG9rZW5zWzBdLnN0YXJ0c1dpdGgoXCItXCIpKSB7XG4gICAgICAgICAgICBbZmlsZW5hbWUsIC4uLm9wdGlvbnNTdHJpbmddID0gdG9rZW5zO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmlsZW5hbWUgPSB0b2tlbnMucG9wKCkgYXMgc3RyaW5nO1xuICAgICAgICAgICAgb3B0aW9uc1N0cmluZyA9IHRva2VucztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnBhcnNlT3B0aW9ucyhvcHRpb25zU3RyaW5nKTtcbiAgICAgICAgb3B0aW9ucy5maWxlbmFtZSA9IGZpbGVuYW1lLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xuXG4gICAgICAgIHJldHVybiBvcHRpb25zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgYW1iaWVudCBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgbWFwX0thIGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfbWFwX0thKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwubWFwQW1iaWVudCA9IHRoaXMucGFyc2VNYXAodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIGRpZmZ1c2UgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyBsaXN0IG9mIHRva2VucyBmb3IgdGhlIG1hcF9LZCBkaXJlY2l2ZVxuICAgICAqL1xuICAgIHBhcnNlX21hcF9LZCh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLm1hcERpZmZ1c2UgPSB0aGlzLnBhcnNlTWFwKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBzcGVjdWxhciBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgbWFwX0tzIGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfbWFwX0tzKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwubWFwU3BlY3VsYXIgPSB0aGlzLnBhcnNlTWFwKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBlbWlzc2l2ZSBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgbWFwX0tlIGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfbWFwX0tlKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwubWFwRW1pc3NpdmUgPSB0aGlzLnBhcnNlTWFwKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBzcGVjdWxhciBleHBvbmVudCBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgbWFwX05zIGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfbWFwX05zKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwubWFwU3BlY3VsYXJFeHBvbmVudCA9IHRoaXMucGFyc2VNYXAodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIGRpc3NvbHZlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgbGlzdCBvZiB0b2tlbnMgZm9yIHRoZSBtYXBfZCBkaXJlY2l2ZVxuICAgICAqL1xuICAgIHBhcnNlX21hcF9kKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwubWFwRGlzc29sdmUgPSB0aGlzLnBhcnNlTWFwKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBhbnRpLWFsaWFzaW5nIG9wdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgbGlzdCBvZiB0b2tlbnMgZm9yIHRoZSBtYXBfYWF0IGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfbWFwX2FhdCh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLmFudGlBbGlhc2luZyA9IHRva2Vuc1swXSA9PSBcIm9uXCI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBidW1wIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgbGlzdCBvZiB0b2tlbnMgZm9yIHRoZSBtYXBfYnVtcCBkaXJlY2l2ZVxuICAgICAqL1xuICAgIHBhcnNlX21hcF9idW1wKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwubWFwQnVtcCA9IHRoaXMucGFyc2VNYXAodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIGJ1bXAgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyBsaXN0IG9mIHRva2VucyBmb3IgdGhlIGJ1bXAgZGlyZWNpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9idW1wKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5wYXJzZV9tYXBfYnVtcCh0b2tlbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgZGlzcCBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgZGlzcCBkaXJlY2l2ZVxuICAgICAqL1xuICAgIHBhcnNlX2Rpc3AodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5tYXBEaXNwbGFjZW1lbnQgPSB0aGlzLnBhcnNlTWFwKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBkZWNhbCBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgbWFwX2RlY2FsIGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfZGVjYWwodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5tYXBEZWNhbCA9IHRoaXMucGFyc2VNYXAodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIHJlZmwgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyBsaXN0IG9mIHRva2VucyBmb3IgdGhlIHJlZmwgZGlyZWNpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9yZWZsKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwubWFwUmVmbGVjdGlvbnMucHVzaCh0aGlzLnBhcnNlTWFwKHRva2VucykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgTVRMIGZpbGUuXG4gICAgICpcbiAgICAgKiBJdGVyYXRlcyBsaW5lIGJ5IGxpbmUgcGFyc2luZyBlYWNoIE1UTCBkaXJlY3RpdmUuXG4gICAgICpcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGV4cGVjdHMgdGhlIGZpcnN0IHRva2VuIGluIHRoZSBsaW5lXG4gICAgICogdG8gYmUgYSB2YWxpZCBNVEwgZGlyZWN0aXZlLiBUaGF0IHRva2VuIGlzIHRoZW4gdXNlZFxuICAgICAqIHRvIHRyeSBhbmQgcnVuIGEgbWV0aG9kIG9uIHRoaXMgY2xhc3MuIHBhcnNlX1tkaXJlY3RpdmVdXG4gICAgICogRS5nLiwgdGhlIGBuZXdtdGxgIGRpcmVjdGl2ZSB3b3VsZCB0cnkgdG8gY2FsbCB0aGUgbWV0aG9kXG4gICAgICogcGFyc2VfbmV3bXRsLiBFYWNoIHBhcnNpbmcgZnVuY3Rpb24gdGFrZXMgaW4gdGhlIHJlbWFpbmluZ1xuICAgICAqIGxpc3Qgb2YgdG9rZW5zIGFuZCB1cGRhdGVzIHRoZSBjdXJyZW50TWF0ZXJpYWwgY2xhc3Mgd2l0aFxuICAgICAqIHRoZSBhdHRyaWJ1dGVzIHByb3ZpZGVkLlxuICAgICAqL1xuICAgIHBhcnNlKCkge1xuICAgICAgICBjb25zdCBsaW5lcyA9IHRoaXMuZGF0YS5zcGxpdCgvXFxyP1xcbi8pO1xuICAgICAgICBmb3IgKGxldCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICAgICAgICBsaW5lID0gbGluZS50cmltKCk7XG4gICAgICAgICAgICBpZiAoIWxpbmUgfHwgbGluZS5zdGFydHNXaXRoKFwiI1wiKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBbZGlyZWN0aXZlLCAuLi50b2tlbnNdID0gbGluZS5zcGxpdCgvXFxzLyk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcnNlTWV0aG9kID0gKHRoaXMgYXMgYW55KVtgcGFyc2VfJHtkaXJlY3RpdmV9YF07XG5cbiAgICAgICAgICAgIGlmICghcGFyc2VNZXRob2QpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYERvbid0IGtub3cgaG93IHRvIHBhcnNlIHRoZSBkaXJlY3RpdmU6IFwiJHtkaXJlY3RpdmV9XCJgKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYFBhcnNpbmcgXCIke2RpcmVjdGl2ZX1cIiB3aXRoIHRva2VuczogJHt0b2tlbnN9YCk7XG4gICAgICAgICAgICBwYXJzZU1ldGhvZC5iaW5kKHRoaXMpKHRva2Vucyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzb21lIGNsZWFudXAuIFRoZXNlIGRvbid0IG5lZWQgdG8gYmUgZXhwb3NlZCBhcyBwdWJsaWMgZGF0YS5cbiAgICAgICAgZGVsZXRlIHRoaXMuZGF0YTtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwgPSBTRU5USU5FTF9NQVRFUklBTDtcbiAgICB9XG5cbiAgICAvKiBlc2xpbnQtZW5hYmxlIGNhbWVsY2FzZSovXG59XG5cbmZ1bmN0aW9uIGVtcHR5VGV4dHVyZU9wdGlvbnMoKTogVGV4dHVyZU1hcERhdGEge1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvbG9yQ29ycmVjdGlvbjogZmFsc2UsXG4gICAgICAgIGhvcml6b250YWxCbGVuZGluZzogdHJ1ZSxcbiAgICAgICAgdmVydGljYWxCbGVuZGluZzogdHJ1ZSxcbiAgICAgICAgYm9vc3RNaXBNYXBTaGFycG5lc3M6IDAsXG4gICAgICAgIG1vZGlmeVRleHR1cmVNYXA6IHtcbiAgICAgICAgICAgIGJyaWdodG5lc3M6IDAsXG4gICAgICAgICAgICBjb250cmFzdDogMSxcbiAgICAgICAgfSxcbiAgICAgICAgb2Zmc2V0OiB7IHU6IDAsIHY6IDAsIHc6IDAgfSxcbiAgICAgICAgc2NhbGU6IHsgdTogMSwgdjogMSwgdzogMSB9LFxuICAgICAgICB0dXJidWxlbmNlOiB7IHU6IDAsIHY6IDAsIHc6IDAgfSxcbiAgICAgICAgY2xhbXA6IGZhbHNlLFxuICAgICAgICB0ZXh0dXJlUmVzb2x1dGlvbjogbnVsbCxcbiAgICAgICAgYnVtcE11bHRpcGxpZXI6IDEsXG4gICAgICAgIGltZkNoYW46IG51bGwsXG4gICAgICAgIGZpbGVuYW1lOiBcIlwiLFxuICAgIH07XG59XG4iLCJpbXBvcnQgeyBMYXlvdXQgfSBmcm9tIFwiLi9sYXlvdXRcIjtcbmltcG9ydCB7IE1hdGVyaWFsLCBNYXRlcmlhbExpYnJhcnkgfSBmcm9tIFwiLi9tYXRlcmlhbFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1lc2hPcHRpb25zIHtcbiAgICBlbmFibGVXVGV4dHVyZUNvb3JkPzogYm9vbGVhbjtcbiAgICBjYWxjVGFuZ2VudHNBbmRCaXRhbmdlbnRzPzogYm9vbGVhbjtcbiAgICBtYXRlcmlhbHM/OiB7IFtrZXk6IHN0cmluZ106IE1hdGVyaWFsIH07XG59XG5cbmludGVyZmFjZSBVbnBhY2tlZEF0dHJzIHtcbiAgICB2ZXJ0czogbnVtYmVyW107XG4gICAgbm9ybXM6IG51bWJlcltdO1xuICAgIHRleHR1cmVzOiBudW1iZXJbXTtcbiAgICBoYXNoaW5kaWNlczogeyBbazogc3RyaW5nXTogbnVtYmVyIH07XG4gICAgaW5kaWNlczogbnVtYmVyW11bXTtcbiAgICBtYXRlcmlhbEluZGljZXM6IG51bWJlcltdO1xuICAgIGluZGV4OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWF0ZXJpYWxOYW1lVG9JbmRleCB7XG4gICAgW2s6IHN0cmluZ106IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbmRleFRvTWF0ZXJpYWwge1xuICAgIFtrOiBudW1iZXJdOiBNYXRlcmlhbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBcnJheUJ1ZmZlcldpdGhJdGVtU2l6ZSBleHRlbmRzIEFycmF5QnVmZmVyIHtcbiAgICBudW1JdGVtcz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVaW50MTZBcnJheVdpdGhJdGVtU2l6ZSBleHRlbmRzIFVpbnQxNkFycmF5IHtcbiAgICBudW1JdGVtcz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaGUgbWFpbiBNZXNoIGNsYXNzLiBUaGUgY29uc3RydWN0b3Igd2lsbCBwYXJzZSB0aHJvdWdoIHRoZSBPQkogZmlsZSBkYXRhXG4gKiBhbmQgY29sbGVjdCB0aGUgdmVydGV4LCB2ZXJ0ZXggbm9ybWFsLCB0ZXh0dXJlLCBhbmQgZmFjZSBpbmZvcm1hdGlvbi4gVGhpc1xuICogaW5mb3JtYXRpb24gY2FuIHRoZW4gYmUgdXNlZCBsYXRlciBvbiB3aGVuIGNyZWF0aW5nIHlvdXIgVkJPcy4gU2VlXG4gKiBPQkouaW5pdE1lc2hCdWZmZXJzIGZvciBhbiBleGFtcGxlIG9mIGhvdyB0byB1c2UgdGhlIG5ld2x5IGNyZWF0ZWQgTWVzaFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXNoIHtcbiAgICBwdWJsaWMgdmVydGljZXM6IG51bWJlcltdO1xuICAgIHB1YmxpYyB2ZXJ0ZXhOb3JtYWxzOiBudW1iZXJbXTtcbiAgICBwdWJsaWMgdGV4dHVyZXM6IG51bWJlcltdO1xuICAgIHB1YmxpYyBpbmRpY2VzOiBudW1iZXJbXTtcbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nID0gXCJcIjtcbiAgICBwdWJsaWMgdmVydGV4TWF0ZXJpYWxJbmRpY2VzOiBudW1iZXJbXTtcbiAgICBwdWJsaWMgaW5kaWNlc1Blck1hdGVyaWFsOiBudW1iZXJbXVtdID0gW107XG4gICAgcHVibGljIG1hdGVyaWFsTmFtZXM6IHN0cmluZ1tdO1xuICAgIHB1YmxpYyBtYXRlcmlhbEluZGljZXM6IE1hdGVyaWFsTmFtZVRvSW5kZXg7XG4gICAgcHVibGljIG1hdGVyaWFsc0J5SW5kZXg6IEluZGV4VG9NYXRlcmlhbCA9IHt9O1xuICAgIHB1YmxpYyB0YW5nZW50czogbnVtYmVyW10gPSBbXTtcbiAgICBwdWJsaWMgYml0YW5nZW50czogbnVtYmVyW10gPSBbXTtcbiAgICBwdWJsaWMgdGV4dHVyZVN0cmlkZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgTWVzaFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvYmplY3REYXRhIC0gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYW4gT0JKIGZpbGUgd2l0aFxuICAgICAqICAgICBuZXdsaW5lcyBwcmVzZXJ2ZWQuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBhIEpTIG9iamVjdCBjb250YWluaW5nIHZhbGlkIG9wdGlvbnMuIFNlZSBjbGFzc1xuICAgICAqICAgICBkb2N1bWVudGF0aW9uIGZvciBvcHRpb25zLlxuICAgICAqIEBwYXJhbSB7Ym9vbH0gb3B0aW9ucy5lbmFibGVXVGV4dHVyZUNvb3JkIC0gVGV4dHVyZSBjb29yZGluYXRlcyBjYW4gaGF2ZVxuICAgICAqICAgICBhbiBvcHRpb25hbCBcIndcIiBjb29yZGluYXRlIGFmdGVyIHRoZSB1IGFuZCB2IGNvb3JkaW5hdGVzLiBUaGlzIGV4dHJhXG4gICAgICogICAgIHZhbHVlIGNhbiBiZSB1c2VkIGluIG9yZGVyIHRvIHBlcmZvcm0gZmFuY3kgdHJhbnNmb3JtYXRpb25zIG9uIHRoZVxuICAgICAqICAgICB0ZXh0dXJlcyB0aGVtc2VsdmVzLiBEZWZhdWx0IGlzIHRvIHRydW5jYXRlIHRvIG9ubHkgdGhlIHUgYW4gdlxuICAgICAqICAgICBjb29yZGluYXRlcy4gUGFzc2luZyB0cnVlIHdpbGwgcHJvdmlkZSBhIGRlZmF1bHQgdmFsdWUgb2YgMCBpbiB0aGVcbiAgICAgKiAgICAgZXZlbnQgdGhhdCBhbnkgb3IgYWxsIHRleHR1cmUgY29vcmRpbmF0ZXMgZG9uJ3QgcHJvdmlkZSBhIHcgdmFsdWUuXG4gICAgICogICAgIEFsd2F5cyB1c2UgdGhlIHRleHR1cmVTdHJpZGUgYXR0cmlidXRlIGluIG9yZGVyIHRvIGRldGVybWluZSB0aGVcbiAgICAgKiAgICAgc3RyaWRlIGxlbmd0aCBvZiB0aGUgdGV4dHVyZSBjb29yZGluYXRlcyB3aGVuIHJlbmRlcmluZyB0aGUgZWxlbWVudFxuICAgICAqICAgICBhcnJheS5cbiAgICAgKiBAcGFyYW0ge2Jvb2x9IG9wdGlvbnMuY2FsY1RhbmdlbnRzQW5kQml0YW5nZW50cyAtIENhbGN1bGF0ZSB0aGUgdGFuZ2VudHNcbiAgICAgKiAgICAgYW5kIGJpdGFuZ2VudHMgd2hlbiBsb2FkaW5nIG9mIHRoZSBPQkogaXMgY29tcGxldGVkLiBUaGlzIGFkZHMgdHdvIG5ld1xuICAgICAqICAgICBhdHRyaWJ1dGVzIHRvIHRoZSBNZXNoIGluc3RhbmNlOiBgdGFuZ2VudHNgIGFuZCBgYml0YW5nZW50c2AuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob2JqZWN0RGF0YTogc3RyaW5nLCBvcHRpb25zPzogTWVzaE9wdGlvbnMpIHtcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgICAgIG9wdGlvbnMubWF0ZXJpYWxzID0gb3B0aW9ucy5tYXRlcmlhbHMgfHwge307XG4gICAgICAgIG9wdGlvbnMuZW5hYmxlV1RleHR1cmVDb29yZCA9ICEhb3B0aW9ucy5lbmFibGVXVGV4dHVyZUNvb3JkO1xuXG4gICAgICAgIC8vIHRoZSBsaXN0IG9mIHVuaXF1ZSB2ZXJ0ZXgsIG5vcm1hbCwgdGV4dHVyZSwgYXR0cmlidXRlc1xuICAgICAgICB0aGlzLnZlcnRleE5vcm1hbHMgPSBbXTtcbiAgICAgICAgdGhpcy50ZXh0dXJlcyA9IFtdO1xuICAgICAgICAvLyB0aGUgaW5kaWNpZXMgdG8gZHJhdyB0aGUgZmFjZXNcbiAgICAgICAgdGhpcy5pbmRpY2VzID0gW107XG4gICAgICAgIHRoaXMudGV4dHVyZVN0cmlkZSA9IG9wdGlvbnMuZW5hYmxlV1RleHR1cmVDb29yZCA/IDMgOiAyO1xuXG4gICAgICAgIC8qXG4gICAgICAgIFRoZSBPQkogZmlsZSBmb3JtYXQgZG9lcyBhIHNvcnQgb2YgY29tcHJlc3Npb24gd2hlbiBzYXZpbmcgYSBtb2RlbCBpbiBhXG4gICAgICAgIHByb2dyYW0gbGlrZSBCbGVuZGVyLiBUaGVyZSBhcmUgYXQgbGVhc3QgMyBzZWN0aW9ucyAoNCBpbmNsdWRpbmcgdGV4dHVyZXMpXG4gICAgICAgIHdpdGhpbiB0aGUgZmlsZS4gRWFjaCBsaW5lIGluIGEgc2VjdGlvbiBiZWdpbnMgd2l0aCB0aGUgc2FtZSBzdHJpbmc6XG4gICAgICAgICAgKiAndic6IGluZGljYXRlcyB2ZXJ0ZXggc2VjdGlvblxuICAgICAgICAgICogJ3ZuJzogaW5kaWNhdGVzIHZlcnRleCBub3JtYWwgc2VjdGlvblxuICAgICAgICAgICogJ2YnOiBpbmRpY2F0ZXMgdGhlIGZhY2VzIHNlY3Rpb25cbiAgICAgICAgICAqICd2dCc6IGluZGljYXRlcyB2ZXJ0ZXggdGV4dHVyZSBzZWN0aW9uIChpZiB0ZXh0dXJlcyB3ZXJlIHVzZWQgb24gdGhlIG1vZGVsKVxuICAgICAgICBFYWNoIG9mIHRoZSBhYm92ZSBzZWN0aW9ucyAoZXhjZXB0IGZvciB0aGUgZmFjZXMgc2VjdGlvbikgaXMgYSBsaXN0L3NldCBvZlxuICAgICAgICB1bmlxdWUgdmVydGljZXMuXG5cbiAgICAgICAgRWFjaCBsaW5lIG9mIHRoZSBmYWNlcyBzZWN0aW9uIGNvbnRhaW5zIGEgbGlzdCBvZlxuICAgICAgICAodmVydGV4LCBbdGV4dHVyZV0sIG5vcm1hbCkgZ3JvdXBzLlxuXG4gICAgICAgICoqTm90ZToqKiBUaGUgZm9sbG93aW5nIGRvY3VtZW50YXRpb24gd2lsbCB1c2UgYSBjYXBpdGFsIFwiVlwiIFZlcnRleCB0b1xuICAgICAgICBkZW5vdGUgdGhlIGFib3ZlICh2ZXJ0ZXgsIFt0ZXh0dXJlXSwgbm9ybWFsKSBncm91cHMgd2hlcmVhcyBhIGxvd2VyY2FzZVxuICAgICAgICBcInZcIiB2ZXJ0ZXggaXMgdXNlZCB0byBkZW5vdGUgYW4gWCwgWSwgWiBjb29yZGluYXRlLlxuXG4gICAgICAgIFNvbWUgZXhhbXBsZXM6XG4gICAgICAgICAgICAvLyB0aGUgdGV4dHVyZSBpbmRleCBpcyBvcHRpb25hbCwgYm90aCBmb3JtYXRzIGFyZSBwb3NzaWJsZSBmb3IgbW9kZWxzXG4gICAgICAgICAgICAvLyB3aXRob3V0IGEgdGV4dHVyZSBhcHBsaWVkXG4gICAgICAgICAgICBmIDEvMjUgMTgvNDYgMTIvMzFcbiAgICAgICAgICAgIGYgMS8vMjUgMTgvLzQ2IDEyLy8zMVxuXG4gICAgICAgICAgICAvLyBBIDMgdmVydGV4IGZhY2Ugd2l0aCB0ZXh0dXJlIGluZGljZXNcbiAgICAgICAgICAgIGYgMTYvOTIvMTEgMTQvMTAxLzIyIDEvNjkvMVxuXG4gICAgICAgICAgICAvLyBBIDQgdmVydGV4IGZhY2VcbiAgICAgICAgICAgIGYgMTYvOTIvMTEgNDAvMTA5LzQwIDM4LzExNC8zOCAxNC8xMDEvMjJcblxuICAgICAgICBUaGUgZmlyc3QgdHdvIGxpbmVzIGFyZSBleGFtcGxlcyBvZiBhIDMgdmVydGV4IGZhY2Ugd2l0aG91dCBhIHRleHR1cmUgYXBwbGllZC5cbiAgICAgICAgVGhlIHNlY29uZCBpcyBhbiBleGFtcGxlIG9mIGEgMyB2ZXJ0ZXggZmFjZSB3aXRoIGEgdGV4dHVyZSBhcHBsaWVkLlxuICAgICAgICBUaGUgdGhpcmQgaXMgYW4gZXhhbXBsZSBvZiBhIDQgdmVydGV4IGZhY2UuIE5vdGU6IGEgZmFjZSBjYW4gY29udGFpbiBOXG4gICAgICAgIG51bWJlciBvZiB2ZXJ0aWNlcy5cblxuICAgICAgICBFYWNoIG51bWJlciB0aGF0IGFwcGVhcnMgaW4gb25lIG9mIHRoZSBncm91cHMgaXMgYSAxLWJhc2VkIGluZGV4XG4gICAgICAgIGNvcnJlc3BvbmRpbmcgdG8gYW4gaXRlbSBmcm9tIHRoZSBvdGhlciBzZWN0aW9ucyAobWVhbmluZyB0aGF0IGluZGV4aW5nXG4gICAgICAgIHN0YXJ0cyBhdCBvbmUgYW5kICpub3QqIHplcm8pLlxuXG4gICAgICAgIEZvciBleGFtcGxlOlxuICAgICAgICAgICAgYGYgMTYvOTIvMTFgIGlzIHNheWluZyB0b1xuICAgICAgICAgICAgICAtIHRha2UgdGhlIDE2dGggZWxlbWVudCBmcm9tIHRoZSBbdl0gdmVydGV4IGFycmF5XG4gICAgICAgICAgICAgIC0gdGFrZSB0aGUgOTJuZCBlbGVtZW50IGZyb20gdGhlIFt2dF0gdGV4dHVyZSBhcnJheVxuICAgICAgICAgICAgICAtIHRha2UgdGhlIDExdGggZWxlbWVudCBmcm9tIHRoZSBbdm5dIG5vcm1hbCBhcnJheVxuICAgICAgICAgICAgYW5kIHRvZ2V0aGVyIHRoZXkgbWFrZSBhIHVuaXF1ZSB2ZXJ0ZXguXG4gICAgICAgIFVzaW5nIGFsbCAzKyB1bmlxdWUgVmVydGljZXMgZnJvbSB0aGUgZmFjZSBsaW5lIHdpbGwgcHJvZHVjZSBhIHBvbHlnb24uXG5cbiAgICAgICAgTm93LCB5b3UgY291bGQganVzdCBnbyB0aHJvdWdoIHRoZSBPQkogZmlsZSBhbmQgY3JlYXRlIGEgbmV3IHZlcnRleCBmb3JcbiAgICAgICAgZWFjaCBmYWNlIGxpbmUgYW5kIFdlYkdMIHdpbGwgZHJhdyB3aGF0IGFwcGVhcnMgdG8gYmUgdGhlIHNhbWUgbW9kZWwuXG4gICAgICAgIEhvd2V2ZXIsIHZlcnRpY2VzIHdpbGwgYmUgb3ZlcmxhcHBlZCBhbmQgZHVwbGljYXRlZCBhbGwgb3ZlciB0aGUgcGxhY2UuXG5cbiAgICAgICAgQ29uc2lkZXIgYSBjdWJlIGluIDNEIHNwYWNlIGNlbnRlcmVkIGFib3V0IHRoZSBvcmlnaW4gYW5kIGVhY2ggc2lkZSBpc1xuICAgICAgICAyIHVuaXRzIGxvbmcuIFRoZSBmcm9udCBmYWNlICh3aXRoIHRoZSBwb3NpdGl2ZSBaLWF4aXMgcG9pbnRpbmcgdG93YXJkc1xuICAgICAgICB5b3UpIHdvdWxkIGhhdmUgYSBUb3AgUmlnaHQgdmVydGV4IChsb29raW5nIG9ydGhvZ29uYWwgdG8gaXRzIG5vcm1hbClcbiAgICAgICAgbWFwcGVkIGF0ICgxLDEsMSkgVGhlIHJpZ2h0IGZhY2Ugd291bGQgaGF2ZSBhIFRvcCBMZWZ0IHZlcnRleCAobG9va2luZ1xuICAgICAgICBvcnRob2dvbmFsIHRvIGl0cyBub3JtYWwpIGF0ICgxLDEsMSkgYW5kIHRoZSB0b3AgZmFjZSB3b3VsZCBoYXZlIGEgQm90dG9tXG4gICAgICAgIFJpZ2h0IHZlcnRleCAobG9va2luZyBvcnRob2dvbmFsIHRvIGl0cyBub3JtYWwpIGF0ICgxLDEsMSkuIEVhY2ggZmFjZVxuICAgICAgICBoYXMgYSB2ZXJ0ZXggYXQgdGhlIHNhbWUgY29vcmRpbmF0ZXMsIGhvd2V2ZXIsIHRocmVlIGRpc3RpbmN0IHZlcnRpY2VzXG4gICAgICAgIHdpbGwgYmUgZHJhd24gYXQgdGhlIHNhbWUgc3BvdC5cblxuICAgICAgICBUbyBzb2x2ZSB0aGUgaXNzdWUgb2YgZHVwbGljYXRlIFZlcnRpY2VzICh0aGUgYCh2ZXJ0ZXgsIFt0ZXh0dXJlXSwgbm9ybWFsKWBcbiAgICAgICAgZ3JvdXBzKSwgd2hpbGUgaXRlcmF0aW5nIHRocm91Z2ggdGhlIGZhY2UgbGluZXMsIHdoZW4gYSBncm91cCBpcyBlbmNvdW50ZXJlZFxuICAgICAgICB0aGUgd2hvbGUgZ3JvdXAgc3RyaW5nICgnMTYvOTIvMTEnKSBpcyBjaGVja2VkIHRvIHNlZSBpZiBpdCBleGlzdHMgaW4gdGhlXG4gICAgICAgIHBhY2tlZC5oYXNoaW5kaWNlcyBvYmplY3QsIGFuZCBpZiBpdCBkb2Vzbid0LCB0aGUgaW5kaWNlcyBpdCBzcGVjaWZpZXNcbiAgICAgICAgYXJlIHVzZWQgdG8gbG9vayB1cCBlYWNoIGF0dHJpYnV0ZSBpbiB0aGUgY29ycmVzcG9uZGluZyBhdHRyaWJ1dGUgYXJyYXlzXG4gICAgICAgIGFscmVhZHkgY3JlYXRlZC4gVGhlIHZhbHVlcyBhcmUgdGhlbiBjb3BpZWQgdG8gdGhlIGNvcnJlc3BvbmRpbmcgdW5wYWNrZWRcbiAgICAgICAgYXJyYXkgKGZsYXR0ZW5lZCB0byBwbGF5IG5pY2Ugd2l0aCBXZWJHTCdzIEVMRU1FTlRfQVJSQVlfQlVGRkVSIGluZGV4aW5nKSxcbiAgICAgICAgdGhlIGdyb3VwIHN0cmluZyBpcyBhZGRlZCB0byB0aGUgaGFzaGluZGljZXMgc2V0IGFuZCB0aGUgY3VycmVudCB1bnBhY2tlZFxuICAgICAgICBpbmRleCBpcyB1c2VkIGFzIHRoaXMgaGFzaGluZGljZXMgdmFsdWUgc28gdGhhdCB0aGUgZ3JvdXAgb2YgZWxlbWVudHMgY2FuXG4gICAgICAgIGJlIHJldXNlZC4gVGhlIHVucGFja2VkIGluZGV4IGlzIGluY3JlbWVudGVkLiBJZiB0aGUgZ3JvdXAgc3RyaW5nIGFscmVhZHlcbiAgICAgICAgZXhpc3RzIGluIHRoZSBoYXNoaW5kaWNlcyBvYmplY3QsIGl0cyBjb3JyZXNwb25kaW5nIHZhbHVlIGlzIHRoZSBpbmRleCBvZlxuICAgICAgICB0aGF0IGdyb3VwIGFuZCBpcyBhcHBlbmRlZCB0byB0aGUgdW5wYWNrZWQgaW5kaWNlcyBhcnJheS5cbiAgICAgICAqL1xuICAgICAgICBjb25zdCB2ZXJ0cyA9IFtdO1xuICAgICAgICBjb25zdCB2ZXJ0Tm9ybWFscyA9IFtdO1xuICAgICAgICBjb25zdCB0ZXh0dXJlcyA9IFtdO1xuICAgICAgICBjb25zdCBtYXRlcmlhbE5hbWVzQnlJbmRleCA9IFtdO1xuICAgICAgICBjb25zdCBtYXRlcmlhbEluZGljZXNCeU5hbWU6IE1hdGVyaWFsTmFtZVRvSW5kZXggPSB7fTtcbiAgICAgICAgLy8ga2VlcCB0cmFjayBvZiB3aGF0IG1hdGVyaWFsIHdlJ3ZlIHNlZW4gbGFzdFxuICAgICAgICBsZXQgY3VycmVudE1hdGVyaWFsSW5kZXggPSAtMTtcbiAgICAgICAgbGV0IGN1cnJlbnRPYmplY3RCeU1hdGVyaWFsSW5kZXggPSAwO1xuICAgICAgICAvLyB1bnBhY2tpbmcgc3R1ZmZcbiAgICAgICAgY29uc3QgdW5wYWNrZWQ6IFVucGFja2VkQXR0cnMgPSB7XG4gICAgICAgICAgICB2ZXJ0czogW10sXG4gICAgICAgICAgICBub3JtczogW10sXG4gICAgICAgICAgICB0ZXh0dXJlczogW10sXG4gICAgICAgICAgICBoYXNoaW5kaWNlczoge30sXG4gICAgICAgICAgICBpbmRpY2VzOiBbW11dLFxuICAgICAgICAgICAgbWF0ZXJpYWxJbmRpY2VzOiBbXSxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IFZFUlRFWF9SRSA9IC9edlxccy87XG4gICAgICAgIGNvbnN0IE5PUk1BTF9SRSA9IC9edm5cXHMvO1xuICAgICAgICBjb25zdCBURVhUVVJFX1JFID0gL152dFxccy87XG4gICAgICAgIGNvbnN0IEZBQ0VfUkUgPSAvXmZcXHMvO1xuICAgICAgICBjb25zdCBXSElURVNQQUNFX1JFID0gL1xccysvO1xuICAgICAgICBjb25zdCBVU0VfTUFURVJJQUxfUkUgPSAvXnVzZW10bC87XG5cbiAgICAgICAgLy8gYXJyYXkgb2YgbGluZXMgc2VwYXJhdGVkIGJ5IHRoZSBuZXdsaW5lXG4gICAgICAgIGNvbnN0IGxpbmVzID0gb2JqZWN0RGF0YS5zcGxpdChcIlxcblwiKTtcblxuICAgICAgICBmb3IgKGxldCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICAgICAgICBsaW5lID0gbGluZS50cmltKCk7XG4gICAgICAgICAgICBpZiAoIWxpbmUgfHwgbGluZS5zdGFydHNXaXRoKFwiI1wiKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZWxlbWVudHMgPSBsaW5lLnNwbGl0KFdISVRFU1BBQ0VfUkUpO1xuICAgICAgICAgICAgZWxlbWVudHMuc2hpZnQoKTtcblxuICAgICAgICAgICAgaWYgKFZFUlRFWF9SRS50ZXN0KGxpbmUpKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgdGhpcyBpcyBhIHZlcnRleFxuICAgICAgICAgICAgICAgIHZlcnRzLnB1c2goLi4uZWxlbWVudHMpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChOT1JNQUxfUkUudGVzdChsaW5lKSkge1xuICAgICAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSB2ZXJ0ZXggbm9ybWFsXG4gICAgICAgICAgICAgICAgdmVydE5vcm1hbHMucHVzaCguLi5lbGVtZW50cyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFRFWFRVUkVfUkUudGVzdChsaW5lKSkge1xuICAgICAgICAgICAgICAgIGxldCBjb29yZHMgPSBlbGVtZW50cztcbiAgICAgICAgICAgICAgICAvLyBieSBkZWZhdWx0LCB0aGUgbG9hZGVyIHdpbGwgb25seSBsb29rIGF0IHRoZSBVIGFuZCBWXG4gICAgICAgICAgICAgICAgLy8gY29vcmRpbmF0ZXMgb2YgdGhlIHZ0IGRlY2xhcmF0aW9uLiBTbywgdGhpcyB0cnVuY2F0ZXMgdGhlXG4gICAgICAgICAgICAgICAgLy8gZWxlbWVudHMgdG8gb25seSB0aG9zZSAyIHZhbHVlcy4gSWYgVyB0ZXh0dXJlIGNvb3JkaW5hdGVcbiAgICAgICAgICAgICAgICAvLyBzdXBwb3J0IGlzIGVuYWJsZWQsIHRoZW4gdGhlIHRleHR1cmUgY29vcmRpbmF0ZSBpc1xuICAgICAgICAgICAgICAgIC8vIGV4cGVjdGVkIHRvIGhhdmUgdGhyZWUgdmFsdWVzIGluIGl0LlxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50cy5sZW5ndGggPiAyICYmICFvcHRpb25zLmVuYWJsZVdUZXh0dXJlQ29vcmQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29vcmRzID0gZWxlbWVudHMuc2xpY2UoMCwgMik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50cy5sZW5ndGggPT09IDIgJiYgb3B0aW9ucy5lbmFibGVXVGV4dHVyZUNvb3JkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIGZvciBzb21lIHJlYXNvbiBXIHRleHR1cmUgY29vcmRpbmF0ZSBzdXBwb3J0IGlzIGVuYWJsZWRcbiAgICAgICAgICAgICAgICAgICAgLy8gYW5kIG9ubHkgdGhlIFUgYW5kIFYgY29vcmRpbmF0ZXMgYXJlIGdpdmVuLCB0aGVuIHdlIHN1cHBseVxuICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZGVmYXVsdCB2YWx1ZSBvZiAwIHNvIHRoYXQgdGhlIHN0cmlkZSBsZW5ndGggaXMgY29ycmVjdFxuICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIHRoZSB0ZXh0dXJlcyBhcmUgdW5wYWNrZWQgYmVsb3cuXG4gICAgICAgICAgICAgICAgICAgIGNvb3Jkcy5wdXNoKFwiMFwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGV4dHVyZXMucHVzaCguLi5jb29yZHMpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChVU0VfTUFURVJJQUxfUkUudGVzdChsaW5lKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsTmFtZSA9IGVsZW1lbnRzWzBdO1xuXG4gICAgICAgICAgICAgICAgLy8gY2hlY2sgdG8gc2VlIGlmIHdlJ3ZlIGV2ZXIgc2VlbiBpdCBiZWZvcmVcbiAgICAgICAgICAgICAgICBpZiAoIShtYXRlcmlhbE5hbWUgaW4gbWF0ZXJpYWxJbmRpY2VzQnlOYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBuZXcgbWF0ZXJpYWwgd2UndmUgbmV2ZXIgc2VlblxuICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbE5hbWVzQnlJbmRleC5wdXNoKG1hdGVyaWFsTmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsSW5kaWNlc0J5TmFtZVttYXRlcmlhbE5hbWVdID0gbWF0ZXJpYWxOYW1lc0J5SW5kZXgubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgLy8gcHVzaCBuZXcgYXJyYXkgaW50byBpbmRpY2VzXG4gICAgICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgY29udGFpbnMgYW4gYXJyYXkgYXQgaW5kZXggemVybywgZG9uJ3QgYWRkXG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXRlcmlhbEluZGljZXNCeU5hbWVbbWF0ZXJpYWxOYW1lXSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLmluZGljZXMucHVzaChbXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8ga2VlcCB0cmFjayBvZiB0aGUgY3VycmVudCBtYXRlcmlhbCBpbmRleFxuICAgICAgICAgICAgICAgIGN1cnJlbnRNYXRlcmlhbEluZGV4ID0gbWF0ZXJpYWxJbmRpY2VzQnlOYW1lW21hdGVyaWFsTmFtZV07XG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlIGN1cnJlbnQgaW5kZXggYXJyYXlcbiAgICAgICAgICAgICAgICBjdXJyZW50T2JqZWN0QnlNYXRlcmlhbEluZGV4ID0gY3VycmVudE1hdGVyaWFsSW5kZXg7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKEZBQ0VfUkUudGVzdChsaW5lKSkge1xuICAgICAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSBmYWNlXG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICBzcGxpdCB0aGlzIGZhY2UgaW50byBhbiBhcnJheSBvZiBWZXJ0ZXggZ3JvdXBzXG4gICAgICAgICAgICAgICAgZm9yIGV4YW1wbGU6XG4gICAgICAgICAgICAgICAgICAgZiAxNi85Mi8xMSAxNC8xMDEvMjIgMS82OS8xXG4gICAgICAgICAgICAgICAgYmVjb21lczpcbiAgICAgICAgICAgICAgICAgIFsnMTYvOTIvMTEnLCAnMTQvMTAxLzIyJywgJzEvNjkvMSddO1xuICAgICAgICAgICAgICAgICovXG5cbiAgICAgICAgICAgICAgICBjb25zdCB0cmlhbmdsZXMgPSB0cmlhbmd1bGF0ZShlbGVtZW50cyk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB0cmlhbmdsZSBvZiB0cmlhbmdsZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDAsIGVsZUxlbiA9IHRyaWFuZ2xlLmxlbmd0aDsgaiA8IGVsZUxlbjsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoYXNoID0gdHJpYW5nbGVbal0gKyBcIixcIiArIGN1cnJlbnRNYXRlcmlhbEluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc2ggaW4gdW5wYWNrZWQuaGFzaGluZGljZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnBhY2tlZC5pbmRpY2VzW2N1cnJlbnRPYmplY3RCeU1hdGVyaWFsSW5kZXhdLnB1c2godW5wYWNrZWQuaGFzaGluZGljZXNbaGFzaF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAgICAgICAgRWFjaCBlbGVtZW50IG9mIHRoZSBmYWNlIGxpbmUgYXJyYXkgaXMgYSBWZXJ0ZXggd2hpY2ggaGFzIGl0c1xuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcyBkZWxpbWl0ZWQgYnkgYSBmb3J3YXJkIHNsYXNoLiBUaGlzIHdpbGwgc2VwYXJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIGVhY2ggYXR0cmlidXRlIGludG8gYW5vdGhlciBhcnJheTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnMTkvOTIvMTEnXG4gICAgICAgICAgICAgICAgICAgICAgICBiZWNvbWVzOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRleCA9IFsnMTknLCAnOTInLCAnMTEnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoZXJlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4WzBdIGlzIHRoZSB2ZXJ0ZXggaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhbMV0gaXMgdGhlIHRleHR1cmUgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhbMl0gaXMgdGhlIG5vcm1hbCBpbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgIFRoaW5rIG9mIGZhY2VzIGhhdmluZyBWZXJ0aWNlcyB3aGljaCBhcmUgY29tcHJpc2VkIG9mIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgbG9jYXRpb24gKHYpLCB0ZXh0dXJlICh2dCksIGFuZCBub3JtYWwgKHZuKS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZlcnRleCA9IGVsZW1lbnRzW2pdLnNwbGl0KFwiL1wiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCdzIHBvc3NpYmxlIGZvciBmYWNlcyB0byBvbmx5IHNwZWNpZnkgdGhlIHZlcnRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB0aGUgbm9ybWFsLiBJbiB0aGlzIGNhc2UsIHZlcnRleCB3aWxsIG9ubHkgaGF2ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgbGVuZ3RoIG9mIDIgYW5kIG5vdCAzIGFuZCB0aGUgbm9ybWFsIHdpbGwgYmUgdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2Vjb25kIGl0ZW0gaW4gdGhlIGxpc3Qgd2l0aCBhbiBpbmRleCBvZiAxLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vcm1hbEluZGV4ID0gdmVydGV4Lmxlbmd0aCAtIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgdmVydHMsIHRleHR1cmVzLCBhbmQgdmVydE5vcm1hbHMgYXJyYXlzIGVhY2ggY29udGFpbiBhXG4gICAgICAgICAgICAgICAgICAgICAgICAgZmxhdHRlbmQgYXJyYXkgb2YgY29vcmRpbmF0ZXMuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICBCZWNhdXNlIGl0IGdldHMgY29uZnVzaW5nIGJ5IHJlZmVycmluZyB0byBWZXJ0ZXggYW5kIHRoZW5cbiAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJ0ZXggKGJvdGggYXJlIGRpZmZlcmVudCBpbiBteSBkZXNjcmlwdGlvbnMpIEkgd2lsbCBleHBsYWluXG4gICAgICAgICAgICAgICAgICAgICAgICAgd2hhdCdzIGdvaW5nIG9uIHVzaW5nIHRoZSB2ZXJ0ZXhOb3JtYWxzIGFycmF5OlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgdmVydGV4WzJdIHdpbGwgY29udGFpbiB0aGUgb25lLWJhc2VkIGluZGV4IG9mIHRoZSB2ZXJ0ZXhOb3JtYWxzXG4gICAgICAgICAgICAgICAgICAgICAgICAgc2VjdGlvbiAodm4pLiBPbmUgaXMgc3VidHJhY3RlZCBmcm9tIHRoaXMgaW5kZXggbnVtYmVyIHRvIHBsYXlcbiAgICAgICAgICAgICAgICAgICAgICAgICBuaWNlIHdpdGggamF2YXNjcmlwdCdzIHplcm8tYmFzZWQgYXJyYXkgaW5kZXhpbmcuXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICBCZWNhdXNlIHZlcnRleE5vcm1hbCBpcyBhIGZsYXR0ZW5lZCBhcnJheSBvZiB4LCB5LCB6IHZhbHVlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICBzaW1wbGUgcG9pbnRlciBhcml0aG1ldGljIGlzIHVzZWQgdG8gc2tpcCB0byB0aGUgc3RhcnQgb2YgdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAgdmVydGV4Tm9ybWFsLCB0aGVuIHRoZSBvZmZzZXQgaXMgYWRkZWQgdG8gZ2V0IHRoZSBjb3JyZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50OiArMCBpcyB4LCArMSBpcyB5LCArMiBpcyB6LlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBzYW1lIHByb2Nlc3MgaXMgcmVwZWF0ZWQgZm9yIHZlcnRzIGFuZCB0ZXh0dXJlcy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZlcnRleCBwb3NpdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLnZlcnRzLnB1c2goK3ZlcnRzWygrdmVydGV4WzBdIC0gMSkgKiAzICsgMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLnZlcnRzLnB1c2goK3ZlcnRzWygrdmVydGV4WzBdIC0gMSkgKiAzICsgMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLnZlcnRzLnB1c2goK3ZlcnRzWygrdmVydGV4WzBdIC0gMSkgKiAzICsgMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZlcnRleCB0ZXh0dXJlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0dXJlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyaWRlID0gb3B0aW9ucy5lbmFibGVXVGV4dHVyZUNvb3JkID8gMyA6IDI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLnRleHR1cmVzLnB1c2goK3RleHR1cmVzWygrdmVydGV4WzFdIC0gMSkgKiBzdHJpZGUgKyAwXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLnRleHR1cmVzLnB1c2goK3RleHR1cmVzWygrdmVydGV4WzFdIC0gMSkgKiBzdHJpZGUgKyAxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmVuYWJsZVdUZXh0dXJlQ29vcmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLnRleHR1cmVzLnB1c2goK3RleHR1cmVzWygrdmVydGV4WzFdIC0gMSkgKiBzdHJpZGUgKyAyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmVydGV4IG5vcm1hbHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnBhY2tlZC5ub3Jtcy5wdXNoKCt2ZXJ0Tm9ybWFsc1soK3ZlcnRleFtub3JtYWxJbmRleF0gLSAxKSAqIDMgKyAwXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQubm9ybXMucHVzaCgrdmVydE5vcm1hbHNbKCt2ZXJ0ZXhbbm9ybWFsSW5kZXhdIC0gMSkgKiAzICsgMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLm5vcm1zLnB1c2goK3ZlcnROb3JtYWxzWygrdmVydGV4W25vcm1hbEluZGV4XSAtIDEpICogMyArIDJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWZXJ0ZXggbWF0ZXJpYWwgaW5kaWNlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLm1hdGVyaWFsSW5kaWNlcy5wdXNoKGN1cnJlbnRNYXRlcmlhbEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgdGhlIG5ld2x5IGNyZWF0ZWQgVmVydGV4IHRvIHRoZSBsaXN0IG9mIGluZGljZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnBhY2tlZC5oYXNoaW5kaWNlc1toYXNoXSA9IHVucGFja2VkLmluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLmluZGljZXNbY3VycmVudE9iamVjdEJ5TWF0ZXJpYWxJbmRleF0ucHVzaCh1bnBhY2tlZC5oYXNoaW5kaWNlc1toYXNoXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5jcmVtZW50IHRoZSBjb3VudGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQuaW5kZXggKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZlcnRpY2VzID0gdW5wYWNrZWQudmVydHM7XG4gICAgICAgIHRoaXMudmVydGV4Tm9ybWFscyA9IHVucGFja2VkLm5vcm1zO1xuICAgICAgICB0aGlzLnRleHR1cmVzID0gdW5wYWNrZWQudGV4dHVyZXM7XG4gICAgICAgIHRoaXMudmVydGV4TWF0ZXJpYWxJbmRpY2VzID0gdW5wYWNrZWQubWF0ZXJpYWxJbmRpY2VzO1xuICAgICAgICB0aGlzLmluZGljZXMgPSB1bnBhY2tlZC5pbmRpY2VzW2N1cnJlbnRPYmplY3RCeU1hdGVyaWFsSW5kZXhdO1xuICAgICAgICB0aGlzLmluZGljZXNQZXJNYXRlcmlhbCA9IHVucGFja2VkLmluZGljZXM7XG5cbiAgICAgICAgdGhpcy5tYXRlcmlhbE5hbWVzID0gbWF0ZXJpYWxOYW1lc0J5SW5kZXg7XG4gICAgICAgIHRoaXMubWF0ZXJpYWxJbmRpY2VzID0gbWF0ZXJpYWxJbmRpY2VzQnlOYW1lO1xuICAgICAgICB0aGlzLm1hdGVyaWFsc0J5SW5kZXggPSB7fTtcblxuICAgICAgICBpZiAob3B0aW9ucy5jYWxjVGFuZ2VudHNBbmRCaXRhbmdlbnRzKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGN1bGF0ZVRhbmdlbnRzQW5kQml0YW5nZW50cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgdGFuZ2VudHMgYW5kIGJpdGFuZ2VudHMgb2YgdGhlIG1lc2ggdGhhdCBmb3JtcyBhbiBvcnRob2dvbmFsIGJhc2lzIHRvZ2V0aGVyIHdpdGggdGhlXG4gICAgICogbm9ybWFsIGluIHRoZSBkaXJlY3Rpb24gb2YgdGhlIHRleHR1cmUgY29vcmRpbmF0ZXMuIFRoZXNlIGFyZSB1c2VmdWwgZm9yIHNldHRpbmcgdXAgdGhlIFRCTiBtYXRyaXhcbiAgICAgKiB3aGVuIGRpc3RvcnRpbmcgdGhlIG5vcm1hbHMgdGhyb3VnaCBub3JtYWwgbWFwcy5cbiAgICAgKiBNZXRob2QgZGVyaXZlZCBmcm9tOiBodHRwOi8vd3d3Lm9wZW5nbC10dXRvcmlhbC5vcmcvaW50ZXJtZWRpYXRlLXR1dG9yaWFscy90dXRvcmlhbC0xMy1ub3JtYWwtbWFwcGluZy9cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0aG9kIHJlcXVpcmVzIHRoZSBub3JtYWxzIGFuZCB0ZXh0dXJlIGNvb3JkaW5hdGVzIHRvIGJlIHBhcnNlZCBhbmQgc2V0IHVwIGNvcnJlY3RseS5cbiAgICAgKiBBZGRzIHRoZSB0YW5nZW50cyBhbmQgYml0YW5nZW50cyBhcyBtZW1iZXJzIG9mIHRoZSBjbGFzcyBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBjYWxjdWxhdGVUYW5nZW50c0FuZEJpdGFuZ2VudHMoKSB7XG4gICAgICAgIGNvbnNvbGUuYXNzZXJ0KFxuICAgICAgICAgICAgISEoXG4gICAgICAgICAgICAgICAgdGhpcy52ZXJ0aWNlcyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmVydGljZXMubGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgdGhpcy52ZXJ0ZXhOb3JtYWxzICYmXG4gICAgICAgICAgICAgICAgdGhpcy52ZXJ0ZXhOb3JtYWxzLmxlbmd0aCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZXMgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnRleHR1cmVzLmxlbmd0aFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIFwiTWlzc2luZyBhdHRyaWJ1dGVzIGZvciBjYWxjdWxhdGluZyB0YW5nZW50cyBhbmQgYml0YW5nZW50c1wiLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHVucGFja2VkID0ge1xuICAgICAgICAgICAgdGFuZ2VudHM6IFsuLi5uZXcgQXJyYXkodGhpcy52ZXJ0aWNlcy5sZW5ndGgpXS5tYXAoXyA9PiAwKSxcbiAgICAgICAgICAgIGJpdGFuZ2VudHM6IFsuLi5uZXcgQXJyYXkodGhpcy52ZXJ0aWNlcy5sZW5ndGgpXS5tYXAoXyA9PiAwKSxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBMb29wIHRocm91Z2ggYWxsIGZhY2VzIGluIHRoZSB3aG9sZSBtZXNoXG4gICAgICAgIGNvbnN0IGluZGljZXMgPSB0aGlzLmluZGljZXM7XG4gICAgICAgIGNvbnN0IHZlcnRpY2VzID0gdGhpcy52ZXJ0aWNlcztcbiAgICAgICAgY29uc3Qgbm9ybWFscyA9IHRoaXMudmVydGV4Tm9ybWFscztcbiAgICAgICAgY29uc3QgdXZzID0gdGhpcy50ZXh0dXJlcztcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGNvbnN0IGkwID0gaW5kaWNlc1tpICsgMF07XG4gICAgICAgICAgICBjb25zdCBpMSA9IGluZGljZXNbaSArIDFdO1xuICAgICAgICAgICAgY29uc3QgaTIgPSBpbmRpY2VzW2kgKyAyXTtcblxuICAgICAgICAgICAgY29uc3QgeF92MCA9IHZlcnRpY2VzW2kwICogMyArIDBdO1xuICAgICAgICAgICAgY29uc3QgeV92MCA9IHZlcnRpY2VzW2kwICogMyArIDFdO1xuICAgICAgICAgICAgY29uc3Qgel92MCA9IHZlcnRpY2VzW2kwICogMyArIDJdO1xuXG4gICAgICAgICAgICBjb25zdCB4X3V2MCA9IHV2c1tpMCAqIDIgKyAwXTtcbiAgICAgICAgICAgIGNvbnN0IHlfdXYwID0gdXZzW2kwICogMiArIDFdO1xuXG4gICAgICAgICAgICBjb25zdCB4X3YxID0gdmVydGljZXNbaTEgKiAzICsgMF07XG4gICAgICAgICAgICBjb25zdCB5X3YxID0gdmVydGljZXNbaTEgKiAzICsgMV07XG4gICAgICAgICAgICBjb25zdCB6X3YxID0gdmVydGljZXNbaTEgKiAzICsgMl07XG5cbiAgICAgICAgICAgIGNvbnN0IHhfdXYxID0gdXZzW2kxICogMiArIDBdO1xuICAgICAgICAgICAgY29uc3QgeV91djEgPSB1dnNbaTEgKiAyICsgMV07XG5cbiAgICAgICAgICAgIGNvbnN0IHhfdjIgPSB2ZXJ0aWNlc1tpMiAqIDMgKyAwXTtcbiAgICAgICAgICAgIGNvbnN0IHlfdjIgPSB2ZXJ0aWNlc1tpMiAqIDMgKyAxXTtcbiAgICAgICAgICAgIGNvbnN0IHpfdjIgPSB2ZXJ0aWNlc1tpMiAqIDMgKyAyXTtcblxuICAgICAgICAgICAgY29uc3QgeF91djIgPSB1dnNbaTIgKiAyICsgMF07XG4gICAgICAgICAgICBjb25zdCB5X3V2MiA9IHV2c1tpMiAqIDIgKyAxXTtcblxuICAgICAgICAgICAgY29uc3QgeF9kZWx0YVBvczEgPSB4X3YxIC0geF92MDtcbiAgICAgICAgICAgIGNvbnN0IHlfZGVsdGFQb3MxID0geV92MSAtIHlfdjA7XG4gICAgICAgICAgICBjb25zdCB6X2RlbHRhUG9zMSA9IHpfdjEgLSB6X3YwO1xuXG4gICAgICAgICAgICBjb25zdCB4X2RlbHRhUG9zMiA9IHhfdjIgLSB4X3YwO1xuICAgICAgICAgICAgY29uc3QgeV9kZWx0YVBvczIgPSB5X3YyIC0geV92MDtcbiAgICAgICAgICAgIGNvbnN0IHpfZGVsdGFQb3MyID0gel92MiAtIHpfdjA7XG5cbiAgICAgICAgICAgIGNvbnN0IHhfdXZEZWx0YVBvczEgPSB4X3V2MSAtIHhfdXYwO1xuICAgICAgICAgICAgY29uc3QgeV91dkRlbHRhUG9zMSA9IHlfdXYxIC0geV91djA7XG5cbiAgICAgICAgICAgIGNvbnN0IHhfdXZEZWx0YVBvczIgPSB4X3V2MiAtIHhfdXYwO1xuICAgICAgICAgICAgY29uc3QgeV91dkRlbHRhUG9zMiA9IHlfdXYyIC0geV91djA7XG5cbiAgICAgICAgICAgIGNvbnN0IHJJbnYgPSB4X3V2RGVsdGFQb3MxICogeV91dkRlbHRhUG9zMiAtIHlfdXZEZWx0YVBvczEgKiB4X3V2RGVsdGFQb3MyO1xuICAgICAgICAgICAgY29uc3QgciA9IDEuMCAvIE1hdGguYWJzKHJJbnYgPCAwLjAwMDEgPyAxLjAgOiBySW52KTtcblxuICAgICAgICAgICAgLy8gVGFuZ2VudFxuICAgICAgICAgICAgY29uc3QgeF90YW5nZW50ID0gKHhfZGVsdGFQb3MxICogeV91dkRlbHRhUG9zMiAtIHhfZGVsdGFQb3MyICogeV91dkRlbHRhUG9zMSkgKiByO1xuICAgICAgICAgICAgY29uc3QgeV90YW5nZW50ID0gKHlfZGVsdGFQb3MxICogeV91dkRlbHRhUG9zMiAtIHlfZGVsdGFQb3MyICogeV91dkRlbHRhUG9zMSkgKiByO1xuICAgICAgICAgICAgY29uc3Qgel90YW5nZW50ID0gKHpfZGVsdGFQb3MxICogeV91dkRlbHRhUG9zMiAtIHpfZGVsdGFQb3MyICogeV91dkRlbHRhUG9zMSkgKiByO1xuXG4gICAgICAgICAgICAvLyBCaXRhbmdlbnRcbiAgICAgICAgICAgIGNvbnN0IHhfYml0YW5nZW50ID0gKHhfZGVsdGFQb3MyICogeF91dkRlbHRhUG9zMSAtIHhfZGVsdGFQb3MxICogeF91dkRlbHRhUG9zMikgKiByO1xuICAgICAgICAgICAgY29uc3QgeV9iaXRhbmdlbnQgPSAoeV9kZWx0YVBvczIgKiB4X3V2RGVsdGFQb3MxIC0geV9kZWx0YVBvczEgKiB4X3V2RGVsdGFQb3MyKSAqIHI7XG4gICAgICAgICAgICBjb25zdCB6X2JpdGFuZ2VudCA9ICh6X2RlbHRhUG9zMiAqIHhfdXZEZWx0YVBvczEgLSB6X2RlbHRhUG9zMSAqIHhfdXZEZWx0YVBvczIpICogcjtcblxuICAgICAgICAgICAgLy8gR3JhbS1TY2htaWR0IG9ydGhvZ29uYWxpemVcbiAgICAgICAgICAgIC8vdCA9IGdsbTo6bm9ybWFsaXplKHQgLSBuICogZ2xtOjogZG90KG4sIHQpKTtcbiAgICAgICAgICAgIGNvbnN0IHhfbjAgPSBub3JtYWxzW2kwICogMyArIDBdO1xuICAgICAgICAgICAgY29uc3QgeV9uMCA9IG5vcm1hbHNbaTAgKiAzICsgMV07XG4gICAgICAgICAgICBjb25zdCB6X24wID0gbm9ybWFsc1tpMCAqIDMgKyAyXTtcblxuICAgICAgICAgICAgY29uc3QgeF9uMSA9IG5vcm1hbHNbaTEgKiAzICsgMF07XG4gICAgICAgICAgICBjb25zdCB5X24xID0gbm9ybWFsc1tpMSAqIDMgKyAxXTtcbiAgICAgICAgICAgIGNvbnN0IHpfbjEgPSBub3JtYWxzW2kxICogMyArIDJdO1xuXG4gICAgICAgICAgICBjb25zdCB4X24yID0gbm9ybWFsc1tpMiAqIDMgKyAwXTtcbiAgICAgICAgICAgIGNvbnN0IHlfbjIgPSBub3JtYWxzW2kyICogMyArIDFdO1xuICAgICAgICAgICAgY29uc3Qgel9uMiA9IG5vcm1hbHNbaTIgKiAzICsgMl07XG5cbiAgICAgICAgICAgIC8vIFRhbmdlbnRcbiAgICAgICAgICAgIGNvbnN0IG4wX2RvdF90ID0geF90YW5nZW50ICogeF9uMCArIHlfdGFuZ2VudCAqIHlfbjAgKyB6X3RhbmdlbnQgKiB6X24wO1xuICAgICAgICAgICAgY29uc3QgbjFfZG90X3QgPSB4X3RhbmdlbnQgKiB4X24xICsgeV90YW5nZW50ICogeV9uMSArIHpfdGFuZ2VudCAqIHpfbjE7XG4gICAgICAgICAgICBjb25zdCBuMl9kb3RfdCA9IHhfdGFuZ2VudCAqIHhfbjIgKyB5X3RhbmdlbnQgKiB5X24yICsgel90YW5nZW50ICogel9uMjtcblxuICAgICAgICAgICAgY29uc3QgeF9yZXNUYW5nZW50MCA9IHhfdGFuZ2VudCAtIHhfbjAgKiBuMF9kb3RfdDtcbiAgICAgICAgICAgIGNvbnN0IHlfcmVzVGFuZ2VudDAgPSB5X3RhbmdlbnQgLSB5X24wICogbjBfZG90X3Q7XG4gICAgICAgICAgICBjb25zdCB6X3Jlc1RhbmdlbnQwID0gel90YW5nZW50IC0gel9uMCAqIG4wX2RvdF90O1xuXG4gICAgICAgICAgICBjb25zdCB4X3Jlc1RhbmdlbnQxID0geF90YW5nZW50IC0geF9uMSAqIG4xX2RvdF90O1xuICAgICAgICAgICAgY29uc3QgeV9yZXNUYW5nZW50MSA9IHlfdGFuZ2VudCAtIHlfbjEgKiBuMV9kb3RfdDtcbiAgICAgICAgICAgIGNvbnN0IHpfcmVzVGFuZ2VudDEgPSB6X3RhbmdlbnQgLSB6X24xICogbjFfZG90X3Q7XG5cbiAgICAgICAgICAgIGNvbnN0IHhfcmVzVGFuZ2VudDIgPSB4X3RhbmdlbnQgLSB4X24yICogbjJfZG90X3Q7XG4gICAgICAgICAgICBjb25zdCB5X3Jlc1RhbmdlbnQyID0geV90YW5nZW50IC0geV9uMiAqIG4yX2RvdF90O1xuICAgICAgICAgICAgY29uc3Qgel9yZXNUYW5nZW50MiA9IHpfdGFuZ2VudCAtIHpfbjIgKiBuMl9kb3RfdDtcblxuICAgICAgICAgICAgY29uc3QgbWFnVGFuZ2VudDAgPSBNYXRoLnNxcnQoXG4gICAgICAgICAgICAgICAgeF9yZXNUYW5nZW50MCAqIHhfcmVzVGFuZ2VudDAgKyB5X3Jlc1RhbmdlbnQwICogeV9yZXNUYW5nZW50MCArIHpfcmVzVGFuZ2VudDAgKiB6X3Jlc1RhbmdlbnQwLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IG1hZ1RhbmdlbnQxID0gTWF0aC5zcXJ0KFxuICAgICAgICAgICAgICAgIHhfcmVzVGFuZ2VudDEgKiB4X3Jlc1RhbmdlbnQxICsgeV9yZXNUYW5nZW50MSAqIHlfcmVzVGFuZ2VudDEgKyB6X3Jlc1RhbmdlbnQxICogel9yZXNUYW5nZW50MSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBtYWdUYW5nZW50MiA9IE1hdGguc3FydChcbiAgICAgICAgICAgICAgICB4X3Jlc1RhbmdlbnQyICogeF9yZXNUYW5nZW50MiArIHlfcmVzVGFuZ2VudDIgKiB5X3Jlc1RhbmdlbnQyICsgel9yZXNUYW5nZW50MiAqIHpfcmVzVGFuZ2VudDIsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBCaXRhbmdlbnRcbiAgICAgICAgICAgIGNvbnN0IG4wX2RvdF9idCA9IHhfYml0YW5nZW50ICogeF9uMCArIHlfYml0YW5nZW50ICogeV9uMCArIHpfYml0YW5nZW50ICogel9uMDtcbiAgICAgICAgICAgIGNvbnN0IG4xX2RvdF9idCA9IHhfYml0YW5nZW50ICogeF9uMSArIHlfYml0YW5nZW50ICogeV9uMSArIHpfYml0YW5nZW50ICogel9uMTtcbiAgICAgICAgICAgIGNvbnN0IG4yX2RvdF9idCA9IHhfYml0YW5nZW50ICogeF9uMiArIHlfYml0YW5nZW50ICogeV9uMiArIHpfYml0YW5nZW50ICogel9uMjtcblxuICAgICAgICAgICAgY29uc3QgeF9yZXNCaXRhbmdlbnQwID0geF9iaXRhbmdlbnQgLSB4X24wICogbjBfZG90X2J0O1xuICAgICAgICAgICAgY29uc3QgeV9yZXNCaXRhbmdlbnQwID0geV9iaXRhbmdlbnQgLSB5X24wICogbjBfZG90X2J0O1xuICAgICAgICAgICAgY29uc3Qgel9yZXNCaXRhbmdlbnQwID0gel9iaXRhbmdlbnQgLSB6X24wICogbjBfZG90X2J0O1xuXG4gICAgICAgICAgICBjb25zdCB4X3Jlc0JpdGFuZ2VudDEgPSB4X2JpdGFuZ2VudCAtIHhfbjEgKiBuMV9kb3RfYnQ7XG4gICAgICAgICAgICBjb25zdCB5X3Jlc0JpdGFuZ2VudDEgPSB5X2JpdGFuZ2VudCAtIHlfbjEgKiBuMV9kb3RfYnQ7XG4gICAgICAgICAgICBjb25zdCB6X3Jlc0JpdGFuZ2VudDEgPSB6X2JpdGFuZ2VudCAtIHpfbjEgKiBuMV9kb3RfYnQ7XG5cbiAgICAgICAgICAgIGNvbnN0IHhfcmVzQml0YW5nZW50MiA9IHhfYml0YW5nZW50IC0geF9uMiAqIG4yX2RvdF9idDtcbiAgICAgICAgICAgIGNvbnN0IHlfcmVzQml0YW5nZW50MiA9IHlfYml0YW5nZW50IC0geV9uMiAqIG4yX2RvdF9idDtcbiAgICAgICAgICAgIGNvbnN0IHpfcmVzQml0YW5nZW50MiA9IHpfYml0YW5nZW50IC0gel9uMiAqIG4yX2RvdF9idDtcblxuICAgICAgICAgICAgY29uc3QgbWFnQml0YW5nZW50MCA9IE1hdGguc3FydChcbiAgICAgICAgICAgICAgICB4X3Jlc0JpdGFuZ2VudDAgKiB4X3Jlc0JpdGFuZ2VudDAgK1xuICAgICAgICAgICAgICAgICAgICB5X3Jlc0JpdGFuZ2VudDAgKiB5X3Jlc0JpdGFuZ2VudDAgK1xuICAgICAgICAgICAgICAgICAgICB6X3Jlc0JpdGFuZ2VudDAgKiB6X3Jlc0JpdGFuZ2VudDAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgbWFnQml0YW5nZW50MSA9IE1hdGguc3FydChcbiAgICAgICAgICAgICAgICB4X3Jlc0JpdGFuZ2VudDEgKiB4X3Jlc0JpdGFuZ2VudDEgK1xuICAgICAgICAgICAgICAgICAgICB5X3Jlc0JpdGFuZ2VudDEgKiB5X3Jlc0JpdGFuZ2VudDEgK1xuICAgICAgICAgICAgICAgICAgICB6X3Jlc0JpdGFuZ2VudDEgKiB6X3Jlc0JpdGFuZ2VudDEsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgbWFnQml0YW5nZW50MiA9IE1hdGguc3FydChcbiAgICAgICAgICAgICAgICB4X3Jlc0JpdGFuZ2VudDIgKiB4X3Jlc0JpdGFuZ2VudDIgK1xuICAgICAgICAgICAgICAgICAgICB5X3Jlc0JpdGFuZ2VudDIgKiB5X3Jlc0JpdGFuZ2VudDIgK1xuICAgICAgICAgICAgICAgICAgICB6X3Jlc0JpdGFuZ2VudDIgKiB6X3Jlc0JpdGFuZ2VudDIsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICB1bnBhY2tlZC50YW5nZW50c1tpMCAqIDMgKyAwXSArPSB4X3Jlc1RhbmdlbnQwIC8gbWFnVGFuZ2VudDA7XG4gICAgICAgICAgICB1bnBhY2tlZC50YW5nZW50c1tpMCAqIDMgKyAxXSArPSB5X3Jlc1RhbmdlbnQwIC8gbWFnVGFuZ2VudDA7XG4gICAgICAgICAgICB1bnBhY2tlZC50YW5nZW50c1tpMCAqIDMgKyAyXSArPSB6X3Jlc1RhbmdlbnQwIC8gbWFnVGFuZ2VudDA7XG5cbiAgICAgICAgICAgIHVucGFja2VkLnRhbmdlbnRzW2kxICogMyArIDBdICs9IHhfcmVzVGFuZ2VudDEgLyBtYWdUYW5nZW50MTtcbiAgICAgICAgICAgIHVucGFja2VkLnRhbmdlbnRzW2kxICogMyArIDFdICs9IHlfcmVzVGFuZ2VudDEgLyBtYWdUYW5nZW50MTtcbiAgICAgICAgICAgIHVucGFja2VkLnRhbmdlbnRzW2kxICogMyArIDJdICs9IHpfcmVzVGFuZ2VudDEgLyBtYWdUYW5nZW50MTtcblxuICAgICAgICAgICAgdW5wYWNrZWQudGFuZ2VudHNbaTIgKiAzICsgMF0gKz0geF9yZXNUYW5nZW50MiAvIG1hZ1RhbmdlbnQyO1xuICAgICAgICAgICAgdW5wYWNrZWQudGFuZ2VudHNbaTIgKiAzICsgMV0gKz0geV9yZXNUYW5nZW50MiAvIG1hZ1RhbmdlbnQyO1xuICAgICAgICAgICAgdW5wYWNrZWQudGFuZ2VudHNbaTIgKiAzICsgMl0gKz0gel9yZXNUYW5nZW50MiAvIG1hZ1RhbmdlbnQyO1xuXG4gICAgICAgICAgICB1bnBhY2tlZC5iaXRhbmdlbnRzW2kwICogMyArIDBdICs9IHhfcmVzQml0YW5nZW50MCAvIG1hZ0JpdGFuZ2VudDA7XG4gICAgICAgICAgICB1bnBhY2tlZC5iaXRhbmdlbnRzW2kwICogMyArIDFdICs9IHlfcmVzQml0YW5nZW50MCAvIG1hZ0JpdGFuZ2VudDA7XG4gICAgICAgICAgICB1bnBhY2tlZC5iaXRhbmdlbnRzW2kwICogMyArIDJdICs9IHpfcmVzQml0YW5nZW50MCAvIG1hZ0JpdGFuZ2VudDA7XG5cbiAgICAgICAgICAgIHVucGFja2VkLmJpdGFuZ2VudHNbaTEgKiAzICsgMF0gKz0geF9yZXNCaXRhbmdlbnQxIC8gbWFnQml0YW5nZW50MTtcbiAgICAgICAgICAgIHVucGFja2VkLmJpdGFuZ2VudHNbaTEgKiAzICsgMV0gKz0geV9yZXNCaXRhbmdlbnQxIC8gbWFnQml0YW5nZW50MTtcbiAgICAgICAgICAgIHVucGFja2VkLmJpdGFuZ2VudHNbaTEgKiAzICsgMl0gKz0gel9yZXNCaXRhbmdlbnQxIC8gbWFnQml0YW5nZW50MTtcblxuICAgICAgICAgICAgdW5wYWNrZWQuYml0YW5nZW50c1tpMiAqIDMgKyAwXSArPSB4X3Jlc0JpdGFuZ2VudDIgLyBtYWdCaXRhbmdlbnQyO1xuICAgICAgICAgICAgdW5wYWNrZWQuYml0YW5nZW50c1tpMiAqIDMgKyAxXSArPSB5X3Jlc0JpdGFuZ2VudDIgLyBtYWdCaXRhbmdlbnQyO1xuICAgICAgICAgICAgdW5wYWNrZWQuYml0YW5nZW50c1tpMiAqIDMgKyAyXSArPSB6X3Jlc0JpdGFuZ2VudDIgLyBtYWdCaXRhbmdlbnQyO1xuXG4gICAgICAgICAgICAvLyBUT0RPOiBjaGVjayBoYW5kZWRuZXNzXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRhbmdlbnRzID0gdW5wYWNrZWQudGFuZ2VudHM7XG4gICAgICAgIHRoaXMuYml0YW5nZW50cyA9IHVucGFja2VkLmJpdGFuZ2VudHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGxheW91dCAtIEEge0BsaW5rIExheW91dH0gb2JqZWN0IHRoYXQgZGVzY3JpYmVzIHRoZVxuICAgICAqIGRlc2lyZWQgbWVtb3J5IGxheW91dCBvZiB0aGUgZ2VuZXJhdGVkIGJ1ZmZlclxuICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZCBhcnJheSBpbiB0aGUgLi4uIFRPRE9cbiAgICAgKi9cbiAgICBtYWtlQnVmZmVyRGF0YShsYXlvdXQ6IExheW91dCk6IEFycmF5QnVmZmVyV2l0aEl0ZW1TaXplIHtcbiAgICAgICAgY29uc3QgbnVtSXRlbXMgPSB0aGlzLnZlcnRpY2VzLmxlbmd0aCAvIDM7XG4gICAgICAgIGNvbnN0IGJ1ZmZlcjogQXJyYXlCdWZmZXJXaXRoSXRlbVNpemUgPSBuZXcgQXJyYXlCdWZmZXIobGF5b3V0LnN0cmlkZSAqIG51bUl0ZW1zKTtcbiAgICAgICAgYnVmZmVyLm51bUl0ZW1zID0gbnVtSXRlbXM7XG4gICAgICAgIGNvbnN0IGRhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGJ1ZmZlcik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCB2ZXJ0ZXhPZmZzZXQgPSAwOyBpIDwgbnVtSXRlbXM7IGkrKykge1xuICAgICAgICAgICAgdmVydGV4T2Zmc2V0ID0gaSAqIGxheW91dC5zdHJpZGU7XG4gICAgICAgICAgICAvLyBjb3B5IGluIHRoZSB2ZXJ0ZXggZGF0YSBpbiB0aGUgb3JkZXIgYW5kIGZvcm1hdCBnaXZlbiBieSB0aGVcbiAgICAgICAgICAgIC8vIGxheW91dCBwYXJhbVxuICAgICAgICAgICAgZm9yIChjb25zdCBhdHRyaWJ1dGUgb2YgbGF5b3V0LmF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSB2ZXJ0ZXhPZmZzZXQgKyBsYXlvdXQuYXR0cmlidXRlTWFwW2F0dHJpYnV0ZS5rZXldLm9mZnNldDtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGF0dHJpYnV0ZS5rZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuUE9TSVRJT04ua2V5OlxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIHRoaXMudmVydGljZXNbaSAqIDNdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgNCwgdGhpcy52ZXJ0aWNlc1tpICogMyArIDFdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgOCwgdGhpcy52ZXJ0aWNlc1tpICogMyArIDJdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5VVi5rZXk6XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCwgdGhpcy50ZXh0dXJlc1tpICogMl0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA0LCB0aGlzLnRleHR1cmVzW2kgKiAyICsgMV0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTGF5b3V0Lk5PUk1BTC5rZXk6XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCwgdGhpcy52ZXJ0ZXhOb3JtYWxzW2kgKiAzXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCArIDQsIHRoaXMudmVydGV4Tm9ybWFsc1tpICogMyArIDFdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgOCwgdGhpcy52ZXJ0ZXhOb3JtYWxzW2kgKiAzICsgMl0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTGF5b3V0Lk1BVEVSSUFMX0lOREVYLmtleTpcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEludDE2KG9mZnNldCwgdGhpcy52ZXJ0ZXhNYXRlcmlhbEluZGljZXNbaV0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTGF5b3V0LkFNQklFTlQua2V5OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbEluZGV4ID0gdGhpcy52ZXJ0ZXhNYXRlcmlhbEluZGljZXNbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IHRoaXMubWF0ZXJpYWxzQnlJbmRleFttYXRlcmlhbEluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbWF0ZXJpYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdNYXRlcmlhbCBcIicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXRlcmlhbE5hbWVzW21hdGVyaWFsSW5kZXhdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdcIiBub3QgZm91bmQgaW4gbWVzaC4gRGlkIHlvdSBmb3JnZXQgdG8gY2FsbCBhZGRNYXRlcmlhbExpYnJhcnkoLi4uKT9cIicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0LCBtYXRlcmlhbC5hbWJpZW50WzBdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgNCwgbWF0ZXJpYWwuYW1iaWVudFsxXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCArIDgsIG1hdGVyaWFsLmFtYmllbnRbMl0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuRElGRlVTRS5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIG1hdGVyaWFsLmRpZmZ1c2VbMF0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA0LCBtYXRlcmlhbC5kaWZmdXNlWzFdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgOCwgbWF0ZXJpYWwuZGlmZnVzZVsyXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5TUEVDVUxBUi5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIG1hdGVyaWFsLnNwZWN1bGFyWzBdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgNCwgbWF0ZXJpYWwuc3BlY3VsYXJbMV0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA4LCBtYXRlcmlhbC5zcGVjdWxhclsyXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5TUEVDVUxBUl9FWFBPTkVOVC5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIG1hdGVyaWFsLnNwZWN1bGFyRXhwb25lbnQsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuRU1JU1NJVkUua2V5OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbEluZGV4ID0gdGhpcy52ZXJ0ZXhNYXRlcmlhbEluZGljZXNbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IHRoaXMubWF0ZXJpYWxzQnlJbmRleFttYXRlcmlhbEluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbWF0ZXJpYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdNYXRlcmlhbCBcIicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXRlcmlhbE5hbWVzW21hdGVyaWFsSW5kZXhdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdcIiBub3QgZm91bmQgaW4gbWVzaC4gRGlkIHlvdSBmb3JnZXQgdG8gY2FsbCBhZGRNYXRlcmlhbExpYnJhcnkoLi4uKT9cIicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0LCBtYXRlcmlhbC5lbWlzc2l2ZVswXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCArIDQsIG1hdGVyaWFsLmVtaXNzaXZlWzFdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgOCwgbWF0ZXJpYWwuZW1pc3NpdmVbMl0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuVFJBTlNNSVNTSU9OX0ZJTFRFUi5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIG1hdGVyaWFsLnRyYW5zbWlzc2lvbkZpbHRlclswXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCArIDQsIG1hdGVyaWFsLnRyYW5zbWlzc2lvbkZpbHRlclsxXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCArIDgsIG1hdGVyaWFsLnRyYW5zbWlzc2lvbkZpbHRlclsyXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5ESVNTT0xWRS5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIG1hdGVyaWFsLmRpc3NvbHZlLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTGF5b3V0LklMTFVNSU5BVElPTi5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0SW50MTYob2Zmc2V0LCBtYXRlcmlhbC5pbGx1bWluYXRpb24sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuUkVGUkFDVElPTl9JTkRFWC5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIG1hdGVyaWFsLnJlZnJhY3Rpb25JbmRleCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5TSEFSUE5FU1Mua2V5OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbEluZGV4ID0gdGhpcy52ZXJ0ZXhNYXRlcmlhbEluZGljZXNbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IHRoaXMubWF0ZXJpYWxzQnlJbmRleFttYXRlcmlhbEluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbWF0ZXJpYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdNYXRlcmlhbCBcIicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXRlcmlhbE5hbWVzW21hdGVyaWFsSW5kZXhdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdcIiBub3QgZm91bmQgaW4gbWVzaC4gRGlkIHlvdSBmb3JnZXQgdG8gY2FsbCBhZGRNYXRlcmlhbExpYnJhcnkoLi4uKT9cIicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0LCBtYXRlcmlhbC5zaGFycG5lc3MsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuQU5USV9BTElBU0lORy5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0SW50MTYob2Zmc2V0LCBtYXRlcmlhbC5hbnRpQWxpYXNpbmcgPyAxIDogMCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYnVmZmVyO1xuICAgIH1cblxuICAgIG1ha2VJbmRleEJ1ZmZlckRhdGEoKTogVWludDE2QXJyYXlXaXRoSXRlbVNpemUge1xuICAgICAgICBjb25zdCBidWZmZXI6IFVpbnQxNkFycmF5V2l0aEl0ZW1TaXplID0gbmV3IFVpbnQxNkFycmF5KHRoaXMuaW5kaWNlcyk7XG4gICAgICAgIGJ1ZmZlci5udW1JdGVtcyA9IHRoaXMuaW5kaWNlcy5sZW5ndGg7XG4gICAgICAgIHJldHVybiBidWZmZXI7XG4gICAgfVxuXG4gICAgYWRkTWF0ZXJpYWxMaWJyYXJ5KG10bDogTWF0ZXJpYWxMaWJyYXJ5KSB7XG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBtdGwubWF0ZXJpYWxzKSB7XG4gICAgICAgICAgICBpZiAoIShuYW1lIGluIHRoaXMubWF0ZXJpYWxJbmRpY2VzKSkge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgbWF0ZXJpYWwgaXMgbm90IHJlZmVyZW5jZWQgYnkgdGhlIG1lc2hcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSBtdGwubWF0ZXJpYWxzW25hbWVdO1xuXG4gICAgICAgICAgICAvLyBGaW5kIHRoZSBtYXRlcmlhbCBpbmRleCBmb3IgdGhpcyBtYXRlcmlhbFxuICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxJbmRleCA9IHRoaXMubWF0ZXJpYWxJbmRpY2VzW21hdGVyaWFsLm5hbWVdO1xuXG4gICAgICAgICAgICAvLyBQdXQgdGhlIG1hdGVyaWFsIGludG8gdGhlIG1hdGVyaWFsc0J5SW5kZXggb2JqZWN0IGF0IHRoZSByaWdodFxuICAgICAgICAgICAgLy8gc3BvdCBhcyBkZXRlcm1pbmVkIHdoZW4gdGhlIG9iaiBmaWxlIHdhcyBwYXJzZWRcbiAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxzQnlJbmRleFttYXRlcmlhbEluZGV4XSA9IG1hdGVyaWFsO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiogdHJpYW5ndWxhdGUoZWxlbWVudHM6IHN0cmluZ1tdKSB7XG4gICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA8PSAzKSB7XG4gICAgICAgIHlpZWxkIGVsZW1lbnRzO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudHMubGVuZ3RoID09PSA0KSB7XG4gICAgICAgIHlpZWxkIFtlbGVtZW50c1swXSwgZWxlbWVudHNbMV0sIGVsZW1lbnRzWzJdXTtcbiAgICAgICAgeWllbGQgW2VsZW1lbnRzWzJdLCBlbGVtZW50c1szXSwgZWxlbWVudHNbMF1dO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZWxlbWVudHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICB5aWVsZCBbZWxlbWVudHNbMF0sIGVsZW1lbnRzW2ldLCBlbGVtZW50c1tpICsgMV1dO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiaW1wb3J0IE1lc2ggZnJvbSBcIi4vbWVzaFwiO1xuaW1wb3J0IHsgTWF0ZXJpYWxMaWJyYXJ5LCBUZXh0dXJlTWFwRGF0YSB9IGZyb20gXCIuL21hdGVyaWFsXCI7XG5cbmZ1bmN0aW9uIGRvd25sb2FkTXRsVGV4dHVyZXMobXRsOiBNYXRlcmlhbExpYnJhcnksIHJvb3Q6IHN0cmluZykge1xuICAgIGNvbnN0IG1hcEF0dHJpYnV0ZXMgPSBbXG4gICAgICAgIFwibWFwRGlmZnVzZVwiLFxuICAgICAgICBcIm1hcEFtYmllbnRcIixcbiAgICAgICAgXCJtYXBTcGVjdWxhclwiLFxuICAgICAgICBcIm1hcERpc3NvbHZlXCIsXG4gICAgICAgIFwibWFwQnVtcFwiLFxuICAgICAgICBcIm1hcERpc3BsYWNlbWVudFwiLFxuICAgICAgICBcIm1hcERlY2FsXCIsXG4gICAgICAgIFwibWFwRW1pc3NpdmVcIixcbiAgICBdO1xuICAgIGlmICghcm9vdC5lbmRzV2l0aChcIi9cIikpIHtcbiAgICAgICAgcm9vdCArPSBcIi9cIjtcbiAgICB9XG4gICAgY29uc3QgdGV4dHVyZXMgPSBbXTtcblxuICAgIGZvciAoY29uc3QgbWF0ZXJpYWxOYW1lIGluIG10bC5tYXRlcmlhbHMpIHtcbiAgICAgICAgaWYgKCFtdGwubWF0ZXJpYWxzLmhhc093blByb3BlcnR5KG1hdGVyaWFsTmFtZSkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hdGVyaWFsID0gbXRsLm1hdGVyaWFsc1ttYXRlcmlhbE5hbWVdO1xuXG4gICAgICAgIGZvciAoY29uc3QgYXR0ciBvZiBtYXBBdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgICBjb25zdCBtYXBEYXRhID0gKG1hdGVyaWFsIGFzIGFueSlbYXR0cl0gYXMgVGV4dHVyZU1hcERhdGE7XG4gICAgICAgICAgICBpZiAoIW1hcERhdGEpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdXJsID0gcm9vdCArIG1hcERhdGEuZmlsZW5hbWU7XG4gICAgICAgICAgICB0ZXh0dXJlcy5wdXNoKFxuICAgICAgICAgICAgICAgIGZldGNoKHVybClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmJsb2IoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlLnNyYyA9IFVSTC5jcmVhdGVPYmplY3RVUkwoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXBEYXRhLnRleHR1cmUgPSBpbWFnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IChpbWFnZS5vbmxvYWQgPSByZXNvbHZlKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBVbmFibGUgdG8gZG93bmxvYWQgdGV4dHVyZTogJHt1cmx9YCk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLmFsbCh0ZXh0dXJlcyk7XG59XG5cbmZ1bmN0aW9uIGdldE10bChtb2RlbE9wdGlvbnM6IERvd25sb2FkTW9kZWxzT3B0aW9ucyk6IHN0cmluZyB7XG4gICAgaWYgKCEodHlwZW9mIG1vZGVsT3B0aW9ucy5tdGwgPT09IFwic3RyaW5nXCIpKSB7XG4gICAgICAgIHJldHVybiBtb2RlbE9wdGlvbnMub2JqLnJlcGxhY2UoL1xcLm9iaiQvLCBcIi5tdGxcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsT3B0aW9ucy5tdGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRG93bmxvYWRNb2RlbHNPcHRpb25zIHtcbiAgICBvYmo6IHN0cmluZztcbiAgICBtdGw/OiBib29sZWFuIHwgc3RyaW5nO1xuICAgIGRvd25sb2FkTXRsVGV4dHVyZXM/OiBib29sZWFuO1xuICAgIG10bFRleHR1cmVSb290Pzogc3RyaW5nO1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgaW5kaWNlc1Blck1hdGVyaWFsPzogYm9vbGVhbjtcbiAgICBjYWxjVGFuZ2VudHNBbmRCaXRhbmdlbnRzPzogYm9vbGVhbjtcbn1cblxudHlwZSBNb2RlbFByb21pc2VzID0gW1Byb21pc2U8c3RyaW5nPiwgUHJvbWlzZTxNZXNoPiwgdW5kZWZpbmVkIHwgUHJvbWlzZTxNYXRlcmlhbExpYnJhcnk+XTtcbmV4cG9ydCB0eXBlIE1lc2hNYXAgPSB7IFtuYW1lOiBzdHJpbmddOiBNZXNoIH07XG4vKipcbiAqIEFjY2VwdHMgYSBsaXN0IG9mIG1vZGVsIHJlcXVlc3Qgb2JqZWN0cyBhbmQgcmV0dXJucyBhIFByb21pc2UgdGhhdFxuICogcmVzb2x2ZXMgd2hlbiBhbGwgbW9kZWxzIGhhdmUgYmVlbiBkb3dubG9hZGVkIGFuZCBwYXJzZWQuXG4gKlxuICogVGhlIGxpc3Qgb2YgbW9kZWwgb2JqZWN0cyBmb2xsb3cgdGhpcyBpbnRlcmZhY2U6XG4gKiB7XG4gKiAgb2JqOiAncGF0aC90by9tb2RlbC5vYmonLFxuICogIG10bDogdHJ1ZSB8ICdwYXRoL3RvL21vZGVsLm10bCcsXG4gKiAgZG93bmxvYWRNdGxUZXh0dXJlczogdHJ1ZSB8IGZhbHNlXG4gKiAgbXRsVGV4dHVyZVJvb3Q6ICcvbW9kZWxzL3N1emFubmUvbWFwcydcbiAqICBuYW1lOiAnc3V6YW5uZSdcbiAqIH1cbiAqXG4gKiBUaGUgYG9iamAgYXR0cmlidXRlIGlzIHJlcXVpcmVkIGFuZCBzaG91bGQgYmUgdGhlIHBhdGggdG8gdGhlXG4gKiBtb2RlbCdzIC5vYmogZmlsZSByZWxhdGl2ZSB0byB0aGUgY3VycmVudCByZXBvIChhYnNvbHV0ZSBVUkxzIGFyZVxuICogc3VnZ2VzdGVkKS5cbiAqXG4gKiBUaGUgYG10bGAgYXR0cmlidXRlIGlzIG9wdGlvbmFsIGFuZCBjYW4gZWl0aGVyIGJlIGEgYm9vbGVhbiBvclxuICogYSBwYXRoIHRvIHRoZSBtb2RlbCdzIC5tdGwgZmlsZSByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBVUkwuIElmXG4gKiB0aGUgdmFsdWUgaXMgYHRydWVgLCB0aGVuIHRoZSBwYXRoIGFuZCBiYXNlbmFtZSBnaXZlbiBmb3IgdGhlIGBvYmpgXG4gKiBhdHRyaWJ1dGUgaXMgdXNlZCByZXBsYWNpbmcgdGhlIC5vYmogc3VmZml4IGZvciAubXRsXG4gKiBFLmcuOiB7b2JqOiAnbW9kZWxzL2Zvby5vYmonLCBtdGw6IHRydWV9IHdvdWxkIHNlYXJjaCBmb3IgJ21vZGVscy9mb28ubXRsJ1xuICpcbiAqIFRoZSBgbmFtZWAgYXR0cmlidXRlIGlzIG9wdGlvbmFsIGFuZCBpcyBhIGh1bWFuIGZyaWVuZGx5IG5hbWUgdG8gYmVcbiAqIGluY2x1ZGVkIHdpdGggdGhlIHBhcnNlZCBPQkogYW5kIE1UTCBmaWxlcy4gSWYgbm90IGdpdmVuLCB0aGUgYmFzZSAub2JqXG4gKiBmaWxlbmFtZSB3aWxsIGJlIHVzZWQuXG4gKlxuICogVGhlIGBkb3dubG9hZE10bFRleHR1cmVzYCBhdHRyaWJ1dGUgaXMgYSBmbGFnIGZvciBhdXRvbWF0aWNhbGx5IGRvd25sb2FkaW5nXG4gKiBhbnkgaW1hZ2VzIGZvdW5kIGluIHRoZSBNVEwgZmlsZSBhbmQgYXR0YWNoaW5nIHRoZW0gdG8gZWFjaCBNYXRlcmlhbFxuICogY3JlYXRlZCBmcm9tIHRoYXQgZmlsZS4gRm9yIGV4YW1wbGUsIGlmIG1hdGVyaWFsLm1hcERpZmZ1c2UgaXMgc2V0ICh0aGVyZVxuICogd2FzIGRhdGEgaW4gdGhlIE1UTCBmaWxlKSwgdGhlbiBtYXRlcmlhbC5tYXBEaWZmdXNlLnRleHR1cmUgd2lsbCBjb250YWluXG4gKiB0aGUgZG93bmxvYWRlZCBpbWFnZS4gVGhpcyBvcHRpb24gZGVmYXVsdHMgdG8gYHRydWVgLiBCeSBkZWZhdWx0LCB0aGUgTVRMJ3NcbiAqIFVSTCB3aWxsIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBsb2NhdGlvbiBvZiB0aGUgaW1hZ2VzLlxuICpcbiAqIFRoZSBgbXRsVGV4dHVyZVJvb3RgIGF0dHJpYnV0ZSBpcyBvcHRpb25hbCBhbmQgc2hvdWxkIHBvaW50IHRvIHRoZSBsb2NhdGlvblxuICogb24gdGhlIHNlcnZlciB0aGF0IHRoaXMgTVRMJ3MgdGV4dHVyZSBmaWxlcyBhcmUgbG9jYXRlZC4gVGhlIGRlZmF1bHQgaXMgdG9cbiAqIHVzZSB0aGUgTVRMIGZpbGUncyBsb2NhdGlvbi5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gdGhlIHJlc3VsdCBvZiBkb3dubG9hZGluZyB0aGUgZ2l2ZW4gbGlzdCBvZiBtb2RlbHMuIFRoZVxuICogcHJvbWlzZSB3aWxsIHJlc29sdmUgd2l0aCBhbiBvYmplY3Qgd2hvc2Uga2V5cyBhcmUgdGhlIG5hbWVzIG9mIHRoZSBtb2RlbHNcbiAqIGFuZCB0aGUgdmFsdWUgaXMgaXRzIE1lc2ggb2JqZWN0LiBFYWNoIE1lc2ggb2JqZWN0IHdpbGwgYXV0b21hdGljYWxseVxuICogaGF2ZSBpdHMgYWRkTWF0ZXJpYWxMaWJyYXJ5KCkgbWV0aG9kIGNhbGxlZCB0byBzZXQgdGhlIGdpdmVuIE1UTCBkYXRhIChpZiBnaXZlbikuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkb3dubG9hZE1vZGVscyhtb2RlbHM6IERvd25sb2FkTW9kZWxzT3B0aW9uc1tdKTogUHJvbWlzZTxNZXNoTWFwPiB7XG4gICAgY29uc3QgZmluaXNoZWQgPSBbXTtcblxuICAgIGZvciAoY29uc3QgbW9kZWwgb2YgbW9kZWxzKSB7XG4gICAgICAgIGlmICghbW9kZWwub2JqKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgJ1wib2JqXCIgYXR0cmlidXRlIG9mIG1vZGVsIG9iamVjdCBub3Qgc2V0LiBUaGUgLm9iaiBmaWxlIGlzIHJlcXVpcmVkIHRvIGJlIHNldCAnICtcbiAgICAgICAgICAgICAgICAgICAgXCJpbiBvcmRlciB0byB1c2UgZG93bmxvYWRNb2RlbHMoKVwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBpbmRpY2VzUGVyTWF0ZXJpYWw6ICEhbW9kZWwuaW5kaWNlc1Blck1hdGVyaWFsLFxuICAgICAgICAgICAgY2FsY1RhbmdlbnRzQW5kQml0YW5nZW50czogISFtb2RlbC5jYWxjVGFuZ2VudHNBbmRCaXRhbmdlbnRzLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIGlmIHRoZSBuYW1lIGlzIG5vdCBwcm92aWRlZCwgZGVydml2ZSBpdCBmcm9tIHRoZSBnaXZlbiBPQkpcbiAgICAgICAgbGV0IG5hbWUgPSBtb2RlbC5uYW1lO1xuICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRzID0gbW9kZWwub2JqLnNwbGl0KFwiL1wiKTtcbiAgICAgICAgICAgIG5hbWUgPSBwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXS5yZXBsYWNlKFwiLm9ialwiLCBcIlwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYW1lUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShuYW1lKTtcblxuICAgICAgICBjb25zdCBtZXNoUHJvbWlzZSA9IGZldGNoKG1vZGVsLm9iailcbiAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLnRleHQoKSlcbiAgICAgICAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWVzaChkYXRhLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIGxldCBtdGxQcm9taXNlO1xuICAgICAgICAvLyBEb3dubG9hZCBNYXRlcmlhbExpYnJhcnkgZmlsZT9cbiAgICAgICAgaWYgKG1vZGVsLm10bCkge1xuICAgICAgICAgICAgY29uc3QgbXRsID0gZ2V0TXRsKG1vZGVsKTtcbiAgICAgICAgICAgIG10bFByb21pc2UgPSBmZXRjaChtdGwpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKVxuICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAoZGF0YTogc3RyaW5nKTogUHJvbWlzZTxbTWF0ZXJpYWxMaWJyYXJ5LCBhbnldPiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IG5ldyBNYXRlcmlhbExpYnJhcnkoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobW9kZWwuZG93bmxvYWRNdGxUZXh0dXJlcyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcm9vdCA9IG1vZGVsLm10bFRleHR1cmVSb290O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcm9vdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGRpcmVjdG9yeSBvZiB0aGUgTVRMIGZpbGUgYXMgZGVmYXVsdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290ID0gbXRsLnN1YnN0cigwLCBtdGwubGFzdEluZGV4T2YoXCIvXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG93bmxvYWRNdGxUZXh0dXJlcyByZXR1cm5zIGEgUHJvbWlzZSB0aGF0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXMgcmVzb2x2ZWQgb25jZSBhbGwgb2YgdGhlIGltYWdlcyBpdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRhaW5zIGFyZSBkb3dubG9hZGVkLiBUaGVzZSBhcmUgdGhlblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0dGFjaGVkIHRvIHRoZSBtYXAgZGF0YSBvYmplY3RzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtQcm9taXNlLnJlc29sdmUobWF0ZXJpYWwpLCBkb3dubG9hZE10bFRleHR1cmVzKG1hdGVyaWFsLCByb290KV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtQcm9taXNlLnJlc29sdmUobWF0ZXJpYWwpLCB1bmRlZmluZWRdKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLnRoZW4oKHZhbHVlOiBbTWF0ZXJpYWxMaWJyYXJ5LCBhbnldKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVswXTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhcnNlZDogTW9kZWxQcm9taXNlcyA9IFtuYW1lUHJvbWlzZSwgbWVzaFByb21pc2UsIG10bFByb21pc2VdO1xuICAgICAgICBmaW5pc2hlZC5wdXNoKFByb21pc2UuYWxsPHN0cmluZywgTWVzaCwgTWF0ZXJpYWxMaWJyYXJ5IHwgdW5kZWZpbmVkPihwYXJzZWQpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoZmluaXNoZWQpLnRoZW4obXMgPT4ge1xuICAgICAgICAvLyB0aGUgXCJmaW5pc2hlZFwiIHByb21pc2UgaXMgYSBsaXN0IG9mIG5hbWUsIE1lc2ggaW5zdGFuY2UsXG4gICAgICAgIC8vIGFuZCBNYXRlcmlhbExpYmFyeSBpbnN0YW5jZS4gVGhpcyB1bnBhY2tzIGFuZCByZXR1cm5zIGFuXG4gICAgICAgIC8vIG9iamVjdCBtYXBwaW5nIG5hbWUgdG8gTWVzaCAoTWVzaCBwb2ludHMgdG8gTVRMKS5cbiAgICAgICAgY29uc3QgbW9kZWxzOiBNZXNoTWFwID0ge307XG5cbiAgICAgICAgZm9yIChjb25zdCBtb2RlbCBvZiBtcykge1xuICAgICAgICAgICAgY29uc3QgW25hbWUsIG1lc2gsIG10bF0gPSBtb2RlbDtcbiAgICAgICAgICAgIG1lc2gubmFtZSA9IG5hbWU7XG4gICAgICAgICAgICBpZiAobXRsKSB7XG4gICAgICAgICAgICAgICAgbWVzaC5hZGRNYXRlcmlhbExpYnJhcnkobXRsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1vZGVsc1tuYW1lXSA9IG1lc2g7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbW9kZWxzO1xuICAgIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5hbWVBbmRVcmxzIHtcbiAgICBbbWVzaE5hbWU6IHN0cmluZ106IHN0cmluZztcbn1cblxuLyoqXG4gKiBUYWtlcyBpbiBhbiBvYmplY3Qgb2YgYG1lc2hfbmFtZWAsIGAnL3VybC90by9PQkovZmlsZSdgIHBhaXJzIGFuZCBhIGNhbGxiYWNrXG4gKiBmdW5jdGlvbi4gRWFjaCBPQkogZmlsZSB3aWxsIGJlIGFqYXhlZCBpbiBhbmQgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG9cbiAqIGFuIE9CSi5NZXNoLiBXaGVuIGFsbCBmaWxlcyBoYXZlIHN1Y2Nlc3NmdWxseSBkb3dubG9hZGVkIHRoZSBjYWxsYmFja1xuICogZnVuY3Rpb24gcHJvdmlkZWQgd2lsbCBiZSBjYWxsZWQgYW5kIHBhc3NlZCBpbiBhbiBvYmplY3QgY29udGFpbmluZ1xuICogdGhlIG5ld2x5IGNyZWF0ZWQgbWVzaGVzLlxuICpcbiAqICoqTm90ZToqKiBJbiBvcmRlciB0byB1c2UgdGhpcyBmdW5jdGlvbiBhcyBhIHdheSB0byBkb3dubG9hZCBtZXNoZXMsIGFcbiAqIHdlYnNlcnZlciBvZiBzb21lIHNvcnQgbXVzdCBiZSB1c2VkLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBuYW1lQW5kQXR0cnMgYW4gb2JqZWN0IHdoZXJlIHRoZSBrZXkgaXMgdGhlIG5hbWUgb2YgdGhlIG1lc2ggYW5kIHRoZSB2YWx1ZSBpcyB0aGUgdXJsIHRvIHRoYXQgbWVzaCdzIE9CSiBmaWxlXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGxldGlvbkNhbGxiYWNrIHNob3VsZCBjb250YWluIGEgZnVuY3Rpb24gdGhhdCB3aWxsIHRha2Ugb25lIHBhcmFtZXRlcjogYW4gb2JqZWN0IGFycmF5IHdoZXJlIHRoZSBrZXlzIHdpbGwgYmUgdGhlIHVuaXF1ZSBvYmplY3QgbmFtZSBhbmQgdGhlIHZhbHVlIHdpbGwgYmUgYSBNZXNoIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBtZXNoZXMgSW4gY2FzZSBvdGhlciBtZXNoZXMgYXJlIGxvYWRlZCBzZXBhcmF0ZWx5IG9yIGlmIGEgcHJldmlvdXNseSBkZWNsYXJlZCB2YXJpYWJsZSBpcyBkZXNpcmVkIHRvIGJlIHVzZWQsIHBhc3MgaW4gYSAocG9zc2libHkgZW1wdHkpIGpzb24gb2JqZWN0IG9mIHRoZSBwYXR0ZXJuOiB7ICc8bWVzaF9uYW1lPic6IE9CSi5NZXNoIH1cbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkb3dubG9hZE1lc2hlcyhcbiAgICBuYW1lQW5kVVJMczogTmFtZUFuZFVybHMsXG4gICAgY29tcGxldGlvbkNhbGxiYWNrOiAobWVzaGVzOiBNZXNoTWFwKSA9PiB2b2lkLFxuICAgIG1lc2hlczogTWVzaE1hcCxcbikge1xuICAgIGlmIChtZXNoZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtZXNoZXMgPSB7fTtcbiAgICB9XG5cbiAgICBjb25zdCBjb21wbGV0ZWQ6IFByb21pc2U8W3N0cmluZywgTWVzaF0+W10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgbWVzaF9uYW1lIGluIG5hbWVBbmRVUkxzKSB7XG4gICAgICAgIGlmICghbmFtZUFuZFVSTHMuaGFzT3duUHJvcGVydHkobWVzaF9uYW1lKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJsID0gbmFtZUFuZFVSTHNbbWVzaF9uYW1lXTtcbiAgICAgICAgY29tcGxldGVkLnB1c2goXG4gICAgICAgICAgICBmZXRjaCh1cmwpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKVxuICAgICAgICAgICAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW21lc2hfbmFtZSwgbmV3IE1lc2goZGF0YSldIGFzIFtzdHJpbmcsIE1lc2hdO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIFByb21pc2UuYWxsKGNvbXBsZXRlZCkudGhlbihtcyA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgW25hbWUsIG1lc2hdIG9mIG1zKSB7XG4gICAgICAgICAgICBtZXNoZXNbbmFtZV0gPSBtZXNoO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbXBsZXRpb25DYWxsYmFjayhtZXNoZXMpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVuZGVkR0xCdWZmZXIgZXh0ZW5kcyBXZWJHTEJ1ZmZlciB7XG4gICAgaXRlbVNpemU6IG51bWJlcjtcbiAgICBudW1JdGVtczogbnVtYmVyO1xufVxuXG5mdW5jdGlvbiBfYnVpbGRCdWZmZXIoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdHlwZTogR0xlbnVtLCBkYXRhOiBudW1iZXJbXSwgaXRlbVNpemU6IG51bWJlcik6IEV4dGVuZGVkR0xCdWZmZXIge1xuICAgIGNvbnN0IGJ1ZmZlciA9IGdsLmNyZWF0ZUJ1ZmZlcigpIGFzIEV4dGVuZGVkR0xCdWZmZXI7XG4gICAgY29uc3QgYXJyYXlWaWV3ID0gdHlwZSA9PT0gZ2wuQVJSQVlfQlVGRkVSID8gRmxvYXQzMkFycmF5IDogVWludDE2QXJyYXk7XG4gICAgZ2wuYmluZEJ1ZmZlcih0eXBlLCBidWZmZXIpO1xuICAgIGdsLmJ1ZmZlckRhdGEodHlwZSwgbmV3IGFycmF5VmlldyhkYXRhKSwgZ2wuU1RBVElDX0RSQVcpO1xuICAgIGJ1ZmZlci5pdGVtU2l6ZSA9IGl0ZW1TaXplO1xuICAgIGJ1ZmZlci5udW1JdGVtcyA9IGRhdGEubGVuZ3RoIC8gaXRlbVNpemU7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNZXNoV2l0aEJ1ZmZlcnMgZXh0ZW5kcyBNZXNoIHtcbiAgICBub3JtYWxCdWZmZXI6IEV4dGVuZGVkR0xCdWZmZXI7XG4gICAgdGV4dHVyZUJ1ZmZlcjogRXh0ZW5kZWRHTEJ1ZmZlcjtcbiAgICB2ZXJ0ZXhCdWZmZXI6IEV4dGVuZGVkR0xCdWZmZXI7XG4gICAgaW5kZXhCdWZmZXI6IEV4dGVuZGVkR0xCdWZmZXI7XG59XG5cbi8qKlxuICogVGFrZXMgaW4gdGhlIFdlYkdMIGNvbnRleHQgYW5kIGEgTWVzaCwgdGhlbiBjcmVhdGVzIGFuZCBhcHBlbmRzIHRoZSBidWZmZXJzXG4gKiB0byB0aGUgbWVzaCBvYmplY3QgYXMgYXR0cmlidXRlcy5cbiAqXG4gKiBAcGFyYW0ge1dlYkdMUmVuZGVyaW5nQ29udGV4dH0gZ2wgdGhlIGBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnKWAgY29udGV4dCBpbnN0YW5jZVxuICogQHBhcmFtIHtNZXNofSBtZXNoIGEgc2luZ2xlIGBPQkouTWVzaGAgaW5zdGFuY2VcbiAqXG4gKiBUaGUgbmV3bHkgY3JlYXRlZCBtZXNoIGF0dHJpYnV0ZXMgYXJlOlxuICpcbiAqIEF0dHJidXRlIHwgRGVzY3JpcHRpb25cbiAqIDotLS0gfCAtLS1cbiAqICoqbm9ybWFsQnVmZmVyKiogICAgICAgfGNvbnRhaW5zIHRoZSBtb2RlbCYjMzk7cyBWZXJ0ZXggTm9ybWFsc1xuICogbm9ybWFsQnVmZmVyLml0ZW1TaXplICB8c2V0IHRvIDMgaXRlbXNcbiAqIG5vcm1hbEJ1ZmZlci5udW1JdGVtcyAgfHRoZSB0b3RhbCBudW1iZXIgb2YgdmVydGV4IG5vcm1hbHNcbiAqIHxcbiAqICoqdGV4dHVyZUJ1ZmZlcioqICAgICAgfGNvbnRhaW5zIHRoZSBtb2RlbCYjMzk7cyBUZXh0dXJlIENvb3JkaW5hdGVzXG4gKiB0ZXh0dXJlQnVmZmVyLml0ZW1TaXplIHxzZXQgdG8gMiBpdGVtc1xuICogdGV4dHVyZUJ1ZmZlci5udW1JdGVtcyB8dGhlIG51bWJlciBvZiB0ZXh0dXJlIGNvb3JkaW5hdGVzXG4gKiB8XG4gKiAqKnZlcnRleEJ1ZmZlcioqICAgICAgIHxjb250YWlucyB0aGUgbW9kZWwmIzM5O3MgVmVydGV4IFBvc2l0aW9uIENvb3JkaW5hdGVzIChkb2VzIG5vdCBpbmNsdWRlIHcpXG4gKiB2ZXJ0ZXhCdWZmZXIuaXRlbVNpemUgIHxzZXQgdG8gMyBpdGVtc1xuICogdmVydGV4QnVmZmVyLm51bUl0ZW1zICB8dGhlIHRvdGFsIG51bWJlciBvZiB2ZXJ0aWNlc1xuICogfFxuICogKippbmRleEJ1ZmZlcioqICAgICAgICB8Y29udGFpbnMgdGhlIGluZGljZXMgb2YgdGhlIGZhY2VzXG4gKiBpbmRleEJ1ZmZlci5pdGVtU2l6ZSAgIHxpcyBzZXQgdG8gMVxuICogaW5kZXhCdWZmZXIubnVtSXRlbXMgICB8dGhlIHRvdGFsIG51bWJlciBvZiBpbmRpY2VzXG4gKlxuICogQSBzaW1wbGUgZXhhbXBsZSAoYSBsb3Qgb2Ygc3RlcHMgYXJlIG1pc3NpbmcsIHNvIGRvbid0IGNvcHkgYW5kIHBhc3RlKTpcbiAqXG4gKiAgICAgY29uc3QgZ2wgICA9IGNhbnZhcy5nZXRDb250ZXh0KCd3ZWJnbCcpLFxuICogICAgICAgICBtZXNoID0gT0JKLk1lc2gob2JqX2ZpbGVfZGF0YSk7XG4gKiAgICAgLy8gY29tcGlsZSB0aGUgc2hhZGVycyBhbmQgY3JlYXRlIGEgc2hhZGVyIHByb2dyYW1cbiAqICAgICBjb25zdCBzaGFkZXJQcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpO1xuICogICAgIC8vIGNvbXBpbGF0aW9uIHN0dWZmIGhlcmVcbiAqICAgICAuLi5cbiAqICAgICAvLyBtYWtlIHN1cmUgeW91IGhhdmUgdmVydGV4LCB2ZXJ0ZXggbm9ybWFsLCBhbmQgdGV4dHVyZSBjb29yZGluYXRlXG4gKiAgICAgLy8gYXR0cmlidXRlcyBsb2NhdGVkIGluIHlvdXIgc2hhZGVycyBhbmQgYXR0YWNoIHRoZW0gdG8gdGhlIHNoYWRlciBwcm9ncmFtXG4gKiAgICAgc2hhZGVyUHJvZ3JhbS52ZXJ0ZXhQb3NpdGlvbkF0dHJpYnV0ZSA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHNoYWRlclByb2dyYW0sIFwiYVZlcnRleFBvc2l0aW9uXCIpO1xuICogICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHNoYWRlclByb2dyYW0udmVydGV4UG9zaXRpb25BdHRyaWJ1dGUpO1xuICpcbiAqICAgICBzaGFkZXJQcm9ncmFtLnZlcnRleE5vcm1hbEF0dHJpYnV0ZSA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHNoYWRlclByb2dyYW0sIFwiYVZlcnRleE5vcm1hbFwiKTtcbiAqICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShzaGFkZXJQcm9ncmFtLnZlcnRleE5vcm1hbEF0dHJpYnV0ZSk7XG4gKlxuICogICAgIHNoYWRlclByb2dyYW0udGV4dHVyZUNvb3JkQXR0cmlidXRlID0gZ2wuZ2V0QXR0cmliTG9jYXRpb24oc2hhZGVyUHJvZ3JhbSwgXCJhVGV4dHVyZUNvb3JkXCIpO1xuICogICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHNoYWRlclByb2dyYW0udGV4dHVyZUNvb3JkQXR0cmlidXRlKTtcbiAqXG4gKiAgICAgLy8gY3JlYXRlIGFuZCBpbml0aWFsaXplIHRoZSB2ZXJ0ZXgsIHZlcnRleCBub3JtYWwsIGFuZCB0ZXh0dXJlIGNvb3JkaW5hdGUgYnVmZmVyc1xuICogICAgIC8vIGFuZCBzYXZlIG9uIHRvIHRoZSBtZXNoIG9iamVjdFxuICogICAgIE9CSi5pbml0TWVzaEJ1ZmZlcnMoZ2wsIG1lc2gpO1xuICpcbiAqICAgICAvLyBub3cgdG8gcmVuZGVyIHRoZSBtZXNoXG4gKiAgICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIG1lc2gudmVydGV4QnVmZmVyKTtcbiAqICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHNoYWRlclByb2dyYW0udmVydGV4UG9zaXRpb25BdHRyaWJ1dGUsIG1lc2gudmVydGV4QnVmZmVyLml0ZW1TaXplLCBnbC5GTE9BVCwgZmFsc2UsIDAsIDApO1xuICogICAgIC8vIGl0J3MgcG9zc2libGUgdGhhdCB0aGUgbWVzaCBkb2Vzbid0IGNvbnRhaW5cbiAqICAgICAvLyBhbnkgdGV4dHVyZSBjb29yZGluYXRlcyAoZS5nLiBzdXphbm5lLm9iaiBpbiB0aGUgZGV2ZWxvcG1lbnQgYnJhbmNoKS5cbiAqICAgICAvLyBpbiB0aGlzIGNhc2UsIHRoZSB0ZXh0dXJlIHZlcnRleEF0dHJpYkFycmF5IHdpbGwgbmVlZCB0byBiZSBkaXNhYmxlZFxuICogICAgIC8vIGJlZm9yZSB0aGUgY2FsbCB0byBkcmF3RWxlbWVudHNcbiAqICAgICBpZighbWVzaC50ZXh0dXJlcy5sZW5ndGgpe1xuICogICAgICAgZ2wuZGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KHNoYWRlclByb2dyYW0udGV4dHVyZUNvb3JkQXR0cmlidXRlKTtcbiAqICAgICB9XG4gKiAgICAgZWxzZXtcbiAqICAgICAgIC8vIGlmIHRoZSB0ZXh0dXJlIHZlcnRleEF0dHJpYkFycmF5IGhhcyBiZWVuIHByZXZpb3VzbHlcbiAqICAgICAgIC8vIGRpc2FibGVkLCB0aGVuIGl0IG5lZWRzIHRvIGJlIHJlLWVuYWJsZWRcbiAqICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHNoYWRlclByb2dyYW0udGV4dHVyZUNvb3JkQXR0cmlidXRlKTtcbiAqICAgICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCBtZXNoLnRleHR1cmVCdWZmZXIpO1xuICogICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcihzaGFkZXJQcm9ncmFtLnRleHR1cmVDb29yZEF0dHJpYnV0ZSwgbWVzaC50ZXh0dXJlQnVmZmVyLml0ZW1TaXplLCBnbC5GTE9BVCwgZmFsc2UsIDAsIDApO1xuICogICAgIH1cbiAqXG4gKiAgICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIG1lc2gubm9ybWFsQnVmZmVyKTtcbiAqICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHNoYWRlclByb2dyYW0udmVydGV4Tm9ybWFsQXR0cmlidXRlLCBtZXNoLm5vcm1hbEJ1ZmZlci5pdGVtU2l6ZSwgZ2wuRkxPQVQsIGZhbHNlLCAwLCAwKTtcbiAqXG4gKiAgICAgZ2wuYmluZEJ1ZmZlcihnbC5FTEVNRU5UX0FSUkFZX0JVRkZFUiwgbW9kZWwubWVzaC5pbmRleEJ1ZmZlcik7XG4gKiAgICAgZ2wuZHJhd0VsZW1lbnRzKGdsLlRSSUFOR0xFUywgbW9kZWwubWVzaC5pbmRleEJ1ZmZlci5udW1JdGVtcywgZ2wuVU5TSUdORURfU0hPUlQsIDApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdE1lc2hCdWZmZXJzKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIG1lc2g6IE1lc2gpOiBNZXNoV2l0aEJ1ZmZlcnMge1xuICAgIChtZXNoIGFzIE1lc2hXaXRoQnVmZmVycykubm9ybWFsQnVmZmVyID0gX2J1aWxkQnVmZmVyKGdsLCBnbC5BUlJBWV9CVUZGRVIsIG1lc2gudmVydGV4Tm9ybWFscywgMyk7XG4gICAgKG1lc2ggYXMgTWVzaFdpdGhCdWZmZXJzKS50ZXh0dXJlQnVmZmVyID0gX2J1aWxkQnVmZmVyKGdsLCBnbC5BUlJBWV9CVUZGRVIsIG1lc2gudGV4dHVyZXMsIG1lc2gudGV4dHVyZVN0cmlkZSk7XG4gICAgKG1lc2ggYXMgTWVzaFdpdGhCdWZmZXJzKS52ZXJ0ZXhCdWZmZXIgPSBfYnVpbGRCdWZmZXIoZ2wsIGdsLkFSUkFZX0JVRkZFUiwgbWVzaC52ZXJ0aWNlcywgMyk7XG4gICAgKG1lc2ggYXMgTWVzaFdpdGhCdWZmZXJzKS5pbmRleEJ1ZmZlciA9IF9idWlsZEJ1ZmZlcihnbCwgZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIG1lc2guaW5kaWNlcywgMSk7XG5cbiAgICByZXR1cm4gbWVzaCBhcyBNZXNoV2l0aEJ1ZmZlcnM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVNZXNoQnVmZmVycyhnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCBtZXNoOiBNZXNoV2l0aEJ1ZmZlcnMpIHtcbiAgICBnbC5kZWxldGVCdWZmZXIobWVzaC5ub3JtYWxCdWZmZXIpO1xuICAgIGdsLmRlbGV0ZUJ1ZmZlcihtZXNoLnRleHR1cmVCdWZmZXIpO1xuICAgIGdsLmRlbGV0ZUJ1ZmZlcihtZXNoLnZlcnRleEJ1ZmZlcik7XG4gICAgZ2wuZGVsZXRlQnVmZmVyKG1lc2guaW5kZXhCdWZmZXIpO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9PQkovd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovL09CSi93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9PQkovLi9zcmMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vT0JKLy4vc3JjL2xheW91dC50cyIsIndlYnBhY2s6Ly9PQkovLi9zcmMvbWF0ZXJpYWwudHMiLCJ3ZWJwYWNrOi8vT0JKLy4vc3JjL21lc2gudHMiLCJ3ZWJwYWNrOi8vT0JKLy4vc3JjL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxPO1FDVkE7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7OztRQUdBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSwwQ0FBMEMsZ0NBQWdDO1FBQzFFO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0Esd0RBQXdELGtCQUFrQjtRQUMxRTtRQUNBLGlEQUFpRCxjQUFjO1FBQy9EOztRQUVBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQSx5Q0FBeUMsaUNBQWlDO1FBQzFFLGdIQUFnSCxtQkFBbUIsRUFBRTtRQUNySTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBLDJCQUEyQiwwQkFBMEIsRUFBRTtRQUN2RCxpQ0FBaUMsZUFBZTtRQUNoRDtRQUNBO1FBQ0E7O1FBRUE7UUFDQSxzREFBc0QsK0RBQStEOztRQUVySDtRQUNBOzs7UUFHQTtRQUNBOzs7Ozs7Ozs7Ozs7O0FDbEZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFB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QUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNqQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNqQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUVqQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNqQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNqQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUVqQyxVQUFVO1lBQ1YsTUFBTSxRQUFRLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxTQUFTLEdBQUcsSUFBSSxHQUFHLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFDeEUsTUFBTSxRQUFRLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxTQUFTLEdBQUcsSUFBSSxHQUFHLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFDeEUsTUFBTSxRQUFRLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxTQUFTLEdBQUcsSUFBSSxHQUFHLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFFeEUsTUFBTSxhQUFhLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxRQUFRLENBQUM7WUFDbEQsTUFBTSxhQUFhLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxRQUFRLENBQUM7WUFDbEQsTUFBTSxhQUFhLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxRQUFRLENBQUM7WUFFbEQsTUFBTSxhQUFhLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxRQUFRLENBQUM7WUFDbEQsTUFBTSxhQUFhLEdBQUcsU0FBUyxHQUFHLElBQUksR0FBRyxRQUFRLENBQUM7WUFDbEQsTUFBTSxhQUFhLEdBQUcsU0FBUyxHQUFHLElB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LENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxhQUFhLEdBQUcsV0FBVyxDQUFDO1lBQzdELFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxhQUFhLEdBQUcsV0FBVyxDQUFDO1lBQzdELFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxhQUFhLEdBQUcsV0FBVyxDQUFDO1lBRTdELFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxhQUFhLEdBQUcsV0FBVyxDQUFDO1lBQzdELFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxhQUFhLEdBQUcsV0FBVyxDQUFDO1lBQzdELFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxhQUFhLEdBQUcsV0FBVyxDQUFDO1lBRTdELFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxlQUFlLEdBQUcsYUFBYSxDQUFDO1lBQ25FLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxlQUFlLEdBQUcsYUFBYSxDQUFDO1lBQ25FLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxlQUFlLEdBQUcsYUFBYSxDQUFDO1lBRW5FLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxlQUFlLEdBQUcsYUFBYSxDQUFDO1lBQ25FLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxlQUFlLEdBQUcsYUFBYSxDQUFDO1lBQ25FLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFB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QUMsYUFBYSxHQUFHLFlBQVksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM5RyxJQUF3QixDQUFDLFlBQVksR0FBRyxZQUFZLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM1RixJQUF3QixDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRW5HLE9BQU8sSUFBdUIsQ0FBQztBQUNuQyxDQUFDO0FBRU0sU0FBUyxpQkFBaUIsQ0FBQyxFQUF5QixFQUFFLElBQXFCO0lBQzlFLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ25DLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3BDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ25DLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3RDLENBQUMiLCJmaWxlIjoid2ViZ2wtb2JqLWxvYWRlci5qcyIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFwiT0JKXCIsIFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcIk9CSlwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJPQkpcIl0gPSBmYWN0b3J5KCk7XG59KSh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDogdGhpcywgZnVuY3Rpb24oKSB7XG5yZXR1cm4gIiwiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZ2V0dGVyIH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4gXHRcdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuIFx0XHR9XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG4gXHR9O1xuXG4gXHQvLyBjcmVhdGUgYSBmYWtlIG5hbWVzcGFjZSBvYmplY3RcbiBcdC8vIG1vZGUgJiAxOiB2YWx1ZSBpcyBhIG1vZHVsZSBpZCwgcmVxdWlyZSBpdFxuIFx0Ly8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXG4gXHQvLyBtb2RlICYgNDogcmV0dXJuIHZhbHVlIHdoZW4gYWxyZWFkeSBucyBvYmplY3RcbiBcdC8vIG1vZGUgJiA4fDE6IGJlaGF2ZSBsaWtlIHJlcXVpcmVcbiBcdF9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XG4gXHRcdGlmKG1vZGUgJiAxKSB2YWx1ZSA9IF9fd2VicGFja19yZXF1aXJlX18odmFsdWUpO1xuIFx0XHRpZihtb2RlICYgOCkgcmV0dXJuIHZhbHVlO1xuIFx0XHRpZigobW9kZSAmIDQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgdmFsdWUuX19lc01vZHVsZSkgcmV0dXJuIHZhbHVlO1xuIFx0XHR2YXIgbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIobnMpO1xuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobnMsICdkZWZhdWx0JywgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XG4gXHRcdGlmKG1vZGUgJiAyICYmIHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgZm9yKHZhciBrZXkgaW4gdmFsdWUpIF9fd2VicGFja19yZXF1aXJlX18uZChucywga2V5LCBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHZhbHVlW2tleV07IH0uYmluZChudWxsLCBrZXkpKTtcbiBcdFx0cmV0dXJuIG5zO1xuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCIvXCI7XG5cblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSAwKTtcbiIsImltcG9ydCBNZXNoLCB7XG4gICAgTWVzaE9wdGlvbnMsXG4gICAgTWF0ZXJpYWxOYW1lVG9JbmRleCxcbiAgICBJbmRleFRvTWF0ZXJpYWwsXG4gICAgQXJyYXlCdWZmZXJXaXRoSXRlbVNpemUsXG4gICAgVWludDE2QXJyYXlXaXRoSXRlbVNpemUsXG59IGZyb20gXCIuL21lc2hcIjtcbmltcG9ydCB7IE1hdGVyaWFsLCBNYXRlcmlhbExpYnJhcnksIFZlYzMsIFVWVywgVGV4dHVyZU1hcERhdGEgfSBmcm9tIFwiLi9tYXRlcmlhbFwiO1xuaW1wb3J0IHsgTGF5b3V0LCBUWVBFUywgQXR0cmlidXRlSW5mbywgRHVwbGljYXRlQXR0cmlidXRlRXhjZXB0aW9uLCBBdHRyaWJ1dGUgfSBmcm9tIFwiLi9sYXlvdXRcIjtcbmltcG9ydCB7XG4gICAgZG93bmxvYWRNb2RlbHMsXG4gICAgZG93bmxvYWRNZXNoZXMsXG4gICAgaW5pdE1lc2hCdWZmZXJzLFxuICAgIGRlbGV0ZU1lc2hCdWZmZXJzLFxuICAgIERvd25sb2FkTW9kZWxzT3B0aW9ucyxcbiAgICBNZXNoTWFwLFxuICAgIE5hbWVBbmRVcmxzLFxuICAgIEV4dGVuZGVkR0xCdWZmZXIsXG4gICAgTWVzaFdpdGhCdWZmZXJzLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuXG5jb25zdCB2ZXJzaW9uID0gXCIyLjAuM1wiO1xuXG4vKipcbiAqIEBuYW1lc3BhY2VcbiAqL1xuZXhwb3J0IHtcbiAgICBBcnJheUJ1ZmZlcldpdGhJdGVtU2l6ZSxcbiAgICBBdHRyaWJ1dGUsXG4gICAgQXR0cmlidXRlSW5mbyxcbiAgICBEb3dubG9hZE1vZGVsc09wdGlvbnMsXG4gICAgRHVwbGljYXRlQXR0cmlidXRlRXhjZXB0aW9uLFxuICAgIEV4dGVuZGVkR0xCdWZmZXIsXG4gICAgSW5kZXhUb01hdGVyaWFsLFxuICAgIExheW91dCxcbiAgICBNYXRlcmlhbCxcbiAgICBNYXRlcmlhbExpYnJhcnksXG4gICAgTWF0ZXJpYWxOYW1lVG9JbmRleCxcbiAgICBNZXNoLFxuICAgIE1lc2hNYXAsXG4gICAgTWVzaE9wdGlvbnMsXG4gICAgTWVzaFdpdGhCdWZmZXJzLFxuICAgIE5hbWVBbmRVcmxzLFxuICAgIFRleHR1cmVNYXBEYXRhLFxuICAgIFRZUEVTLFxuICAgIFVpbnQxNkFycmF5V2l0aEl0ZW1TaXplLFxuICAgIFVWVyxcbiAgICBWZWMzLFxuICAgIGRvd25sb2FkTW9kZWxzLFxuICAgIGRvd25sb2FkTWVzaGVzLFxuICAgIGluaXRNZXNoQnVmZmVycyxcbiAgICBkZWxldGVNZXNoQnVmZmVycyxcbiAgICB2ZXJzaW9uLFxufTtcbiIsImV4cG9ydCBlbnVtIFRZUEVTIHtcbiAgICBcIkJZVEVcIiA9IFwiQllURVwiLFxuICAgIFwiVU5TSUdORURfQllURVwiID0gXCJVTlNJR05FRF9CWVRFXCIsXG4gICAgXCJTSE9SVFwiID0gXCJTSE9SVFwiLFxuICAgIFwiVU5TSUdORURfU0hPUlRcIiA9IFwiVU5TSUdORURfU0hPUlRcIixcbiAgICBcIkZMT0FUXCIgPSBcIkZMT0FUXCIsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXR0cmlidXRlSW5mbyB7XG4gICAgYXR0cmlidXRlOiBBdHRyaWJ1dGU7XG4gICAgc2l6ZTogQXR0cmlidXRlW1wic2l6ZVwiXTtcbiAgICB0eXBlOiBBdHRyaWJ1dGVbXCJ0eXBlXCJdO1xuICAgIG5vcm1hbGl6ZWQ6IEF0dHJpYnV0ZVtcIm5vcm1hbGl6ZWRcIl07XG4gICAgb2Zmc2V0OiBudW1iZXI7XG4gICAgc3RyaWRlOiBudW1iZXI7XG59XG5cbi8qKlxuICogQW4gZXhjZXB0aW9uIGZvciB3aGVuIHR3byBvciBtb3JlIG9mIHRoZSBzYW1lIGF0dHJpYnV0ZXMgYXJlIGZvdW5kIGluIHRoZVxuICogc2FtZSBsYXlvdXQuXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgRHVwbGljYXRlQXR0cmlidXRlRXhjZXB0aW9uIGV4dGVuZHMgRXJyb3Ige1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIER1cGxpY2F0ZUF0dHJpYnV0ZUV4Y2VwdGlvblxuICAgICAqIEBwYXJhbSB7QXR0cmlidXRlfSBhdHRyaWJ1dGUgLSBUaGUgYXR0cmlidXRlIHRoYXQgd2FzIGZvdW5kIG1vcmUgdGhhblxuICAgICAqICAgICAgICBvbmNlIGluIHRoZSB7QGxpbmsgTGF5b3V0fVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGF0dHJpYnV0ZTogQXR0cmlidXRlKSB7XG4gICAgICAgIHN1cGVyKGBmb3VuZCBkdXBsaWNhdGUgYXR0cmlidXRlOiAke2F0dHJpYnV0ZS5rZXl9YCk7XG4gICAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgaG93IGEgdmVydGV4IGF0dHJpYnV0ZSBzaG91bGQgYmUgcGFja2VkIGludG8gYW4gYnVmZmVyLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIEF0dHJpYnV0ZSB7XG4gICAgcHVibGljIHNpemVPZlR5cGU6IG51bWJlcjtcbiAgICBwdWJsaWMgc2l6ZUluQnl0ZXM6IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gYXR0cmlidXRlLiBEbyBub3QgY2FsbCB0aGlzIGRpcmVjdGx5LCB1c2UgdGhlIHByZWRlZmluZWRcbiAgICAgKiBjb25zdGFudHMuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBuYW1lIG9mIHRoaXMgYXR0cmlidXRlIGFzIGlmIGl0IHdlcmUgYSBrZXkgaW5cbiAgICAgKiAgICAgICAgYW4gT2JqZWN0LiBVc2UgdGhlIGNhbWVsIGNhc2UgdmVyc2lvbiBvZiB0aGUgdXBwZXIgc25ha2UgY2FzZVxuICAgICAqICAgICAgICBjb25zdCBuYW1lLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIC0gVGhlIG51bWJlciBvZiBjb21wb25lbnRzIHBlciB2ZXJ0ZXggYXR0cmlidXRlLlxuICAgICAqICAgICAgICBNdXN0IGJlIDEsIDIsIDMsIG9yIDQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgLSBUaGUgZGF0YSB0eXBlIG9mIGVhY2ggY29tcG9uZW50IGZvciB0aGlzXG4gICAgICogICAgICAgIGF0dHJpYnV0ZS4gUG9zc2libGUgdmFsdWVzOjxici8+XG4gICAgICogICAgICAgIFwiQllURVwiOiBzaWduZWQgOC1iaXQgaW50ZWdlciwgd2l0aCB2YWx1ZXMgaW4gWy0xMjgsIDEyN108YnIvPlxuICAgICAqICAgICAgICBcIlNIT1JUXCI6IHNpZ25lZCAxNi1iaXQgaW50ZWdlciwgd2l0aCB2YWx1ZXMgaW5cbiAgICAgKiAgICAgICAgICAgIFstMzI3NjgsIDMyNzY3XTxici8+XG4gICAgICogICAgICAgIFwiVU5TSUdORURfQllURVwiOiB1bnNpZ25lZCA4LWJpdCBpbnRlZ2VyLCB3aXRoIHZhbHVlcyBpblxuICAgICAqICAgICAgICAgICAgWzAsIDI1NV08YnIvPlxuICAgICAqICAgICAgICBcIlVOU0lHTkVEX1NIT1JUXCI6IHVuc2lnbmVkIDE2LWJpdCBpbnRlZ2VyLCB3aXRoIHZhbHVlcyBpblxuICAgICAqICAgICAgICAgICAgWzAsIDY1NTM1XTxici8+XG4gICAgICogICAgICAgIFwiRkxPQVRcIjogMzItYml0IGZsb2F0aW5nIHBvaW50IG51bWJlclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gbm9ybWFsaXplZCAtIFdoZXRoZXIgaW50ZWdlciBkYXRhIHZhbHVlcyBzaG91bGQgYmVcbiAgICAgKiAgICAgICAgbm9ybWFsaXplZCB3aGVuIGJlaW5nIGNhc3RlZCB0byBhIGZsb2F0Ljxici8+XG4gICAgICogICAgICAgIElmIHRydWUsIHNpZ25lZCBpbnRlZ2VycyBhcmUgbm9ybWFsaXplZCB0byBbLTEsIDFdLjxici8+XG4gICAgICogICAgICAgIElmIHRydWUsIHVuc2lnbmVkIGludGVnZXJzIGFyZSBub3JtYWxpemVkIHRvIFswLCAxXS48YnIvPlxuICAgICAqICAgICAgICBGb3IgdHlwZSBcIkZMT0FUXCIsIHRoaXMgcGFyYW1ldGVyIGhhcyBubyBlZmZlY3QuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHVibGljIGtleTogc3RyaW5nLCBwdWJsaWMgc2l6ZTogbnVtYmVyLCBwdWJsaWMgdHlwZTogVFlQRVMsIHB1YmxpYyBub3JtYWxpemVkOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlIFwiQllURVwiOlxuICAgICAgICAgICAgY2FzZSBcIlVOU0lHTkVEX0JZVEVcIjpcbiAgICAgICAgICAgICAgICB0aGlzLnNpemVPZlR5cGUgPSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIlNIT1JUXCI6XG4gICAgICAgICAgICBjYXNlIFwiVU5TSUdORURfU0hPUlRcIjpcbiAgICAgICAgICAgICAgICB0aGlzLnNpemVPZlR5cGUgPSAyO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIkZMT0FUXCI6XG4gICAgICAgICAgICAgICAgdGhpcy5zaXplT2ZUeXBlID0gNDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGdsIHR5cGU6ICR7dHlwZX1gKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNpemVJbkJ5dGVzID0gdGhpcy5zaXplT2ZUeXBlICogc2l6ZTtcbiAgICB9XG59XG5cbi8qKlxuICogQSBjbGFzcyB0byByZXByZXNlbnQgdGhlIG1lbW9yeSBsYXlvdXQgZm9yIGEgdmVydGV4IGF0dHJpYnV0ZSBhcnJheS4gVXNlZCBieVxuICoge0BsaW5rIE1lc2h9J3MgVEJEKC4uLikgbWV0aG9kIHRvIGdlbmVyYXRlIGEgcGFja2VkIGFycmF5IGZyb20gbWVzaCBkYXRhLlxuICogPHA+XG4gKiBMYXlvdXQgY2FuIHNvcnQgb2YgYmUgdGhvdWdodCBvZiBhcyBhIEMtc3R5bGUgc3RydWN0IGRlY2xhcmF0aW9uLlxuICoge0BsaW5rIE1lc2h9J3MgVEJEKC4uLikgbWV0aG9kIHdpbGwgdXNlIHRoZSB7QGxpbmsgTGF5b3V0fSBpbnN0YW5jZSB0b1xuICogcGFjayBhbiBhcnJheSBpbiB0aGUgZ2l2ZW4gYXR0cmlidXRlIG9yZGVyLlxuICogPHA+XG4gKiBMYXlvdXQgYWxzbyBpcyB2ZXJ5IGhlbHBmdWwgd2hlbiBjYWxsaW5nIGEgV2ViR0wgY29udGV4dCdzXG4gKiA8Y29kZT52ZXJ0ZXhBdHRyaWJQb2ludGVyPC9jb2RlPiBtZXRob2QuIElmIHlvdSd2ZSBjcmVhdGVkIGEgYnVmZmVyIHVzaW5nXG4gKiBhIExheW91dCBpbnN0YW5jZSwgdGhlbiB0aGUgc2FtZSBMYXlvdXQgaW5zdGFuY2UgY2FuIGJlIHVzZWQgdG8gZGV0ZXJtaW5lXG4gKiB0aGUgc2l6ZSwgdHlwZSwgbm9ybWFsaXplZCwgc3RyaWRlLCBhbmQgb2Zmc2V0IHBhcmFtZXRlcnMgZm9yXG4gKiA8Y29kZT52ZXJ0ZXhBdHRyaWJQb2ludGVyPC9jb2RlPi5cbiAqIDxwPlxuICogRm9yIGV4YW1wbGU6XG4gKiA8cHJlPjxjb2RlPlxuICpcbiAqIGNvbnN0IGluZGV4ID0gZ2xjdHguZ2V0QXR0cmliTG9jYXRpb24oc2hhZGVyUHJvZ3JhbSwgXCJwb3NcIik7XG4gKiBnbGN0eC52ZXJ0ZXhBdHRyaWJQb2ludGVyKFxuICogICBsYXlvdXQucG9zaXRpb24uc2l6ZSxcbiAqICAgZ2xjdHhbbGF5b3V0LnBvc2l0aW9uLnR5cGVdLFxuICogICBsYXlvdXQucG9zaXRpb24ubm9ybWFsaXplZCxcbiAqICAgbGF5b3V0LnBvc2l0aW9uLnN0cmlkZSxcbiAqICAgbGF5b3V0LnBvc2l0aW9uLm9mZnNldCk7XG4gKiA8L2NvZGU+PC9wcmU+XG4gKiBAc2VlIHtAbGluayBNZXNofVxuICovXG5leHBvcnQgY2xhc3MgTGF5b3V0IHtcbiAgICAvLyBHZW9tZXRyeSBhdHRyaWJ1dGVzXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlIGxheW91dCB0byBwYWNrIGEgdmVydGV4J3MgeCwgeSwgJiB6IGFzIGZsb2F0c1xuICAgICAqXG4gICAgICogQHNlZSB7QGxpbmsgTGF5b3V0fVxuICAgICAqL1xuICAgIHN0YXRpYyBQT1NJVElPTiA9IG5ldyBBdHRyaWJ1dGUoXCJwb3NpdGlvblwiLCAzLCBUWVBFUy5GTE9BVCk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGUgbGF5b3V0IHRvIHBhY2sgYSB2ZXJ0ZXgncyBub3JtYWwncyB4LCB5LCAmIHogYXMgZmxvYXRzXG4gICAgICpcbiAgICAgKiBAc2VlIHtAbGluayBMYXlvdXR9XG4gICAgICovXG4gICAgc3RhdGljIE5PUk1BTCA9IG5ldyBBdHRyaWJ1dGUoXCJub3JtYWxcIiwgMywgVFlQRVMuRkxPQVQpO1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlIGxheW91dCB0byBwYWNrIGEgdmVydGV4J3Mgbm9ybWFsJ3MgeCwgeSwgJiB6IGFzIGZsb2F0cy5cbiAgICAgKiA8cD5cbiAgICAgKiBUaGlzIHZhbHVlIHdpbGwgYmUgY29tcHV0ZWQgb24tdGhlLWZseSBiYXNlZCBvbiB0aGUgdGV4dHVyZSBjb29yZGluYXRlcy5cbiAgICAgKiBJZiBubyB0ZXh0dXJlIGNvb3JkaW5hdGVzIGFyZSBhdmFpbGFibGUsIHRoZSBnZW5lcmF0ZWQgdmFsdWUgd2lsbCBkZWZhdWx0IHRvXG4gICAgICogMCwgMCwgMC5cbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIExheW91dH1cbiAgICAgKi9cbiAgICBzdGF0aWMgVEFOR0VOVCA9IG5ldyBBdHRyaWJ1dGUoXCJ0YW5nZW50XCIsIDMsIFRZUEVTLkZMT0FUKTtcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZSBsYXlvdXQgdG8gcGFjayBhIHZlcnRleCdzIG5vcm1hbCdzIGJpdGFuZ2VudCB4LCB5LCAmIHogYXMgZmxvYXRzLlxuICAgICAqIDxwPlxuICAgICAqIFRoaXMgdmFsdWUgd2lsbCBiZSBjb21wdXRlZCBvbi10aGUtZmx5IGJhc2VkIG9uIHRoZSB0ZXh0dXJlIGNvb3JkaW5hdGVzLlxuICAgICAqIElmIG5vIHRleHR1cmUgY29vcmRpbmF0ZXMgYXJlIGF2YWlsYWJsZSwgdGhlIGdlbmVyYXRlZCB2YWx1ZSB3aWxsIGRlZmF1bHQgdG9cbiAgICAgKiAwLCAwLCAwLlxuICAgICAqIEBzZWUge0BsaW5rIExheW91dH1cbiAgICAgKi9cbiAgICBzdGF0aWMgQklUQU5HRU5UID0gbmV3IEF0dHJpYnV0ZShcImJpdGFuZ2VudFwiLCAzLCBUWVBFUy5GTE9BVCk7XG5cbiAgICAvKipcbiAgICAgKiBBdHRyaWJ1dGUgbGF5b3V0IHRvIHBhY2sgYSB2ZXJ0ZXgncyB0ZXh0dXJlIGNvb3JkaW5hdGVzJyB1ICYgdiBhcyBmbG9hdHNcbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIExheW91dH1cbiAgICAgKi9cbiAgICBzdGF0aWMgVVYgPSBuZXcgQXR0cmlidXRlKFwidXZcIiwgMiwgVFlQRVMuRkxPQVQpO1xuXG4gICAgLy8gTWF0ZXJpYWwgYXR0cmlidXRlc1xuXG4gICAgLyoqXG4gICAgICogQXR0cmlidXRlIGxheW91dCB0byBwYWNrIGFuIHVuc2lnbmVkIHNob3J0IHRvIGJlIGludGVycHJldGVkIGFzIGEgdGhlIGluZGV4XG4gICAgICogaW50byBhIHtAbGluayBNZXNofSdzIG1hdGVyaWFscyBsaXN0LlxuICAgICAqIDxwPlxuICAgICAqIFRoZSBpbnRlbnRpb24gb2YgdGhpcyB2YWx1ZSBpcyB0byBzZW5kIGFsbCBvZiB0aGUge0BsaW5rIE1lc2h9J3MgbWF0ZXJpYWxzXG4gICAgICogaW50byBtdWx0aXBsZSBzaGFkZXIgdW5pZm9ybXMgYW5kIHRoZW4gcmVmZXJlbmNlIHRoZSBjdXJyZW50IG9uZSBieSB0aGlzXG4gICAgICogdmVydGV4IGF0dHJpYnV0ZS5cbiAgICAgKiA8cD5cbiAgICAgKiBleGFtcGxlIGdsc2wgY29kZTpcbiAgICAgKlxuICAgICAqIDxwcmU+PGNvZGU+XG4gICAgICogIC8vIHRoaXMgaXMgYm91bmQgdXNpbmcgTUFURVJJQUxfSU5ERVhcbiAgICAgKiAgYXR0cmlidXRlIGludCBtYXRlcmlhbEluZGV4O1xuICAgICAqXG4gICAgICogIHN0cnVjdCBNYXRlcmlhbCB7XG4gICAgICogICAgdmVjMyBkaWZmdXNlO1xuICAgICAqICAgIHZlYzMgc3BlY3VsYXI7XG4gICAgICogICAgdmVjMyBzcGVjdWxhckV4cG9uZW50O1xuICAgICAqICB9O1xuICAgICAqXG4gICAgICogIHVuaWZvcm0gTWF0ZXJpYWwgbWF0ZXJpYWxzW01BWF9NQVRFUklBTFNdO1xuICAgICAqXG4gICAgICogIC8vIC4uLlxuICAgICAqXG4gICAgICogIHZlYzMgZGlmZnVzZSA9IG1hdGVyaWFsc1ttYXRlcmlhbEluZGV4XTtcbiAgICAgKlxuICAgICAqIDwvY29kZT48L3ByZT5cbiAgICAgKiBUT0RPOiBNb3JlIGRlc2NyaXB0aW9uICYgdGVzdCB0byBtYWtlIHN1cmUgc3Vic2NyaXB0aW5nIGJ5IGF0dHJpYnV0ZXMgZXZlblxuICAgICAqIHdvcmtzIGZvciB3ZWJnbFxuICAgICAqXG4gICAgICogQHNlZSB7QGxpbmsgTGF5b3V0fVxuICAgICAqL1xuICAgIHN0YXRpYyBNQVRFUklBTF9JTkRFWCA9IG5ldyBBdHRyaWJ1dGUoXCJtYXRlcmlhbEluZGV4XCIsIDEsIFRZUEVTLlNIT1JUKTtcbiAgICBzdGF0aWMgTUFURVJJQUxfRU5BQkxFRCA9IG5ldyBBdHRyaWJ1dGUoXCJtYXRlcmlhbEVuYWJsZWRcIiwgMSwgVFlQRVMuVU5TSUdORURfU0hPUlQpO1xuICAgIHN0YXRpYyBBTUJJRU5UID0gbmV3IEF0dHJpYnV0ZShcImFtYmllbnRcIiwgMywgVFlQRVMuRkxPQVQpO1xuICAgIHN0YXRpYyBESUZGVVNFID0gbmV3IEF0dHJpYnV0ZShcImRpZmZ1c2VcIiwgMywgVFlQRVMuRkxPQVQpO1xuICAgIHN0YXRpYyBTUEVDVUxBUiA9IG5ldyBBdHRyaWJ1dGUoXCJzcGVjdWxhclwiLCAzLCBUWVBFUy5GTE9BVCk7XG4gICAgc3RhdGljIFNQRUNVTEFSX0VYUE9ORU5UID0gbmV3IEF0dHJpYnV0ZShcInNwZWN1bGFyRXhwb25lbnRcIiwgMywgVFlQRVMuRkxPQVQpO1xuICAgIHN0YXRpYyBFTUlTU0lWRSA9IG5ldyBBdHRyaWJ1dGUoXCJlbWlzc2l2ZVwiLCAzLCBUWVBFUy5GTE9BVCk7XG4gICAgc3RhdGljIFRSQU5TTUlTU0lPTl9GSUxURVIgPSBuZXcgQXR0cmlidXRlKFwidHJhbnNtaXNzaW9uRmlsdGVyXCIsIDMsIFRZUEVTLkZMT0FUKTtcbiAgICBzdGF0aWMgRElTU09MVkUgPSBuZXcgQXR0cmlidXRlKFwiZGlzc29sdmVcIiwgMSwgVFlQRVMuRkxPQVQpO1xuICAgIHN0YXRpYyBJTExVTUlOQVRJT04gPSBuZXcgQXR0cmlidXRlKFwiaWxsdW1pbmF0aW9uXCIsIDEsIFRZUEVTLlVOU0lHTkVEX1NIT1JUKTtcbiAgICBzdGF0aWMgUkVGUkFDVElPTl9JTkRFWCA9IG5ldyBBdHRyaWJ1dGUoXCJyZWZyYWN0aW9uSW5kZXhcIiwgMSwgVFlQRVMuRkxPQVQpO1xuICAgIHN0YXRpYyBTSEFSUE5FU1MgPSBuZXcgQXR0cmlidXRlKFwic2hhcnBuZXNzXCIsIDEsIFRZUEVTLkZMT0FUKTtcbiAgICBzdGF0aWMgTUFQX0RJRkZVU0UgPSBuZXcgQXR0cmlidXRlKFwibWFwRGlmZnVzZVwiLCAxLCBUWVBFUy5TSE9SVCk7XG4gICAgc3RhdGljIE1BUF9BTUJJRU5UID0gbmV3IEF0dHJpYnV0ZShcIm1hcEFtYmllbnRcIiwgMSwgVFlQRVMuU0hPUlQpO1xuICAgIHN0YXRpYyBNQVBfU1BFQ1VMQVIgPSBuZXcgQXR0cmlidXRlKFwibWFwU3BlY3VsYXJcIiwgMSwgVFlQRVMuU0hPUlQpO1xuICAgIHN0YXRpYyBNQVBfU1BFQ1VMQVJfRVhQT05FTlQgPSBuZXcgQXR0cmlidXRlKFwibWFwU3BlY3VsYXJFeHBvbmVudFwiLCAxLCBUWVBFUy5TSE9SVCk7XG4gICAgc3RhdGljIE1BUF9ESVNTT0xWRSA9IG5ldyBBdHRyaWJ1dGUoXCJtYXBEaXNzb2x2ZVwiLCAxLCBUWVBFUy5TSE9SVCk7XG4gICAgc3RhdGljIEFOVElfQUxJQVNJTkcgPSBuZXcgQXR0cmlidXRlKFwiYW50aUFsaWFzaW5nXCIsIDEsIFRZUEVTLlVOU0lHTkVEX1NIT1JUKTtcbiAgICBzdGF0aWMgTUFQX0JVTVAgPSBuZXcgQXR0cmlidXRlKFwibWFwQnVtcFwiLCAxLCBUWVBFUy5TSE9SVCk7XG4gICAgc3RhdGljIE1BUF9ESVNQTEFDRU1FTlQgPSBuZXcgQXR0cmlidXRlKFwibWFwRGlzcGxhY2VtZW50XCIsIDEsIFRZUEVTLlNIT1JUKTtcbiAgICBzdGF0aWMgTUFQX0RFQ0FMID0gbmV3IEF0dHJpYnV0ZShcIm1hcERlY2FsXCIsIDEsIFRZUEVTLlNIT1JUKTtcbiAgICBzdGF0aWMgTUFQX0VNSVNTSVZFID0gbmV3IEF0dHJpYnV0ZShcIm1hcEVtaXNzaXZlXCIsIDEsIFRZUEVTLlNIT1JUKTtcblxuICAgIHB1YmxpYyBzdHJpZGU6IG51bWJlcjtcbiAgICBwdWJsaWMgYXR0cmlidXRlczogQXR0cmlidXRlW107XG4gICAgcHVibGljIGF0dHJpYnV0ZU1hcDogeyBbaWR4OiBzdHJpbmddOiBBdHRyaWJ1dGVJbmZvIH07XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgTGF5b3V0IG9iamVjdC4gVGhpcyBjb25zdHJ1Y3RvciB3aWxsIHRocm93IGlmIGFueSBkdXBsaWNhdGVcbiAgICAgKiBhdHRyaWJ1dGVzIGFyZSBnaXZlbi5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSAuLi5hdHRyaWJ1dGVzIC0gQW4gb3JkZXJlZCBsaXN0IG9mIGF0dHJpYnV0ZXMgdGhhdFxuICAgICAqICAgICAgICBkZXNjcmliZSB0aGUgZGVzaXJlZCBtZW1vcnkgbGF5b3V0IGZvciBlYWNoIHZlcnRleCBhdHRyaWJ1dGUuXG4gICAgICogICAgICAgIDxwPlxuICAgICAqXG4gICAgICogQHNlZSB7QGxpbmsgTWVzaH1cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvciguLi5hdHRyaWJ1dGVzOiBBdHRyaWJ1dGVbXSkge1xuICAgICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzO1xuICAgICAgICB0aGlzLmF0dHJpYnV0ZU1hcCA9IHt9O1xuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAgICAgbGV0IG1heFN0cmlkZU11bHRpcGxlID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBhdHRyaWJ1dGUgb2YgYXR0cmlidXRlcykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYXR0cmlidXRlTWFwW2F0dHJpYnV0ZS5rZXldKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IER1cGxpY2F0ZUF0dHJpYnV0ZUV4Y2VwdGlvbihhdHRyaWJ1dGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmcgdG8gc2F0aXNmeSBXZWJHTCdzIHJlcXVpcmVtZW50IHRoYXQgYWxsXG4gICAgICAgICAgICAvLyB2ZXJ0ZXhBdHRyaWJQb2ludGVyIGNhbGxzIGhhdmUgYW4gb2Zmc2V0IHRoYXQgaXMgYSBtdWx0aXBsZSBvZlxuICAgICAgICAgICAgLy8gdGhlIHR5cGUgc2l6ZS5cbiAgICAgICAgICAgIGlmIChvZmZzZXQgJSBhdHRyaWJ1dGUuc2l6ZU9mVHlwZSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSBhdHRyaWJ1dGUuc2l6ZU9mVHlwZSAtIChvZmZzZXQgJSBhdHRyaWJ1dGUuc2l6ZU9mVHlwZSk7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiTGF5b3V0IHJlcXVpcmVzIHBhZGRpbmcgYmVmb3JlIFwiICsgYXR0cmlidXRlLmtleSArIFwiIGF0dHJpYnV0ZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlTWFwW2F0dHJpYnV0ZS5rZXldID0ge1xuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogYXR0cmlidXRlLFxuICAgICAgICAgICAgICAgIHNpemU6IGF0dHJpYnV0ZS5zaXplLFxuICAgICAgICAgICAgICAgIHR5cGU6IGF0dHJpYnV0ZS50eXBlLFxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWQ6IGF0dHJpYnV0ZS5ub3JtYWxpemVkLFxuICAgICAgICAgICAgICAgIG9mZnNldDogb2Zmc2V0LFxuICAgICAgICAgICAgfSBhcyBBdHRyaWJ1dGVJbmZvO1xuICAgICAgICAgICAgb2Zmc2V0ICs9IGF0dHJpYnV0ZS5zaXplSW5CeXRlcztcbiAgICAgICAgICAgIG1heFN0cmlkZU11bHRpcGxlID0gTWF0aC5tYXgobWF4U3RyaWRlTXVsdGlwbGUsIGF0dHJpYnV0ZS5zaXplT2ZUeXBlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBBZGQgcGFkZGluZyB0byB0aGUgZW5kIHRvIHNhdGlzZnkgV2ViR0wncyByZXF1aXJlbWVudCB0aGF0IGFsbFxuICAgICAgICAvLyB2ZXJ0ZXhBdHRyaWJQb2ludGVyIGNhbGxzIGhhdmUgYSBzdHJpZGUgdGhhdCBpcyBhIG11bHRpcGxlIG9mIHRoZVxuICAgICAgICAvLyB0eXBlIHNpemUuIEJlY2F1c2Ugd2UncmUgcHV0dGluZyBkaWZmZXJlbnRseSBzaXplZCBhdHRyaWJ1dGVzIGludG9cbiAgICAgICAgLy8gdGhlIHNhbWUgYnVmZmVyLCBpdCBtdXN0IGJlIHBhZGRlZCB0byBhIG11bHRpcGxlIG9mIHRoZSBsYXJnZXN0XG4gICAgICAgIC8vIHR5cGUgc2l6ZS5cbiAgICAgICAgaWYgKG9mZnNldCAlIG1heFN0cmlkZU11bHRpcGxlICE9PSAwKSB7XG4gICAgICAgICAgICBvZmZzZXQgKz0gbWF4U3RyaWRlTXVsdGlwbGUgLSAob2Zmc2V0ICUgbWF4U3RyaWRlTXVsdGlwbGUpO1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFwiTGF5b3V0IHJlcXVpcmVzIHBhZGRpbmcgYXQgdGhlIGJhY2tcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHJpZGUgPSBvZmZzZXQ7XG4gICAgICAgIGZvciAoY29uc3QgYXR0cmlidXRlIG9mIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlTWFwW2F0dHJpYnV0ZS5rZXldLnN0cmlkZSA9IHRoaXMuc3RyaWRlO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiZXhwb3J0IHR5cGUgVmVjMyA9IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcblxuZXhwb3J0IGludGVyZmFjZSBVVlcge1xuICAgIHU6IG51bWJlcjtcbiAgICB2OiBudW1iZXI7XG4gICAgdzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVNYXBEYXRhIHtcbiAgICBjb2xvckNvcnJlY3Rpb246IGJvb2xlYW47XG4gICAgaG9yaXpvbnRhbEJsZW5kaW5nOiBib29sZWFuO1xuICAgIHZlcnRpY2FsQmxlbmRpbmc6IGJvb2xlYW47XG4gICAgYm9vc3RNaXBNYXBTaGFycG5lc3M6IG51bWJlcjtcbiAgICBtb2RpZnlUZXh0dXJlTWFwOiB7XG4gICAgICAgIGJyaWdodG5lc3M6IG51bWJlcjtcbiAgICAgICAgY29udHJhc3Q6IG51bWJlcjtcbiAgICB9O1xuICAgIG9mZnNldDogVVZXO1xuICAgIHNjYWxlOiBVVlc7XG4gICAgdHVyYnVsZW5jZTogVVZXO1xuICAgIGNsYW1wOiBib29sZWFuO1xuICAgIHRleHR1cmVSZXNvbHV0aW9uOiBudW1iZXIgfCBudWxsO1xuICAgIGJ1bXBNdWx0aXBsaWVyOiBudW1iZXI7XG4gICAgaW1mQ2hhbjogc3RyaW5nIHwgbnVsbDtcbiAgICBmaWxlbmFtZTogc3RyaW5nO1xuICAgIHJlZmxlY3Rpb25UeXBlPzogc3RyaW5nO1xuICAgIHRleHR1cmU/OiBIVE1MSW1hZ2VFbGVtZW50O1xufVxuXG4vKipcbiAqIFRoZSBNYXRlcmlhbCBjbGFzcy5cbiAqL1xuZXhwb3J0IGNsYXNzIE1hdGVyaWFsIHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIHRoZSB1bmlxdWUgbmFtZSBvZiB0aGUgbWF0ZXJpYWxcbiAgICAgKi9cbiAgICAvLyBUaGUgdmFsdWVzIGZvciB0aGUgZm9sbG93aW5nIGF0dGlidXRlc1xuICAgIC8vIGFyZSBhbiBhcnJheSBvZiBSLCBHLCBCIG5vcm1hbGl6ZWQgdmFsdWVzLlxuICAgIC8vIEthIC0gQW1iaWVudCBSZWZsZWN0aXZpdHlcbiAgICBhbWJpZW50OiBWZWMzID0gWzAsIDAsIDBdO1xuICAgIC8vIEtkIC0gRGVmdXNlIFJlZmxlY3Rpdml0eVxuICAgIGRpZmZ1c2U6IFZlYzMgPSBbMCwgMCwgMF07XG4gICAgLy8gS3NcbiAgICBzcGVjdWxhcjogVmVjMyA9IFswLCAwLCAwXTtcbiAgICAvLyBLZVxuICAgIGVtaXNzaXZlOiBWZWMzID0gWzAsIDAsIDBdO1xuICAgIC8vIFRmXG4gICAgdHJhbnNtaXNzaW9uRmlsdGVyOiBWZWMzID0gWzAsIDAsIDBdO1xuICAgIC8vIGRcbiAgICBkaXNzb2x2ZTogbnVtYmVyID0gMDtcbiAgICAvLyB2YWxpZCByYW5nZSBpcyBiZXR3ZWVuIDAgYW5kIDEwMDBcbiAgICBzcGVjdWxhckV4cG9uZW50OiBudW1iZXIgPSAwO1xuICAgIC8vIGVpdGhlciBkIG9yIFRyOyB2YWxpZCB2YWx1ZXMgYXJlIG5vcm1hbGl6ZWRcbiAgICB0cmFuc3BhcmVuY3k6IG51bWJlciA9IDA7XG4gICAgLy8gaWxsdW0gLSB0aGUgZW51bSBvZiB0aGUgaWxsdW1pbmF0aW9uIG1vZGVsIHRvIHVzZVxuICAgIGlsbHVtaW5hdGlvbjogbnVtYmVyID0gMDtcbiAgICAvLyBOaSAtIFNldCB0byBcIm5vcm1hbFwiIChhaXIpLlxuICAgIHJlZnJhY3Rpb25JbmRleDogbnVtYmVyID0gMTtcbiAgICAvLyBzaGFycG5lc3NcbiAgICBzaGFycG5lc3M6IG51bWJlciA9IDA7XG4gICAgLy8gbWFwX0tkXG4gICAgbWFwRGlmZnVzZTogVGV4dHVyZU1hcERhdGEgPSBlbXB0eVRleHR1cmVPcHRpb25zKCk7XG4gICAgLy8gbWFwX0thXG4gICAgbWFwQW1iaWVudDogVGV4dHVyZU1hcERhdGEgPSBlbXB0eVRleHR1cmVPcHRpb25zKCk7XG4gICAgLy8gbWFwX0tzXG4gICAgbWFwU3BlY3VsYXI6IFRleHR1cmVNYXBEYXRhID0gZW1wdHlUZXh0dXJlT3B0aW9ucygpO1xuICAgIC8vIG1hcF9Oc1xuICAgIG1hcFNwZWN1bGFyRXhwb25lbnQ6IFRleHR1cmVNYXBEYXRhID0gZW1wdHlUZXh0dXJlT3B0aW9ucygpO1xuICAgIC8vIG1hcF9kXG4gICAgbWFwRGlzc29sdmU6IFRleHR1cmVNYXBEYXRhID0gZW1wdHlUZXh0dXJlT3B0aW9ucygpO1xuICAgIC8vIG1hcF9hYXRcbiAgICBhbnRpQWxpYXNpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICAvLyBtYXBfYnVtcCBvciBidW1wXG4gICAgbWFwQnVtcDogVGV4dHVyZU1hcERhdGEgPSBlbXB0eVRleHR1cmVPcHRpb25zKCk7XG4gICAgLy8gZGlzcFxuICAgIG1hcERpc3BsYWNlbWVudDogVGV4dHVyZU1hcERhdGEgPSBlbXB0eVRleHR1cmVPcHRpb25zKCk7XG4gICAgLy8gZGVjYWxcbiAgICBtYXBEZWNhbDogVGV4dHVyZU1hcERhdGEgPSBlbXB0eVRleHR1cmVPcHRpb25zKCk7XG4gICAgLy8gbWFwX0tlXG4gICAgbWFwRW1pc3NpdmU6IFRleHR1cmVNYXBEYXRhID0gZW1wdHlUZXh0dXJlT3B0aW9ucygpO1xuICAgIC8vIHJlZmwgLSB3aGVuIHRoZSByZWZsZWN0aW9uIHR5cGUgaXMgYSBjdWJlLCB0aGVyZSB3aWxsIGJlIG11bHRpcGxlIHJlZmxcbiAgICAvLyAgICAgICAgc3RhdGVtZW50cyBmb3IgZWFjaCBzaWRlIG9mIHRoZSBjdWJlLiBJZiBpdCdzIGEgc3BoZXJpY2FsXG4gICAgLy8gICAgICAgIHJlZmxlY3Rpb24sIHRoZXJlIHNob3VsZCBvbmx5IGV2ZXIgYmUgb25lLlxuICAgIG1hcFJlZmxlY3Rpb25zOiBUZXh0dXJlTWFwRGF0YVtdID0gW107XG4gICAgY29uc3RydWN0b3IocHVibGljIG5hbWU6IHN0cmluZykge31cbn1cblxuY29uc3QgU0VOVElORUxfTUFURVJJQUwgPSBuZXcgTWF0ZXJpYWwoXCJzZW50aW5lbFwiKTtcblxuLyoqXG4gKiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9XYXZlZnJvbnRfLm9ial9maWxlXG4gKiBodHRwOi8vcGF1bGJvdXJrZS5uZXQvZGF0YWZvcm1hdHMvbXRsL1xuICovXG5leHBvcnQgY2xhc3MgTWF0ZXJpYWxMaWJyYXJ5IHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIHRoZSBNYXRlcmlhbCBQYXJzZXJcbiAgICAgKiBAcGFyYW0gbXRsRGF0YSB0aGUgTVRMIGZpbGUgY29udGVudHNcbiAgICAgKi9cbiAgICBwdWJsaWMgY3VycmVudE1hdGVyaWFsOiBNYXRlcmlhbCA9IFNFTlRJTkVMX01BVEVSSUFMO1xuICAgIHB1YmxpYyBtYXRlcmlhbHM6IHsgW2s6IHN0cmluZ106IE1hdGVyaWFsIH0gPSB7fTtcblxuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBkYXRhOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5wYXJzZSgpO1xuICAgIH1cblxuICAgIC8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuICAgIC8qIHRoZSBmdW5jdGlvbiBuYW1lcyBoZXJlIGRpc29iZXkgY2FtZWxDYXNlIGNvbnZlbnRpb25zXG4gICAgIHRvIG1ha2UgcGFyc2luZy9yb3V0aW5nIGVhc2llci4gc2VlIHRoZSBwYXJzZSBmdW5jdGlvblxuICAgICBkb2N1bWVudGF0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLiAqL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBNYXRlcmlhbCBvYmplY3QgYW5kIGFkZHMgdG8gdGhlIHJlZ2lzdHJ5LlxuICAgICAqIEBwYXJhbSB0b2tlbnMgdGhlIHRva2VucyBhc3NvY2lhdGVkIHdpdGggdGhlIGRpcmVjdGl2ZVxuICAgICAqL1xuICAgIHBhcnNlX25ld210bCh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIGNvbnN0IG5hbWUgPSB0b2tlbnNbMF07XG4gICAgICAgIC8vIGNvbnNvbGUuaW5mbygnUGFyc2luZyBuZXcgTWF0ZXJpYWw6JywgbmFtZSk7XG5cbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwgPSBuZXcgTWF0ZXJpYWwobmFtZSk7XG4gICAgICAgIHRoaXMubWF0ZXJpYWxzW25hbWVdID0gdGhpcy5jdXJyZW50TWF0ZXJpYWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIHRoZSBkb2N1bWVuYXRpb24gZm9yIHBhcnNlX0thIGJlbG93IGZvciBhIGJldHRlciB1bmRlcnN0YW5kaW5nLlxuICAgICAqXG4gICAgICogR2l2ZW4gYSBsaXN0IG9mIHBvc3NpYmxlIGNvbG9yIHRva2VucywgcmV0dXJucyBhbiBhcnJheSBvZiBSLCBHLCBhbmQgQlxuICAgICAqIGNvbG9yIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgdGhlIHRva2VucyBhc3NvY2lhdGVkIHdpdGggdGhlIGRpcmVjdGl2ZVxuICAgICAqIEByZXR1cm4geyp9IGEgMyBlbGVtZW50IGFycmF5IGNvbnRhaW5pbmcgdGhlIFIsIEcsIGFuZCBCIHZhbHVlc1xuICAgICAqIG9mIHRoZSBjb2xvci5cbiAgICAgKi9cbiAgICBwYXJzZUNvbG9yKHRva2Vuczogc3RyaW5nW10pOiBWZWMzIHtcbiAgICAgICAgaWYgKHRva2Vuc1swXSA9PSBcInNwZWN0cmFsXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBcIlRoZSBNVEwgcGFyc2VyIGRvZXMgbm90IHN1cHBvcnQgc3BlY3RyYWwgY3VydmUgZmlsZXMuIFlvdSB3aWxsIFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJuZWVkIHRvIGNvbnZlcnQgdGhlIE1UTCBjb2xvcnMgdG8gZWl0aGVyIFJHQiBvciBDSUVYWVouXCIsXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRva2Vuc1swXSA9PSBcInh5elwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJUaGUgTVRMIHBhcnNlciBkb2VzIG5vdCBjdXJyZW50bHkgc3VwcG9ydCBYWVogY29sb3JzLiBFaXRoZXIgY29udmVydCB0aGUgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcIlhZWiB2YWx1ZXMgdG8gUkdCIG9yIGNyZWF0ZSBhbiBpc3N1ZSB0byBhZGQgc3VwcG9ydCBmb3IgWFlaXCIsXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZnJvbSBteSB1bmRlcnN0YW5kaW5nIG9mIHRoZSBzcGVjLCBSR0IgdmFsdWVzIGF0IHRoaXMgcG9pbnRcbiAgICAgICAgLy8gd2lsbCBlaXRoZXIgYmUgMyBmbG9hdHMgb3IgZXhhY3RseSAxIGZsb2F0LCBzbyB0aGF0J3MgdGhlIGNoZWNrXG4gICAgICAgIC8vIHRoYXQgaSdtIGdvaW5nIHRvIHBlcmZvcm0gaGVyZVxuICAgICAgICBpZiAodG9rZW5zLmxlbmd0aCA9PSAzKSB7XG4gICAgICAgICAgICBjb25zdCBbeCwgeSwgel0gPSB0b2tlbnM7XG4gICAgICAgICAgICByZXR1cm4gW3BhcnNlRmxvYXQoeCksIHBhcnNlRmxvYXQoeSksIHBhcnNlRmxvYXQoeildO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2luY2UgdG9rZW5zIGF0IHRoaXMgcG9pbnQgaGFzIGEgbGVuZ3RoIG9mIDMsIHdlJ3JlIGdvaW5nIHRvIGFzc3VtZVxuICAgICAgICAvLyBpdCdzIGV4YWN0bHkgMSwgc2tpcHBpbmcgdGhlIGNoZWNrIGZvciAyLlxuICAgICAgICBjb25zdCB2YWx1ZSA9IHBhcnNlRmxvYXQodG9rZW5zWzBdKTtcbiAgICAgICAgLy8gaW4gdGhpcyBjYXNlLCBhbGwgdmFsdWVzIGFyZSBlcXVpdmFsZW50XG4gICAgICAgIHJldHVybiBbdmFsdWUsIHZhbHVlLCB2YWx1ZV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2UgdGhlIGFtYmllbnQgcmVmbGVjdGl2aXR5XG4gICAgICpcbiAgICAgKiBBIEthIGRpcmVjdGl2ZSBjYW4gdGFrZSBvbmUgb2YgdGhyZWUgZm9ybXM6XG4gICAgICogICAtIEthIHIgZyBiXG4gICAgICogICAtIEthIHNwZWN0cmFsIGZpbGUucmZsXG4gICAgICogICAtIEthIHh5eiB4IHkgelxuICAgICAqIFRoZXNlIHRocmVlIGZvcm1zIGFyZSBtdXR1YWxseSBleGNsdXNpdmUgaW4gdGhhdCBvbmx5IG9uZVxuICAgICAqIGRlY2xhcmF0aW9uIGNhbiBleGlzdCBwZXIgbWF0ZXJpYWwuIEl0IGlzIGNvbnNpZGVyZWQgYSBzeW50YXhcbiAgICAgKiBlcnJvciBvdGhlcndpc2UuXG4gICAgICpcbiAgICAgKiBUaGUgXCJLYVwiIGZvcm0gc3BlY2lmaWVzIHRoZSBhbWJpZW50IHJlZmxlY3Rpdml0eSB1c2luZyBSR0IgdmFsdWVzLlxuICAgICAqIFRoZSBcImdcIiBhbmQgXCJiXCIgdmFsdWVzIGFyZSBvcHRpb25hbC4gSWYgb25seSB0aGUgXCJyXCIgdmFsdWUgaXNcbiAgICAgKiBzcGVjaWZpZWQsIHRoZW4gdGhlIFwiZ1wiIGFuZCBcImJcIiB2YWx1ZXMgYXJlIGFzc2lnbmVkIHRoZSB2YWx1ZSBvZlxuICAgICAqIFwiclwiLiBWYWx1ZXMgYXJlIG5vcm1hbGx5IGluIHRoZSByYW5nZSAwLjAgdG8gMS4wLiBWYWx1ZXMgb3V0c2lkZVxuICAgICAqIG9mIHRoaXMgcmFuZ2UgaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHJlZmxlY3Rpdml0eSBhY2NvcmRpbmdseS5cbiAgICAgKlxuICAgICAqIFRoZSBcIkthIHNwZWN0cmFsXCIgZm9ybSBzcGVjaWZpZXMgdGhlIGFtYmllbnQgcmVmbGVjdGl2aXR5IHVzaW5nIGFcbiAgICAgKiBzcGVjdHJhbCBjdXJ2ZS4gXCJmaWxlLnJmbFwiIGlzIHRoZSBuYW1lIG9mIHRoZSBcIi5yZmxcIiBmaWxlIGNvbnRhaW5pbmdcbiAgICAgKiB0aGUgY3VydmUgZGF0YS4gXCJmYWN0b3JcIiBpcyBhbiBvcHRpb25hbCBhcmd1bWVudCB3aGljaCBpcyBhIG11bHRpcGxpZXJcbiAgICAgKiBmb3IgdGhlIHZhbHVlcyBpbiB0aGUgLnJmbCBmaWxlIGFuZCBkZWZhdWx0cyB0byAxLjAgaWYgbm90IHNwZWNpZmllZC5cbiAgICAgKlxuICAgICAqIFRoZSBcIkthIHh5elwiIGZvcm0gc3BlY2lmaWVzIHRoZSBhbWJpZW50IHJlZmxlY3Rpdml0eSB1c2luZyBDSUVYWVogdmFsdWVzLlxuICAgICAqIFwieCB5IHpcIiBhcmUgdGhlIHZhbHVlcyBvZiB0aGUgQ0lFWFlaIGNvbG9yIHNwYWNlLiBUaGUgXCJ5XCIgYW5kIFwielwiIGFyZ3VtZW50c1xuICAgICAqIGFyZSBvcHRpb25hbCBhbmQgdGFrZSBvbiB0aGUgdmFsdWUgb2YgdGhlIFwieFwiIGNvbXBvbmVudCBpZiBvbmx5IFwieFwiIGlzXG4gICAgICogc3BlY2lmaWVkLiBUaGUgXCJ4IHkgelwiIHZhbHVlcyBhcmUgbm9ybWFsbHkgaW4gdGhlIHJhbmdlIG9mIDAuMCB0byAxLjAgYW5kXG4gICAgICogaW5jcmVhc2Ugb3IgZGVjcmVhc2UgYW1iaWVudCByZWZsZWN0aXZpdHkgYWNjb3JkaW5nbHkgb3V0c2lkZSBvZiB0aGF0XG4gICAgICogcmFuZ2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9LYSh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLmFtYmllbnQgPSB0aGlzLnBhcnNlQ29sb3IodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEaWZmdXNlIFJlZmxlY3Rpdml0eVxuICAgICAqXG4gICAgICogU2ltaWxhciB0byB0aGUgS2EgZGlyZWN0aXZlLiBTaW1wbHkgcmVwbGFjZSBcIkthXCIgd2l0aCBcIktkXCIgYW5kIHRoZSBydWxlc1xuICAgICAqIGFyZSB0aGUgc2FtZVxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyB0aGUgdG9rZW5zIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGlyZWN0aXZlXG4gICAgICovXG4gICAgcGFyc2VfS2QodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5kaWZmdXNlID0gdGhpcy5wYXJzZUNvbG9yKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3BlY3RyYWwgUmVmbGVjdGl2aXR5XG4gICAgICpcbiAgICAgKiBTaW1pbGFyIHRvIHRoZSBLYSBkaXJlY3RpdmUuIFNpbXBseSByZXBsYWNlIFwiS3NcIiB3aXRoIFwiS2RcIiBhbmQgdGhlIHJ1bGVzXG4gICAgICogYXJlIHRoZSBzYW1lXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9Lcyh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLnNwZWN1bGFyID0gdGhpcy5wYXJzZUNvbG9yKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW1pc3NpdmVcbiAgICAgKlxuICAgICAqIFRoZSBhbW91bnQgYW5kIGNvbG9yIG9mIGxpZ2h0IGVtaXR0ZWQgYnkgdGhlIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgdGhlIHRva2VucyBhc3NvY2lhdGVkIHdpdGggdGhlIGRpcmVjdGl2ZVxuICAgICAqL1xuICAgIHBhcnNlX0tlKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwuZW1pc3NpdmUgPSB0aGlzLnBhcnNlQ29sb3IodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmFuc21pc3Npb24gRmlsdGVyXG4gICAgICpcbiAgICAgKiBBbnkgbGlnaHQgcGFzc2luZyB0aHJvdWdoIHRoZSBvYmplY3QgaXMgZmlsdGVyZWQgYnkgdGhlIHRyYW5zbWlzc2lvblxuICAgICAqIGZpbHRlciwgd2hpY2ggb25seSBhbGxvd3Mgc3BlY2lmaWMgY29sb3JzIHRvIHBhc3MgdGhyb3VnaC4gRm9yIGV4YW1wbGUsIFRmXG4gICAgICogMCAxIDAgYWxsb3dzIGFsbCBvZiB0aGUgZ3JlZW4gdG8gcGFzcyB0aHJvdWdoIGFuZCBmaWx0ZXJzIG91dCBhbGwgb2YgdGhlXG4gICAgICogcmVkIGFuZCBibHVlLlxuICAgICAqXG4gICAgICogU2ltaWxhciB0byB0aGUgS2EgZGlyZWN0aXZlLiBTaW1wbHkgcmVwbGFjZSBcIktzXCIgd2l0aCBcIlRmXCIgYW5kIHRoZSBydWxlc1xuICAgICAqIGFyZSB0aGUgc2FtZVxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyB0aGUgdG9rZW5zIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGlyZWN0aXZlXG4gICAgICovXG4gICAgcGFyc2VfVGYodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC50cmFuc21pc3Npb25GaWx0ZXIgPSB0aGlzLnBhcnNlQ29sb3IodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTcGVjaWZpZXMgdGhlIGRpc3NvbHZlIGZvciB0aGUgY3VycmVudCBtYXRlcmlhbC5cbiAgICAgKlxuICAgICAqIFN0YXRlbWVudDogZCBbLWhhbG9dIGBmYWN0b3JgXG4gICAgICpcbiAgICAgKiBFeGFtcGxlOiBcImQgMC41XCJcbiAgICAgKlxuICAgICAqIFRoZSBmYWN0b3IgaXMgdGhlIGFtb3VudCB0aGlzIG1hdGVyaWFsIGRpc3NvbHZlcyBpbnRvIHRoZSBiYWNrZ3JvdW5kLiBBXG4gICAgICogZmFjdG9yIG9mIDEuMCBpcyBmdWxseSBvcGFxdWUuIFRoaXMgaXMgdGhlIGRlZmF1bHQgd2hlbiBhIG5ldyBtYXRlcmlhbCBpc1xuICAgICAqIGNyZWF0ZWQuIEEgZmFjdG9yIG9mIDAuMCBpcyBmdWxseSBkaXNzb2x2ZWQgKGNvbXBsZXRlbHkgdHJhbnNwYXJlbnQpLlxuICAgICAqXG4gICAgICogVW5saWtlIGEgcmVhbCB0cmFuc3BhcmVudCBtYXRlcmlhbCwgdGhlIGRpc3NvbHZlIGRvZXMgbm90IGRlcGVuZCB1cG9uXG4gICAgICogbWF0ZXJpYWwgdGhpY2tuZXNzIG5vciBkb2VzIGl0IGhhdmUgYW55IHNwZWN0cmFsIGNoYXJhY3Rlci4gRGlzc29sdmUgd29ya3NcbiAgICAgKiBvbiBhbGwgaWxsdW1pbmF0aW9uIG1vZGVscy5cbiAgICAgKlxuICAgICAqIFRoZSBkaXNzb2x2ZSBzdGF0ZW1lbnQgYWxsb3dzIGZvciBhbiBvcHRpb25hbCBcIi1oYWxvXCIgZmxhZyB3aGljaCBpbmRpY2F0ZXNcbiAgICAgKiB0aGF0IGEgZGlzc29sdmUgaXMgZGVwZW5kZW50IG9uIHRoZSBzdXJmYWNlIG9yaWVudGF0aW9uIHJlbGF0aXZlIHRvIHRoZVxuICAgICAqIHZpZXdlci4gRm9yIGV4YW1wbGUsIGEgc3BoZXJlIHdpdGggdGhlIGZvbGxvd2luZyBkaXNzb2x2ZSwgXCJkIC1oYWxvIDAuMFwiLFxuICAgICAqIHdpbGwgYmUgZnVsbHkgZGlzc29sdmVkIGF0IGl0cyBjZW50ZXIgYW5kIHdpbGwgYXBwZWFyIGdyYWR1YWxseSBtb3JlIG9wYXF1ZVxuICAgICAqIHRvd2FyZCBpdHMgZWRnZS5cbiAgICAgKlxuICAgICAqIFwiZmFjdG9yXCIgaXMgdGhlIG1pbmltdW0gYW1vdW50IG9mIGRpc3NvbHZlIGFwcGxpZWQgdG8gdGhlIG1hdGVyaWFsLiBUaGVcbiAgICAgKiBhbW91bnQgb2YgZGlzc29sdmUgd2lsbCB2YXJ5IGJldHdlZW4gMS4wIChmdWxseSBvcGFxdWUpIGFuZCB0aGUgc3BlY2lmaWVkXG4gICAgICogXCJmYWN0b3JcIi4gVGhlIGZvcm11bGEgaXM6XG4gICAgICpcbiAgICAgKiAgICBkaXNzb2x2ZSA9IDEuMCAtIChOKnYpKDEuMC1mYWN0b3IpXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9kKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgLy8gdGhpcyBpZ25vcmVzIHRoZSAtaGFsbyBvcHRpb24gYXMgSSBjYW4ndCBmaW5kIGFueSBkb2N1bWVudGF0aW9uIG9uIHdoYXRcbiAgICAgICAgLy8gaXQncyBzdXBwb3NlZCB0byBiZS5cbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwuZGlzc29sdmUgPSBwYXJzZUZsb2F0KHRva2Vucy5wb3AoKSB8fCBcIjBcIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIFwiaWxsdW1cIiBzdGF0ZW1lbnQgc3BlY2lmaWVzIHRoZSBpbGx1bWluYXRpb24gbW9kZWwgdG8gdXNlIGluIHRoZVxuICAgICAqIG1hdGVyaWFsLiBJbGx1bWluYXRpb24gbW9kZWxzIGFyZSBtYXRoZW1hdGljYWwgZXF1YXRpb25zIHRoYXQgcmVwcmVzZW50XG4gICAgICogdmFyaW91cyBtYXRlcmlhbCBsaWdodGluZyBhbmQgc2hhZGluZyBlZmZlY3RzLlxuICAgICAqXG4gICAgICogVGhlIGlsbHVtaW5hdGlvbiBudW1iZXIgY2FuIGJlIGEgbnVtYmVyIGZyb20gMCB0byAxMC4gVGhlIGZvbGxvd2luZyBhcmVcbiAgICAgKiB0aGUgbGlzdCBvZiBpbGx1bWluYXRpb24gZW51bWVyYXRpb25zIGFuZCB0aGVpciBzdW1tYXJpZXM6XG4gICAgICogMC4gQ29sb3Igb24gYW5kIEFtYmllbnQgb2ZmXG4gICAgICogMS4gQ29sb3Igb24gYW5kIEFtYmllbnQgb25cbiAgICAgKiAyLiBIaWdobGlnaHQgb25cbiAgICAgKiAzLiBSZWZsZWN0aW9uIG9uIGFuZCBSYXkgdHJhY2Ugb25cbiAgICAgKiA0LiBUcmFuc3BhcmVuY3k6IEdsYXNzIG9uLCBSZWZsZWN0aW9uOiBSYXkgdHJhY2Ugb25cbiAgICAgKiA1LiBSZWZsZWN0aW9uOiBGcmVzbmVsIG9uIGFuZCBSYXkgdHJhY2Ugb25cbiAgICAgKiA2LiBUcmFuc3BhcmVuY3k6IFJlZnJhY3Rpb24gb24sIFJlZmxlY3Rpb246IEZyZXNuZWwgb2ZmIGFuZCBSYXkgdHJhY2Ugb25cbiAgICAgKiA3LiBUcmFuc3BhcmVuY3k6IFJlZnJhY3Rpb24gb24sIFJlZmxlY3Rpb246IEZyZXNuZWwgb24gYW5kIFJheSB0cmFjZSBvblxuICAgICAqIDguIFJlZmxlY3Rpb24gb24gYW5kIFJheSB0cmFjZSBvZmZcbiAgICAgKiA5LiBUcmFuc3BhcmVuY3k6IEdsYXNzIG9uLCBSZWZsZWN0aW9uOiBSYXkgdHJhY2Ugb2ZmXG4gICAgICogMTAuIENhc3RzIHNoYWRvd3Mgb250byBpbnZpc2libGUgc3VyZmFjZXNcbiAgICAgKlxuICAgICAqIEV4YW1wbGU6IFwiaWxsdW0gMlwiIHRvIHNwZWNpZnkgdGhlIFwiSGlnaGxpZ2h0IG9uXCIgbW9kZWxcbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgdGhlIHRva2VucyBhc3NvY2lhdGVkIHdpdGggdGhlIGRpcmVjdGl2ZVxuICAgICAqL1xuICAgIHBhcnNlX2lsbHVtKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwuaWxsdW1pbmF0aW9uID0gcGFyc2VJbnQodG9rZW5zWzBdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcHRpY2FsIERlbnNpdHkgKEFLQSBJbmRleCBvZiBSZWZyYWN0aW9uKVxuICAgICAqXG4gICAgICogU3RhdGVtZW50OiBOaSBgaW5kZXhgXG4gICAgICpcbiAgICAgKiBFeGFtcGxlOiBOaSAxLjBcbiAgICAgKlxuICAgICAqIFNwZWNpZmllcyB0aGUgb3B0aWNhbCBkZW5zaXR5IGZvciB0aGUgc3VyZmFjZS4gYGluZGV4YCBpcyB0aGUgdmFsdWVcbiAgICAgKiBmb3IgdGhlIG9wdGljYWwgZGVuc2l0eS4gVGhlIHZhbHVlcyBjYW4gcmFuZ2UgZnJvbSAwLjAwMSB0byAxMC4gIEEgdmFsdWUgb2ZcbiAgICAgKiAxLjAgbWVhbnMgdGhhdCBsaWdodCBkb2VzIG5vdCBiZW5kIGFzIGl0IHBhc3NlcyB0aHJvdWdoIGFuIG9iamVjdC5cbiAgICAgKiBJbmNyZWFzaW5nIHRoZSBvcHRpY2FsX2RlbnNpdHkgaW5jcmVhc2VzIHRoZSBhbW91bnQgb2YgYmVuZGluZy4gR2xhc3MgaGFzXG4gICAgICogYW4gaW5kZXggb2YgcmVmcmFjdGlvbiBvZiBhYm91dCAxLjUuIFZhbHVlcyBvZiBsZXNzIHRoYW4gMS4wIHByb2R1Y2VcbiAgICAgKiBiaXphcnJlIHJlc3VsdHMgYW5kIGFyZSBub3QgcmVjb21tZW5kZWRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgdGhlIHRva2VucyBhc3NvY2lhdGVkIHdpdGggdGhlIGRpcmVjdGl2ZVxuICAgICAqL1xuICAgIHBhcnNlX05pKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwucmVmcmFjdGlvbkluZGV4ID0gcGFyc2VGbG9hdCh0b2tlbnNbMF0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNwZWNpZmllcyB0aGUgc3BlY3VsYXIgZXhwb25lbnQgZm9yIHRoZSBjdXJyZW50IG1hdGVyaWFsLiBUaGlzIGRlZmluZXMgdGhlXG4gICAgICogZm9jdXMgb2YgdGhlIHNwZWN1bGFyIGhpZ2hsaWdodC5cbiAgICAgKlxuICAgICAqIFN0YXRlbWVudDogTnMgYGV4cG9uZW50YFxuICAgICAqXG4gICAgICogRXhhbXBsZTogXCJOcyAyNTBcIlxuICAgICAqXG4gICAgICogYGV4cG9uZW50YCBpcyB0aGUgdmFsdWUgZm9yIHRoZSBzcGVjdWxhciBleHBvbmVudC4gQSBoaWdoIGV4cG9uZW50IHJlc3VsdHNcbiAgICAgKiBpbiBhIHRpZ2h0LCBjb25jZW50cmF0ZWQgaGlnaGxpZ2h0LiBOcyBWYWx1ZXMgbm9ybWFsbHkgcmFuZ2UgZnJvbSAwIHRvXG4gICAgICogMTAwMC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgdGhlIHRva2VucyBhc3NvY2lhdGVkIHdpdGggdGhlIGRpcmVjdGl2ZVxuICAgICAqL1xuICAgIHBhcnNlX05zKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwuc3BlY3VsYXJFeHBvbmVudCA9IHBhcnNlSW50KHRva2Vuc1swXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3BlY2lmaWVzIHRoZSBzaGFycG5lc3Mgb2YgdGhlIHJlZmxlY3Rpb25zIGZyb20gdGhlIGxvY2FsIHJlZmxlY3Rpb24gbWFwLlxuICAgICAqXG4gICAgICogU3RhdGVtZW50OiBzaGFycG5lc3MgYHZhbHVlYFxuICAgICAqXG4gICAgICogRXhhbXBsZTogXCJzaGFycG5lc3MgMTAwXCJcbiAgICAgKlxuICAgICAqIElmIGEgbWF0ZXJpYWwgZG9lcyBub3QgaGF2ZSBhIGxvY2FsIHJlZmxlY3Rpb24gbWFwIGRlZmluZWQgaW4gaXRzIG1hdGVyaWFsXG4gICAgICogZGVmaW50aW9ucywgc2hhcnBuZXNzIHdpbGwgYXBwbHkgdG8gdGhlIGdsb2JhbCByZWZsZWN0aW9uIG1hcCBkZWZpbmVkIGluXG4gICAgICogUHJlVmlldy5cbiAgICAgKlxuICAgICAqIGB2YWx1ZWAgY2FuIGJlIGEgbnVtYmVyIGZyb20gMCB0byAxMDAwLiBUaGUgZGVmYXVsdCBpcyA2MC4gQSBoaWdoIHZhbHVlXG4gICAgICogcmVzdWx0cyBpbiBhIGNsZWFyIHJlZmxlY3Rpb24gb2Ygb2JqZWN0cyBpbiB0aGUgcmVmbGVjdGlvbiBtYXAuXG4gICAgICpcbiAgICAgKiBUaXA6IHNoYXJwbmVzcyB2YWx1ZXMgZ3JlYXRlciB0aGFuIDEwMCBpbnRyb2R1Y2UgYWxpYXNpbmcgZWZmZWN0cyBpblxuICAgICAqIGZsYXQgc3VyZmFjZXMgdGhhdCBhcmUgdmlld2VkIGF0IGEgc2hhcnAgYW5nbGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIHRoZSB0b2tlbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBkaXJlY3RpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9zaGFycG5lc3ModG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5zaGFycG5lc3MgPSBwYXJzZUludCh0b2tlbnNbMF0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgLWNjIGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC1jYyBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX2NjKHZhbHVlczogc3RyaW5nW10sIG9wdGlvbnM6IFRleHR1cmVNYXBEYXRhKSB7XG4gICAgICAgIG9wdGlvbnMuY29sb3JDb3JyZWN0aW9uID0gdmFsdWVzWzBdID09IFwib25cIjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC1ibGVuZHUgZmxhZyBhbmQgdXBkYXRlcyB0aGUgb3B0aW9ucyBvYmplY3Qgd2l0aCB0aGUgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlcyB0aGUgdmFsdWVzIHBhc3NlZCB0byB0aGUgLWJsZW5kdSBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX2JsZW5kdSh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICBvcHRpb25zLmhvcml6b250YWxCbGVuZGluZyA9IHZhbHVlc1swXSA9PSBcIm9uXCI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSAtYmxlbmR2IGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC1ibGVuZHYgZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV9ibGVuZHYodmFsdWVzOiBzdHJpbmdbXSwgb3B0aW9uczogVGV4dHVyZU1hcERhdGEpIHtcbiAgICAgICAgb3B0aW9ucy52ZXJ0aWNhbEJsZW5kaW5nID0gdmFsdWVzWzBdID09IFwib25cIjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC1ib29zdCBmbGFnIGFuZCB1cGRhdGVzIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtYm9vc3QgZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV9ib29zdCh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICBvcHRpb25zLmJvb3N0TWlwTWFwU2hhcnBuZXNzID0gcGFyc2VGbG9hdCh2YWx1ZXNbMF0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgLW1tIGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC1tbSBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX21tKHZhbHVlczogc3RyaW5nW10sIG9wdGlvbnM6IFRleHR1cmVNYXBEYXRhKSB7XG4gICAgICAgIG9wdGlvbnMubW9kaWZ5VGV4dHVyZU1hcC5icmlnaHRuZXNzID0gcGFyc2VGbG9hdCh2YWx1ZXNbMF0pO1xuICAgICAgICBvcHRpb25zLm1vZGlmeVRleHR1cmVNYXAuY29udHJhc3QgPSBwYXJzZUZsb2F0KHZhbHVlc1sxXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIGFuZCBzZXRzIHRoZSAtbywgLXMsIGFuZCAtdCAgdSwgdiwgYW5kIHcgdmFsdWVzXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtbywgLXMsIC10IGZsYWdcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uIHRoZSBPYmplY3Qgb2YgZWl0aGVyIHRoZSAtbywgLXMsIC10IG9wdGlvblxuICAgICAqIEBwYXJhbSB7SW50ZWdlcn0gZGVmYXVsdFZhbHVlIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV9vc3QodmFsdWVzOiBzdHJpbmdbXSwgb3B0aW9uOiBVVlcsIGRlZmF1bHRWYWx1ZTogbnVtYmVyKSB7XG4gICAgICAgIHdoaWxlICh2YWx1ZXMubGVuZ3RoIDwgMykge1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goZGVmYXVsdFZhbHVlLnRvU3RyaW5nKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9uLnUgPSBwYXJzZUZsb2F0KHZhbHVlc1swXSk7XG4gICAgICAgIG9wdGlvbi52ID0gcGFyc2VGbG9hdCh2YWx1ZXNbMV0pO1xuICAgICAgICBvcHRpb24udyA9IHBhcnNlRmxvYXQodmFsdWVzWzJdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC1vIGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC1vIGZsYWdcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgT2JqZWN0IG9mIGFsbCBpbWFnZSBvcHRpb25zXG4gICAgICovXG4gICAgcGFyc2Vfbyh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICB0aGlzLnBhcnNlX29zdCh2YWx1ZXMsIG9wdGlvbnMub2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC1zIGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC1zIGZsYWdcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgT2JqZWN0IG9mIGFsbCBpbWFnZSBvcHRpb25zXG4gICAgICovXG4gICAgcGFyc2Vfcyh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICB0aGlzLnBhcnNlX29zdCh2YWx1ZXMsIG9wdGlvbnMuc2NhbGUsIDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgLXQgZmxhZyBhbmQgdXBkYXRlcyB0aGUgb3B0aW9ucyBvYmplY3Qgd2l0aCB0aGUgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlcyB0aGUgdmFsdWVzIHBhc3NlZCB0byB0aGUgLXQgZmxhZ1xuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBPYmplY3Qgb2YgYWxsIGltYWdlIG9wdGlvbnNcbiAgICAgKi9cbiAgICBwYXJzZV90KHZhbHVlczogc3RyaW5nW10sIG9wdGlvbnM6IFRleHR1cmVNYXBEYXRhKSB7XG4gICAgICAgIHRoaXMucGFyc2Vfb3N0KHZhbHVlcywgb3B0aW9ucy50dXJidWxlbmNlLCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIC10ZXhyZXMgZmxhZyBhbmQgdXBkYXRlcyB0aGUgb3B0aW9ucyBvYmplY3Qgd2l0aCB0aGUgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlcyB0aGUgdmFsdWVzIHBhc3NlZCB0byB0aGUgLXRleHJlcyBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX3RleHJlcyh2YWx1ZXM6IHN0cmluZ1tdLCBvcHRpb25zOiBUZXh0dXJlTWFwRGF0YSkge1xuICAgICAgICBvcHRpb25zLnRleHR1cmVSZXNvbHV0aW9uID0gcGFyc2VGbG9hdCh2YWx1ZXNbMF0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgLWNsYW1wIGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC1jbGFtcCBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX2NsYW1wKHZhbHVlczogc3RyaW5nW10sIG9wdGlvbnM6IFRleHR1cmVNYXBEYXRhKSB7XG4gICAgICAgIG9wdGlvbnMuY2xhbXAgPSB2YWx1ZXNbMF0gPT0gXCJvblwiO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgLWJtIGZsYWcgYW5kIHVwZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZXMgdGhlIHZhbHVlcyBwYXNzZWQgdG8gdGhlIC1ibSBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX2JtKHZhbHVlczogc3RyaW5nW10sIG9wdGlvbnM6IFRleHR1cmVNYXBEYXRhKSB7XG4gICAgICAgIG9wdGlvbnMuYnVtcE11bHRpcGxpZXIgPSBwYXJzZUZsb2F0KHZhbHVlc1swXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSAtaW1mY2hhbiBmbGFnIGFuZCB1cGRhdGVzIHRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHRoZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtaW1mY2hhbiBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX2ltZmNoYW4odmFsdWVzOiBzdHJpbmdbXSwgb3B0aW9uczogVGV4dHVyZU1hcERhdGEpIHtcbiAgICAgICAgb3B0aW9ucy5pbWZDaGFuID0gdmFsdWVzWzBdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgb25seSBleGlzdHMgZm9yIHJlbGVjdGlvbiBtYXBzIGFuZCBkZW5vdGVzIHRoZSB0eXBlIG9mIHJlZmxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWVzIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSAtdHlwZSBmbGFnXG4gICAgICogQHBhcmFtIG9wdGlvbnMgdGhlIE9iamVjdCBvZiBhbGwgaW1hZ2Ugb3B0aW9uc1xuICAgICAqL1xuICAgIHBhcnNlX3R5cGUodmFsdWVzOiBzdHJpbmdbXSwgb3B0aW9uczogVGV4dHVyZU1hcERhdGEpIHtcbiAgICAgICAgb3B0aW9ucy5yZWZsZWN0aW9uVHlwZSA9IHZhbHVlc1swXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIHRleHR1cmUncyBvcHRpb25zIGFuZCByZXR1cm5zIGFuIG9wdGlvbnMgb2JqZWN0IHdpdGggdGhlIGluZm9cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgYWxsIG9mIHRoZSBvcHRpb24gdG9rZW5zIHRvIHBhc3MgdG8gdGhlIHRleHR1cmVcbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IGEgY29tcGxldGUgb2JqZWN0IG9mIG9iamVjdHMgdG8gYXBwbHkgdG8gdGhlIHRleHR1cmVcbiAgICAgKi9cbiAgICBwYXJzZU9wdGlvbnModG9rZW5zOiBzdHJpbmdbXSk6IFRleHR1cmVNYXBEYXRhIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGVtcHR5VGV4dHVyZU9wdGlvbnMoKTtcblxuICAgICAgICBsZXQgb3B0aW9uO1xuICAgICAgICBsZXQgdmFsdWVzO1xuICAgICAgICBjb25zdCBvcHRpb25zVG9WYWx1ZXM6IHsgW2s6IHN0cmluZ106IHN0cmluZ1tdIH0gPSB7fTtcblxuICAgICAgICB0b2tlbnMucmV2ZXJzZSgpO1xuXG4gICAgICAgIHdoaWxlICh0b2tlbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAvLyB0b2tlbiBpcyBndWFyYW50ZWVkIHRvIGV4aXN0cyBoZXJlLCBoZW5jZSB0aGUgZXhwbGljaXQgXCJhc1wiXG4gICAgICAgICAgICBjb25zdCB0b2tlbiA9IHRva2Vucy5wb3AoKSBhcyBzdHJpbmc7XG5cbiAgICAgICAgICAgIGlmICh0b2tlbi5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgICAgICAgICAgIG9wdGlvbiA9IHRva2VuLnN1YnN0cigxKTtcbiAgICAgICAgICAgICAgICBvcHRpb25zVG9WYWx1ZXNbb3B0aW9uXSA9IFtdO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChvcHRpb24pIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zVG9WYWx1ZXNbb3B0aW9uXS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAob3B0aW9uIGluIG9wdGlvbnNUb1ZhbHVlcykge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zVG9WYWx1ZXMuaGFzT3duUHJvcGVydHkob3B0aW9uKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFsdWVzID0gb3B0aW9uc1RvVmFsdWVzW29wdGlvbl07XG4gICAgICAgICAgICBjb25zdCBvcHRpb25NZXRob2QgPSAodGhpcyBhcyBhbnkpW2BwYXJzZV8ke29wdGlvbn1gXTtcbiAgICAgICAgICAgIGlmIChvcHRpb25NZXRob2QpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25NZXRob2QuYmluZCh0aGlzKSh2YWx1ZXMsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBnaXZlbiB0ZXh0dXJlIG1hcCBsaW5lLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyBhbGwgb2YgdGhlIHRva2VucyByZXByZXNlbnRpbmcgdGhlIHRleHR1cmVcbiAgICAgKiBAcmV0dXJuIGEgY29tcGxldGUgb2JqZWN0IG9mIG9iamVjdHMgdG8gYXBwbHkgdG8gdGhlIHRleHR1cmVcbiAgICAgKi9cbiAgICBwYXJzZU1hcCh0b2tlbnM6IHN0cmluZ1tdKTogVGV4dHVyZU1hcERhdGEge1xuICAgICAgICAvLyBhY2NvcmRpbmcgdG8gd2lraXBlZGlhOlxuICAgICAgICAvLyAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvV2F2ZWZyb250Xy5vYmpfZmlsZSNWZW5kb3Jfc3BlY2lmaWNfYWx0ZXJhdGlvbnMpXG4gICAgICAgIC8vIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSB2ZW5kb3IgdGhhdCBwbGFjZXMgdGhlIGZpbGVuYW1lIGJlZm9yZSB0aGUgb3B0aW9uc1xuICAgICAgICAvLyByYXRoZXIgdGhhbiBhZnRlciAod2hpY2ggaXMgdG8gc3BlYykuIEFsbCBvcHRpb25zIHN0YXJ0IHdpdGggYSAnLSdcbiAgICAgICAgLy8gc28gaWYgdGhlIGZpcnN0IHRva2VuIGRvZXNuJ3Qgc3RhcnQgd2l0aCBhICctJywgd2UncmUgZ29pbmcgdG8gYXNzdW1lXG4gICAgICAgIC8vIGl0J3MgdGhlIG5hbWUgb2YgdGhlIG1hcCBmaWxlLlxuICAgICAgICBsZXQgb3B0aW9uc1N0cmluZztcbiAgICAgICAgbGV0IGZpbGVuYW1lID0gXCJcIjtcbiAgICAgICAgaWYgKCF0b2tlbnNbMF0uc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgICAgICAgIFtmaWxlbmFtZSwgLi4ub3B0aW9uc1N0cmluZ10gPSB0b2tlbnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmaWxlbmFtZSA9IHRva2Vucy5wb3AoKSBhcyBzdHJpbmc7XG4gICAgICAgICAgICBvcHRpb25zU3RyaW5nID0gdG9rZW5zO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMucGFyc2VPcHRpb25zKG9wdGlvbnNTdHJpbmcpO1xuICAgICAgICBvcHRpb25zLmZpbGVuYW1lID0gZmlsZW5hbWUucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG5cbiAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBhbWJpZW50IG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgbGlzdCBvZiB0b2tlbnMgZm9yIHRoZSBtYXBfS2EgZGlyZWNpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9tYXBfS2EodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5tYXBBbWJpZW50ID0gdGhpcy5wYXJzZU1hcCh0b2tlbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgZGlmZnVzZSBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgbWFwX0tkIGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfbWFwX0tkKHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwubWFwRGlmZnVzZSA9IHRoaXMucGFyc2VNYXAodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIHNwZWN1bGFyIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgbGlzdCBvZiB0b2tlbnMgZm9yIHRoZSBtYXBfS3MgZGlyZWNpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9tYXBfS3ModG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5tYXBTcGVjdWxhciA9IHRoaXMucGFyc2VNYXAodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIGVtaXNzaXZlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgbGlzdCBvZiB0b2tlbnMgZm9yIHRoZSBtYXBfS2UgZGlyZWNpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9tYXBfS2UodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5tYXBFbWlzc2l2ZSA9IHRoaXMucGFyc2VNYXAodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIHNwZWN1bGFyIGV4cG9uZW50IG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgbGlzdCBvZiB0b2tlbnMgZm9yIHRoZSBtYXBfTnMgZGlyZWNpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9tYXBfTnModG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5tYXBTcGVjdWxhckV4cG9uZW50ID0gdGhpcy5wYXJzZU1hcCh0b2tlbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgZGlzc29sdmUgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyBsaXN0IG9mIHRva2VucyBmb3IgdGhlIG1hcF9kIGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfbWFwX2QodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5tYXBEaXNzb2x2ZSA9IHRoaXMucGFyc2VNYXAodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIGFudGktYWxpYXNpbmcgb3B0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyBsaXN0IG9mIHRva2VucyBmb3IgdGhlIG1hcF9hYXQgZGlyZWNpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9tYXBfYWF0KHRva2Vuczogc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TWF0ZXJpYWwuYW50aUFsaWFzaW5nID0gdG9rZW5zWzBdID09IFwib25cIjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIGJ1bXAgbWFwLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRva2VucyBsaXN0IG9mIHRva2VucyBmb3IgdGhlIG1hcF9idW1wIGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfbWFwX2J1bXAodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5tYXBCdW1wID0gdGhpcy5wYXJzZU1hcCh0b2tlbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgYnVtcCBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgYnVtcCBkaXJlY2l2ZVxuICAgICAqL1xuICAgIHBhcnNlX2J1bXAodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLnBhcnNlX21hcF9idW1wKHRva2Vucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBkaXNwIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgbGlzdCBvZiB0b2tlbnMgZm9yIHRoZSBkaXNwIGRpcmVjaXZlXG4gICAgICovXG4gICAgcGFyc2VfZGlzcCh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLm1hcERpc3BsYWNlbWVudCA9IHRoaXMucGFyc2VNYXAodG9rZW5zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZXMgdGhlIGRlY2FsIG1hcC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2tlbnMgbGlzdCBvZiB0b2tlbnMgZm9yIHRoZSBtYXBfZGVjYWwgZGlyZWNpdmVcbiAgICAgKi9cbiAgICBwYXJzZV9kZWNhbCh0b2tlbnM6IHN0cmluZ1tdKSB7XG4gICAgICAgIHRoaXMuY3VycmVudE1hdGVyaWFsLm1hcERlY2FsID0gdGhpcy5wYXJzZU1hcCh0b2tlbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyB0aGUgcmVmbCBtYXAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9rZW5zIGxpc3Qgb2YgdG9rZW5zIGZvciB0aGUgcmVmbCBkaXJlY2l2ZVxuICAgICAqL1xuICAgIHBhcnNlX3JlZmwodG9rZW5zOiBzdHJpbmdbXSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbC5tYXBSZWZsZWN0aW9ucy5wdXNoKHRoaXMucGFyc2VNYXAodG9rZW5zKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFyc2VzIHRoZSBNVEwgZmlsZS5cbiAgICAgKlxuICAgICAqIEl0ZXJhdGVzIGxpbmUgYnkgbGluZSBwYXJzaW5nIGVhY2ggTVRMIGRpcmVjdGl2ZS5cbiAgICAgKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gZXhwZWN0cyB0aGUgZmlyc3QgdG9rZW4gaW4gdGhlIGxpbmVcbiAgICAgKiB0byBiZSBhIHZhbGlkIE1UTCBkaXJlY3RpdmUuIFRoYXQgdG9rZW4gaXMgdGhlbiB1c2VkXG4gICAgICogdG8gdHJ5IGFuZCBydW4gYSBtZXRob2Qgb24gdGhpcyBjbGFzcy4gcGFyc2VfW2RpcmVjdGl2ZV1cbiAgICAgKiBFLmcuLCB0aGUgYG5ld210bGAgZGlyZWN0aXZlIHdvdWxkIHRyeSB0byBjYWxsIHRoZSBtZXRob2RcbiAgICAgKiBwYXJzZV9uZXdtdGwuIEVhY2ggcGFyc2luZyBmdW5jdGlvbiB0YWtlcyBpbiB0aGUgcmVtYWluaW5nXG4gICAgICogbGlzdCBvZiB0b2tlbnMgYW5kIHVwZGF0ZXMgdGhlIGN1cnJlbnRNYXRlcmlhbCBjbGFzcyB3aXRoXG4gICAgICogdGhlIGF0dHJpYnV0ZXMgcHJvdmlkZWQuXG4gICAgICovXG4gICAgcGFyc2UoKSB7XG4gICAgICAgIGNvbnN0IGxpbmVzID0gdGhpcy5kYXRhLnNwbGl0KC9cXHI/XFxuLyk7XG4gICAgICAgIGZvciAobGV0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgICAgICAgIGxpbmUgPSBsaW5lLnRyaW0oKTtcbiAgICAgICAgICAgIGlmICghbGluZSB8fCBsaW5lLnN0YXJ0c1dpdGgoXCIjXCIpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IFtkaXJlY3RpdmUsIC4uLnRva2Vuc10gPSBsaW5lLnNwbGl0KC9cXHMvKTtcblxuICAgICAgICAgICAgY29uc3QgcGFyc2VNZXRob2QgPSAodGhpcyBhcyBhbnkpW2BwYXJzZV8ke2RpcmVjdGl2ZX1gXTtcblxuICAgICAgICAgICAgaWYgKCFwYXJzZU1ldGhvZCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgRG9uJ3Qga25vdyBob3cgdG8gcGFyc2UgdGhlIGRpcmVjdGl2ZTogXCIke2RpcmVjdGl2ZX1cImApO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgUGFyc2luZyBcIiR7ZGlyZWN0aXZlfVwiIHdpdGggdG9rZW5zOiAke3Rva2Vuc31gKTtcbiAgICAgICAgICAgIHBhcnNlTWV0aG9kLmJpbmQodGhpcykodG9rZW5zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNvbWUgY2xlYW51cC4gVGhlc2UgZG9uJ3QgbmVlZCB0byBiZSBleHBvc2VkIGFzIHB1YmxpYyBkYXRhLlxuICAgICAgICBkZWxldGUgdGhpcy5kYXRhO1xuICAgICAgICB0aGlzLmN1cnJlbnRNYXRlcmlhbCA9IFNFTlRJTkVMX01BVEVSSUFMO1xuICAgIH1cblxuICAgIC8qIGVzbGludC1lbmFibGUgY2FtZWxjYXNlKi9cbn1cblxuZnVuY3Rpb24gZW1wdHlUZXh0dXJlT3B0aW9ucygpOiBUZXh0dXJlTWFwRGF0YSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29sb3JDb3JyZWN0aW9uOiBmYWxzZSxcbiAgICAgICAgaG9yaXpvbnRhbEJsZW5kaW5nOiB0cnVlLFxuICAgICAgICB2ZXJ0aWNhbEJsZW5kaW5nOiB0cnVlLFxuICAgICAgICBib29zdE1pcE1hcFNoYXJwbmVzczogMCxcbiAgICAgICAgbW9kaWZ5VGV4dHVyZU1hcDoge1xuICAgICAgICAgICAgYnJpZ2h0bmVzczogMCxcbiAgICAgICAgICAgIGNvbnRyYXN0OiAxLFxuICAgICAgICB9LFxuICAgICAgICBvZmZzZXQ6IHsgdTogMCwgdjogMCwgdzogMCB9LFxuICAgICAgICBzY2FsZTogeyB1OiAxLCB2OiAxLCB3OiAxIH0sXG4gICAgICAgIHR1cmJ1bGVuY2U6IHsgdTogMCwgdjogMCwgdzogMCB9LFxuICAgICAgICBjbGFtcDogZmFsc2UsXG4gICAgICAgIHRleHR1cmVSZXNvbHV0aW9uOiBudWxsLFxuICAgICAgICBidW1wTXVsdGlwbGllcjogMSxcbiAgICAgICAgaW1mQ2hhbjogbnVsbCxcbiAgICAgICAgZmlsZW5hbWU6IFwiXCIsXG4gICAgfTtcbn1cbiIsImltcG9ydCB7IExheW91dCB9IGZyb20gXCIuL2xheW91dFwiO1xuaW1wb3J0IHsgTWF0ZXJpYWwsIE1hdGVyaWFsTGlicmFyeSB9IGZyb20gXCIuL21hdGVyaWFsXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVzaE9wdGlvbnMge1xuICAgIGVuYWJsZVdUZXh0dXJlQ29vcmQ/OiBib29sZWFuO1xuICAgIGNhbGNUYW5nZW50c0FuZEJpdGFuZ2VudHM/OiBib29sZWFuO1xuICAgIG1hdGVyaWFscz86IHsgW2tleTogc3RyaW5nXTogTWF0ZXJpYWwgfTtcbn1cblxuaW50ZXJmYWNlIFVucGFja2VkQXR0cnMge1xuICAgIHZlcnRzOiBudW1iZXJbXTtcbiAgICBub3JtczogbnVtYmVyW107XG4gICAgdGV4dHVyZXM6IG51bWJlcltdO1xuICAgIGhhc2hpbmRpY2VzOiB7IFtrOiBzdHJpbmddOiBudW1iZXIgfTtcbiAgICBpbmRpY2VzOiBudW1iZXJbXVtdO1xuICAgIG1hdGVyaWFsSW5kaWNlczogbnVtYmVyW107XG4gICAgaW5kZXg6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNYXRlcmlhbE5hbWVUb0luZGV4IHtcbiAgICBbazogc3RyaW5nXTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEluZGV4VG9NYXRlcmlhbCB7XG4gICAgW2s6IG51bWJlcl06IE1hdGVyaWFsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5QnVmZmVyV2l0aEl0ZW1TaXplIGV4dGVuZHMgQXJyYXlCdWZmZXIge1xuICAgIG51bUl0ZW1zPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVpbnQxNkFycmF5V2l0aEl0ZW1TaXplIGV4dGVuZHMgVWludDE2QXJyYXkge1xuICAgIG51bUl0ZW1zPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBtYWluIE1lc2ggY2xhc3MuIFRoZSBjb25zdHJ1Y3RvciB3aWxsIHBhcnNlIHRocm91Z2ggdGhlIE9CSiBmaWxlIGRhdGFcbiAqIGFuZCBjb2xsZWN0IHRoZSB2ZXJ0ZXgsIHZlcnRleCBub3JtYWwsIHRleHR1cmUsIGFuZCBmYWNlIGluZm9ybWF0aW9uLiBUaGlzXG4gKiBpbmZvcm1hdGlvbiBjYW4gdGhlbiBiZSB1c2VkIGxhdGVyIG9uIHdoZW4gY3JlYXRpbmcgeW91ciBWQk9zLiBTZWVcbiAqIE9CSi5pbml0TWVzaEJ1ZmZlcnMgZm9yIGFuIGV4YW1wbGUgb2YgaG93IHRvIHVzZSB0aGUgbmV3bHkgY3JlYXRlZCBNZXNoXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1lc2gge1xuICAgIHB1YmxpYyB2ZXJ0aWNlczogbnVtYmVyW107XG4gICAgcHVibGljIHZlcnRleE5vcm1hbHM6IG51bWJlcltdO1xuICAgIHB1YmxpYyB0ZXh0dXJlczogbnVtYmVyW107XG4gICAgcHVibGljIGluZGljZXM6IG51bWJlcltdO1xuICAgIHB1YmxpYyBuYW1lOiBzdHJpbmcgPSBcIlwiO1xuICAgIHB1YmxpYyB2ZXJ0ZXhNYXRlcmlhbEluZGljZXM6IG51bWJlcltdO1xuICAgIHB1YmxpYyBpbmRpY2VzUGVyTWF0ZXJpYWw6IG51bWJlcltdW10gPSBbXTtcbiAgICBwdWJsaWMgbWF0ZXJpYWxOYW1lczogc3RyaW5nW107XG4gICAgcHVibGljIG1hdGVyaWFsSW5kaWNlczogTWF0ZXJpYWxOYW1lVG9JbmRleDtcbiAgICBwdWJsaWMgbWF0ZXJpYWxzQnlJbmRleDogSW5kZXhUb01hdGVyaWFsID0ge307XG4gICAgcHVibGljIHRhbmdlbnRzOiBudW1iZXJbXSA9IFtdO1xuICAgIHB1YmxpYyBiaXRhbmdlbnRzOiBudW1iZXJbXSA9IFtdO1xuICAgIHB1YmxpYyB0ZXh0dXJlU3RyaWRlOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBNZXNoXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG9iamVjdERhdGEgLSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhbiBPQkogZmlsZSB3aXRoXG4gICAgICogICAgIG5ld2xpbmVzIHByZXNlcnZlZC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIGEgSlMgb2JqZWN0IGNvbnRhaW5pbmcgdmFsaWQgb3B0aW9ucy4gU2VlIGNsYXNzXG4gICAgICogICAgIGRvY3VtZW50YXRpb24gZm9yIG9wdGlvbnMuXG4gICAgICogQHBhcmFtIHtib29sfSBvcHRpb25zLmVuYWJsZVdUZXh0dXJlQ29vcmQgLSBUZXh0dXJlIGNvb3JkaW5hdGVzIGNhbiBoYXZlXG4gICAgICogICAgIGFuIG9wdGlvbmFsIFwid1wiIGNvb3JkaW5hdGUgYWZ0ZXIgdGhlIHUgYW5kIHYgY29vcmRpbmF0ZXMuIFRoaXMgZXh0cmFcbiAgICAgKiAgICAgdmFsdWUgY2FuIGJlIHVzZWQgaW4gb3JkZXIgdG8gcGVyZm9ybSBmYW5jeSB0cmFuc2Zvcm1hdGlvbnMgb24gdGhlXG4gICAgICogICAgIHRleHR1cmVzIHRoZW1zZWx2ZXMuIERlZmF1bHQgaXMgdG8gdHJ1bmNhdGUgdG8gb25seSB0aGUgdSBhbiB2XG4gICAgICogICAgIGNvb3JkaW5hdGVzLiBQYXNzaW5nIHRydWUgd2lsbCBwcm92aWRlIGEgZGVmYXVsdCB2YWx1ZSBvZiAwIGluIHRoZVxuICAgICAqICAgICBldmVudCB0aGF0IGFueSBvciBhbGwgdGV4dHVyZSBjb29yZGluYXRlcyBkb24ndCBwcm92aWRlIGEgdyB2YWx1ZS5cbiAgICAgKiAgICAgQWx3YXlzIHVzZSB0aGUgdGV4dHVyZVN0cmlkZSBhdHRyaWJ1dGUgaW4gb3JkZXIgdG8gZGV0ZXJtaW5lIHRoZVxuICAgICAqICAgICBzdHJpZGUgbGVuZ3RoIG9mIHRoZSB0ZXh0dXJlIGNvb3JkaW5hdGVzIHdoZW4gcmVuZGVyaW5nIHRoZSBlbGVtZW50XG4gICAgICogICAgIGFycmF5LlxuICAgICAqIEBwYXJhbSB7Ym9vbH0gb3B0aW9ucy5jYWxjVGFuZ2VudHNBbmRCaXRhbmdlbnRzIC0gQ2FsY3VsYXRlIHRoZSB0YW5nZW50c1xuICAgICAqICAgICBhbmQgYml0YW5nZW50cyB3aGVuIGxvYWRpbmcgb2YgdGhlIE9CSiBpcyBjb21wbGV0ZWQuIFRoaXMgYWRkcyB0d28gbmV3XG4gICAgICogICAgIGF0dHJpYnV0ZXMgdG8gdGhlIE1lc2ggaW5zdGFuY2U6IGB0YW5nZW50c2AgYW5kIGBiaXRhbmdlbnRzYC5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvYmplY3REYXRhOiBzdHJpbmcsIG9wdGlvbnM/OiBNZXNoT3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICAgICAgb3B0aW9ucy5tYXRlcmlhbHMgPSBvcHRpb25zLm1hdGVyaWFscyB8fCB7fTtcbiAgICAgICAgb3B0aW9ucy5lbmFibGVXVGV4dHVyZUNvb3JkID0gISFvcHRpb25zLmVuYWJsZVdUZXh0dXJlQ29vcmQ7XG5cbiAgICAgICAgLy8gdGhlIGxpc3Qgb2YgdW5pcXVlIHZlcnRleCwgbm9ybWFsLCB0ZXh0dXJlLCBhdHRyaWJ1dGVzXG4gICAgICAgIHRoaXMudmVydGV4Tm9ybWFscyA9IFtdO1xuICAgICAgICB0aGlzLnRleHR1cmVzID0gW107XG4gICAgICAgIC8vIHRoZSBpbmRpY2llcyB0byBkcmF3IHRoZSBmYWNlc1xuICAgICAgICB0aGlzLmluZGljZXMgPSBbXTtcbiAgICAgICAgdGhpcy50ZXh0dXJlU3RyaWRlID0gb3B0aW9ucy5lbmFibGVXVGV4dHVyZUNvb3JkID8gMyA6IDI7XG5cbiAgICAgICAgLypcbiAgICAgICAgVGhlIE9CSiBmaWxlIGZvcm1hdCBkb2VzIGEgc29ydCBvZiBjb21wcmVzc2lvbiB3aGVuIHNhdmluZyBhIG1vZGVsIGluIGFcbiAgICAgICAgcHJvZ3JhbSBsaWtlIEJsZW5kZXIuIFRoZXJlIGFyZSBhdCBsZWFzdCAzIHNlY3Rpb25zICg0IGluY2x1ZGluZyB0ZXh0dXJlcylcbiAgICAgICAgd2l0aGluIHRoZSBmaWxlLiBFYWNoIGxpbmUgaW4gYSBzZWN0aW9uIGJlZ2lucyB3aXRoIHRoZSBzYW1lIHN0cmluZzpcbiAgICAgICAgICAqICd2JzogaW5kaWNhdGVzIHZlcnRleCBzZWN0aW9uXG4gICAgICAgICAgKiAndm4nOiBpbmRpY2F0ZXMgdmVydGV4IG5vcm1hbCBzZWN0aW9uXG4gICAgICAgICAgKiAnZic6IGluZGljYXRlcyB0aGUgZmFjZXMgc2VjdGlvblxuICAgICAgICAgICogJ3Z0JzogaW5kaWNhdGVzIHZlcnRleCB0ZXh0dXJlIHNlY3Rpb24gKGlmIHRleHR1cmVzIHdlcmUgdXNlZCBvbiB0aGUgbW9kZWwpXG4gICAgICAgIEVhY2ggb2YgdGhlIGFib3ZlIHNlY3Rpb25zIChleGNlcHQgZm9yIHRoZSBmYWNlcyBzZWN0aW9uKSBpcyBhIGxpc3Qvc2V0IG9mXG4gICAgICAgIHVuaXF1ZSB2ZXJ0aWNlcy5cblxuICAgICAgICBFYWNoIGxpbmUgb2YgdGhlIGZhY2VzIHNlY3Rpb24gY29udGFpbnMgYSBsaXN0IG9mXG4gICAgICAgICh2ZXJ0ZXgsIFt0ZXh0dXJlXSwgbm9ybWFsKSBncm91cHMuXG5cbiAgICAgICAgKipOb3RlOioqIFRoZSBmb2xsb3dpbmcgZG9jdW1lbnRhdGlvbiB3aWxsIHVzZSBhIGNhcGl0YWwgXCJWXCIgVmVydGV4IHRvXG4gICAgICAgIGRlbm90ZSB0aGUgYWJvdmUgKHZlcnRleCwgW3RleHR1cmVdLCBub3JtYWwpIGdyb3VwcyB3aGVyZWFzIGEgbG93ZXJjYXNlXG4gICAgICAgIFwidlwiIHZlcnRleCBpcyB1c2VkIHRvIGRlbm90ZSBhbiBYLCBZLCBaIGNvb3JkaW5hdGUuXG5cbiAgICAgICAgU29tZSBleGFtcGxlczpcbiAgICAgICAgICAgIC8vIHRoZSB0ZXh0dXJlIGluZGV4IGlzIG9wdGlvbmFsLCBib3RoIGZvcm1hdHMgYXJlIHBvc3NpYmxlIGZvciBtb2RlbHNcbiAgICAgICAgICAgIC8vIHdpdGhvdXQgYSB0ZXh0dXJlIGFwcGxpZWRcbiAgICAgICAgICAgIGYgMS8yNSAxOC80NiAxMi8zMVxuICAgICAgICAgICAgZiAxLy8yNSAxOC8vNDYgMTIvLzMxXG5cbiAgICAgICAgICAgIC8vIEEgMyB2ZXJ0ZXggZmFjZSB3aXRoIHRleHR1cmUgaW5kaWNlc1xuICAgICAgICAgICAgZiAxNi85Mi8xMSAxNC8xMDEvMjIgMS82OS8xXG5cbiAgICAgICAgICAgIC8vIEEgNCB2ZXJ0ZXggZmFjZVxuICAgICAgICAgICAgZiAxNi85Mi8xMSA0MC8xMDkvNDAgMzgvMTE0LzM4IDE0LzEwMS8yMlxuXG4gICAgICAgIFRoZSBmaXJzdCB0d28gbGluZXMgYXJlIGV4YW1wbGVzIG9mIGEgMyB2ZXJ0ZXggZmFjZSB3aXRob3V0IGEgdGV4dHVyZSBhcHBsaWVkLlxuICAgICAgICBUaGUgc2Vjb25kIGlzIGFuIGV4YW1wbGUgb2YgYSAzIHZlcnRleCBmYWNlIHdpdGggYSB0ZXh0dXJlIGFwcGxpZWQuXG4gICAgICAgIFRoZSB0aGlyZCBpcyBhbiBleGFtcGxlIG9mIGEgNCB2ZXJ0ZXggZmFjZS4gTm90ZTogYSBmYWNlIGNhbiBjb250YWluIE5cbiAgICAgICAgbnVtYmVyIG9mIHZlcnRpY2VzLlxuXG4gICAgICAgIEVhY2ggbnVtYmVyIHRoYXQgYXBwZWFycyBpbiBvbmUgb2YgdGhlIGdyb3VwcyBpcyBhIDEtYmFzZWQgaW5kZXhcbiAgICAgICAgY29ycmVzcG9uZGluZyB0byBhbiBpdGVtIGZyb20gdGhlIG90aGVyIHNlY3Rpb25zIChtZWFuaW5nIHRoYXQgaW5kZXhpbmdcbiAgICAgICAgc3RhcnRzIGF0IG9uZSBhbmQgKm5vdCogemVybykuXG5cbiAgICAgICAgRm9yIGV4YW1wbGU6XG4gICAgICAgICAgICBgZiAxNi85Mi8xMWAgaXMgc2F5aW5nIHRvXG4gICAgICAgICAgICAgIC0gdGFrZSB0aGUgMTZ0aCBlbGVtZW50IGZyb20gdGhlIFt2XSB2ZXJ0ZXggYXJyYXlcbiAgICAgICAgICAgICAgLSB0YWtlIHRoZSA5Mm5kIGVsZW1lbnQgZnJvbSB0aGUgW3Z0XSB0ZXh0dXJlIGFycmF5XG4gICAgICAgICAgICAgIC0gdGFrZSB0aGUgMTF0aCBlbGVtZW50IGZyb20gdGhlIFt2bl0gbm9ybWFsIGFycmF5XG4gICAgICAgICAgICBhbmQgdG9nZXRoZXIgdGhleSBtYWtlIGEgdW5pcXVlIHZlcnRleC5cbiAgICAgICAgVXNpbmcgYWxsIDMrIHVuaXF1ZSBWZXJ0aWNlcyBmcm9tIHRoZSBmYWNlIGxpbmUgd2lsbCBwcm9kdWNlIGEgcG9seWdvbi5cblxuICAgICAgICBOb3csIHlvdSBjb3VsZCBqdXN0IGdvIHRocm91Z2ggdGhlIE9CSiBmaWxlIGFuZCBjcmVhdGUgYSBuZXcgdmVydGV4IGZvclxuICAgICAgICBlYWNoIGZhY2UgbGluZSBhbmQgV2ViR0wgd2lsbCBkcmF3IHdoYXQgYXBwZWFycyB0byBiZSB0aGUgc2FtZSBtb2RlbC5cbiAgICAgICAgSG93ZXZlciwgdmVydGljZXMgd2lsbCBiZSBvdmVybGFwcGVkIGFuZCBkdXBsaWNhdGVkIGFsbCBvdmVyIHRoZSBwbGFjZS5cblxuICAgICAgICBDb25zaWRlciBhIGN1YmUgaW4gM0Qgc3BhY2UgY2VudGVyZWQgYWJvdXQgdGhlIG9yaWdpbiBhbmQgZWFjaCBzaWRlIGlzXG4gICAgICAgIDIgdW5pdHMgbG9uZy4gVGhlIGZyb250IGZhY2UgKHdpdGggdGhlIHBvc2l0aXZlIFotYXhpcyBwb2ludGluZyB0b3dhcmRzXG4gICAgICAgIHlvdSkgd291bGQgaGF2ZSBhIFRvcCBSaWdodCB2ZXJ0ZXggKGxvb2tpbmcgb3J0aG9nb25hbCB0byBpdHMgbm9ybWFsKVxuICAgICAgICBtYXBwZWQgYXQgKDEsMSwxKSBUaGUgcmlnaHQgZmFjZSB3b3VsZCBoYXZlIGEgVG9wIExlZnQgdmVydGV4IChsb29raW5nXG4gICAgICAgIG9ydGhvZ29uYWwgdG8gaXRzIG5vcm1hbCkgYXQgKDEsMSwxKSBhbmQgdGhlIHRvcCBmYWNlIHdvdWxkIGhhdmUgYSBCb3R0b21cbiAgICAgICAgUmlnaHQgdmVydGV4IChsb29raW5nIG9ydGhvZ29uYWwgdG8gaXRzIG5vcm1hbCkgYXQgKDEsMSwxKS4gRWFjaCBmYWNlXG4gICAgICAgIGhhcyBhIHZlcnRleCBhdCB0aGUgc2FtZSBjb29yZGluYXRlcywgaG93ZXZlciwgdGhyZWUgZGlzdGluY3QgdmVydGljZXNcbiAgICAgICAgd2lsbCBiZSBkcmF3biBhdCB0aGUgc2FtZSBzcG90LlxuXG4gICAgICAgIFRvIHNvbHZlIHRoZSBpc3N1ZSBvZiBkdXBsaWNhdGUgVmVydGljZXMgKHRoZSBgKHZlcnRleCwgW3RleHR1cmVdLCBub3JtYWwpYFxuICAgICAgICBncm91cHMpLCB3aGlsZSBpdGVyYXRpbmcgdGhyb3VnaCB0aGUgZmFjZSBsaW5lcywgd2hlbiBhIGdyb3VwIGlzIGVuY291bnRlcmVkXG4gICAgICAgIHRoZSB3aG9sZSBncm91cCBzdHJpbmcgKCcxNi85Mi8xMScpIGlzIGNoZWNrZWQgdG8gc2VlIGlmIGl0IGV4aXN0cyBpbiB0aGVcbiAgICAgICAgcGFja2VkLmhhc2hpbmRpY2VzIG9iamVjdCwgYW5kIGlmIGl0IGRvZXNuJ3QsIHRoZSBpbmRpY2VzIGl0IHNwZWNpZmllc1xuICAgICAgICBhcmUgdXNlZCB0byBsb29rIHVwIGVhY2ggYXR0cmlidXRlIGluIHRoZSBjb3JyZXNwb25kaW5nIGF0dHJpYnV0ZSBhcnJheXNcbiAgICAgICAgYWxyZWFkeSBjcmVhdGVkLiBUaGUgdmFsdWVzIGFyZSB0aGVuIGNvcGllZCB0byB0aGUgY29ycmVzcG9uZGluZyB1bnBhY2tlZFxuICAgICAgICBhcnJheSAoZmxhdHRlbmVkIHRvIHBsYXkgbmljZSB3aXRoIFdlYkdMJ3MgRUxFTUVOVF9BUlJBWV9CVUZGRVIgaW5kZXhpbmcpLFxuICAgICAgICB0aGUgZ3JvdXAgc3RyaW5nIGlzIGFkZGVkIHRvIHRoZSBoYXNoaW5kaWNlcyBzZXQgYW5kIHRoZSBjdXJyZW50IHVucGFja2VkXG4gICAgICAgIGluZGV4IGlzIHVzZWQgYXMgdGhpcyBoYXNoaW5kaWNlcyB2YWx1ZSBzbyB0aGF0IHRoZSBncm91cCBvZiBlbGVtZW50cyBjYW5cbiAgICAgICAgYmUgcmV1c2VkLiBUaGUgdW5wYWNrZWQgaW5kZXggaXMgaW5jcmVtZW50ZWQuIElmIHRoZSBncm91cCBzdHJpbmcgYWxyZWFkeVxuICAgICAgICBleGlzdHMgaW4gdGhlIGhhc2hpbmRpY2VzIG9iamVjdCwgaXRzIGNvcnJlc3BvbmRpbmcgdmFsdWUgaXMgdGhlIGluZGV4IG9mXG4gICAgICAgIHRoYXQgZ3JvdXAgYW5kIGlzIGFwcGVuZGVkIHRvIHRoZSB1bnBhY2tlZCBpbmRpY2VzIGFycmF5LlxuICAgICAgICovXG4gICAgICAgIGNvbnN0IHZlcnRzID0gW107XG4gICAgICAgIGNvbnN0IHZlcnROb3JtYWxzID0gW107XG4gICAgICAgIGNvbnN0IHRleHR1cmVzID0gW107XG4gICAgICAgIGNvbnN0IG1hdGVyaWFsTmFtZXNCeUluZGV4ID0gW107XG4gICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kaWNlc0J5TmFtZTogTWF0ZXJpYWxOYW1lVG9JbmRleCA9IHt9O1xuICAgICAgICAvLyBrZWVwIHRyYWNrIG9mIHdoYXQgbWF0ZXJpYWwgd2UndmUgc2VlbiBsYXN0XG4gICAgICAgIGxldCBjdXJyZW50TWF0ZXJpYWxJbmRleCA9IC0xO1xuICAgICAgICBsZXQgY3VycmVudE9iamVjdEJ5TWF0ZXJpYWxJbmRleCA9IDA7XG4gICAgICAgIC8vIHVucGFja2luZyBzdHVmZlxuICAgICAgICBjb25zdCB1bnBhY2tlZDogVW5wYWNrZWRBdHRycyA9IHtcbiAgICAgICAgICAgIHZlcnRzOiBbXSxcbiAgICAgICAgICAgIG5vcm1zOiBbXSxcbiAgICAgICAgICAgIHRleHR1cmVzOiBbXSxcbiAgICAgICAgICAgIGhhc2hpbmRpY2VzOiB7fSxcbiAgICAgICAgICAgIGluZGljZXM6IFtbXV0sXG4gICAgICAgICAgICBtYXRlcmlhbEluZGljZXM6IFtdLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgVkVSVEVYX1JFID0gL152XFxzLztcbiAgICAgICAgY29uc3QgTk9STUFMX1JFID0gL152blxccy87XG4gICAgICAgIGNvbnN0IFRFWFRVUkVfUkUgPSAvXnZ0XFxzLztcbiAgICAgICAgY29uc3QgRkFDRV9SRSA9IC9eZlxccy87XG4gICAgICAgIGNvbnN0IFdISVRFU1BBQ0VfUkUgPSAvXFxzKy87XG4gICAgICAgIGNvbnN0IFVTRV9NQVRFUklBTF9SRSA9IC9edXNlbXRsLztcblxuICAgICAgICAvLyBhcnJheSBvZiBsaW5lcyBzZXBhcmF0ZWQgYnkgdGhlIG5ld2xpbmVcbiAgICAgICAgY29uc3QgbGluZXMgPSBvYmplY3REYXRhLnNwbGl0KFwiXFxuXCIpO1xuXG4gICAgICAgIGZvciAobGV0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgICAgICAgIGxpbmUgPSBsaW5lLnRyaW0oKTtcbiAgICAgICAgICAgIGlmICghbGluZSB8fCBsaW5lLnN0YXJ0c1dpdGgoXCIjXCIpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IGxpbmUuc3BsaXQoV0hJVEVTUEFDRV9SRSk7XG4gICAgICAgICAgICBlbGVtZW50cy5zaGlmdCgpO1xuXG4gICAgICAgICAgICBpZiAoVkVSVEVYX1JFLnRlc3QobGluZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIGlzIGEgdmVydGV4XG4gICAgICAgICAgICAgICAgdmVydHMucHVzaCguLi5lbGVtZW50cyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKE5PUk1BTF9SRS50ZXN0KGxpbmUpKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgdGhpcyBpcyBhIHZlcnRleCBub3JtYWxcbiAgICAgICAgICAgICAgICB2ZXJ0Tm9ybWFscy5wdXNoKC4uLmVsZW1lbnRzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoVEVYVFVSRV9SRS50ZXN0KGxpbmUpKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNvb3JkcyA9IGVsZW1lbnRzO1xuICAgICAgICAgICAgICAgIC8vIGJ5IGRlZmF1bHQsIHRoZSBsb2FkZXIgd2lsbCBvbmx5IGxvb2sgYXQgdGhlIFUgYW5kIFZcbiAgICAgICAgICAgICAgICAvLyBjb29yZGluYXRlcyBvZiB0aGUgdnQgZGVjbGFyYXRpb24uIFNvLCB0aGlzIHRydW5jYXRlcyB0aGVcbiAgICAgICAgICAgICAgICAvLyBlbGVtZW50cyB0byBvbmx5IHRob3NlIDIgdmFsdWVzLiBJZiBXIHRleHR1cmUgY29vcmRpbmF0ZVxuICAgICAgICAgICAgICAgIC8vIHN1cHBvcnQgaXMgZW5hYmxlZCwgdGhlbiB0aGUgdGV4dHVyZSBjb29yZGluYXRlIGlzXG4gICAgICAgICAgICAgICAgLy8gZXhwZWN0ZWQgdG8gaGF2ZSB0aHJlZSB2YWx1ZXMgaW4gaXQuXG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA+IDIgJiYgIW9wdGlvbnMuZW5hYmxlV1RleHR1cmVDb29yZCkge1xuICAgICAgICAgICAgICAgICAgICBjb29yZHMgPSBlbGVtZW50cy5zbGljZSgwLCAyKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnRzLmxlbmd0aCA9PT0gMiAmJiBvcHRpb25zLmVuYWJsZVdUZXh0dXJlQ29vcmQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgZm9yIHNvbWUgcmVhc29uIFcgdGV4dHVyZSBjb29yZGluYXRlIHN1cHBvcnQgaXMgZW5hYmxlZFxuICAgICAgICAgICAgICAgICAgICAvLyBhbmQgb25seSB0aGUgVSBhbmQgViBjb29yZGluYXRlcyBhcmUgZ2l2ZW4sIHRoZW4gd2Ugc3VwcGx5XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBkZWZhdWx0IHZhbHVlIG9mIDAgc28gdGhhdCB0aGUgc3RyaWRlIGxlbmd0aCBpcyBjb3JyZWN0XG4gICAgICAgICAgICAgICAgICAgIC8vIHdoZW4gdGhlIHRleHR1cmVzIGFyZSB1bnBhY2tlZCBiZWxvdy5cbiAgICAgICAgICAgICAgICAgICAgY29vcmRzLnB1c2goXCIwXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0ZXh0dXJlcy5wdXNoKC4uLmNvb3Jkcyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFVTRV9NQVRFUklBTF9SRS50ZXN0KGxpbmUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxOYW1lID0gZWxlbWVudHNbMF07XG5cbiAgICAgICAgICAgICAgICAvLyBjaGVjayB0byBzZWUgaWYgd2UndmUgZXZlciBzZWVuIGl0IGJlZm9yZVxuICAgICAgICAgICAgICAgIGlmICghKG1hdGVyaWFsTmFtZSBpbiBtYXRlcmlhbEluZGljZXNCeU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIG5ldyBtYXRlcmlhbCB3ZSd2ZSBuZXZlciBzZWVuXG4gICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsTmFtZXNCeUluZGV4LnB1c2gobWF0ZXJpYWxOYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWxJbmRpY2VzQnlOYW1lW21hdGVyaWFsTmFtZV0gPSBtYXRlcmlhbE5hbWVzQnlJbmRleC5sZW5ndGggLSAxO1xuICAgICAgICAgICAgICAgICAgICAvLyBwdXNoIG5ldyBhcnJheSBpbnRvIGluZGljZXNcbiAgICAgICAgICAgICAgICAgICAgLy8gYWxyZWFkeSBjb250YWlucyBhbiBhcnJheSBhdCBpbmRleCB6ZXJvLCBkb24ndCBhZGRcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGVyaWFsSW5kaWNlc0J5TmFtZVttYXRlcmlhbE5hbWVdID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQuaW5kaWNlcy5wdXNoKFtdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBrZWVwIHRyYWNrIG9mIHRoZSBjdXJyZW50IG1hdGVyaWFsIGluZGV4XG4gICAgICAgICAgICAgICAgY3VycmVudE1hdGVyaWFsSW5kZXggPSBtYXRlcmlhbEluZGljZXNCeU5hbWVbbWF0ZXJpYWxOYW1lXTtcbiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgY3VycmVudCBpbmRleCBhcnJheVxuICAgICAgICAgICAgICAgIGN1cnJlbnRPYmplY3RCeU1hdGVyaWFsSW5kZXggPSBjdXJyZW50TWF0ZXJpYWxJbmRleDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoRkFDRV9SRS50ZXN0KGxpbmUpKSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgdGhpcyBpcyBhIGZhY2VcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgIHNwbGl0IHRoaXMgZmFjZSBpbnRvIGFuIGFycmF5IG9mIFZlcnRleCBncm91cHNcbiAgICAgICAgICAgICAgICBmb3IgZXhhbXBsZTpcbiAgICAgICAgICAgICAgICAgICBmIDE2LzkyLzExIDE0LzEwMS8yMiAxLzY5LzFcbiAgICAgICAgICAgICAgICBiZWNvbWVzOlxuICAgICAgICAgICAgICAgICAgWycxNi85Mi8xMScsICcxNC8xMDEvMjInLCAnMS82OS8xJ107XG4gICAgICAgICAgICAgICAgKi9cblxuICAgICAgICAgICAgICAgIGNvbnN0IHRyaWFuZ2xlcyA9IHRyaWFuZ3VsYXRlKGVsZW1lbnRzKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyaWFuZ2xlIG9mIHRyaWFuZ2xlcykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMCwgZWxlTGVuID0gdHJpYW5nbGUubGVuZ3RoOyBqIDwgZWxlTGVuOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGhhc2ggPSB0cmlhbmdsZVtqXSArIFwiLFwiICsgY3VycmVudE1hdGVyaWFsSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzaCBpbiB1bnBhY2tlZC5oYXNoaW5kaWNlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLmluZGljZXNbY3VycmVudE9iamVjdEJ5TWF0ZXJpYWxJbmRleF0ucHVzaCh1bnBhY2tlZC5oYXNoaW5kaWNlc1toYXNoXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICAgICAgICBFYWNoIGVsZW1lbnQgb2YgdGhlIGZhY2UgbGluZSBhcnJheSBpcyBhIFZlcnRleCB3aGljaCBoYXMgaXRzXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzIGRlbGltaXRlZCBieSBhIGZvcndhcmQgc2xhc2guIFRoaXMgd2lsbCBzZXBhcmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaCBhdHRyaWJ1dGUgaW50byBhbm90aGVyIGFycmF5OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICcxOS85Mi8xMSdcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlY29tZXM6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVydGV4ID0gWycxOScsICc5MicsICcxMSddO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hlcmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJ0ZXhbMF0gaXMgdGhlIHZlcnRleCBpbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRleFsxXSBpcyB0aGUgdGV4dHVyZSBpbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnRleFsyXSBpcyB0aGUgbm9ybWFsIGluZGV4XG4gICAgICAgICAgICAgICAgICAgICAgICAgVGhpbmsgb2YgZmFjZXMgaGF2aW5nIFZlcnRpY2VzIHdoaWNoIGFyZSBjb21wcmlzZWQgb2YgdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcyBsb2NhdGlvbiAodiksIHRleHR1cmUgKHZ0KSwgYW5kIG5vcm1hbCAodm4pLlxuICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVydGV4ID0gdHJpYW5nbGVbal0uc3BsaXQoXCIvXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0J3MgcG9zc2libGUgZm9yIGZhY2VzIHRvIG9ubHkgc3BlY2lmeSB0aGUgdmVydGV4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHRoZSBub3JtYWwuIEluIHRoaXMgY2FzZSwgdmVydGV4IHdpbGwgb25seSBoYXZlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYSBsZW5ndGggb2YgMiBhbmQgbm90IDMgYW5kIHRoZSBub3JtYWwgd2lsbCBiZSB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzZWNvbmQgaXRlbSBpbiB0aGUgbGlzdCB3aXRoIGFuIGluZGV4IG9mIDEuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9ybWFsSW5kZXggPSB2ZXJ0ZXgubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSB2ZXJ0cywgdGV4dHVyZXMsIGFuZCB2ZXJ0Tm9ybWFscyBhcnJheXMgZWFjaCBjb250YWluIGFcbiAgICAgICAgICAgICAgICAgICAgICAgICBmbGF0dGVuZCBhcnJheSBvZiBjb29yZGluYXRlcy5cblxuICAgICAgICAgICAgICAgICAgICAgICAgIEJlY2F1c2UgaXQgZ2V0cyBjb25mdXNpbmcgYnkgcmVmZXJyaW5nIHRvIFZlcnRleCBhbmQgdGhlblxuICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRleCAoYm90aCBhcmUgZGlmZmVyZW50IGluIG15IGRlc2NyaXB0aW9ucykgSSB3aWxsIGV4cGxhaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICB3aGF0J3MgZ29pbmcgb24gdXNpbmcgdGhlIHZlcnRleE5vcm1hbHMgYXJyYXk6XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJ0ZXhbMl0gd2lsbCBjb250YWluIHRoZSBvbmUtYmFzZWQgaW5kZXggb2YgdGhlIHZlcnRleE5vcm1hbHNcbiAgICAgICAgICAgICAgICAgICAgICAgICBzZWN0aW9uICh2bikuIE9uZSBpcyBzdWJ0cmFjdGVkIGZyb20gdGhpcyBpbmRleCBudW1iZXIgdG8gcGxheVxuICAgICAgICAgICAgICAgICAgICAgICAgIG5pY2Ugd2l0aCBqYXZhc2NyaXB0J3MgemVyby1iYXNlZCBhcnJheSBpbmRleGluZy5cblxuICAgICAgICAgICAgICAgICAgICAgICAgIEJlY2F1c2UgdmVydGV4Tm9ybWFsIGlzIGEgZmxhdHRlbmVkIGFycmF5IG9mIHgsIHksIHogdmFsdWVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgIHNpbXBsZSBwb2ludGVyIGFyaXRobWV0aWMgaXMgdXNlZCB0byBza2lwIHRvIHRoZSBzdGFydCBvZiB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJ0ZXhOb3JtYWwsIHRoZW4gdGhlIG9mZnNldCBpcyBhZGRlZCB0byBnZXQgdGhlIGNvcnJlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQ6ICswIGlzIHgsICsxIGlzIHksICsyIGlzIHouXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIHNhbWUgcHJvY2VzcyBpcyByZXBlYXRlZCBmb3IgdmVydHMgYW5kIHRleHR1cmVzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmVydGV4IHBvc2l0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQudmVydHMucHVzaCgrdmVydHNbKCt2ZXJ0ZXhbMF0gLSAxKSAqIDMgKyAwXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQudmVydHMucHVzaCgrdmVydHNbKCt2ZXJ0ZXhbMF0gLSAxKSAqIDMgKyAxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQudmVydHMucHVzaCgrdmVydHNbKCt2ZXJ0ZXhbMF0gLSAxKSAqIDMgKyAyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmVydGV4IHRleHR1cmVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHR1cmVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJpZGUgPSBvcHRpb25zLmVuYWJsZVdUZXh0dXJlQ29vcmQgPyAzIDogMjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQudGV4dHVyZXMucHVzaCgrdGV4dHVyZXNbKCt2ZXJ0ZXhbMV0gLSAxKSAqIHN0cmlkZSArIDBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQudGV4dHVyZXMucHVzaCgrdGV4dHVyZXNbKCt2ZXJ0ZXhbMV0gLSAxKSAqIHN0cmlkZSArIDFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZW5hYmxlV1RleHR1cmVDb29yZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQudGV4dHVyZXMucHVzaCgrdGV4dHVyZXNbKCt2ZXJ0ZXhbMV0gLSAxKSAqIHN0cmlkZSArIDJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWZXJ0ZXggbm9ybWFsc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLm5vcm1zLnB1c2goK3ZlcnROb3JtYWxzWygrdmVydGV4W25vcm1hbEluZGV4XSAtIDEpICogMyArIDBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnBhY2tlZC5ub3Jtcy5wdXNoKCt2ZXJ0Tm9ybWFsc1soK3ZlcnRleFtub3JtYWxJbmRleF0gLSAxKSAqIDMgKyAxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQubm9ybXMucHVzaCgrdmVydE5vcm1hbHNbKCt2ZXJ0ZXhbbm9ybWFsSW5kZXhdIC0gMSkgKiAzICsgMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZlcnRleCBtYXRlcmlhbCBpbmRpY2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQubWF0ZXJpYWxJbmRpY2VzLnB1c2goY3VycmVudE1hdGVyaWFsSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkZCB0aGUgbmV3bHkgY3JlYXRlZCBWZXJ0ZXggdG8gdGhlIGxpc3Qgb2YgaW5kaWNlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGFja2VkLmhhc2hpbmRpY2VzW2hhc2hdID0gdW5wYWNrZWQuaW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYWNrZWQuaW5kaWNlc1tjdXJyZW50T2JqZWN0QnlNYXRlcmlhbEluZGV4XS5wdXNoKHVucGFja2VkLmhhc2hpbmRpY2VzW2hhc2hdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmNyZW1lbnQgdGhlIGNvdW50ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnBhY2tlZC5pbmRleCArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMudmVydGljZXMgPSB1bnBhY2tlZC52ZXJ0cztcbiAgICAgICAgdGhpcy52ZXJ0ZXhOb3JtYWxzID0gdW5wYWNrZWQubm9ybXM7XG4gICAgICAgIHRoaXMudGV4dHVyZXMgPSB1bnBhY2tlZC50ZXh0dXJlcztcbiAgICAgICAgdGhpcy52ZXJ0ZXhNYXRlcmlhbEluZGljZXMgPSB1bnBhY2tlZC5tYXRlcmlhbEluZGljZXM7XG4gICAgICAgIHRoaXMuaW5kaWNlcyA9IHVucGFja2VkLmluZGljZXNbY3VycmVudE9iamVjdEJ5TWF0ZXJpYWxJbmRleF07XG4gICAgICAgIHRoaXMuaW5kaWNlc1Blck1hdGVyaWFsID0gdW5wYWNrZWQuaW5kaWNlcztcblxuICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXMgPSBtYXRlcmlhbE5hbWVzQnlJbmRleDtcbiAgICAgICAgdGhpcy5tYXRlcmlhbEluZGljZXMgPSBtYXRlcmlhbEluZGljZXNCeU5hbWU7XG4gICAgICAgIHRoaXMubWF0ZXJpYWxzQnlJbmRleCA9IHt9O1xuXG4gICAgICAgIGlmIChvcHRpb25zLmNhbGNUYW5nZW50c0FuZEJpdGFuZ2VudHMpIHtcbiAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlVGFuZ2VudHNBbmRCaXRhbmdlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSB0YW5nZW50cyBhbmQgYml0YW5nZW50cyBvZiB0aGUgbWVzaCB0aGF0IGZvcm1zIGFuIG9ydGhvZ29uYWwgYmFzaXMgdG9nZXRoZXIgd2l0aCB0aGVcbiAgICAgKiBub3JtYWwgaW4gdGhlIGRpcmVjdGlvbiBvZiB0aGUgdGV4dHVyZSBjb29yZGluYXRlcy4gVGhlc2UgYXJlIHVzZWZ1bCBmb3Igc2V0dGluZyB1cCB0aGUgVEJOIG1hdHJpeFxuICAgICAqIHdoZW4gZGlzdG9ydGluZyB0aGUgbm9ybWFscyB0aHJvdWdoIG5vcm1hbCBtYXBzLlxuICAgICAqIE1ldGhvZCBkZXJpdmVkIGZyb206IGh0dHA6Ly93d3cub3BlbmdsLXR1dG9yaWFsLm9yZy9pbnRlcm1lZGlhdGUtdHV0b3JpYWxzL3R1dG9yaWFsLTEzLW5vcm1hbC1tYXBwaW5nL1xuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgcmVxdWlyZXMgdGhlIG5vcm1hbHMgYW5kIHRleHR1cmUgY29vcmRpbmF0ZXMgdG8gYmUgcGFyc2VkIGFuZCBzZXQgdXAgY29ycmVjdGx5LlxuICAgICAqIEFkZHMgdGhlIHRhbmdlbnRzIGFuZCBiaXRhbmdlbnRzIGFzIG1lbWJlcnMgb2YgdGhlIGNsYXNzIGluc3RhbmNlLlxuICAgICAqL1xuICAgIGNhbGN1bGF0ZVRhbmdlbnRzQW5kQml0YW5nZW50cygpIHtcbiAgICAgICAgY29uc29sZS5hc3NlcnQoXG4gICAgICAgICAgICAhIShcbiAgICAgICAgICAgICAgICB0aGlzLnZlcnRpY2VzICYmXG4gICAgICAgICAgICAgICAgdGhpcy52ZXJ0aWNlcy5sZW5ndGggJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZlcnRleE5vcm1hbHMgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZlcnRleE5vcm1hbHMubGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgdGhpcy50ZXh0dXJlcyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZXMubGVuZ3RoXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgXCJNaXNzaW5nIGF0dHJpYnV0ZXMgZm9yIGNhbGN1bGF0aW5nIHRhbmdlbnRzIGFuZCBiaXRhbmdlbnRzXCIsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgdW5wYWNrZWQgPSB7XG4gICAgICAgICAgICB0YW5nZW50czogWy4uLm5ldyBBcnJheSh0aGlzLnZlcnRpY2VzLmxlbmd0aCldLm1hcChfID0+IDApLFxuICAgICAgICAgICAgYml0YW5nZW50czogWy4uLm5ldyBBcnJheSh0aGlzLnZlcnRpY2VzLmxlbmd0aCldLm1hcChfID0+IDApLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIExvb3AgdGhyb3VnaCBhbGwgZmFjZXMgaW4gdGhlIHdob2xlIG1lc2hcbiAgICAgICAgY29uc3QgaW5kaWNlcyA9IHRoaXMuaW5kaWNlcztcbiAgICAgICAgY29uc3QgdmVydGljZXMgPSB0aGlzLnZlcnRpY2VzO1xuICAgICAgICBjb25zdCBub3JtYWxzID0gdGhpcy52ZXJ0ZXhOb3JtYWxzO1xuICAgICAgICBjb25zdCB1dnMgPSB0aGlzLnRleHR1cmVzO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICAgICAgY29uc3QgaTAgPSBpbmRpY2VzW2kgKyAwXTtcbiAgICAgICAgICAgIGNvbnN0IGkxID0gaW5kaWNlc1tpICsgMV07XG4gICAgICAgICAgICBjb25zdCBpMiA9IGluZGljZXNbaSArIDJdO1xuXG4gICAgICAgICAgICBjb25zdCB4X3YwID0gdmVydGljZXNbaTAgKiAzICsgMF07XG4gICAgICAgICAgICBjb25zdCB5X3YwID0gdmVydGljZXNbaTAgKiAzICsgMV07XG4gICAgICAgICAgICBjb25zdCB6X3YwID0gdmVydGljZXNbaTAgKiAzICsgMl07XG5cbiAgICAgICAgICAgIGNvbnN0IHhfdXYwID0gdXZzW2kwICogMiArIDBdO1xuICAgICAgICAgICAgY29uc3QgeV91djAgPSB1dnNbaTAgKiAyICsgMV07XG5cbiAgICAgICAgICAgIGNvbnN0IHhfdjEgPSB2ZXJ0aWNlc1tpMSAqIDMgKyAwXTtcbiAgICAgICAgICAgIGNvbnN0IHlfdjEgPSB2ZXJ0aWNlc1tpMSAqIDMgKyAxXTtcbiAgICAgICAgICAgIGNvbnN0IHpfdjEgPSB2ZXJ0aWNlc1tpMSAqIDMgKyAyXTtcblxuICAgICAgICAgICAgY29uc3QgeF91djEgPSB1dnNbaTEgKiAyICsgMF07XG4gICAgICAgICAgICBjb25zdCB5X3V2MSA9IHV2c1tpMSAqIDIgKyAxXTtcblxuICAgICAgICAgICAgY29uc3QgeF92MiA9IHZlcnRpY2VzW2kyICogMyArIDBdO1xuICAgICAgICAgICAgY29uc3QgeV92MiA9IHZlcnRpY2VzW2kyICogMyArIDFdO1xuICAgICAgICAgICAgY29uc3Qgel92MiA9IHZlcnRpY2VzW2kyICogMyArIDJdO1xuXG4gICAgICAgICAgICBjb25zdCB4X3V2MiA9IHV2c1tpMiAqIDIgKyAwXTtcbiAgICAgICAgICAgIGNvbnN0IHlfdXYyID0gdXZzW2kyICogMiArIDFdO1xuXG4gICAgICAgICAgICBjb25zdCB4X2RlbHRhUG9zMSA9IHhfdjEgLSB4X3YwO1xuICAgICAgICAgICAgY29uc3QgeV9kZWx0YVBvczEgPSB5X3YxIC0geV92MDtcbiAgICAgICAgICAgIGNvbnN0IHpfZGVsdGFQb3MxID0gel92MSAtIHpfdjA7XG5cbiAgICAgICAgICAgIGNvbnN0IHhfZGVsdGFQb3MyID0geF92MiAtIHhfdjA7XG4gICAgICAgICAgICBjb25zdCB5X2RlbHRhUG9zMiA9IHlfdjIgLSB5X3YwO1xuICAgICAgICAgICAgY29uc3Qgel9kZWx0YVBvczIgPSB6X3YyIC0gel92MDtcblxuICAgICAgICAgICAgY29uc3QgeF91dkRlbHRhUG9zMSA9IHhfdXYxIC0geF91djA7XG4gICAgICAgICAgICBjb25zdCB5X3V2RGVsdGFQb3MxID0geV91djEgLSB5X3V2MDtcblxuICAgICAgICAgICAgY29uc3QgeF91dkRlbHRhUG9zMiA9IHhfdXYyIC0geF91djA7XG4gICAgICAgICAgICBjb25zdCB5X3V2RGVsdGFQb3MyID0geV91djIgLSB5X3V2MDtcblxuICAgICAgICAgICAgY29uc3QgckludiA9IHhfdXZEZWx0YVBvczEgKiB5X3V2RGVsdGFQb3MyIC0geV91dkRlbHRhUG9zMSAqIHhfdXZEZWx0YVBvczI7XG4gICAgICAgICAgICBjb25zdCByID0gMS4wIC8gTWF0aC5hYnMockludiA8IDAuMDAwMSA/IDEuMCA6IHJJbnYpO1xuXG4gICAgICAgICAgICAvLyBUYW5nZW50XG4gICAgICAgICAgICBjb25zdCB4X3RhbmdlbnQgPSAoeF9kZWx0YVBvczEgKiB5X3V2RGVsdGFQb3MyIC0geF9kZWx0YVBvczIgKiB5X3V2RGVsdGFQb3MxKSAqIHI7XG4gICAgICAgICAgICBjb25zdCB5X3RhbmdlbnQgPSAoeV9kZWx0YVBvczEgKiB5X3V2RGVsdGFQb3MyIC0geV9kZWx0YVBvczIgKiB5X3V2RGVsdGFQb3MxKSAqIHI7XG4gICAgICAgICAgICBjb25zdCB6X3RhbmdlbnQgPSAoel9kZWx0YVBvczEgKiB5X3V2RGVsdGFQb3MyIC0gel9kZWx0YVBvczIgKiB5X3V2RGVsdGFQb3MxKSAqIHI7XG5cbiAgICAgICAgICAgIC8vIEJpdGFuZ2VudFxuICAgICAgICAgICAgY29uc3QgeF9iaXRhbmdlbnQgPSAoeF9kZWx0YVBvczIgKiB4X3V2RGVsdGFQb3MxIC0geF9kZWx0YVBvczEgKiB4X3V2RGVsdGFQb3MyKSAqIHI7XG4gICAgICAgICAgICBjb25zdCB5X2JpdGFuZ2VudCA9ICh5X2RlbHRhUG9zMiAqIHhfdXZEZWx0YVBvczEgLSB5X2RlbHRhUG9zMSAqIHhfdXZEZWx0YVBvczIpICogcjtcbiAgICAgICAgICAgIGNvbnN0IHpfYml0YW5nZW50ID0gKHpfZGVsdGFQb3MyICogeF91dkRlbHRhUG9zMSAtIHpfZGVsdGFQb3MxICogeF91dkRlbHRhUG9zMikgKiByO1xuXG4gICAgICAgICAgICAvLyBHcmFtLVNjaG1pZHQgb3J0aG9nb25hbGl6ZVxuICAgICAgICAgICAgLy90ID0gZ2xtOjpub3JtYWxpemUodCAtIG4gKiBnbG06OiBkb3QobiwgdCkpO1xuICAgICAgICAgICAgY29uc3QgeF9uMCA9IG5vcm1hbHNbaTAgKiAzICsgMF07XG4gICAgICAgICAgICBjb25zdCB5X24wID0gbm9ybWFsc1tpMCAqIDMgKyAxXTtcbiAgICAgICAgICAgIGNvbnN0IHpfbjAgPSBub3JtYWxzW2kwICogMyArIDJdO1xuXG4gICAgICAgICAgICBjb25zdCB4X24xID0gbm9ybWFsc1tpMSAqIDMgKyAwXTtcbiAgICAgICAgICAgIGNvbnN0IHlfbjEgPSBub3JtYWxzW2kxICogMyArIDFdO1xuICAgICAgICAgICAgY29uc3Qgel9uMSA9IG5vcm1hbHNbaTEgKiAzICsgMl07XG5cbiAgICAgICAgICAgIGNvbnN0IHhfbjIgPSBub3JtYWxzW2kyICogMyArIDBdO1xuICAgICAgICAgICAgY29uc3QgeV9uMiA9IG5vcm1hbHNbaTIgKiAzICsgMV07XG4gICAgICAgICAgICBjb25zdCB6X24yID0gbm9ybWFsc1tpMiAqIDMgKyAyXTtcblxuICAgICAgICAgICAgLy8gVGFuZ2VudFxuICAgICAgICAgICAgY29uc3QgbjBfZG90X3QgPSB4X3RhbmdlbnQgKiB4X24wICsgeV90YW5nZW50ICogeV9uMCArIHpfdGFuZ2VudCAqIHpfbjA7XG4gICAgICAgICAgICBjb25zdCBuMV9kb3RfdCA9IHhfdGFuZ2VudCAqIHhfbjEgKyB5X3RhbmdlbnQgKiB5X24xICsgel90YW5nZW50ICogel9uMTtcbiAgICAgICAgICAgIGNvbnN0IG4yX2RvdF90ID0geF90YW5nZW50ICogeF9uMiArIHlfdGFuZ2VudCAqIHlfbjIgKyB6X3RhbmdlbnQgKiB6X24yO1xuXG4gICAgICAgICAgICBjb25zdCB4X3Jlc1RhbmdlbnQwID0geF90YW5nZW50IC0geF9uMCAqIG4wX2RvdF90O1xuICAgICAgICAgICAgY29uc3QgeV9yZXNUYW5nZW50MCA9IHlfdGFuZ2VudCAtIHlfbjAgKiBuMF9kb3RfdDtcbiAgICAgICAgICAgIGNvbnN0IHpfcmVzVGFuZ2VudDAgPSB6X3RhbmdlbnQgLSB6X24wICogbjBfZG90X3Q7XG5cbiAgICAgICAgICAgIGNvbnN0IHhfcmVzVGFuZ2VudDEgPSB4X3RhbmdlbnQgLSB4X24xICogbjFfZG90X3Q7XG4gICAgICAgICAgICBjb25zdCB5X3Jlc1RhbmdlbnQxID0geV90YW5nZW50IC0geV9uMSAqIG4xX2RvdF90O1xuICAgICAgICAgICAgY29uc3Qgel9yZXNUYW5nZW50MSA9IHpfdGFuZ2VudCAtIHpfbjEgKiBuMV9kb3RfdDtcblxuICAgICAgICAgICAgY29uc3QgeF9yZXNUYW5nZW50MiA9IHhfdGFuZ2VudCAtIHhfbjIgKiBuMl9kb3RfdDtcbiAgICAgICAgICAgIGNvbnN0IHlfcmVzVGFuZ2VudDIgPSB5X3RhbmdlbnQgLSB5X24yICogbjJfZG90X3Q7XG4gICAgICAgICAgICBjb25zdCB6X3Jlc1RhbmdlbnQyID0gel90YW5nZW50IC0gel9uMiAqIG4yX2RvdF90O1xuXG4gICAgICAgICAgICBjb25zdCBtYWdUYW5nZW50MCA9IE1hdGguc3FydChcbiAgICAgICAgICAgICAgICB4X3Jlc1RhbmdlbnQwICogeF9yZXNUYW5nZW50MCArIHlfcmVzVGFuZ2VudDAgKiB5X3Jlc1RhbmdlbnQwICsgel9yZXNUYW5nZW50MCAqIHpfcmVzVGFuZ2VudDAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgbWFnVGFuZ2VudDEgPSBNYXRoLnNxcnQoXG4gICAgICAgICAgICAgICAgeF9yZXNUYW5nZW50MSAqIHhfcmVzVGFuZ2VudDEgKyB5X3Jlc1RhbmdlbnQxICogeV9yZXNUYW5nZW50MSArIHpfcmVzVGFuZ2VudDEgKiB6X3Jlc1RhbmdlbnQxLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IG1hZ1RhbmdlbnQyID0gTWF0aC5zcXJ0KFxuICAgICAgICAgICAgICAgIHhfcmVzVGFuZ2VudDIgKiB4X3Jlc1RhbmdlbnQyICsgeV9yZXNUYW5nZW50MiAqIHlfcmVzVGFuZ2VudDIgKyB6X3Jlc1RhbmdlbnQyICogel9yZXNUYW5nZW50MixcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIEJpdGFuZ2VudFxuICAgICAgICAgICAgY29uc3QgbjBfZG90X2J0ID0geF9iaXRhbmdlbnQgKiB4X24wICsgeV9iaXRhbmdlbnQgKiB5X24wICsgel9iaXRhbmdlbnQgKiB6X24wO1xuICAgICAgICAgICAgY29uc3QgbjFfZG90X2J0ID0geF9iaXRhbmdlbnQgKiB4X24xICsgeV9iaXRhbmdlbnQgKiB5X24xICsgel9iaXRhbmdlbnQgKiB6X24xO1xuICAgICAgICAgICAgY29uc3QgbjJfZG90X2J0ID0geF9iaXRhbmdlbnQgKiB4X24yICsgeV9iaXRhbmdlbnQgKiB5X24yICsgel9iaXRhbmdlbnQgKiB6X24yO1xuXG4gICAgICAgICAgICBjb25zdCB4X3Jlc0JpdGFuZ2VudDAgPSB4X2JpdGFuZ2VudCAtIHhfbjAgKiBuMF9kb3RfYnQ7XG4gICAgICAgICAgICBjb25zdCB5X3Jlc0JpdGFuZ2VudDAgPSB5X2JpdGFuZ2VudCAtIHlfbjAgKiBuMF9kb3RfYnQ7XG4gICAgICAgICAgICBjb25zdCB6X3Jlc0JpdGFuZ2VudDAgPSB6X2JpdGFuZ2VudCAtIHpfbjAgKiBuMF9kb3RfYnQ7XG5cbiAgICAgICAgICAgIGNvbnN0IHhfcmVzQml0YW5nZW50MSA9IHhfYml0YW5nZW50IC0geF9uMSAqIG4xX2RvdF9idDtcbiAgICAgICAgICAgIGNvbnN0IHlfcmVzQml0YW5nZW50MSA9IHlfYml0YW5nZW50IC0geV9uMSAqIG4xX2RvdF9idDtcbiAgICAgICAgICAgIGNvbnN0IHpfcmVzQml0YW5nZW50MSA9IHpfYml0YW5nZW50IC0gel9uMSAqIG4xX2RvdF9idDtcblxuICAgICAgICAgICAgY29uc3QgeF9yZXNCaXRhbmdlbnQyID0geF9iaXRhbmdlbnQgLSB4X24yICogbjJfZG90X2J0O1xuICAgICAgICAgICAgY29uc3QgeV9yZXNCaXRhbmdlbnQyID0geV9iaXRhbmdlbnQgLSB5X24yICogbjJfZG90X2J0O1xuICAgICAgICAgICAgY29uc3Qgel9yZXNCaXRhbmdlbnQyID0gel9iaXRhbmdlbnQgLSB6X24yICogbjJfZG90X2J0O1xuXG4gICAgICAgICAgICBjb25zdCBtYWdCaXRhbmdlbnQwID0gTWF0aC5zcXJ0KFxuICAgICAgICAgICAgICAgIHhfcmVzQml0YW5nZW50MCAqIHhfcmVzQml0YW5nZW50MCArXG4gICAgICAgICAgICAgICAgICAgIHlfcmVzQml0YW5nZW50MCAqIHlfcmVzQml0YW5nZW50MCArXG4gICAgICAgICAgICAgICAgICAgIHpfcmVzQml0YW5nZW50MCAqIHpfcmVzQml0YW5nZW50MCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBtYWdCaXRhbmdlbnQxID0gTWF0aC5zcXJ0KFxuICAgICAgICAgICAgICAgIHhfcmVzQml0YW5nZW50MSAqIHhfcmVzQml0YW5nZW50MSArXG4gICAgICAgICAgICAgICAgICAgIHlfcmVzQml0YW5nZW50MSAqIHlfcmVzQml0YW5nZW50MSArXG4gICAgICAgICAgICAgICAgICAgIHpfcmVzQml0YW5nZW50MSAqIHpfcmVzQml0YW5nZW50MSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBtYWdCaXRhbmdlbnQyID0gTWF0aC5zcXJ0KFxuICAgICAgICAgICAgICAgIHhfcmVzQml0YW5nZW50MiAqIHhfcmVzQml0YW5nZW50MiArXG4gICAgICAgICAgICAgICAgICAgIHlfcmVzQml0YW5nZW50MiAqIHlfcmVzQml0YW5nZW50MiArXG4gICAgICAgICAgICAgICAgICAgIHpfcmVzQml0YW5nZW50MiAqIHpfcmVzQml0YW5nZW50MixcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHVucGFja2VkLnRhbmdlbnRzW2kwICogMyArIDBdICs9IHhfcmVzVGFuZ2VudDAgLyBtYWdUYW5nZW50MDtcbiAgICAgICAgICAgIHVucGFja2VkLnRhbmdlbnRzW2kwICogMyArIDFdICs9IHlfcmVzVGFuZ2VudDAgLyBtYWdUYW5nZW50MDtcbiAgICAgICAgICAgIHVucGFja2VkLnRhbmdlbnRzW2kwICogMyArIDJdICs9IHpfcmVzVGFuZ2VudDAgLyBtYWdUYW5nZW50MDtcblxuICAgICAgICAgICAgdW5wYWNrZWQudGFuZ2VudHNbaTEgKiAzICsgMF0gKz0geF9yZXNUYW5nZW50MSAvIG1hZ1RhbmdlbnQxO1xuICAgICAgICAgICAgdW5wYWNrZWQudGFuZ2VudHNbaTEgKiAzICsgMV0gKz0geV9yZXNUYW5nZW50MSAvIG1hZ1RhbmdlbnQxO1xuICAgICAgICAgICAgdW5wYWNrZWQudGFuZ2VudHNbaTEgKiAzICsgMl0gKz0gel9yZXNUYW5nZW50MSAvIG1hZ1RhbmdlbnQxO1xuXG4gICAgICAgICAgICB1bnBhY2tlZC50YW5nZW50c1tpMiAqIDMgKyAwXSArPSB4X3Jlc1RhbmdlbnQyIC8gbWFnVGFuZ2VudDI7XG4gICAgICAgICAgICB1bnBhY2tlZC50YW5nZW50c1tpMiAqIDMgKyAxXSArPSB5X3Jlc1RhbmdlbnQyIC8gbWFnVGFuZ2VudDI7XG4gICAgICAgICAgICB1bnBhY2tlZC50YW5nZW50c1tpMiAqIDMgKyAyXSArPSB6X3Jlc1RhbmdlbnQyIC8gbWFnVGFuZ2VudDI7XG5cbiAgICAgICAgICAgIHVucGFja2VkLmJpdGFuZ2VudHNbaTAgKiAzICsgMF0gKz0geF9yZXNCaXRhbmdlbnQwIC8gbWFnQml0YW5nZW50MDtcbiAgICAgICAgICAgIHVucGFja2VkLmJpdGFuZ2VudHNbaTAgKiAzICsgMV0gKz0geV9yZXNCaXRhbmdlbnQwIC8gbWFnQml0YW5nZW50MDtcbiAgICAgICAgICAgIHVucGFja2VkLmJpdGFuZ2VudHNbaTAgKiAzICsgMl0gKz0gel9yZXNCaXRhbmdlbnQwIC8gbWFnQml0YW5nZW50MDtcblxuICAgICAgICAgICAgdW5wYWNrZWQuYml0YW5nZW50c1tpMSAqIDMgKyAwXSArPSB4X3Jlc0JpdGFuZ2VudDEgLyBtYWdCaXRhbmdlbnQxO1xuICAgICAgICAgICAgdW5wYWNrZWQuYml0YW5nZW50c1tpMSAqIDMgKyAxXSArPSB5X3Jlc0JpdGFuZ2VudDEgLyBtYWdCaXRhbmdlbnQxO1xuICAgICAgICAgICAgdW5wYWNrZWQuYml0YW5nZW50c1tpMSAqIDMgKyAyXSArPSB6X3Jlc0JpdGFuZ2VudDEgLyBtYWdCaXRhbmdlbnQxO1xuXG4gICAgICAgICAgICB1bnBhY2tlZC5iaXRhbmdlbnRzW2kyICogMyArIDBdICs9IHhfcmVzQml0YW5nZW50MiAvIG1hZ0JpdGFuZ2VudDI7XG4gICAgICAgICAgICB1bnBhY2tlZC5iaXRhbmdlbnRzW2kyICogMyArIDFdICs9IHlfcmVzQml0YW5nZW50MiAvIG1hZ0JpdGFuZ2VudDI7XG4gICAgICAgICAgICB1bnBhY2tlZC5iaXRhbmdlbnRzW2kyICogMyArIDJdICs9IHpfcmVzQml0YW5nZW50MiAvIG1hZ0JpdGFuZ2VudDI7XG5cbiAgICAgICAgICAgIC8vIFRPRE86IGNoZWNrIGhhbmRlZG5lc3NcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudGFuZ2VudHMgPSB1bnBhY2tlZC50YW5nZW50cztcbiAgICAgICAgdGhpcy5iaXRhbmdlbnRzID0gdW5wYWNrZWQuYml0YW5nZW50cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbGF5b3V0IC0gQSB7QGxpbmsgTGF5b3V0fSBvYmplY3QgdGhhdCBkZXNjcmliZXMgdGhlXG4gICAgICogZGVzaXJlZCBtZW1vcnkgbGF5b3V0IG9mIHRoZSBnZW5lcmF0ZWQgYnVmZmVyXG4gICAgICogQHJldHVybiBUaGUgcGFja2VkIGFycmF5IGluIHRoZSAuLi4gVE9ET1xuICAgICAqL1xuICAgIG1ha2VCdWZmZXJEYXRhKGxheW91dDogTGF5b3V0KTogQXJyYXlCdWZmZXJXaXRoSXRlbVNpemUge1xuICAgICAgICBjb25zdCBudW1JdGVtcyA9IHRoaXMudmVydGljZXMubGVuZ3RoIC8gMztcbiAgICAgICAgY29uc3QgYnVmZmVyOiBBcnJheUJ1ZmZlcldpdGhJdGVtU2l6ZSA9IG5ldyBBcnJheUJ1ZmZlcihsYXlvdXQuc3RyaWRlICogbnVtSXRlbXMpO1xuICAgICAgICBidWZmZXIubnVtSXRlbXMgPSBudW1JdGVtcztcbiAgICAgICAgY29uc3QgZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoYnVmZmVyKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIHZlcnRleE9mZnNldCA9IDA7IGkgPCBudW1JdGVtczsgaSsrKSB7XG4gICAgICAgICAgICB2ZXJ0ZXhPZmZzZXQgPSBpICogbGF5b3V0LnN0cmlkZTtcbiAgICAgICAgICAgIC8vIGNvcHkgaW4gdGhlIHZlcnRleCBkYXRhIGluIHRoZSBvcmRlciBhbmQgZm9ybWF0IGdpdmVuIGJ5IHRoZVxuICAgICAgICAgICAgLy8gbGF5b3V0IHBhcmFtXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZSBvZiBsYXlvdXQuYXR0cmlidXRlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IHZlcnRleE9mZnNldCArIGxheW91dC5hdHRyaWJ1dGVNYXBbYXR0cmlidXRlLmtleV0ub2Zmc2V0O1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoYXR0cmlidXRlLmtleSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5QT1NJVElPTi5rZXk6XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCwgdGhpcy52ZXJ0aWNlc1tpICogM10sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA0LCB0aGlzLnZlcnRpY2VzW2kgKiAzICsgMV0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA4LCB0aGlzLnZlcnRpY2VzW2kgKiAzICsgMl0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTGF5b3V0LlVWLmtleTpcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0LCB0aGlzLnRleHR1cmVzW2kgKiAyXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCArIDQsIHRoaXMudGV4dHVyZXNbaSAqIDIgKyAxXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuTk9STUFMLmtleTpcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0LCB0aGlzLnZlcnRleE5vcm1hbHNbaSAqIDNdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgNCwgdGhpcy52ZXJ0ZXhOb3JtYWxzW2kgKiAzICsgMV0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA4LCB0aGlzLnZlcnRleE5vcm1hbHNbaSAqIDMgKyAyXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuTUFURVJJQUxfSU5ERVgua2V5OlxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0SW50MTYob2Zmc2V0LCB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuQU1CSUVOVC5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIG1hdGVyaWFsLmFtYmllbnRbMF0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA0LCBtYXRlcmlhbC5hbWJpZW50WzFdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgOCwgbWF0ZXJpYWwuYW1iaWVudFsyXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5ESUZGVVNFLmtleToge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxJbmRleCA9IHRoaXMudmVydGV4TWF0ZXJpYWxJbmRpY2VzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSB0aGlzLm1hdGVyaWFsc0J5SW5kZXhbbWF0ZXJpYWxJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGVyaWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTWF0ZXJpYWwgXCInICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxOYW1lc1ttYXRlcmlhbEluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCIgbm90IGZvdW5kIGluIG1lc2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgYWRkTWF0ZXJpYWxMaWJyYXJ5KC4uLik/XCInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCwgbWF0ZXJpYWwuZGlmZnVzZVswXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCArIDQsIG1hdGVyaWFsLmRpZmZ1c2VbMV0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA4LCBtYXRlcmlhbC5kaWZmdXNlWzJdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTGF5b3V0LlNQRUNVTEFSLmtleToge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxJbmRleCA9IHRoaXMudmVydGV4TWF0ZXJpYWxJbmRpY2VzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSB0aGlzLm1hdGVyaWFsc0J5SW5kZXhbbWF0ZXJpYWxJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGVyaWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTWF0ZXJpYWwgXCInICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxOYW1lc1ttYXRlcmlhbEluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCIgbm90IGZvdW5kIGluIG1lc2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgYWRkTWF0ZXJpYWxMaWJyYXJ5KC4uLik/XCInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCwgbWF0ZXJpYWwuc3BlY3VsYXJbMF0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA0LCBtYXRlcmlhbC5zcGVjdWxhclsxXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCArIDgsIG1hdGVyaWFsLnNwZWN1bGFyWzJdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTGF5b3V0LlNQRUNVTEFSX0VYUE9ORU5ULmtleToge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxJbmRleCA9IHRoaXMudmVydGV4TWF0ZXJpYWxJbmRpY2VzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSB0aGlzLm1hdGVyaWFsc0J5SW5kZXhbbWF0ZXJpYWxJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGVyaWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTWF0ZXJpYWwgXCInICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxOYW1lc1ttYXRlcmlhbEluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCIgbm90IGZvdW5kIGluIG1lc2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgYWRkTWF0ZXJpYWxMaWJyYXJ5KC4uLik/XCInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCwgbWF0ZXJpYWwuc3BlY3VsYXJFeHBvbmVudCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5FTUlTU0lWRS5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIG1hdGVyaWFsLmVtaXNzaXZlWzBdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgNCwgbWF0ZXJpYWwuZW1pc3NpdmVbMV0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQgKyA4LCBtYXRlcmlhbC5lbWlzc2l2ZVsyXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5UUkFOU01JU1NJT05fRklMVEVSLmtleToge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxJbmRleCA9IHRoaXMudmVydGV4TWF0ZXJpYWxJbmRpY2VzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSB0aGlzLm1hdGVyaWFsc0J5SW5kZXhbbWF0ZXJpYWxJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGVyaWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTWF0ZXJpYWwgXCInICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxOYW1lc1ttYXRlcmlhbEluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCIgbm90IGZvdW5kIGluIG1lc2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgYWRkTWF0ZXJpYWxMaWJyYXJ5KC4uLik/XCInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCwgbWF0ZXJpYWwudHJhbnNtaXNzaW9uRmlsdGVyWzBdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgNCwgbWF0ZXJpYWwudHJhbnNtaXNzaW9uRmlsdGVyWzFdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFWaWV3LnNldEZsb2F0MzIob2Zmc2V0ICsgOCwgbWF0ZXJpYWwudHJhbnNtaXNzaW9uRmlsdGVyWzJdLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTGF5b3V0LkRJU1NPTFZFLmtleToge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxJbmRleCA9IHRoaXMudmVydGV4TWF0ZXJpYWxJbmRpY2VzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSB0aGlzLm1hdGVyaWFsc0J5SW5kZXhbbWF0ZXJpYWxJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGVyaWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTWF0ZXJpYWwgXCInICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxOYW1lc1ttYXRlcmlhbEluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCIgbm90IGZvdW5kIGluIG1lc2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgYWRkTWF0ZXJpYWxMaWJyYXJ5KC4uLik/XCInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCwgbWF0ZXJpYWwuZGlzc29sdmUsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMYXlvdXQuSUxMVU1JTkFUSU9OLmtleToge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxJbmRleCA9IHRoaXMudmVydGV4TWF0ZXJpYWxJbmRpY2VzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSB0aGlzLm1hdGVyaWFsc0J5SW5kZXhbbWF0ZXJpYWxJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGVyaWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTWF0ZXJpYWwgXCInICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxOYW1lc1ttYXRlcmlhbEluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCIgbm90IGZvdW5kIGluIG1lc2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgYWRkTWF0ZXJpYWxMaWJyYXJ5KC4uLik/XCInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRJbnQxNihvZmZzZXQsIG1hdGVyaWFsLmlsbHVtaW5hdGlvbiwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5SRUZSQUNUSU9OX0lOREVYLmtleToge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxJbmRleCA9IHRoaXMudmVydGV4TWF0ZXJpYWxJbmRpY2VzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSB0aGlzLm1hdGVyaWFsc0J5SW5kZXhbbWF0ZXJpYWxJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGVyaWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTWF0ZXJpYWwgXCInICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxOYW1lc1ttYXRlcmlhbEluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCIgbm90IGZvdW5kIGluIG1lc2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgYWRkTWF0ZXJpYWxMaWJyYXJ5KC4uLik/XCInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRGbG9hdDMyKG9mZnNldCwgbWF0ZXJpYWwucmVmcmFjdGlvbkluZGV4LCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTGF5b3V0LlNIQVJQTkVTUy5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsSW5kZXggPSB0aGlzLnZlcnRleE1hdGVyaWFsSW5kaWNlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdGVyaWFsID0gdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtYXRlcmlhbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ01hdGVyaWFsIFwiJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdGVyaWFsTmFtZXNbbWF0ZXJpYWxJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1wiIG5vdCBmb3VuZCBpbiBtZXNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIGFkZE1hdGVyaWFsTGlicmFyeSguLi4pP1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVZpZXcuc2V0RmxvYXQzMihvZmZzZXQsIG1hdGVyaWFsLnNoYXJwbmVzcywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIExheW91dC5BTlRJX0FMSUFTSU5HLmtleToge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxJbmRleCA9IHRoaXMudmVydGV4TWF0ZXJpYWxJbmRpY2VzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSB0aGlzLm1hdGVyaWFsc0J5SW5kZXhbbWF0ZXJpYWxJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hdGVyaWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnTWF0ZXJpYWwgXCInICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxOYW1lc1ttYXRlcmlhbEluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCIgbm90IGZvdW5kIGluIG1lc2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgYWRkTWF0ZXJpYWxMaWJyYXJ5KC4uLik/XCInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhVmlldy5zZXRJbnQxNihvZmZzZXQsIG1hdGVyaWFsLmFudGlBbGlhc2luZyA/IDEgOiAwLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBidWZmZXI7XG4gICAgfVxuXG4gICAgbWFrZUluZGV4QnVmZmVyRGF0YSgpOiBVaW50MTZBcnJheVdpdGhJdGVtU2l6ZSB7XG4gICAgICAgIGNvbnN0IGJ1ZmZlcjogVWludDE2QXJyYXlXaXRoSXRlbVNpemUgPSBuZXcgVWludDE2QXJyYXkodGhpcy5pbmRpY2VzKTtcbiAgICAgICAgYnVmZmVyLm51bUl0ZW1zID0gdGhpcy5pbmRpY2VzLmxlbmd0aDtcbiAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICB9XG5cbiAgICBtYWtlSW5kZXhCdWZmZXJEYXRhRm9yTWF0ZXJpYWxzKC4uLm1hdGVyaWFsSW5kaWNlczogQXJyYXk8bnVtYmVyPik6IFVpbnQxNkFycmF5V2l0aEl0ZW1TaXplIHtcbiAgICAgICAgY29uc3QgaW5kaWNlczogbnVtYmVyW10gPSBuZXcgQXJyYXk8bnVtYmVyPigpLmNvbmNhdChcbiAgICAgICAgICAgIC4uLm1hdGVyaWFsSW5kaWNlcy5tYXAobXRsSWR4ID0+IHRoaXMuaW5kaWNlc1Blck1hdGVyaWFsW210bElkeF0pLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBidWZmZXI6IFVpbnQxNkFycmF5V2l0aEl0ZW1TaXplID0gbmV3IFVpbnQxNkFycmF5KGluZGljZXMpO1xuICAgICAgICBidWZmZXIubnVtSXRlbXMgPSBpbmRpY2VzLmxlbmd0aDtcbiAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICB9XG5cbiAgICBhZGRNYXRlcmlhbExpYnJhcnkobXRsOiBNYXRlcmlhbExpYnJhcnkpIHtcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIG10bC5tYXRlcmlhbHMpIHtcbiAgICAgICAgICAgIGlmICghKG5hbWUgaW4gdGhpcy5tYXRlcmlhbEluZGljZXMpKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBtYXRlcmlhbCBpcyBub3QgcmVmZXJlbmNlZCBieSB0aGUgbWVzaFxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IG10bC5tYXRlcmlhbHNbbmFtZV07XG5cbiAgICAgICAgICAgIC8vIEZpbmQgdGhlIG1hdGVyaWFsIGluZGV4IGZvciB0aGlzIG1hdGVyaWFsXG4gICAgICAgICAgICBjb25zdCBtYXRlcmlhbEluZGV4ID0gdGhpcy5tYXRlcmlhbEluZGljZXNbbWF0ZXJpYWwubmFtZV07XG5cbiAgICAgICAgICAgIC8vIFB1dCB0aGUgbWF0ZXJpYWwgaW50byB0aGUgbWF0ZXJpYWxzQnlJbmRleCBvYmplY3QgYXQgdGhlIHJpZ2h0XG4gICAgICAgICAgICAvLyBzcG90IGFzIGRldGVybWluZWQgd2hlbiB0aGUgb2JqIGZpbGUgd2FzIHBhcnNlZFxuICAgICAgICAgICAgdGhpcy5tYXRlcmlhbHNCeUluZGV4W21hdGVyaWFsSW5kZXhdID0gbWF0ZXJpYWw7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uKiB0cmlhbmd1bGF0ZShlbGVtZW50czogc3RyaW5nW10pIHtcbiAgICBpZiAoZWxlbWVudHMubGVuZ3RoIDw9IDMpIHtcbiAgICAgICAgeWllbGQgZWxlbWVudHM7XG4gICAgfSBlbHNlIGlmIChlbGVtZW50cy5sZW5ndGggPT09IDQpIHtcbiAgICAgICAgeWllbGQgW2VsZW1lbnRzWzBdLCBlbGVtZW50c1sxXSwgZWxlbWVudHNbMl1dO1xuICAgICAgICB5aWVsZCBbZWxlbWVudHNbMl0sIGVsZW1lbnRzWzNdLCBlbGVtZW50c1swXV07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBlbGVtZW50cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICAgIHlpZWxkIFtlbGVtZW50c1swXSwgZWxlbWVudHNbaV0sIGVsZW1lbnRzW2kgKyAxXV07XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgTWVzaCBmcm9tIFwiLi9tZXNoXCI7XG5pbXBvcnQgeyBNYXRlcmlhbExpYnJhcnksIFRleHR1cmVNYXBEYXRhIH0gZnJvbSBcIi4vbWF0ZXJpYWxcIjtcblxuZnVuY3Rpb24gZG93bmxvYWRNdGxUZXh0dXJlcyhtdGw6IE1hdGVyaWFsTGlicmFyeSwgcm9vdDogc3RyaW5nKSB7XG4gICAgY29uc3QgbWFwQXR0cmlidXRlcyA9IFtcbiAgICAgICAgXCJtYXBEaWZmdXNlXCIsXG4gICAgICAgIFwibWFwQW1iaWVudFwiLFxuICAgICAgICBcIm1hcFNwZWN1bGFyXCIsXG4gICAgICAgIFwibWFwRGlzc29sdmVcIixcbiAgICAgICAgXCJtYXBCdW1wXCIsXG4gICAgICAgIFwibWFwRGlzcGxhY2VtZW50XCIsXG4gICAgICAgIFwibWFwRGVjYWxcIixcbiAgICAgICAgXCJtYXBFbWlzc2l2ZVwiLFxuICAgIF07XG4gICAgaWYgKCFyb290LmVuZHNXaXRoKFwiL1wiKSkge1xuICAgICAgICByb290ICs9IFwiL1wiO1xuICAgIH1cbiAgICBjb25zdCB0ZXh0dXJlcyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBtYXRlcmlhbE5hbWUgaW4gbXRsLm1hdGVyaWFscykge1xuICAgICAgICBpZiAoIW10bC5tYXRlcmlhbHMuaGFzT3duUHJvcGVydHkobWF0ZXJpYWxOYW1lKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSBtdGwubWF0ZXJpYWxzW21hdGVyaWFsTmFtZV07XG5cbiAgICAgICAgZm9yIChjb25zdCBhdHRyIG9mIG1hcEF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IG1hcERhdGEgPSAobWF0ZXJpYWwgYXMgYW55KVthdHRyXSBhcyBUZXh0dXJlTWFwRGF0YTtcbiAgICAgICAgICAgIGlmICghbWFwRGF0YSB8fCAhbWFwRGF0YS5maWxlbmFtZSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdXJsID0gcm9vdCArIG1hcERhdGEuZmlsZW5hbWU7XG4gICAgICAgICAgICB0ZXh0dXJlcy5wdXNoKFxuICAgICAgICAgICAgICAgIGZldGNoKHVybClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmJsb2IoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlLnNyYyA9IFVSTC5jcmVhdGVPYmplY3RVUkwoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXBEYXRhLnRleHR1cmUgPSBpbWFnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IChpbWFnZS5vbmxvYWQgPSByZXNvbHZlKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBVbmFibGUgdG8gZG93bmxvYWQgdGV4dHVyZTogJHt1cmx9YCk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLmFsbCh0ZXh0dXJlcyk7XG59XG5cbmZ1bmN0aW9uIGdldE10bChtb2RlbE9wdGlvbnM6IERvd25sb2FkTW9kZWxzT3B0aW9ucyk6IHN0cmluZyB7XG4gICAgaWYgKCEodHlwZW9mIG1vZGVsT3B0aW9ucy5tdGwgPT09IFwic3RyaW5nXCIpKSB7XG4gICAgICAgIHJldHVybiBtb2RlbE9wdGlvbnMub2JqLnJlcGxhY2UoL1xcLm9iaiQvLCBcIi5tdGxcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVsT3B0aW9ucy5tdGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRG93bmxvYWRNb2RlbHNPcHRpb25zIHtcbiAgICBvYmo6IHN0cmluZztcbiAgICBtdGw/OiBib29sZWFuIHwgc3RyaW5nO1xuICAgIGRvd25sb2FkTXRsVGV4dHVyZXM/OiBib29sZWFuO1xuICAgIG10bFRleHR1cmVSb290Pzogc3RyaW5nO1xuICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgaW5kaWNlc1Blck1hdGVyaWFsPzogYm9vbGVhbjtcbiAgICBjYWxjVGFuZ2VudHNBbmRCaXRhbmdlbnRzPzogYm9vbGVhbjtcbn1cblxudHlwZSBNb2RlbFByb21pc2VzID0gW1Byb21pc2U8c3RyaW5nPiwgUHJvbWlzZTxNZXNoPiwgdW5kZWZpbmVkIHwgUHJvbWlzZTxNYXRlcmlhbExpYnJhcnk+XTtcbmV4cG9ydCB0eXBlIE1lc2hNYXAgPSB7IFtuYW1lOiBzdHJpbmddOiBNZXNoIH07XG4vKipcbiAqIEFjY2VwdHMgYSBsaXN0IG9mIG1vZGVsIHJlcXVlc3Qgb2JqZWN0cyBhbmQgcmV0dXJucyBhIFByb21pc2UgdGhhdFxuICogcmVzb2x2ZXMgd2hlbiBhbGwgbW9kZWxzIGhhdmUgYmVlbiBkb3dubG9hZGVkIGFuZCBwYXJzZWQuXG4gKlxuICogVGhlIGxpc3Qgb2YgbW9kZWwgb2JqZWN0cyBmb2xsb3cgdGhpcyBpbnRlcmZhY2U6XG4gKiB7XG4gKiAgb2JqOiAncGF0aC90by9tb2RlbC5vYmonLFxuICogIG10bDogdHJ1ZSB8ICdwYXRoL3RvL21vZGVsLm10bCcsXG4gKiAgZG93bmxvYWRNdGxUZXh0dXJlczogdHJ1ZSB8IGZhbHNlXG4gKiAgbXRsVGV4dHVyZVJvb3Q6ICcvbW9kZWxzL3N1emFubmUvbWFwcydcbiAqICBuYW1lOiAnc3V6YW5uZSdcbiAqIH1cbiAqXG4gKiBUaGUgYG9iamAgYXR0cmlidXRlIGlzIHJlcXVpcmVkIGFuZCBzaG91bGQgYmUgdGhlIHBhdGggdG8gdGhlXG4gKiBtb2RlbCdzIC5vYmogZmlsZSByZWxhdGl2ZSB0byB0aGUgY3VycmVudCByZXBvIChhYnNvbHV0ZSBVUkxzIGFyZVxuICogc3VnZ2VzdGVkKS5cbiAqXG4gKiBUaGUgYG10bGAgYXR0cmlidXRlIGlzIG9wdGlvbmFsIGFuZCBjYW4gZWl0aGVyIGJlIGEgYm9vbGVhbiBvclxuICogYSBwYXRoIHRvIHRoZSBtb2RlbCdzIC5tdGwgZmlsZSByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBVUkwuIElmXG4gKiB0aGUgdmFsdWUgaXMgYHRydWVgLCB0aGVuIHRoZSBwYXRoIGFuZCBiYXNlbmFtZSBnaXZlbiBmb3IgdGhlIGBvYmpgXG4gKiBhdHRyaWJ1dGUgaXMgdXNlZCByZXBsYWNpbmcgdGhlIC5vYmogc3VmZml4IGZvciAubXRsXG4gKiBFLmcuOiB7b2JqOiAnbW9kZWxzL2Zvby5vYmonLCBtdGw6IHRydWV9IHdvdWxkIHNlYXJjaCBmb3IgJ21vZGVscy9mb28ubXRsJ1xuICpcbiAqIFRoZSBgbmFtZWAgYXR0cmlidXRlIGlzIG9wdGlvbmFsIGFuZCBpcyBhIGh1bWFuIGZyaWVuZGx5IG5hbWUgdG8gYmVcbiAqIGluY2x1ZGVkIHdpdGggdGhlIHBhcnNlZCBPQkogYW5kIE1UTCBmaWxlcy4gSWYgbm90IGdpdmVuLCB0aGUgYmFzZSAub2JqXG4gKiBmaWxlbmFtZSB3aWxsIGJlIHVzZWQuXG4gKlxuICogVGhlIGBkb3dubG9hZE10bFRleHR1cmVzYCBhdHRyaWJ1dGUgaXMgYSBmbGFnIGZvciBhdXRvbWF0aWNhbGx5IGRvd25sb2FkaW5nXG4gKiBhbnkgaW1hZ2VzIGZvdW5kIGluIHRoZSBNVEwgZmlsZSBhbmQgYXR0YWNoaW5nIHRoZW0gdG8gZWFjaCBNYXRlcmlhbFxuICogY3JlYXRlZCBmcm9tIHRoYXQgZmlsZS4gRm9yIGV4YW1wbGUsIGlmIG1hdGVyaWFsLm1hcERpZmZ1c2UgaXMgc2V0ICh0aGVyZVxuICogd2FzIGRhdGEgaW4gdGhlIE1UTCBmaWxlKSwgdGhlbiBtYXRlcmlhbC5tYXBEaWZmdXNlLnRleHR1cmUgd2lsbCBjb250YWluXG4gKiB0aGUgZG93bmxvYWRlZCBpbWFnZS4gVGhpcyBvcHRpb24gZGVmYXVsdHMgdG8gYHRydWVgLiBCeSBkZWZhdWx0LCB0aGUgTVRMJ3NcbiAqIFVSTCB3aWxsIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBsb2NhdGlvbiBvZiB0aGUgaW1hZ2VzLlxuICpcbiAqIFRoZSBgbXRsVGV4dHVyZVJvb3RgIGF0dHJpYnV0ZSBpcyBvcHRpb25hbCBhbmQgc2hvdWxkIHBvaW50IHRvIHRoZSBsb2NhdGlvblxuICogb24gdGhlIHNlcnZlciB0aGF0IHRoaXMgTVRMJ3MgdGV4dHVyZSBmaWxlcyBhcmUgbG9jYXRlZC4gVGhlIGRlZmF1bHQgaXMgdG9cbiAqIHVzZSB0aGUgTVRMIGZpbGUncyBsb2NhdGlvbi5cbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gdGhlIHJlc3VsdCBvZiBkb3dubG9hZGluZyB0aGUgZ2l2ZW4gbGlzdCBvZiBtb2RlbHMuIFRoZVxuICogcHJvbWlzZSB3aWxsIHJlc29sdmUgd2l0aCBhbiBvYmplY3Qgd2hvc2Uga2V5cyBhcmUgdGhlIG5hbWVzIG9mIHRoZSBtb2RlbHNcbiAqIGFuZCB0aGUgdmFsdWUgaXMgaXRzIE1lc2ggb2JqZWN0LiBFYWNoIE1lc2ggb2JqZWN0IHdpbGwgYXV0b21hdGljYWxseVxuICogaGF2ZSBpdHMgYWRkTWF0ZXJpYWxMaWJyYXJ5KCkgbWV0aG9kIGNhbGxlZCB0byBzZXQgdGhlIGdpdmVuIE1UTCBkYXRhIChpZiBnaXZlbikuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkb3dubG9hZE1vZGVscyhtb2RlbHM6IERvd25sb2FkTW9kZWxzT3B0aW9uc1tdKTogUHJvbWlzZTxNZXNoTWFwPiB7XG4gICAgY29uc3QgZmluaXNoZWQgPSBbXTtcblxuICAgIGZvciAoY29uc3QgbW9kZWwgb2YgbW9kZWxzKSB7XG4gICAgICAgIGlmICghbW9kZWwub2JqKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgJ1wib2JqXCIgYXR0cmlidXRlIG9mIG1vZGVsIG9iamVjdCBub3Qgc2V0LiBUaGUgLm9iaiBmaWxlIGlzIHJlcXVpcmVkIHRvIGJlIHNldCAnICtcbiAgICAgICAgICAgICAgICAgICAgXCJpbiBvcmRlciB0byB1c2UgZG93bmxvYWRNb2RlbHMoKVwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICBpbmRpY2VzUGVyTWF0ZXJpYWw6ICEhbW9kZWwuaW5kaWNlc1Blck1hdGVyaWFsLFxuICAgICAgICAgICAgY2FsY1RhbmdlbnRzQW5kQml0YW5nZW50czogISFtb2RlbC5jYWxjVGFuZ2VudHNBbmRCaXRhbmdlbnRzLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIGlmIHRoZSBuYW1lIGlzIG5vdCBwcm92aWRlZCwgZGVydml2ZSBpdCBmcm9tIHRoZSBnaXZlbiBPQkpcbiAgICAgICAgbGV0IG5hbWUgPSBtb2RlbC5uYW1lO1xuICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRzID0gbW9kZWwub2JqLnNwbGl0KFwiL1wiKTtcbiAgICAgICAgICAgIG5hbWUgPSBwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXS5yZXBsYWNlKFwiLm9ialwiLCBcIlwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYW1lUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShuYW1lKTtcblxuICAgICAgICBjb25zdCBtZXNoUHJvbWlzZSA9IGZldGNoKG1vZGVsLm9iailcbiAgICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLnRleHQoKSlcbiAgICAgICAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWVzaChkYXRhLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIGxldCBtdGxQcm9taXNlO1xuICAgICAgICAvLyBEb3dubG9hZCBNYXRlcmlhbExpYnJhcnkgZmlsZT9cbiAgICAgICAgaWYgKG1vZGVsLm10bCkge1xuICAgICAgICAgICAgY29uc3QgbXRsID0gZ2V0TXRsKG1vZGVsKTtcbiAgICAgICAgICAgIG10bFByb21pc2UgPSBmZXRjaChtdGwpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKVxuICAgICAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgICAgICAoZGF0YTogc3RyaW5nKTogUHJvbWlzZTxbTWF0ZXJpYWxMaWJyYXJ5LCBhbnldPiA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXRlcmlhbCA9IG5ldyBNYXRlcmlhbExpYnJhcnkoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobW9kZWwuZG93bmxvYWRNdGxUZXh0dXJlcyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcm9vdCA9IG1vZGVsLm10bFRleHR1cmVSb290O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcm9vdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGRpcmVjdG9yeSBvZiB0aGUgTVRMIGZpbGUgYXMgZGVmYXVsdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290ID0gbXRsLnN1YnN0cigwLCBtdGwubGFzdEluZGV4T2YoXCIvXCIpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG93bmxvYWRNdGxUZXh0dXJlcyByZXR1cm5zIGEgUHJvbWlzZSB0aGF0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXMgcmVzb2x2ZWQgb25jZSBhbGwgb2YgdGhlIGltYWdlcyBpdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRhaW5zIGFyZSBkb3dubG9hZGVkLiBUaGVzZSBhcmUgdGhlblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGF0dGFjaGVkIHRvIHRoZSBtYXAgZGF0YSBvYmplY3RzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtQcm9taXNlLnJlc29sdmUobWF0ZXJpYWwpLCBkb3dubG9hZE10bFRleHR1cmVzKG1hdGVyaWFsLCByb290KV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtQcm9taXNlLnJlc29sdmUobWF0ZXJpYWwpLCB1bmRlZmluZWRdKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLnRoZW4oKHZhbHVlOiBbTWF0ZXJpYWxMaWJyYXJ5LCBhbnldKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVswXTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhcnNlZDogTW9kZWxQcm9taXNlcyA9IFtuYW1lUHJvbWlzZSwgbWVzaFByb21pc2UsIG10bFByb21pc2VdO1xuICAgICAgICBmaW5pc2hlZC5wdXNoKFByb21pc2UuYWxsPHN0cmluZywgTWVzaCwgTWF0ZXJpYWxMaWJyYXJ5IHwgdW5kZWZpbmVkPihwYXJzZWQpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoZmluaXNoZWQpLnRoZW4obXMgPT4ge1xuICAgICAgICAvLyB0aGUgXCJmaW5pc2hlZFwiIHByb21pc2UgaXMgYSBsaXN0IG9mIG5hbWUsIE1lc2ggaW5zdGFuY2UsXG4gICAgICAgIC8vIGFuZCBNYXRlcmlhbExpYmFyeSBpbnN0YW5jZS4gVGhpcyB1bnBhY2tzIGFuZCByZXR1cm5zIGFuXG4gICAgICAgIC8vIG9iamVjdCBtYXBwaW5nIG5hbWUgdG8gTWVzaCAoTWVzaCBwb2ludHMgdG8gTVRMKS5cbiAgICAgICAgY29uc3QgbW9kZWxzOiBNZXNoTWFwID0ge307XG5cbiAgICAgICAgZm9yIChjb25zdCBtb2RlbCBvZiBtcykge1xuICAgICAgICAgICAgY29uc3QgW25hbWUsIG1lc2gsIG10bF0gPSBtb2RlbDtcbiAgICAgICAgICAgIG1lc2gubmFtZSA9IG5hbWU7XG4gICAgICAgICAgICBpZiAobXRsKSB7XG4gICAgICAgICAgICAgICAgbWVzaC5hZGRNYXRlcmlhbExpYnJhcnkobXRsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1vZGVsc1tuYW1lXSA9IG1lc2g7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbW9kZWxzO1xuICAgIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE5hbWVBbmRVcmxzIHtcbiAgICBbbWVzaE5hbWU6IHN0cmluZ106IHN0cmluZztcbn1cblxuLyoqXG4gKiBUYWtlcyBpbiBhbiBvYmplY3Qgb2YgYG1lc2hfbmFtZWAsIGAnL3VybC90by9PQkovZmlsZSdgIHBhaXJzIGFuZCBhIGNhbGxiYWNrXG4gKiBmdW5jdGlvbi4gRWFjaCBPQkogZmlsZSB3aWxsIGJlIGFqYXhlZCBpbiBhbmQgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG9cbiAqIGFuIE9CSi5NZXNoLiBXaGVuIGFsbCBmaWxlcyBoYXZlIHN1Y2Nlc3NmdWxseSBkb3dubG9hZGVkIHRoZSBjYWxsYmFja1xuICogZnVuY3Rpb24gcHJvdmlkZWQgd2lsbCBiZSBjYWxsZWQgYW5kIHBhc3NlZCBpbiBhbiBvYmplY3QgY29udGFpbmluZ1xuICogdGhlIG5ld2x5IGNyZWF0ZWQgbWVzaGVzLlxuICpcbiAqICoqTm90ZToqKiBJbiBvcmRlciB0byB1c2UgdGhpcyBmdW5jdGlvbiBhcyBhIHdheSB0byBkb3dubG9hZCBtZXNoZXMsIGFcbiAqIHdlYnNlcnZlciBvZiBzb21lIHNvcnQgbXVzdCBiZSB1c2VkLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBuYW1lQW5kQXR0cnMgYW4gb2JqZWN0IHdoZXJlIHRoZSBrZXkgaXMgdGhlIG5hbWUgb2YgdGhlIG1lc2ggYW5kIHRoZSB2YWx1ZSBpcyB0aGUgdXJsIHRvIHRoYXQgbWVzaCdzIE9CSiBmaWxlXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGxldGlvbkNhbGxiYWNrIHNob3VsZCBjb250YWluIGEgZnVuY3Rpb24gdGhhdCB3aWxsIHRha2Ugb25lIHBhcmFtZXRlcjogYW4gb2JqZWN0IGFycmF5IHdoZXJlIHRoZSBrZXlzIHdpbGwgYmUgdGhlIHVuaXF1ZSBvYmplY3QgbmFtZSBhbmQgdGhlIHZhbHVlIHdpbGwgYmUgYSBNZXNoIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBtZXNoZXMgSW4gY2FzZSBvdGhlciBtZXNoZXMgYXJlIGxvYWRlZCBzZXBhcmF0ZWx5IG9yIGlmIGEgcHJldmlvdXNseSBkZWNsYXJlZCB2YXJpYWJsZSBpcyBkZXNpcmVkIHRvIGJlIHVzZWQsIHBhc3MgaW4gYSAocG9zc2libHkgZW1wdHkpIGpzb24gb2JqZWN0IG9mIHRoZSBwYXR0ZXJuOiB7ICc8bWVzaF9uYW1lPic6IE9CSi5NZXNoIH1cbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkb3dubG9hZE1lc2hlcyhcbiAgICBuYW1lQW5kVVJMczogTmFtZUFuZFVybHMsXG4gICAgY29tcGxldGlvbkNhbGxiYWNrOiAobWVzaGVzOiBNZXNoTWFwKSA9PiB2b2lkLFxuICAgIG1lc2hlczogTWVzaE1hcCxcbikge1xuICAgIGlmIChtZXNoZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtZXNoZXMgPSB7fTtcbiAgICB9XG5cbiAgICBjb25zdCBjb21wbGV0ZWQ6IFByb21pc2U8W3N0cmluZywgTWVzaF0+W10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgbWVzaF9uYW1lIGluIG5hbWVBbmRVUkxzKSB7XG4gICAgICAgIGlmICghbmFtZUFuZFVSTHMuaGFzT3duUHJvcGVydHkobWVzaF9uYW1lKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJsID0gbmFtZUFuZFVSTHNbbWVzaF9uYW1lXTtcbiAgICAgICAgY29tcGxldGVkLnB1c2goXG4gICAgICAgICAgICBmZXRjaCh1cmwpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4gcmVzcG9uc2UudGV4dCgpKVxuICAgICAgICAgICAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW21lc2hfbmFtZSwgbmV3IE1lc2goZGF0YSldIGFzIFtzdHJpbmcsIE1lc2hdO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIFByb21pc2UuYWxsKGNvbXBsZXRlZCkudGhlbihtcyA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgW25hbWUsIG1lc2hdIG9mIG1zKSB7XG4gICAgICAgICAgICBtZXNoZXNbbmFtZV0gPSBtZXNoO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbXBsZXRpb25DYWxsYmFjayhtZXNoZXMpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVuZGVkR0xCdWZmZXIgZXh0ZW5kcyBXZWJHTEJ1ZmZlciB7XG4gICAgaXRlbVNpemU6IG51bWJlcjtcbiAgICBudW1JdGVtczogbnVtYmVyO1xufVxuXG5mdW5jdGlvbiBfYnVpbGRCdWZmZXIoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdHlwZTogR0xlbnVtLCBkYXRhOiBudW1iZXJbXSwgaXRlbVNpemU6IG51bWJlcik6IEV4dGVuZGVkR0xCdWZmZXIge1xuICAgIGNvbnN0IGJ1ZmZlciA9IGdsLmNyZWF0ZUJ1ZmZlcigpIGFzIEV4dGVuZGVkR0xCdWZmZXI7XG4gICAgY29uc3QgYXJyYXlWaWV3ID0gdHlwZSA9PT0gZ2wuQVJSQVlfQlVGRkVSID8gRmxvYXQzMkFycmF5IDogVWludDE2QXJyYXk7XG4gICAgZ2wuYmluZEJ1ZmZlcih0eXBlLCBidWZmZXIpO1xuICAgIGdsLmJ1ZmZlckRhdGEodHlwZSwgbmV3IGFycmF5VmlldyhkYXRhKSwgZ2wuU1RBVElDX0RSQVcpO1xuICAgIGJ1ZmZlci5pdGVtU2l6ZSA9IGl0ZW1TaXplO1xuICAgIGJ1ZmZlci5udW1JdGVtcyA9IGRhdGEubGVuZ3RoIC8gaXRlbVNpemU7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNZXNoV2l0aEJ1ZmZlcnMgZXh0ZW5kcyBNZXNoIHtcbiAgICBub3JtYWxCdWZmZXI6IEV4dGVuZGVkR0xCdWZmZXI7XG4gICAgdGV4dHVyZUJ1ZmZlcjogRXh0ZW5kZWRHTEJ1ZmZlcjtcbiAgICB2ZXJ0ZXhCdWZmZXI6IEV4dGVuZGVkR0xCdWZmZXI7XG4gICAgaW5kZXhCdWZmZXI6IEV4dGVuZGVkR0xCdWZmZXI7XG59XG5cbi8qKlxuICogVGFrZXMgaW4gdGhlIFdlYkdMIGNvbnRleHQgYW5kIGEgTWVzaCwgdGhlbiBjcmVhdGVzIGFuZCBhcHBlbmRzIHRoZSBidWZmZXJzXG4gKiB0byB0aGUgbWVzaCBvYmplY3QgYXMgYXR0cmlidXRlcy5cbiAqXG4gKiBAcGFyYW0ge1dlYkdMUmVuZGVyaW5nQ29udGV4dH0gZ2wgdGhlIGBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnKWAgY29udGV4dCBpbnN0YW5jZVxuICogQHBhcmFtIHtNZXNofSBtZXNoIGEgc2luZ2xlIGBPQkouTWVzaGAgaW5zdGFuY2VcbiAqXG4gKiBUaGUgbmV3bHkgY3JlYXRlZCBtZXNoIGF0dHJpYnV0ZXMgYXJlOlxuICpcbiAqIEF0dHJidXRlIHwgRGVzY3JpcHRpb25cbiAqIDotLS0gfCAtLS1cbiAqICoqbm9ybWFsQnVmZmVyKiogICAgICAgfGNvbnRhaW5zIHRoZSBtb2RlbCYjMzk7cyBWZXJ0ZXggTm9ybWFsc1xuICogbm9ybWFsQnVmZmVyLml0ZW1TaXplICB8c2V0IHRvIDMgaXRlbXNcbiAqIG5vcm1hbEJ1ZmZlci5udW1JdGVtcyAgfHRoZSB0b3RhbCBudW1iZXIgb2YgdmVydGV4IG5vcm1hbHNcbiAqIHxcbiAqICoqdGV4dHVyZUJ1ZmZlcioqICAgICAgfGNvbnRhaW5zIHRoZSBtb2RlbCYjMzk7cyBUZXh0dXJlIENvb3JkaW5hdGVzXG4gKiB0ZXh0dXJlQnVmZmVyLml0ZW1TaXplIHxzZXQgdG8gMiBpdGVtc1xuICogdGV4dHVyZUJ1ZmZlci5udW1JdGVtcyB8dGhlIG51bWJlciBvZiB0ZXh0dXJlIGNvb3JkaW5hdGVzXG4gKiB8XG4gKiAqKnZlcnRleEJ1ZmZlcioqICAgICAgIHxjb250YWlucyB0aGUgbW9kZWwmIzM5O3MgVmVydGV4IFBvc2l0aW9uIENvb3JkaW5hdGVzIChkb2VzIG5vdCBpbmNsdWRlIHcpXG4gKiB2ZXJ0ZXhCdWZmZXIuaXRlbVNpemUgIHxzZXQgdG8gMyBpdGVtc1xuICogdmVydGV4QnVmZmVyLm51bUl0ZW1zICB8dGhlIHRvdGFsIG51bWJlciBvZiB2ZXJ0aWNlc1xuICogfFxuICogKippbmRleEJ1ZmZlcioqICAgICAgICB8Y29udGFpbnMgdGhlIGluZGljZXMgb2YgdGhlIGZhY2VzXG4gKiBpbmRleEJ1ZmZlci5pdGVtU2l6ZSAgIHxpcyBzZXQgdG8gMVxuICogaW5kZXhCdWZmZXIubnVtSXRlbXMgICB8dGhlIHRvdGFsIG51bWJlciBvZiBpbmRpY2VzXG4gKlxuICogQSBzaW1wbGUgZXhhbXBsZSAoYSBsb3Qgb2Ygc3RlcHMgYXJlIG1pc3NpbmcsIHNvIGRvbid0IGNvcHkgYW5kIHBhc3RlKTpcbiAqXG4gKiAgICAgY29uc3QgZ2wgICA9IGNhbnZhcy5nZXRDb250ZXh0KCd3ZWJnbCcpLFxuICogICAgICAgICBtZXNoID0gT0JKLk1lc2gob2JqX2ZpbGVfZGF0YSk7XG4gKiAgICAgLy8gY29tcGlsZSB0aGUgc2hhZGVycyBhbmQgY3JlYXRlIGEgc2hhZGVyIHByb2dyYW1cbiAqICAgICBjb25zdCBzaGFkZXJQcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpO1xuICogICAgIC8vIGNvbXBpbGF0aW9uIHN0dWZmIGhlcmVcbiAqICAgICAuLi5cbiAqICAgICAvLyBtYWtlIHN1cmUgeW91IGhhdmUgdmVydGV4LCB2ZXJ0ZXggbm9ybWFsLCBhbmQgdGV4dHVyZSBjb29yZGluYXRlXG4gKiAgICAgLy8gYXR0cmlidXRlcyBsb2NhdGVkIGluIHlvdXIgc2hhZGVycyBhbmQgYXR0YWNoIHRoZW0gdG8gdGhlIHNoYWRlciBwcm9ncmFtXG4gKiAgICAgc2hhZGVyUHJvZ3JhbS52ZXJ0ZXhQb3NpdGlvbkF0dHJpYnV0ZSA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHNoYWRlclByb2dyYW0sIFwiYVZlcnRleFBvc2l0aW9uXCIpO1xuICogICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHNoYWRlclByb2dyYW0udmVydGV4UG9zaXRpb25BdHRyaWJ1dGUpO1xuICpcbiAqICAgICBzaGFkZXJQcm9ncmFtLnZlcnRleE5vcm1hbEF0dHJpYnV0ZSA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHNoYWRlclByb2dyYW0sIFwiYVZlcnRleE5vcm1hbFwiKTtcbiAqICAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShzaGFkZXJQcm9ncmFtLnZlcnRleE5vcm1hbEF0dHJpYnV0ZSk7XG4gKlxuICogICAgIHNoYWRlclByb2dyYW0udGV4dHVyZUNvb3JkQXR0cmlidXRlID0gZ2wuZ2V0QXR0cmliTG9jYXRpb24oc2hhZGVyUHJvZ3JhbSwgXCJhVGV4dHVyZUNvb3JkXCIpO1xuICogICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHNoYWRlclByb2dyYW0udGV4dHVyZUNvb3JkQXR0cmlidXRlKTtcbiAqXG4gKiAgICAgLy8gY3JlYXRlIGFuZCBpbml0aWFsaXplIHRoZSB2ZXJ0ZXgsIHZlcnRleCBub3JtYWwsIGFuZCB0ZXh0dXJlIGNvb3JkaW5hdGUgYnVmZmVyc1xuICogICAgIC8vIGFuZCBzYXZlIG9uIHRvIHRoZSBtZXNoIG9iamVjdFxuICogICAgIE9CSi5pbml0TWVzaEJ1ZmZlcnMoZ2wsIG1lc2gpO1xuICpcbiAqICAgICAvLyBub3cgdG8gcmVuZGVyIHRoZSBtZXNoXG4gKiAgICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIG1lc2gudmVydGV4QnVmZmVyKTtcbiAqICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHNoYWRlclByb2dyYW0udmVydGV4UG9zaXRpb25BdHRyaWJ1dGUsIG1lc2gudmVydGV4QnVmZmVyLml0ZW1TaXplLCBnbC5GTE9BVCwgZmFsc2UsIDAsIDApO1xuICogICAgIC8vIGl0J3MgcG9zc2libGUgdGhhdCB0aGUgbWVzaCBkb2Vzbid0IGNvbnRhaW5cbiAqICAgICAvLyBhbnkgdGV4dHVyZSBjb29yZGluYXRlcyAoZS5nLiBzdXphbm5lLm9iaiBpbiB0aGUgZGV2ZWxvcG1lbnQgYnJhbmNoKS5cbiAqICAgICAvLyBpbiB0aGlzIGNhc2UsIHRoZSB0ZXh0dXJlIHZlcnRleEF0dHJpYkFycmF5IHdpbGwgbmVlZCB0byBiZSBkaXNhYmxlZFxuICogICAgIC8vIGJlZm9yZSB0aGUgY2FsbCB0byBkcmF3RWxlbWVudHNcbiAqICAgICBpZighbWVzaC50ZXh0dXJlcy5sZW5ndGgpe1xuICogICAgICAgZ2wuZGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KHNoYWRlclByb2dyYW0udGV4dHVyZUNvb3JkQXR0cmlidXRlKTtcbiAqICAgICB9XG4gKiAgICAgZWxzZXtcbiAqICAgICAgIC8vIGlmIHRoZSB0ZXh0dXJlIHZlcnRleEF0dHJpYkFycmF5IGhhcyBiZWVuIHByZXZpb3VzbHlcbiAqICAgICAgIC8vIGRpc2FibGVkLCB0aGVuIGl0IG5lZWRzIHRvIGJlIHJlLWVuYWJsZWRcbiAqICAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHNoYWRlclByb2dyYW0udGV4dHVyZUNvb3JkQXR0cmlidXRlKTtcbiAqICAgICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCBtZXNoLnRleHR1cmVCdWZmZXIpO1xuICogICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcihzaGFkZXJQcm9ncmFtLnRleHR1cmVDb29yZEF0dHJpYnV0ZSwgbWVzaC50ZXh0dXJlQnVmZmVyLml0ZW1TaXplLCBnbC5GTE9BVCwgZmFsc2UsIDAsIDApO1xuICogICAgIH1cbiAqXG4gKiAgICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIG1lc2gubm9ybWFsQnVmZmVyKTtcbiAqICAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHNoYWRlclByb2dyYW0udmVydGV4Tm9ybWFsQXR0cmlidXRlLCBtZXNoLm5vcm1hbEJ1ZmZlci5pdGVtU2l6ZSwgZ2wuRkxPQVQsIGZhbHNlLCAwLCAwKTtcbiAqXG4gKiAgICAgZ2wuYmluZEJ1ZmZlcihnbC5FTEVNRU5UX0FSUkFZX0JVRkZFUiwgbW9kZWwubWVzaC5pbmRleEJ1ZmZlcik7XG4gKiAgICAgZ2wuZHJhd0VsZW1lbnRzKGdsLlRSSUFOR0xFUywgbW9kZWwubWVzaC5pbmRleEJ1ZmZlci5udW1JdGVtcywgZ2wuVU5TSUdORURfU0hPUlQsIDApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdE1lc2hCdWZmZXJzKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIG1lc2g6IE1lc2gpOiBNZXNoV2l0aEJ1ZmZlcnMge1xuICAgIChtZXNoIGFzIE1lc2hXaXRoQnVmZmVycykubm9ybWFsQnVmZmVyID0gX2J1aWxkQnVmZmVyKGdsLCBnbC5BUlJBWV9CVUZGRVIsIG1lc2gudmVydGV4Tm9ybWFscywgMyk7XG4gICAgKG1lc2ggYXMgTWVzaFdpdGhCdWZmZXJzKS50ZXh0dXJlQnVmZmVyID0gX2J1aWxkQnVmZmVyKGdsLCBnbC5BUlJBWV9CVUZGRVIsIG1lc2gudGV4dHVyZXMsIG1lc2gudGV4dHVyZVN0cmlkZSk7XG4gICAgKG1lc2ggYXMgTWVzaFdpdGhCdWZmZXJzKS52ZXJ0ZXhCdWZmZXIgPSBfYnVpbGRCdWZmZXIoZ2wsIGdsLkFSUkFZX0JVRkZFUiwgbWVzaC52ZXJ0aWNlcywgMyk7XG4gICAgKG1lc2ggYXMgTWVzaFdpdGhCdWZmZXJzKS5pbmRleEJ1ZmZlciA9IF9idWlsZEJ1ZmZlcihnbCwgZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIG1lc2guaW5kaWNlcywgMSk7XG5cbiAgICByZXR1cm4gbWVzaCBhcyBNZXNoV2l0aEJ1ZmZlcnM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVNZXNoQnVmZmVycyhnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCBtZXNoOiBNZXNoV2l0aEJ1ZmZlcnMpIHtcbiAgICBnbC5kZWxldGVCdWZmZXIobWVzaC5ub3JtYWxCdWZmZXIpO1xuICAgIGdsLmRlbGV0ZUJ1ZmZlcihtZXNoLnRleHR1cmVCdWZmZXIpO1xuICAgIGdsLmRlbGV0ZUJ1ZmZlcihtZXNoLnZlcnRleEJ1ZmZlcik7XG4gICAgZ2wuZGVsZXRlQnVmZmVyKG1lc2guaW5kZXhCdWZmZXIpO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/dist/webgl-obj-loader.min.js b/dist/webgl-obj-loader.min.js index 89ecf53..0a5122e 100644 --- a/dist/webgl-obj-loader.min.js +++ b/dist/webgl-obj-loader.min.js @@ -6,7 +6,7 @@ /*!***********************!*\ !*** ./src/layout.ts ***! \***********************/ -/*! exports provided: TYPES, DuplicateAttributeException, Attribute, Layout */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TYPES", function() { return TYPES; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DuplicateAttributeException", function() { return DuplicateAttributeException; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Attribute", function() { return Attribute; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Layout", function() { return Layout; });\nvar TYPES;\n(function (TYPES) {\n TYPES[TYPES["BYTE"] = 1] = "BYTE";\n TYPES[TYPES["UNSIGNED_BYTE"] = 1] = "UNSIGNED_BYTE";\n TYPES[TYPES["SHORT"] = 2] = "SHORT";\n TYPES[TYPES["UNSIGNED_SHORT"] = 2] = "UNSIGNED_SHORT";\n TYPES[TYPES["FLOAT"] = 4] = "FLOAT";\n})(TYPES || (TYPES = {}));\n/**\n * An exception for when two or more of the same attributes are found in the\n * same layout.\n * @private\n */\nclass DuplicateAttributeException extends Error {\n /**\n * Create a DuplicateAttributeException\n * @param {Attribute} attribute - The attribute that was found more than\n * once in the {@link Layout}\n */\n constructor(attribute) {\n super(`found duplicate attribute: ${attribute.key}`);\n }\n}\n/**\n * Represents how a vertex attribute should be packed into an buffer.\n * @private\n */\nclass Attribute {\n /**\n * Create an attribute. Do not call this directly, use the predefined\n * constants.\n * @param {string} key - The name of this attribute as if it were a key in\n * an Object. Use the camel case version of the upper snake case\n * const name.\n * @param {number} size - The number of components per vertex attribute.\n * Must be 1, 2, 3, or 4.\n * @param {string} type - The data type of each component for this\n * attribute. Possible values:
\n * "BYTE": signed 8-bit integer, with values in [-128, 127]
\n * "SHORT": signed 16-bit integer, with values in\n * [-32768, 32767]
\n * "UNSIGNED_BYTE": unsigned 8-bit integer, with values in\n * [0, 255]
\n * "UNSIGNED_SHORT": unsigned 16-bit integer, with values in\n * [0, 65535]
\n * "FLOAT": 32-bit floating point number\n * @param {boolean} normalized - Whether integer data values should be\n * normalized when being casted to a float.
\n * If true, signed integers are normalized to [-1, 1].
\n * If true, unsigned integers are normalized to [0, 1].
\n * For type "FLOAT", this parameter has no effect.\n */\n constructor(key, size, type, normalized = false) {\n this.key = key;\n this.size = size;\n this.type = type;\n this.normalized = normalized;\n this.sizeOfType = this.type;\n this.sizeInBytes = this.sizeOfType * size;\n }\n}\n/**\n * A class to represent the memory layout for a vertex attribute array. Used by\n * {@link Mesh}\'s TBD(...) method to generate a packed array from mesh data.\n *

\n * Layout can sort of be thought of as a C-style struct declaration.\n * {@link Mesh}\'s TBD(...) method will use the {@link Layout} instance to\n * pack an array in the given attribute order.\n *

\n * Layout also is very helpful when calling a WebGL context\'s\n * vertexAttribPointer method. If you\'ve created a buffer using\n * a Layout instance, then the same Layout instance can be used to determine\n * the size, type, normalized, stride, and offset parameters for\n * vertexAttribPointer.\n *

\n * For example:\n *

\n *\n * const index = glctx.getAttribLocation(shaderProgram, "pos");\n * glctx.vertexAttribPointer(\n *   layout.position.size,\n *   glctx[layout.position.type],\n *   layout.position.normalized,\n *   layout.position.stride,\n *   layout.position.offset);\n * 
\n * @see {@link Mesh}\n */\nclass Layout {\n /**\n * Create a Layout object. This constructor will throw if any duplicate\n * attributes are given.\n * @param {Array} ...attributes - An ordered list of attributes that\n * describe the desired memory layout for each vertex attribute.\n *

\n *\n * @see {@link Mesh}\n */\n constructor(...attributes) {\n this.attributes = attributes;\n this.attributeMap = {};\n let offset = 0;\n let maxStrideMultiple = 0;\n for (const attribute of attributes) {\n if (this.attributeMap[attribute.key]) {\n throw new DuplicateAttributeException(attribute);\n }\n // Add padding to satisfy WebGL\'s requirement that all\n // vertexAttribPointer calls have an offset that is a multiple of\n // the type size.\n if (offset % attribute.sizeOfType !== 0) {\n offset += attribute.sizeOfType - (offset % attribute.sizeOfType);\n console.warn("Layout requires padding before " + attribute.key + " attribute");\n }\n this.attributeMap[attribute.key] = {\n attribute: attribute,\n size: attribute.size,\n type: attribute.type,\n normalized: attribute.normalized,\n offset: offset,\n };\n offset += attribute.sizeInBytes;\n maxStrideMultiple = Math.max(maxStrideMultiple, attribute.sizeOfType);\n }\n // Add padding to the end to satisfy WebGL\'s requirement that all\n // vertexAttribPointer calls have a stride that is a multiple of the\n // type size. Because we\'re putting differently sized attributes into\n // the same buffer, it must be padded to a multiple of the largest\n // type size.\n if (offset % maxStrideMultiple !== 0) {\n offset += maxStrideMultiple - (offset % maxStrideMultiple);\n console.warn("Layout requires padding at the back");\n }\n this.stride = offset;\n for (const attribute of attributes) {\n this.attributeMap[attribute.key].stride = this.stride;\n }\n }\n}\n// Geometry attributes\n/**\n * Attribute layout to pack a vertex\'s x, y, & z as floats\n *\n * @see {@link Layout}\n */\nLayout.POSITION = new Attribute("position", 3, TYPES.FLOAT);\n/**\n * Attribute layout to pack a vertex\'s normal\'s x, y, & z as floats\n *\n * @see {@link Layout}\n */\nLayout.NORMAL = new Attribute("normal", 3, TYPES.FLOAT);\n/**\n * Attribute layout to pack a vertex\'s normal\'s x, y, & z as floats.\n *

\n * This value will be computed on-the-fly based on the texture coordinates.\n * If no texture coordinates are available, the generated value will default to\n * 0, 0, 0.\n *\n * @see {@link Layout}\n */\nLayout.TANGENT = new Attribute("tangent", 3, TYPES.FLOAT);\n/**\n * Attribute layout to pack a vertex\'s normal\'s bitangent x, y, & z as floats.\n *

\n * This value will be computed on-the-fly based on the texture coordinates.\n * If no texture coordinates are available, the generated value will default to\n * 0, 0, 0.\n * @see {@link Layout}\n */\nLayout.BITANGENT = new Attribute("bitangent", 3, TYPES.FLOAT);\n/**\n * Attribute layout to pack a vertex\'s texture coordinates\' u & v as floats\n *\n * @see {@link Layout}\n */\nLayout.UV = new Attribute("uv", 2, TYPES.FLOAT);\n// Material attributes\n/**\n * Attribute layout to pack an unsigned short to be interpreted as a the index\n * into a {@link Mesh}\'s materials list.\n *

\n * The intention of this value is to send all of the {@link Mesh}\'s materials\n * into multiple shader uniforms and then reference the current one by this\n * vertex attribute.\n *

\n * example glsl code:\n *\n *

\n *  // this is bound using MATERIAL_INDEX\n *  attribute int materialIndex;\n *\n *  struct Material {\n *    vec3 diffuse;\n *    vec3 specular;\n *    vec3 specularExponent;\n *  };\n *\n *  uniform Material materials[MAX_MATERIALS];\n *\n *  // ...\n *\n *  vec3 diffuse = materials[materialIndex];\n *\n * 
\n * TODO: More description & test to make sure subscripting by attributes even\n * works for webgl\n *\n * @see {@link Layout}\n */\nLayout.MATERIAL_INDEX = new Attribute("materialIndex", 1, TYPES.SHORT);\nLayout.MATERIAL_ENABLED = new Attribute("materialEnabled", 1, TYPES.UNSIGNED_SHORT);\nLayout.AMBIENT = new Attribute("ambient", 3, TYPES.FLOAT);\nLayout.DIFFUSE = new Attribute("diffuse", 3, TYPES.FLOAT);\nLayout.SPECULAR = new Attribute("specular", 3, TYPES.FLOAT);\nLayout.SPECULAR_EXPONENT = new Attribute("specularExponent", 3, TYPES.FLOAT);\nLayout.EMISSIVE = new Attribute("emissive", 3, TYPES.FLOAT);\nLayout.TRANSMISSION_FILTER = new Attribute("transmissionFilter", 3, TYPES.FLOAT);\nLayout.DISSOLVE = new Attribute("dissolve", 1, TYPES.FLOAT);\nLayout.ILLUMINATION = new Attribute("illumination", 1, TYPES.UNSIGNED_SHORT);\nLayout.REFRACTION_INDEX = new Attribute("refractionIndex", 1, TYPES.FLOAT);\nLayout.SHARPNESS = new Attribute("sharpness", 1, TYPES.FLOAT);\nLayout.MAP_DIFFUSE = new Attribute("mapDiffuse", 1, TYPES.SHORT);\nLayout.MAP_AMBIENT = new Attribute("mapAmbient", 1, TYPES.SHORT);\nLayout.MAP_SPECULAR = new Attribute("mapSpecular", 1, TYPES.SHORT);\nLayout.MAP_SPECULAR_EXPONENT = new Attribute("mapSpecularExponent", 1, TYPES.SHORT);\nLayout.MAP_DISSOLVE = new Attribute("mapDissolve", 1, TYPES.SHORT);\nLayout.ANTI_ALIASING = new Attribute("antiAliasing", 1, TYPES.UNSIGNED_SHORT);\nLayout.MAP_BUMP = new Attribute("mapBump", 1, TYPES.SHORT);\nLayout.MAP_DISPLACEMENT = new Attribute("mapDisplacement", 1, TYPES.SHORT);\nLayout.MAP_DECAL = new Attribute("mapDecal", 1, TYPES.SHORT);\nLayout.MAP_EMISSIVE = new Attribute("mapEmissive", 1, TYPES.SHORT);\n\n\n//# sourceURL=webpack://OBJ/./src/layout.ts?')},"./src/material.ts": +/*! exports provided: TYPES, DuplicateAttributeException, Attribute, Layout */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TYPES", function() { return TYPES; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DuplicateAttributeException", function() { return DuplicateAttributeException; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Attribute", function() { return Attribute; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Layout", function() { return Layout; });\nvar TYPES;\n(function (TYPES) {\n TYPES["BYTE"] = "BYTE";\n TYPES["UNSIGNED_BYTE"] = "UNSIGNED_BYTE";\n TYPES["SHORT"] = "SHORT";\n TYPES["UNSIGNED_SHORT"] = "UNSIGNED_SHORT";\n TYPES["FLOAT"] = "FLOAT";\n})(TYPES || (TYPES = {}));\n/**\n * An exception for when two or more of the same attributes are found in the\n * same layout.\n * @private\n */\nclass DuplicateAttributeException extends Error {\n /**\n * Create a DuplicateAttributeException\n * @param {Attribute} attribute - The attribute that was found more than\n * once in the {@link Layout}\n */\n constructor(attribute) {\n super(`found duplicate attribute: ${attribute.key}`);\n }\n}\n/**\n * Represents how a vertex attribute should be packed into an buffer.\n * @private\n */\nclass Attribute {\n /**\n * Create an attribute. Do not call this directly, use the predefined\n * constants.\n * @param {string} key - The name of this attribute as if it were a key in\n * an Object. Use the camel case version of the upper snake case\n * const name.\n * @param {number} size - The number of components per vertex attribute.\n * Must be 1, 2, 3, or 4.\n * @param {string} type - The data type of each component for this\n * attribute. Possible values:
\n * "BYTE": signed 8-bit integer, with values in [-128, 127]
\n * "SHORT": signed 16-bit integer, with values in\n * [-32768, 32767]
\n * "UNSIGNED_BYTE": unsigned 8-bit integer, with values in\n * [0, 255]
\n * "UNSIGNED_SHORT": unsigned 16-bit integer, with values in\n * [0, 65535]
\n * "FLOAT": 32-bit floating point number\n * @param {boolean} normalized - Whether integer data values should be\n * normalized when being casted to a float.
\n * If true, signed integers are normalized to [-1, 1].
\n * If true, unsigned integers are normalized to [0, 1].
\n * For type "FLOAT", this parameter has no effect.\n */\n constructor(key, size, type, normalized = false) {\n this.key = key;\n this.size = size;\n this.type = type;\n this.normalized = normalized;\n switch (type) {\n case "BYTE":\n case "UNSIGNED_BYTE":\n this.sizeOfType = 1;\n break;\n case "SHORT":\n case "UNSIGNED_SHORT":\n this.sizeOfType = 2;\n break;\n case "FLOAT":\n this.sizeOfType = 4;\n break;\n default:\n throw new Error(`Unknown gl type: ${type}`);\n }\n this.sizeInBytes = this.sizeOfType * size;\n }\n}\n/**\n * A class to represent the memory layout for a vertex attribute array. Used by\n * {@link Mesh}\'s TBD(...) method to generate a packed array from mesh data.\n *

\n * Layout can sort of be thought of as a C-style struct declaration.\n * {@link Mesh}\'s TBD(...) method will use the {@link Layout} instance to\n * pack an array in the given attribute order.\n *

\n * Layout also is very helpful when calling a WebGL context\'s\n * vertexAttribPointer method. If you\'ve created a buffer using\n * a Layout instance, then the same Layout instance can be used to determine\n * the size, type, normalized, stride, and offset parameters for\n * vertexAttribPointer.\n *

\n * For example:\n *

\n *\n * const index = glctx.getAttribLocation(shaderProgram, "pos");\n * glctx.vertexAttribPointer(\n *   layout.position.size,\n *   glctx[layout.position.type],\n *   layout.position.normalized,\n *   layout.position.stride,\n *   layout.position.offset);\n * 
\n * @see {@link Mesh}\n */\nclass Layout {\n /**\n * Create a Layout object. This constructor will throw if any duplicate\n * attributes are given.\n * @param {Array} ...attributes - An ordered list of attributes that\n * describe the desired memory layout for each vertex attribute.\n *

\n *\n * @see {@link Mesh}\n */\n constructor(...attributes) {\n this.attributes = attributes;\n this.attributeMap = {};\n let offset = 0;\n let maxStrideMultiple = 0;\n for (const attribute of attributes) {\n if (this.attributeMap[attribute.key]) {\n throw new DuplicateAttributeException(attribute);\n }\n // Add padding to satisfy WebGL\'s requirement that all\n // vertexAttribPointer calls have an offset that is a multiple of\n // the type size.\n if (offset % attribute.sizeOfType !== 0) {\n offset += attribute.sizeOfType - (offset % attribute.sizeOfType);\n console.warn("Layout requires padding before " + attribute.key + " attribute");\n }\n this.attributeMap[attribute.key] = {\n attribute: attribute,\n size: attribute.size,\n type: attribute.type,\n normalized: attribute.normalized,\n offset: offset,\n };\n offset += attribute.sizeInBytes;\n maxStrideMultiple = Math.max(maxStrideMultiple, attribute.sizeOfType);\n }\n // Add padding to the end to satisfy WebGL\'s requirement that all\n // vertexAttribPointer calls have a stride that is a multiple of the\n // type size. Because we\'re putting differently sized attributes into\n // the same buffer, it must be padded to a multiple of the largest\n // type size.\n if (offset % maxStrideMultiple !== 0) {\n offset += maxStrideMultiple - (offset % maxStrideMultiple);\n console.warn("Layout requires padding at the back");\n }\n this.stride = offset;\n for (const attribute of attributes) {\n this.attributeMap[attribute.key].stride = this.stride;\n }\n }\n}\n// Geometry attributes\n/**\n * Attribute layout to pack a vertex\'s x, y, & z as floats\n *\n * @see {@link Layout}\n */\nLayout.POSITION = new Attribute("position", 3, TYPES.FLOAT);\n/**\n * Attribute layout to pack a vertex\'s normal\'s x, y, & z as floats\n *\n * @see {@link Layout}\n */\nLayout.NORMAL = new Attribute("normal", 3, TYPES.FLOAT);\n/**\n * Attribute layout to pack a vertex\'s normal\'s x, y, & z as floats.\n *

\n * This value will be computed on-the-fly based on the texture coordinates.\n * If no texture coordinates are available, the generated value will default to\n * 0, 0, 0.\n *\n * @see {@link Layout}\n */\nLayout.TANGENT = new Attribute("tangent", 3, TYPES.FLOAT);\n/**\n * Attribute layout to pack a vertex\'s normal\'s bitangent x, y, & z as floats.\n *

\n * This value will be computed on-the-fly based on the texture coordinates.\n * If no texture coordinates are available, the generated value will default to\n * 0, 0, 0.\n * @see {@link Layout}\n */\nLayout.BITANGENT = new Attribute("bitangent", 3, TYPES.FLOAT);\n/**\n * Attribute layout to pack a vertex\'s texture coordinates\' u & v as floats\n *\n * @see {@link Layout}\n */\nLayout.UV = new Attribute("uv", 2, TYPES.FLOAT);\n// Material attributes\n/**\n * Attribute layout to pack an unsigned short to be interpreted as a the index\n * into a {@link Mesh}\'s materials list.\n *

\n * The intention of this value is to send all of the {@link Mesh}\'s materials\n * into multiple shader uniforms and then reference the current one by this\n * vertex attribute.\n *

\n * example glsl code:\n *\n *

\n *  // this is bound using MATERIAL_INDEX\n *  attribute int materialIndex;\n *\n *  struct Material {\n *    vec3 diffuse;\n *    vec3 specular;\n *    vec3 specularExponent;\n *  };\n *\n *  uniform Material materials[MAX_MATERIALS];\n *\n *  // ...\n *\n *  vec3 diffuse = materials[materialIndex];\n *\n * 
\n * TODO: More description & test to make sure subscripting by attributes even\n * works for webgl\n *\n * @see {@link Layout}\n */\nLayout.MATERIAL_INDEX = new Attribute("materialIndex", 1, TYPES.SHORT);\nLayout.MATERIAL_ENABLED = new Attribute("materialEnabled", 1, TYPES.UNSIGNED_SHORT);\nLayout.AMBIENT = new Attribute("ambient", 3, TYPES.FLOAT);\nLayout.DIFFUSE = new Attribute("diffuse", 3, TYPES.FLOAT);\nLayout.SPECULAR = new Attribute("specular", 3, TYPES.FLOAT);\nLayout.SPECULAR_EXPONENT = new Attribute("specularExponent", 3, TYPES.FLOAT);\nLayout.EMISSIVE = new Attribute("emissive", 3, TYPES.FLOAT);\nLayout.TRANSMISSION_FILTER = new Attribute("transmissionFilter", 3, TYPES.FLOAT);\nLayout.DISSOLVE = new Attribute("dissolve", 1, TYPES.FLOAT);\nLayout.ILLUMINATION = new Attribute("illumination", 1, TYPES.UNSIGNED_SHORT);\nLayout.REFRACTION_INDEX = new Attribute("refractionIndex", 1, TYPES.FLOAT);\nLayout.SHARPNESS = new Attribute("sharpness", 1, TYPES.FLOAT);\nLayout.MAP_DIFFUSE = new Attribute("mapDiffuse", 1, TYPES.SHORT);\nLayout.MAP_AMBIENT = new Attribute("mapAmbient", 1, TYPES.SHORT);\nLayout.MAP_SPECULAR = new Attribute("mapSpecular", 1, TYPES.SHORT);\nLayout.MAP_SPECULAR_EXPONENT = new Attribute("mapSpecularExponent", 1, TYPES.SHORT);\nLayout.MAP_DISSOLVE = new Attribute("mapDissolve", 1, TYPES.SHORT);\nLayout.ANTI_ALIASING = new Attribute("antiAliasing", 1, TYPES.UNSIGNED_SHORT);\nLayout.MAP_BUMP = new Attribute("mapBump", 1, TYPES.SHORT);\nLayout.MAP_DISPLACEMENT = new Attribute("mapDisplacement", 1, TYPES.SHORT);\nLayout.MAP_DECAL = new Attribute("mapDecal", 1, TYPES.SHORT);\nLayout.MAP_EMISSIVE = new Attribute("mapEmissive", 1, TYPES.SHORT);\n\n\n//# sourceURL=webpack://OBJ/./src/layout.ts?')},"./src/material.ts": /*!*************************!*\ !*** ./src/material.ts ***! \*************************/ @@ -14,12 +14,12 @@ /*!*********************!*\ !*** ./src/mesh.ts ***! \*********************/ -/*! exports provided: default */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Mesh; });\n/* harmony import */ var _layout__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./layout */ "./src/layout.ts");\n\n/**\n * The main Mesh class. The constructor will parse through the OBJ file data\n * and collect the vertex, vertex normal, texture, and face information. This\n * information can then be used later on when creating your VBOs. See\n * OBJ.initMeshBuffers for an example of how to use the newly created Mesh\n */\nclass Mesh {\n /**\n * Create a Mesh\n * @param {String} objectData - a string representation of an OBJ file with\n * newlines preserved.\n * @param {Object} options - a JS object containing valid options. See class\n * documentation for options.\n * @param {bool} options.enableWTextureCoord - Texture coordinates can have\n * an optional "w" coordinate after the u and v coordinates. This extra\n * value can be used in order to perform fancy transformations on the\n * textures themselves. Default is to truncate to only the u an v\n * coordinates. Passing true will provide a default value of 0 in the\n * event that any or all texture coordinates don\'t provide a w value.\n * Always use the textureStride attribute in order to determine the\n * stride length of the texture coordinates when rendering the element\n * array.\n * @param {bool} options.calcTangentsAndBitangents - Calculate the tangents\n * and bitangents when loading of the OBJ is completed. This adds two new\n * attributes to the Mesh instance: `tangents` and `bitangents`.\n */\n constructor(objectData, options) {\n this.name = "";\n this.indicesPerMaterial = [];\n this.materialsByIndex = {};\n this.tangents = [];\n this.bitangents = [];\n options = options || {};\n options.materials = options.materials || {};\n options.enableWTextureCoord = !!options.enableWTextureCoord;\n // the list of unique vertex, normal, texture, attributes\n this.vertexNormals = [];\n this.textures = [];\n // the indicies to draw the faces\n this.indices = [];\n this.textureStride = options.enableWTextureCoord ? 3 : 2;\n /*\n The OBJ file format does a sort of compression when saving a model in a\n program like Blender. There are at least 3 sections (4 including textures)\n within the file. Each line in a section begins with the same string:\n * \'v\': indicates vertex section\n * \'vn\': indicates vertex normal section\n * \'f\': indicates the faces section\n * \'vt\': indicates vertex texture section (if textures were used on the model)\n Each of the above sections (except for the faces section) is a list/set of\n unique vertices.\n\n Each line of the faces section contains a list of\n (vertex, [texture], normal) groups.\n\n **Note:** The following documentation will use a capital "V" Vertex to\n denote the above (vertex, [texture], normal) groups whereas a lowercase\n "v" vertex is used to denote an X, Y, Z coordinate.\n\n Some examples:\n // the texture index is optional, both formats are possible for models\n // without a texture applied\n f 1/25 18/46 12/31\n f 1//25 18//46 12//31\n\n // A 3 vertex face with texture indices\n f 16/92/11 14/101/22 1/69/1\n\n // A 4 vertex face\n f 16/92/11 40/109/40 38/114/38 14/101/22\n\n The first two lines are examples of a 3 vertex face without a texture applied.\n The second is an example of a 3 vertex face with a texture applied.\n The third is an example of a 4 vertex face. Note: a face can contain N\n number of vertices.\n\n Each number that appears in one of the groups is a 1-based index\n corresponding to an item from the other sections (meaning that indexing\n starts at one and *not* zero).\n\n For example:\n `f 16/92/11` is saying to\n - take the 16th element from the [v] vertex array\n - take the 92nd element from the [vt] texture array\n - take the 11th element from the [vn] normal array\n and together they make a unique vertex.\n Using all 3+ unique Vertices from the face line will produce a polygon.\n\n Now, you could just go through the OBJ file and create a new vertex for\n each face line and WebGL will draw what appears to be the same model.\n However, vertices will be overlapped and duplicated all over the place.\n\n Consider a cube in 3D space centered about the origin and each side is\n 2 units long. The front face (with the positive Z-axis pointing towards\n you) would have a Top Right vertex (looking orthogonal to its normal)\n mapped at (1,1,1) The right face would have a Top Left vertex (looking\n orthogonal to its normal) at (1,1,1) and the top face would have a Bottom\n Right vertex (looking orthogonal to its normal) at (1,1,1). Each face\n has a vertex at the same coordinates, however, three distinct vertices\n will be drawn at the same spot.\n\n To solve the issue of duplicate Vertices (the `(vertex, [texture], normal)`\n groups), while iterating through the face lines, when a group is encountered\n the whole group string (\'16/92/11\') is checked to see if it exists in the\n packed.hashindices object, and if it doesn\'t, the indices it specifies\n are used to look up each attribute in the corresponding attribute arrays\n already created. The values are then copied to the corresponding unpacked\n array (flattened to play nice with WebGL\'s ELEMENT_ARRAY_BUFFER indexing),\n the group string is added to the hashindices set and the current unpacked\n index is used as this hashindices value so that the group of elements can\n be reused. The unpacked index is incremented. If the group string already\n exists in the hashindices object, its corresponding value is the index of\n that group and is appended to the unpacked indices array.\n */\n const verts = [];\n const vertNormals = [];\n const textures = [];\n const materialNamesByIndex = [];\n const materialIndicesByName = {};\n // keep track of what material we\'ve seen last\n let currentMaterialIndex = -1;\n let currentObjectByMaterialIndex = 0;\n // unpacking stuff\n const unpacked = {\n verts: [],\n norms: [],\n textures: [],\n hashindices: {},\n indices: [[]],\n materialIndices: [],\n index: 0,\n };\n const VERTEX_RE = /^v\\s/;\n const NORMAL_RE = /^vn\\s/;\n const TEXTURE_RE = /^vt\\s/;\n const FACE_RE = /^f\\s/;\n const WHITESPACE_RE = /\\s+/;\n const USE_MATERIAL_RE = /^usemtl/;\n // array of lines separated by the newline\n const lines = objectData.split("\\n");\n for (let line of lines) {\n line = line.trim();\n if (!line || line.startsWith("#")) {\n continue;\n }\n const elements = line.split(WHITESPACE_RE);\n elements.shift();\n if (VERTEX_RE.test(line)) {\n // if this is a vertex\n verts.push(...elements);\n }\n else if (NORMAL_RE.test(line)) {\n // if this is a vertex normal\n vertNormals.push(...elements);\n }\n else if (TEXTURE_RE.test(line)) {\n let coords = elements;\n // by default, the loader will only look at the U and V\n // coordinates of the vt declaration. So, this truncates the\n // elements to only those 2 values. If W texture coordinate\n // support is enabled, then the texture coordinate is\n // expected to have three values in it.\n if (elements.length > 2 && !options.enableWTextureCoord) {\n coords = elements.slice(0, 2);\n }\n else if (elements.length === 2 && options.enableWTextureCoord) {\n // If for some reason W texture coordinate support is enabled\n // and only the U and V coordinates are given, then we supply\n // the default value of 0 so that the stride length is correct\n // when the textures are unpacked below.\n coords.push("0");\n }\n textures.push(...coords);\n }\n else if (USE_MATERIAL_RE.test(line)) {\n const materialName = elements[0];\n // check to see if we\'ve ever seen it before\n if (!(materialName in materialIndicesByName)) {\n // new material we\'ve never seen\n materialNamesByIndex.push(materialName);\n materialIndicesByName[materialName] = materialNamesByIndex.length - 1;\n // push new array into indices\n // already contains an array at index zero, don\'t add\n if (materialIndicesByName[materialName] > 0) {\n unpacked.indices.push([]);\n }\n }\n // keep track of the current material index\n currentMaterialIndex = materialIndicesByName[materialName];\n // update current index array\n currentObjectByMaterialIndex = currentMaterialIndex;\n }\n else if (FACE_RE.test(line)) {\n // if this is a face\n /*\n split this face into an array of Vertex groups\n for example:\n f 16/92/11 14/101/22 1/69/1\n becomes:\n [\'16/92/11\', \'14/101/22\', \'1/69/1\'];\n */\n const triangles = triangulate(elements);\n for (const triangle of triangles) {\n for (let j = 0, eleLen = triangle.length; j < eleLen; j++) {\n const hash = triangle[j] + "," + currentMaterialIndex;\n if (hash in unpacked.hashindices) {\n unpacked.indices[currentObjectByMaterialIndex].push(unpacked.hashindices[hash]);\n }\n else {\n /*\n Each element of the face line array is a Vertex which has its\n attributes delimited by a forward slash. This will separate\n each attribute into another array:\n \'19/92/11\'\n becomes:\n Vertex = [\'19\', \'92\', \'11\'];\n where\n Vertex[0] is the vertex index\n Vertex[1] is the texture index\n Vertex[2] is the normal index\n Think of faces having Vertices which are comprised of the\n attributes location (v), texture (vt), and normal (vn).\n */\n const vertex = elements[j].split("/");\n // it\'s possible for faces to only specify the vertex\n // and the normal. In this case, vertex will only have\n // a length of 2 and not 3 and the normal will be the\n // second item in the list with an index of 1.\n const normalIndex = vertex.length - 1;\n /*\n The verts, textures, and vertNormals arrays each contain a\n flattend array of coordinates.\n\n Because it gets confusing by referring to Vertex and then\n vertex (both are different in my descriptions) I will explain\n what\'s going on using the vertexNormals array:\n\n vertex[2] will contain the one-based index of the vertexNormals\n section (vn). One is subtracted from this index number to play\n nice with javascript\'s zero-based array indexing.\n\n Because vertexNormal is a flattened array of x, y, z values,\n simple pointer arithmetic is used to skip to the start of the\n vertexNormal, then the offset is added to get the correct\n component: +0 is x, +1 is y, +2 is z.\n\n This same process is repeated for verts and textures.\n */\n // Vertex position\n unpacked.verts.push(+verts[(+vertex[0] - 1) * 3 + 0]);\n unpacked.verts.push(+verts[(+vertex[0] - 1) * 3 + 1]);\n unpacked.verts.push(+verts[(+vertex[0] - 1) * 3 + 2]);\n // Vertex textures\n if (textures.length) {\n const stride = options.enableWTextureCoord ? 3 : 2;\n unpacked.textures.push(+textures[(+vertex[1] - 1) * stride + 0]);\n unpacked.textures.push(+textures[(+vertex[1] - 1) * stride + 1]);\n if (options.enableWTextureCoord) {\n unpacked.textures.push(+textures[(+vertex[1] - 1) * stride + 2]);\n }\n }\n // Vertex normals\n unpacked.norms.push(+vertNormals[(+vertex[normalIndex] - 1) * 3 + 0]);\n unpacked.norms.push(+vertNormals[(+vertex[normalIndex] - 1) * 3 + 1]);\n unpacked.norms.push(+vertNormals[(+vertex[normalIndex] - 1) * 3 + 2]);\n // Vertex material indices\n unpacked.materialIndices.push(currentMaterialIndex);\n // add the newly created Vertex to the list of indices\n unpacked.hashindices[hash] = unpacked.index;\n unpacked.indices[currentObjectByMaterialIndex].push(unpacked.hashindices[hash]);\n // increment the counter\n unpacked.index += 1;\n }\n }\n }\n }\n }\n this.vertices = unpacked.verts;\n this.vertexNormals = unpacked.norms;\n this.textures = unpacked.textures;\n this.vertexMaterialIndices = unpacked.materialIndices;\n this.indices = unpacked.indices[currentObjectByMaterialIndex];\n this.indicesPerMaterial = unpacked.indices;\n this.materialNames = materialNamesByIndex;\n this.materialIndices = materialIndicesByName;\n this.materialsByIndex = {};\n if (options.calcTangentsAndBitangents) {\n this.calculateTangentsAndBitangents();\n }\n }\n /**\n * Calculates the tangents and bitangents of the mesh that forms an orthogonal basis together with the\n * normal in the direction of the texture coordinates. These are useful for setting up the TBN matrix\n * when distorting the normals through normal maps.\n * Method derived from: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/\n *\n * This method requires the normals and texture coordinates to be parsed and set up correctly.\n * Adds the tangents and bitangents as members of the class instance.\n */\n calculateTangentsAndBitangents() {\n console.assert(!!(this.vertices &&\n this.vertices.length &&\n this.vertexNormals &&\n this.vertexNormals.length &&\n this.textures &&\n this.textures.length), "Missing attributes for calculating tangents and bitangents");\n const unpacked = {\n tangents: [...new Array(this.vertices.length)].map(_ => 0),\n bitangents: [...new Array(this.vertices.length)].map(_ => 0),\n };\n // Loop through all faces in the whole mesh\n const indices = this.indices;\n const vertices = this.vertices;\n const normals = this.vertexNormals;\n const uvs = this.textures;\n for (let i = 0; i < indices.length; i += 3) {\n const i0 = indices[i + 0];\n const i1 = indices[i + 1];\n const i2 = indices[i + 2];\n const x_v0 = vertices[i0 * 3 + 0];\n const y_v0 = vertices[i0 * 3 + 1];\n const z_v0 = vertices[i0 * 3 + 2];\n const x_uv0 = uvs[i0 * 2 + 0];\n const y_uv0 = uvs[i0 * 2 + 1];\n const x_v1 = vertices[i1 * 3 + 0];\n const y_v1 = vertices[i1 * 3 + 1];\n const z_v1 = vertices[i1 * 3 + 2];\n const x_uv1 = uvs[i1 * 2 + 0];\n const y_uv1 = uvs[i1 * 2 + 1];\n const x_v2 = vertices[i2 * 3 + 0];\n const y_v2 = vertices[i2 * 3 + 1];\n const z_v2 = vertices[i2 * 3 + 2];\n const x_uv2 = uvs[i2 * 2 + 0];\n const y_uv2 = uvs[i2 * 2 + 1];\n const x_deltaPos1 = x_v1 - x_v0;\n const y_deltaPos1 = y_v1 - y_v0;\n const z_deltaPos1 = z_v1 - z_v0;\n const x_deltaPos2 = x_v2 - x_v0;\n const y_deltaPos2 = y_v2 - y_v0;\n const z_deltaPos2 = z_v2 - z_v0;\n const x_uvDeltaPos1 = x_uv1 - x_uv0;\n const y_uvDeltaPos1 = y_uv1 - y_uv0;\n const x_uvDeltaPos2 = x_uv2 - x_uv0;\n const y_uvDeltaPos2 = y_uv2 - y_uv0;\n const rInv = x_uvDeltaPos1 * y_uvDeltaPos2 - y_uvDeltaPos1 * x_uvDeltaPos2;\n const r = 1.0 / Math.abs(rInv < 0.0001 ? 1.0 : rInv);\n // Tangent\n const x_tangent = (x_deltaPos1 * y_uvDeltaPos2 - x_deltaPos2 * y_uvDeltaPos1) * r;\n const y_tangent = (y_deltaPos1 * y_uvDeltaPos2 - y_deltaPos2 * y_uvDeltaPos1) * r;\n const z_tangent = (z_deltaPos1 * y_uvDeltaPos2 - z_deltaPos2 * y_uvDeltaPos1) * r;\n // Bitangent\n const x_bitangent = (x_deltaPos2 * x_uvDeltaPos1 - x_deltaPos1 * x_uvDeltaPos2) * r;\n const y_bitangent = (y_deltaPos2 * x_uvDeltaPos1 - y_deltaPos1 * x_uvDeltaPos2) * r;\n const z_bitangent = (z_deltaPos2 * x_uvDeltaPos1 - z_deltaPos1 * x_uvDeltaPos2) * r;\n // Gram-Schmidt orthogonalize\n //t = glm::normalize(t - n * glm:: dot(n, t));\n const x_n0 = normals[i0 * 3 + 0];\n const y_n0 = normals[i0 * 3 + 1];\n const z_n0 = normals[i0 * 3 + 2];\n const x_n1 = normals[i1 * 3 + 0];\n const y_n1 = normals[i1 * 3 + 1];\n const z_n1 = normals[i1 * 3 + 2];\n const x_n2 = normals[i2 * 3 + 0];\n const y_n2 = normals[i2 * 3 + 1];\n const z_n2 = normals[i2 * 3 + 2];\n // Tangent\n const n0_dot_t = x_tangent * x_n0 + y_tangent * y_n0 + z_tangent * z_n0;\n const n1_dot_t = x_tangent * x_n1 + y_tangent * y_n1 + z_tangent * z_n1;\n const n2_dot_t = x_tangent * x_n2 + y_tangent * y_n2 + z_tangent * z_n2;\n const x_resTangent0 = x_tangent - x_n0 * n0_dot_t;\n const y_resTangent0 = y_tangent - y_n0 * n0_dot_t;\n const z_resTangent0 = z_tangent - z_n0 * n0_dot_t;\n const x_resTangent1 = x_tangent - x_n1 * n1_dot_t;\n const y_resTangent1 = y_tangent - y_n1 * n1_dot_t;\n const z_resTangent1 = z_tangent - z_n1 * n1_dot_t;\n const x_resTangent2 = x_tangent - x_n2 * n2_dot_t;\n const y_resTangent2 = y_tangent - y_n2 * n2_dot_t;\n const z_resTangent2 = z_tangent - z_n2 * n2_dot_t;\n const magTangent0 = Math.sqrt(x_resTangent0 * x_resTangent0 + y_resTangent0 * y_resTangent0 + z_resTangent0 * z_resTangent0);\n const magTangent1 = Math.sqrt(x_resTangent1 * x_resTangent1 + y_resTangent1 * y_resTangent1 + z_resTangent1 * z_resTangent1);\n const magTangent2 = Math.sqrt(x_resTangent2 * x_resTangent2 + y_resTangent2 * y_resTangent2 + z_resTangent2 * z_resTangent2);\n // Bitangent\n const n0_dot_bt = x_bitangent * x_n0 + y_bitangent * y_n0 + z_bitangent * z_n0;\n const n1_dot_bt = x_bitangent * x_n1 + y_bitangent * y_n1 + z_bitangent * z_n1;\n const n2_dot_bt = x_bitangent * x_n2 + y_bitangent * y_n2 + z_bitangent * z_n2;\n const x_resBitangent0 = x_bitangent - x_n0 * n0_dot_bt;\n const y_resBitangent0 = y_bitangent - y_n0 * n0_dot_bt;\n const z_resBitangent0 = z_bitangent - z_n0 * n0_dot_bt;\n const x_resBitangent1 = x_bitangent - x_n1 * n1_dot_bt;\n const y_resBitangent1 = y_bitangent - y_n1 * n1_dot_bt;\n const z_resBitangent1 = z_bitangent - z_n1 * n1_dot_bt;\n const x_resBitangent2 = x_bitangent - x_n2 * n2_dot_bt;\n const y_resBitangent2 = y_bitangent - y_n2 * n2_dot_bt;\n const z_resBitangent2 = z_bitangent - z_n2 * n2_dot_bt;\n const magBitangent0 = Math.sqrt(x_resBitangent0 * x_resBitangent0 +\n y_resBitangent0 * y_resBitangent0 +\n z_resBitangent0 * z_resBitangent0);\n const magBitangent1 = Math.sqrt(x_resBitangent1 * x_resBitangent1 +\n y_resBitangent1 * y_resBitangent1 +\n z_resBitangent1 * z_resBitangent1);\n const magBitangent2 = Math.sqrt(x_resBitangent2 * x_resBitangent2 +\n y_resBitangent2 * y_resBitangent2 +\n z_resBitangent2 * z_resBitangent2);\n unpacked.tangents[i0 * 3 + 0] += x_resTangent0 / magTangent0;\n unpacked.tangents[i0 * 3 + 1] += y_resTangent0 / magTangent0;\n unpacked.tangents[i0 * 3 + 2] += z_resTangent0 / magTangent0;\n unpacked.tangents[i1 * 3 + 0] += x_resTangent1 / magTangent1;\n unpacked.tangents[i1 * 3 + 1] += y_resTangent1 / magTangent1;\n unpacked.tangents[i1 * 3 + 2] += z_resTangent1 / magTangent1;\n unpacked.tangents[i2 * 3 + 0] += x_resTangent2 / magTangent2;\n unpacked.tangents[i2 * 3 + 1] += y_resTangent2 / magTangent2;\n unpacked.tangents[i2 * 3 + 2] += z_resTangent2 / magTangent2;\n unpacked.bitangents[i0 * 3 + 0] += x_resBitangent0 / magBitangent0;\n unpacked.bitangents[i0 * 3 + 1] += y_resBitangent0 / magBitangent0;\n unpacked.bitangents[i0 * 3 + 2] += z_resBitangent0 / magBitangent0;\n unpacked.bitangents[i1 * 3 + 0] += x_resBitangent1 / magBitangent1;\n unpacked.bitangents[i1 * 3 + 1] += y_resBitangent1 / magBitangent1;\n unpacked.bitangents[i1 * 3 + 2] += z_resBitangent1 / magBitangent1;\n unpacked.bitangents[i2 * 3 + 0] += x_resBitangent2 / magBitangent2;\n unpacked.bitangents[i2 * 3 + 1] += y_resBitangent2 / magBitangent2;\n unpacked.bitangents[i2 * 3 + 2] += z_resBitangent2 / magBitangent2;\n // TODO: check handedness\n }\n this.tangents = unpacked.tangents;\n this.bitangents = unpacked.bitangents;\n }\n /**\n * @param layout - A {@link Layout} object that describes the\n * desired memory layout of the generated buffer\n * @return The packed array in the ... TODO\n */\n makeBufferData(layout) {\n const numItems = this.vertices.length / 3;\n const buffer = new ArrayBuffer(layout.stride * numItems);\n buffer.numItems = numItems;\n const dataView = new DataView(buffer);\n for (let i = 0, vertexOffset = 0; i < numItems; i++) {\n vertexOffset = i * layout.stride;\n // copy in the vertex data in the order and format given by the\n // layout param\n for (const attribute of layout.attributes) {\n const offset = vertexOffset + layout.attributeMap[attribute.key].offset;\n switch (attribute.key) {\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].POSITION.key:\n dataView.setFloat32(offset, this.vertices[i * 3], true);\n dataView.setFloat32(offset + 4, this.vertices[i * 3 + 1], true);\n dataView.setFloat32(offset + 8, this.vertices[i * 3 + 2], true);\n break;\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].UV.key:\n dataView.setFloat32(offset, this.textures[i * 2], true);\n dataView.setFloat32(offset + 4, this.textures[i * 2 + 1], true);\n break;\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].NORMAL.key:\n dataView.setFloat32(offset, this.vertexNormals[i * 3], true);\n dataView.setFloat32(offset + 4, this.vertexNormals[i * 3 + 1], true);\n dataView.setFloat32(offset + 8, this.vertexNormals[i * 3 + 2], true);\n break;\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].MATERIAL_INDEX.key:\n dataView.setInt16(offset, this.vertexMaterialIndices[i], true);\n break;\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].AMBIENT.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.ambient[0], true);\n dataView.setFloat32(offset + 4, material.ambient[1], true);\n dataView.setFloat32(offset + 8, material.ambient[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].DIFFUSE.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.diffuse[0], true);\n dataView.setFloat32(offset + 4, material.diffuse[1], true);\n dataView.setFloat32(offset + 8, material.diffuse[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].SPECULAR.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.specular[0], true);\n dataView.setFloat32(offset + 4, material.specular[1], true);\n dataView.setFloat32(offset + 8, material.specular[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].SPECULAR_EXPONENT.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.specularExponent, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].EMISSIVE.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.emissive[0], true);\n dataView.setFloat32(offset + 4, material.emissive[1], true);\n dataView.setFloat32(offset + 8, material.emissive[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].TRANSMISSION_FILTER.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.transmissionFilter[0], true);\n dataView.setFloat32(offset + 4, material.transmissionFilter[1], true);\n dataView.setFloat32(offset + 8, material.transmissionFilter[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].DISSOLVE.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.dissolve, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].ILLUMINATION.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setInt16(offset, material.illumination, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].REFRACTION_INDEX.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.refractionIndex, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].SHARPNESS.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.sharpness, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].ANTI_ALIASING.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setInt16(offset, material.antiAliasing ? 1 : 0, true);\n break;\n }\n }\n }\n }\n return buffer;\n }\n makeIndexBufferData() {\n const buffer = new Uint16Array(this.indices);\n buffer.numItems = this.indices.length;\n return buffer;\n }\n addMaterialLibrary(mtl) {\n for (const name in mtl.materials) {\n if (!(name in this.materialIndices)) {\n // This material is not referenced by the mesh\n continue;\n }\n const material = mtl.materials[name];\n // Find the material index for this material\n const materialIndex = this.materialIndices[material.name];\n // Put the material into the materialsByIndex object at the right\n // spot as determined when the obj file was parsed\n this.materialsByIndex[materialIndex] = material;\n }\n }\n}\nfunction* triangulate(elements) {\n if (elements.length <= 3) {\n yield elements;\n }\n else if (elements.length === 4) {\n yield [elements[0], elements[1], elements[2]];\n yield [elements[2], elements[3], elements[0]];\n }\n else {\n for (let i = 1; i < elements.length - 1; i++) {\n yield [elements[0], elements[i], elements[i + 1]];\n }\n }\n}\n\n\n//# sourceURL=webpack://OBJ/./src/mesh.ts?')},"./src/utils.ts": +/*! exports provided: default */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Mesh; });\n/* harmony import */ var _layout__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./layout */ "./src/layout.ts");\n\n/**\n * The main Mesh class. The constructor will parse through the OBJ file data\n * and collect the vertex, vertex normal, texture, and face information. This\n * information can then be used later on when creating your VBOs. See\n * OBJ.initMeshBuffers for an example of how to use the newly created Mesh\n */\nclass Mesh {\n /**\n * Create a Mesh\n * @param {String} objectData - a string representation of an OBJ file with\n * newlines preserved.\n * @param {Object} options - a JS object containing valid options. See class\n * documentation for options.\n * @param {bool} options.enableWTextureCoord - Texture coordinates can have\n * an optional "w" coordinate after the u and v coordinates. This extra\n * value can be used in order to perform fancy transformations on the\n * textures themselves. Default is to truncate to only the u an v\n * coordinates. Passing true will provide a default value of 0 in the\n * event that any or all texture coordinates don\'t provide a w value.\n * Always use the textureStride attribute in order to determine the\n * stride length of the texture coordinates when rendering the element\n * array.\n * @param {bool} options.calcTangentsAndBitangents - Calculate the tangents\n * and bitangents when loading of the OBJ is completed. This adds two new\n * attributes to the Mesh instance: `tangents` and `bitangents`.\n */\n constructor(objectData, options) {\n this.name = "";\n this.indicesPerMaterial = [];\n this.materialsByIndex = {};\n this.tangents = [];\n this.bitangents = [];\n options = options || {};\n options.materials = options.materials || {};\n options.enableWTextureCoord = !!options.enableWTextureCoord;\n // the list of unique vertex, normal, texture, attributes\n this.vertexNormals = [];\n this.textures = [];\n // the indicies to draw the faces\n this.indices = [];\n this.textureStride = options.enableWTextureCoord ? 3 : 2;\n /*\n The OBJ file format does a sort of compression when saving a model in a\n program like Blender. There are at least 3 sections (4 including textures)\n within the file. Each line in a section begins with the same string:\n * \'v\': indicates vertex section\n * \'vn\': indicates vertex normal section\n * \'f\': indicates the faces section\n * \'vt\': indicates vertex texture section (if textures were used on the model)\n Each of the above sections (except for the faces section) is a list/set of\n unique vertices.\n\n Each line of the faces section contains a list of\n (vertex, [texture], normal) groups.\n\n **Note:** The following documentation will use a capital "V" Vertex to\n denote the above (vertex, [texture], normal) groups whereas a lowercase\n "v" vertex is used to denote an X, Y, Z coordinate.\n\n Some examples:\n // the texture index is optional, both formats are possible for models\n // without a texture applied\n f 1/25 18/46 12/31\n f 1//25 18//46 12//31\n\n // A 3 vertex face with texture indices\n f 16/92/11 14/101/22 1/69/1\n\n // A 4 vertex face\n f 16/92/11 40/109/40 38/114/38 14/101/22\n\n The first two lines are examples of a 3 vertex face without a texture applied.\n The second is an example of a 3 vertex face with a texture applied.\n The third is an example of a 4 vertex face. Note: a face can contain N\n number of vertices.\n\n Each number that appears in one of the groups is a 1-based index\n corresponding to an item from the other sections (meaning that indexing\n starts at one and *not* zero).\n\n For example:\n `f 16/92/11` is saying to\n - take the 16th element from the [v] vertex array\n - take the 92nd element from the [vt] texture array\n - take the 11th element from the [vn] normal array\n and together they make a unique vertex.\n Using all 3+ unique Vertices from the face line will produce a polygon.\n\n Now, you could just go through the OBJ file and create a new vertex for\n each face line and WebGL will draw what appears to be the same model.\n However, vertices will be overlapped and duplicated all over the place.\n\n Consider a cube in 3D space centered about the origin and each side is\n 2 units long. The front face (with the positive Z-axis pointing towards\n you) would have a Top Right vertex (looking orthogonal to its normal)\n mapped at (1,1,1) The right face would have a Top Left vertex (looking\n orthogonal to its normal) at (1,1,1) and the top face would have a Bottom\n Right vertex (looking orthogonal to its normal) at (1,1,1). Each face\n has a vertex at the same coordinates, however, three distinct vertices\n will be drawn at the same spot.\n\n To solve the issue of duplicate Vertices (the `(vertex, [texture], normal)`\n groups), while iterating through the face lines, when a group is encountered\n the whole group string (\'16/92/11\') is checked to see if it exists in the\n packed.hashindices object, and if it doesn\'t, the indices it specifies\n are used to look up each attribute in the corresponding attribute arrays\n already created. The values are then copied to the corresponding unpacked\n array (flattened to play nice with WebGL\'s ELEMENT_ARRAY_BUFFER indexing),\n the group string is added to the hashindices set and the current unpacked\n index is used as this hashindices value so that the group of elements can\n be reused. The unpacked index is incremented. If the group string already\n exists in the hashindices object, its corresponding value is the index of\n that group and is appended to the unpacked indices array.\n */\n const verts = [];\n const vertNormals = [];\n const textures = [];\n const materialNamesByIndex = [];\n const materialIndicesByName = {};\n // keep track of what material we\'ve seen last\n let currentMaterialIndex = -1;\n let currentObjectByMaterialIndex = 0;\n // unpacking stuff\n const unpacked = {\n verts: [],\n norms: [],\n textures: [],\n hashindices: {},\n indices: [[]],\n materialIndices: [],\n index: 0,\n };\n const VERTEX_RE = /^v\\s/;\n const NORMAL_RE = /^vn\\s/;\n const TEXTURE_RE = /^vt\\s/;\n const FACE_RE = /^f\\s/;\n const WHITESPACE_RE = /\\s+/;\n const USE_MATERIAL_RE = /^usemtl/;\n // array of lines separated by the newline\n const lines = objectData.split("\\n");\n for (let line of lines) {\n line = line.trim();\n if (!line || line.startsWith("#")) {\n continue;\n }\n const elements = line.split(WHITESPACE_RE);\n elements.shift();\n if (VERTEX_RE.test(line)) {\n // if this is a vertex\n verts.push(...elements);\n }\n else if (NORMAL_RE.test(line)) {\n // if this is a vertex normal\n vertNormals.push(...elements);\n }\n else if (TEXTURE_RE.test(line)) {\n let coords = elements;\n // by default, the loader will only look at the U and V\n // coordinates of the vt declaration. So, this truncates the\n // elements to only those 2 values. If W texture coordinate\n // support is enabled, then the texture coordinate is\n // expected to have three values in it.\n if (elements.length > 2 && !options.enableWTextureCoord) {\n coords = elements.slice(0, 2);\n }\n else if (elements.length === 2 && options.enableWTextureCoord) {\n // If for some reason W texture coordinate support is enabled\n // and only the U and V coordinates are given, then we supply\n // the default value of 0 so that the stride length is correct\n // when the textures are unpacked below.\n coords.push("0");\n }\n textures.push(...coords);\n }\n else if (USE_MATERIAL_RE.test(line)) {\n const materialName = elements[0];\n // check to see if we\'ve ever seen it before\n if (!(materialName in materialIndicesByName)) {\n // new material we\'ve never seen\n materialNamesByIndex.push(materialName);\n materialIndicesByName[materialName] = materialNamesByIndex.length - 1;\n // push new array into indices\n // already contains an array at index zero, don\'t add\n if (materialIndicesByName[materialName] > 0) {\n unpacked.indices.push([]);\n }\n }\n // keep track of the current material index\n currentMaterialIndex = materialIndicesByName[materialName];\n // update current index array\n currentObjectByMaterialIndex = currentMaterialIndex;\n }\n else if (FACE_RE.test(line)) {\n // if this is a face\n /*\n split this face into an array of Vertex groups\n for example:\n f 16/92/11 14/101/22 1/69/1\n becomes:\n [\'16/92/11\', \'14/101/22\', \'1/69/1\'];\n */\n const triangles = triangulate(elements);\n for (const triangle of triangles) {\n for (let j = 0, eleLen = triangle.length; j < eleLen; j++) {\n const hash = triangle[j] + "," + currentMaterialIndex;\n if (hash in unpacked.hashindices) {\n unpacked.indices[currentObjectByMaterialIndex].push(unpacked.hashindices[hash]);\n }\n else {\n /*\n Each element of the face line array is a Vertex which has its\n attributes delimited by a forward slash. This will separate\n each attribute into another array:\n \'19/92/11\'\n becomes:\n Vertex = [\'19\', \'92\', \'11\'];\n where\n Vertex[0] is the vertex index\n Vertex[1] is the texture index\n Vertex[2] is the normal index\n Think of faces having Vertices which are comprised of the\n attributes location (v), texture (vt), and normal (vn).\n */\n const vertex = triangle[j].split("/");\n // it\'s possible for faces to only specify the vertex\n // and the normal. In this case, vertex will only have\n // a length of 2 and not 3 and the normal will be the\n // second item in the list with an index of 1.\n const normalIndex = vertex.length - 1;\n /*\n The verts, textures, and vertNormals arrays each contain a\n flattend array of coordinates.\n\n Because it gets confusing by referring to Vertex and then\n vertex (both are different in my descriptions) I will explain\n what\'s going on using the vertexNormals array:\n\n vertex[2] will contain the one-based index of the vertexNormals\n section (vn). One is subtracted from this index number to play\n nice with javascript\'s zero-based array indexing.\n\n Because vertexNormal is a flattened array of x, y, z values,\n simple pointer arithmetic is used to skip to the start of the\n vertexNormal, then the offset is added to get the correct\n component: +0 is x, +1 is y, +2 is z.\n\n This same process is repeated for verts and textures.\n */\n // Vertex position\n unpacked.verts.push(+verts[(+vertex[0] - 1) * 3 + 0]);\n unpacked.verts.push(+verts[(+vertex[0] - 1) * 3 + 1]);\n unpacked.verts.push(+verts[(+vertex[0] - 1) * 3 + 2]);\n // Vertex textures\n if (textures.length) {\n const stride = options.enableWTextureCoord ? 3 : 2;\n unpacked.textures.push(+textures[(+vertex[1] - 1) * stride + 0]);\n unpacked.textures.push(+textures[(+vertex[1] - 1) * stride + 1]);\n if (options.enableWTextureCoord) {\n unpacked.textures.push(+textures[(+vertex[1] - 1) * stride + 2]);\n }\n }\n // Vertex normals\n unpacked.norms.push(+vertNormals[(+vertex[normalIndex] - 1) * 3 + 0]);\n unpacked.norms.push(+vertNormals[(+vertex[normalIndex] - 1) * 3 + 1]);\n unpacked.norms.push(+vertNormals[(+vertex[normalIndex] - 1) * 3 + 2]);\n // Vertex material indices\n unpacked.materialIndices.push(currentMaterialIndex);\n // add the newly created Vertex to the list of indices\n unpacked.hashindices[hash] = unpacked.index;\n unpacked.indices[currentObjectByMaterialIndex].push(unpacked.hashindices[hash]);\n // increment the counter\n unpacked.index += 1;\n }\n }\n }\n }\n }\n this.vertices = unpacked.verts;\n this.vertexNormals = unpacked.norms;\n this.textures = unpacked.textures;\n this.vertexMaterialIndices = unpacked.materialIndices;\n this.indices = unpacked.indices[currentObjectByMaterialIndex];\n this.indicesPerMaterial = unpacked.indices;\n this.materialNames = materialNamesByIndex;\n this.materialIndices = materialIndicesByName;\n this.materialsByIndex = {};\n if (options.calcTangentsAndBitangents) {\n this.calculateTangentsAndBitangents();\n }\n }\n /**\n * Calculates the tangents and bitangents of the mesh that forms an orthogonal basis together with the\n * normal in the direction of the texture coordinates. These are useful for setting up the TBN matrix\n * when distorting the normals through normal maps.\n * Method derived from: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/\n *\n * This method requires the normals and texture coordinates to be parsed and set up correctly.\n * Adds the tangents and bitangents as members of the class instance.\n */\n calculateTangentsAndBitangents() {\n console.assert(!!(this.vertices &&\n this.vertices.length &&\n this.vertexNormals &&\n this.vertexNormals.length &&\n this.textures &&\n this.textures.length), "Missing attributes for calculating tangents and bitangents");\n const unpacked = {\n tangents: [...new Array(this.vertices.length)].map(_ => 0),\n bitangents: [...new Array(this.vertices.length)].map(_ => 0),\n };\n // Loop through all faces in the whole mesh\n const indices = this.indices;\n const vertices = this.vertices;\n const normals = this.vertexNormals;\n const uvs = this.textures;\n for (let i = 0; i < indices.length; i += 3) {\n const i0 = indices[i + 0];\n const i1 = indices[i + 1];\n const i2 = indices[i + 2];\n const x_v0 = vertices[i0 * 3 + 0];\n const y_v0 = vertices[i0 * 3 + 1];\n const z_v0 = vertices[i0 * 3 + 2];\n const x_uv0 = uvs[i0 * 2 + 0];\n const y_uv0 = uvs[i0 * 2 + 1];\n const x_v1 = vertices[i1 * 3 + 0];\n const y_v1 = vertices[i1 * 3 + 1];\n const z_v1 = vertices[i1 * 3 + 2];\n const x_uv1 = uvs[i1 * 2 + 0];\n const y_uv1 = uvs[i1 * 2 + 1];\n const x_v2 = vertices[i2 * 3 + 0];\n const y_v2 = vertices[i2 * 3 + 1];\n const z_v2 = vertices[i2 * 3 + 2];\n const x_uv2 = uvs[i2 * 2 + 0];\n const y_uv2 = uvs[i2 * 2 + 1];\n const x_deltaPos1 = x_v1 - x_v0;\n const y_deltaPos1 = y_v1 - y_v0;\n const z_deltaPos1 = z_v1 - z_v0;\n const x_deltaPos2 = x_v2 - x_v0;\n const y_deltaPos2 = y_v2 - y_v0;\n const z_deltaPos2 = z_v2 - z_v0;\n const x_uvDeltaPos1 = x_uv1 - x_uv0;\n const y_uvDeltaPos1 = y_uv1 - y_uv0;\n const x_uvDeltaPos2 = x_uv2 - x_uv0;\n const y_uvDeltaPos2 = y_uv2 - y_uv0;\n const rInv = x_uvDeltaPos1 * y_uvDeltaPos2 - y_uvDeltaPos1 * x_uvDeltaPos2;\n const r = 1.0 / Math.abs(rInv < 0.0001 ? 1.0 : rInv);\n // Tangent\n const x_tangent = (x_deltaPos1 * y_uvDeltaPos2 - x_deltaPos2 * y_uvDeltaPos1) * r;\n const y_tangent = (y_deltaPos1 * y_uvDeltaPos2 - y_deltaPos2 * y_uvDeltaPos1) * r;\n const z_tangent = (z_deltaPos1 * y_uvDeltaPos2 - z_deltaPos2 * y_uvDeltaPos1) * r;\n // Bitangent\n const x_bitangent = (x_deltaPos2 * x_uvDeltaPos1 - x_deltaPos1 * x_uvDeltaPos2) * r;\n const y_bitangent = (y_deltaPos2 * x_uvDeltaPos1 - y_deltaPos1 * x_uvDeltaPos2) * r;\n const z_bitangent = (z_deltaPos2 * x_uvDeltaPos1 - z_deltaPos1 * x_uvDeltaPos2) * r;\n // Gram-Schmidt orthogonalize\n //t = glm::normalize(t - n * glm:: dot(n, t));\n const x_n0 = normals[i0 * 3 + 0];\n const y_n0 = normals[i0 * 3 + 1];\n const z_n0 = normals[i0 * 3 + 2];\n const x_n1 = normals[i1 * 3 + 0];\n const y_n1 = normals[i1 * 3 + 1];\n const z_n1 = normals[i1 * 3 + 2];\n const x_n2 = normals[i2 * 3 + 0];\n const y_n2 = normals[i2 * 3 + 1];\n const z_n2 = normals[i2 * 3 + 2];\n // Tangent\n const n0_dot_t = x_tangent * x_n0 + y_tangent * y_n0 + z_tangent * z_n0;\n const n1_dot_t = x_tangent * x_n1 + y_tangent * y_n1 + z_tangent * z_n1;\n const n2_dot_t = x_tangent * x_n2 + y_tangent * y_n2 + z_tangent * z_n2;\n const x_resTangent0 = x_tangent - x_n0 * n0_dot_t;\n const y_resTangent0 = y_tangent - y_n0 * n0_dot_t;\n const z_resTangent0 = z_tangent - z_n0 * n0_dot_t;\n const x_resTangent1 = x_tangent - x_n1 * n1_dot_t;\n const y_resTangent1 = y_tangent - y_n1 * n1_dot_t;\n const z_resTangent1 = z_tangent - z_n1 * n1_dot_t;\n const x_resTangent2 = x_tangent - x_n2 * n2_dot_t;\n const y_resTangent2 = y_tangent - y_n2 * n2_dot_t;\n const z_resTangent2 = z_tangent - z_n2 * n2_dot_t;\n const magTangent0 = Math.sqrt(x_resTangent0 * x_resTangent0 + y_resTangent0 * y_resTangent0 + z_resTangent0 * z_resTangent0);\n const magTangent1 = Math.sqrt(x_resTangent1 * x_resTangent1 + y_resTangent1 * y_resTangent1 + z_resTangent1 * z_resTangent1);\n const magTangent2 = Math.sqrt(x_resTangent2 * x_resTangent2 + y_resTangent2 * y_resTangent2 + z_resTangent2 * z_resTangent2);\n // Bitangent\n const n0_dot_bt = x_bitangent * x_n0 + y_bitangent * y_n0 + z_bitangent * z_n0;\n const n1_dot_bt = x_bitangent * x_n1 + y_bitangent * y_n1 + z_bitangent * z_n1;\n const n2_dot_bt = x_bitangent * x_n2 + y_bitangent * y_n2 + z_bitangent * z_n2;\n const x_resBitangent0 = x_bitangent - x_n0 * n0_dot_bt;\n const y_resBitangent0 = y_bitangent - y_n0 * n0_dot_bt;\n const z_resBitangent0 = z_bitangent - z_n0 * n0_dot_bt;\n const x_resBitangent1 = x_bitangent - x_n1 * n1_dot_bt;\n const y_resBitangent1 = y_bitangent - y_n1 * n1_dot_bt;\n const z_resBitangent1 = z_bitangent - z_n1 * n1_dot_bt;\n const x_resBitangent2 = x_bitangent - x_n2 * n2_dot_bt;\n const y_resBitangent2 = y_bitangent - y_n2 * n2_dot_bt;\n const z_resBitangent2 = z_bitangent - z_n2 * n2_dot_bt;\n const magBitangent0 = Math.sqrt(x_resBitangent0 * x_resBitangent0 +\n y_resBitangent0 * y_resBitangent0 +\n z_resBitangent0 * z_resBitangent0);\n const magBitangent1 = Math.sqrt(x_resBitangent1 * x_resBitangent1 +\n y_resBitangent1 * y_resBitangent1 +\n z_resBitangent1 * z_resBitangent1);\n const magBitangent2 = Math.sqrt(x_resBitangent2 * x_resBitangent2 +\n y_resBitangent2 * y_resBitangent2 +\n z_resBitangent2 * z_resBitangent2);\n unpacked.tangents[i0 * 3 + 0] += x_resTangent0 / magTangent0;\n unpacked.tangents[i0 * 3 + 1] += y_resTangent0 / magTangent0;\n unpacked.tangents[i0 * 3 + 2] += z_resTangent0 / magTangent0;\n unpacked.tangents[i1 * 3 + 0] += x_resTangent1 / magTangent1;\n unpacked.tangents[i1 * 3 + 1] += y_resTangent1 / magTangent1;\n unpacked.tangents[i1 * 3 + 2] += z_resTangent1 / magTangent1;\n unpacked.tangents[i2 * 3 + 0] += x_resTangent2 / magTangent2;\n unpacked.tangents[i2 * 3 + 1] += y_resTangent2 / magTangent2;\n unpacked.tangents[i2 * 3 + 2] += z_resTangent2 / magTangent2;\n unpacked.bitangents[i0 * 3 + 0] += x_resBitangent0 / magBitangent0;\n unpacked.bitangents[i0 * 3 + 1] += y_resBitangent0 / magBitangent0;\n unpacked.bitangents[i0 * 3 + 2] += z_resBitangent0 / magBitangent0;\n unpacked.bitangents[i1 * 3 + 0] += x_resBitangent1 / magBitangent1;\n unpacked.bitangents[i1 * 3 + 1] += y_resBitangent1 / magBitangent1;\n unpacked.bitangents[i1 * 3 + 2] += z_resBitangent1 / magBitangent1;\n unpacked.bitangents[i2 * 3 + 0] += x_resBitangent2 / magBitangent2;\n unpacked.bitangents[i2 * 3 + 1] += y_resBitangent2 / magBitangent2;\n unpacked.bitangents[i2 * 3 + 2] += z_resBitangent2 / magBitangent2;\n // TODO: check handedness\n }\n this.tangents = unpacked.tangents;\n this.bitangents = unpacked.bitangents;\n }\n /**\n * @param layout - A {@link Layout} object that describes the\n * desired memory layout of the generated buffer\n * @return The packed array in the ... TODO\n */\n makeBufferData(layout) {\n const numItems = this.vertices.length / 3;\n const buffer = new ArrayBuffer(layout.stride * numItems);\n buffer.numItems = numItems;\n const dataView = new DataView(buffer);\n for (let i = 0, vertexOffset = 0; i < numItems; i++) {\n vertexOffset = i * layout.stride;\n // copy in the vertex data in the order and format given by the\n // layout param\n for (const attribute of layout.attributes) {\n const offset = vertexOffset + layout.attributeMap[attribute.key].offset;\n switch (attribute.key) {\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].POSITION.key:\n dataView.setFloat32(offset, this.vertices[i * 3], true);\n dataView.setFloat32(offset + 4, this.vertices[i * 3 + 1], true);\n dataView.setFloat32(offset + 8, this.vertices[i * 3 + 2], true);\n break;\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].UV.key:\n dataView.setFloat32(offset, this.textures[i * 2], true);\n dataView.setFloat32(offset + 4, this.textures[i * 2 + 1], true);\n break;\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].NORMAL.key:\n dataView.setFloat32(offset, this.vertexNormals[i * 3], true);\n dataView.setFloat32(offset + 4, this.vertexNormals[i * 3 + 1], true);\n dataView.setFloat32(offset + 8, this.vertexNormals[i * 3 + 2], true);\n break;\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].MATERIAL_INDEX.key:\n dataView.setInt16(offset, this.vertexMaterialIndices[i], true);\n break;\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].AMBIENT.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.ambient[0], true);\n dataView.setFloat32(offset + 4, material.ambient[1], true);\n dataView.setFloat32(offset + 8, material.ambient[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].DIFFUSE.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.diffuse[0], true);\n dataView.setFloat32(offset + 4, material.diffuse[1], true);\n dataView.setFloat32(offset + 8, material.diffuse[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].SPECULAR.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.specular[0], true);\n dataView.setFloat32(offset + 4, material.specular[1], true);\n dataView.setFloat32(offset + 8, material.specular[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].SPECULAR_EXPONENT.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.specularExponent, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].EMISSIVE.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.emissive[0], true);\n dataView.setFloat32(offset + 4, material.emissive[1], true);\n dataView.setFloat32(offset + 8, material.emissive[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].TRANSMISSION_FILTER.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.transmissionFilter[0], true);\n dataView.setFloat32(offset + 4, material.transmissionFilter[1], true);\n dataView.setFloat32(offset + 8, material.transmissionFilter[2], true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].DISSOLVE.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.dissolve, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].ILLUMINATION.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setInt16(offset, material.illumination, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].REFRACTION_INDEX.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.refractionIndex, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].SHARPNESS.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setFloat32(offset, material.sharpness, true);\n break;\n }\n case _layout__WEBPACK_IMPORTED_MODULE_0__["Layout"].ANTI_ALIASING.key: {\n const materialIndex = this.vertexMaterialIndices[i];\n const material = this.materialsByIndex[materialIndex];\n if (!material) {\n console.warn(\'Material "\' +\n this.materialNames[materialIndex] +\n \'" not found in mesh. Did you forget to call addMaterialLibrary(...)?"\');\n break;\n }\n dataView.setInt16(offset, material.antiAliasing ? 1 : 0, true);\n break;\n }\n }\n }\n }\n return buffer;\n }\n makeIndexBufferData() {\n const buffer = new Uint16Array(this.indices);\n buffer.numItems = this.indices.length;\n return buffer;\n }\n makeIndexBufferDataForMaterials(...materialIndices) {\n const indices = new Array().concat(...materialIndices.map(mtlIdx => this.indicesPerMaterial[mtlIdx]));\n const buffer = new Uint16Array(indices);\n buffer.numItems = indices.length;\n return buffer;\n }\n addMaterialLibrary(mtl) {\n for (const name in mtl.materials) {\n if (!(name in this.materialIndices)) {\n // This material is not referenced by the mesh\n continue;\n }\n const material = mtl.materials[name];\n // Find the material index for this material\n const materialIndex = this.materialIndices[material.name];\n // Put the material into the materialsByIndex object at the right\n // spot as determined when the obj file was parsed\n this.materialsByIndex[materialIndex] = material;\n }\n }\n}\nfunction* triangulate(elements) {\n if (elements.length <= 3) {\n yield elements;\n }\n else if (elements.length === 4) {\n yield [elements[0], elements[1], elements[2]];\n yield [elements[2], elements[3], elements[0]];\n }\n else {\n for (let i = 1; i < elements.length - 1; i++) {\n yield [elements[0], elements[i], elements[i + 1]];\n }\n }\n}\n\n\n//# sourceURL=webpack://OBJ/./src/mesh.ts?')},"./src/utils.ts": /*!**********************!*\ !*** ./src/utils.ts ***! \**********************/ -/*! exports provided: downloadModels, downloadMeshes, initMeshBuffers, deleteMeshBuffers */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "downloadModels", function() { return downloadModels; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "downloadMeshes", function() { return downloadMeshes; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initMeshBuffers", function() { return initMeshBuffers; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "deleteMeshBuffers", function() { return deleteMeshBuffers; });\n/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mesh */ "./src/mesh.ts");\n/* harmony import */ var _material__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./material */ "./src/material.ts");\n\n\nfunction downloadMtlTextures(mtl, root) {\n const mapAttributes = [\n "mapDiffuse",\n "mapAmbient",\n "mapSpecular",\n "mapDissolve",\n "mapBump",\n "mapDisplacement",\n "mapDecal",\n "mapEmissive",\n ];\n if (!root.endsWith("/")) {\n root += "/";\n }\n const textures = [];\n for (const materialName in mtl.materials) {\n if (!mtl.materials.hasOwnProperty(materialName)) {\n continue;\n }\n const material = mtl.materials[materialName];\n for (const attr of mapAttributes) {\n const mapData = material[attr];\n if (!mapData) {\n continue;\n }\n const url = root + mapData.filename;\n textures.push(fetch(url)\n .then(response => {\n if (!response.ok) {\n throw new Error();\n }\n return response.blob();\n })\n .then(function (data) {\n const image = new Image();\n image.src = URL.createObjectURL(data);\n mapData.texture = image;\n return new Promise(resolve => (image.onload = resolve));\n })\n .catch(() => {\n console.error(`Unable to download texture: ${url}`);\n }));\n }\n }\n return Promise.all(textures);\n}\nfunction getMtl(modelOptions) {\n if (!(typeof modelOptions.mtl === "string")) {\n return modelOptions.obj.replace(/\\.obj$/, ".mtl");\n }\n return modelOptions.mtl;\n}\n/**\n * Accepts a list of model request objects and returns a Promise that\n * resolves when all models have been downloaded and parsed.\n *\n * The list of model objects follow this interface:\n * {\n * obj: \'path/to/model.obj\',\n * mtl: true | \'path/to/model.mtl\',\n * downloadMtlTextures: true | false\n * mtlTextureRoot: \'/models/suzanne/maps\'\n * name: \'suzanne\'\n * }\n *\n * The `obj` attribute is required and should be the path to the\n * model\'s .obj file relative to the current repo (absolute URLs are\n * suggested).\n *\n * The `mtl` attribute is optional and can either be a boolean or\n * a path to the model\'s .mtl file relative to the current URL. If\n * the value is `true`, then the path and basename given for the `obj`\n * attribute is used replacing the .obj suffix for .mtl\n * E.g.: {obj: \'models/foo.obj\', mtl: true} would search for \'models/foo.mtl\'\n *\n * The `name` attribute is optional and is a human friendly name to be\n * included with the parsed OBJ and MTL files. If not given, the base .obj\n * filename will be used.\n *\n * The `downloadMtlTextures` attribute is a flag for automatically downloading\n * any images found in the MTL file and attaching them to each Material\n * created from that file. For example, if material.mapDiffuse is set (there\n * was data in the MTL file), then material.mapDiffuse.texture will contain\n * the downloaded image. This option defaults to `true`. By default, the MTL\'s\n * URL will be used to determine the location of the images.\n *\n * The `mtlTextureRoot` attribute is optional and should point to the location\n * on the server that this MTL\'s texture files are located. The default is to\n * use the MTL file\'s location.\n *\n * @returns {Promise} the result of downloading the given list of models. The\n * promise will resolve with an object whose keys are the names of the models\n * and the value is its Mesh object. Each Mesh object will automatically\n * have its addMaterialLibrary() method called to set the given MTL data (if given).\n */\nfunction downloadModels(models) {\n const finished = [];\n for (const model of models) {\n if (!model.obj) {\n throw new Error(\'"obj" attribute of model object not set. The .obj file is required to be set \' +\n "in order to use downloadModels()");\n }\n const options = {\n indicesPerMaterial: !!model.indicesPerMaterial,\n calcTangentsAndBitangents: !!model.calcTangentsAndBitangents,\n };\n // if the name is not provided, dervive it from the given OBJ\n let name = model.name;\n if (!name) {\n const parts = model.obj.split("/");\n name = parts[parts.length - 1].replace(".obj", "");\n }\n const namePromise = Promise.resolve(name);\n const meshPromise = fetch(model.obj)\n .then(response => response.text())\n .then(data => {\n return new _mesh__WEBPACK_IMPORTED_MODULE_0__["default"](data, options);\n });\n let mtlPromise;\n // Download MaterialLibrary file?\n if (model.mtl) {\n const mtl = getMtl(model);\n mtlPromise = fetch(mtl)\n .then(response => response.text())\n .then((data) => {\n const material = new _material__WEBPACK_IMPORTED_MODULE_1__["MaterialLibrary"](data);\n if (model.downloadMtlTextures !== false) {\n let root = model.mtlTextureRoot;\n if (!root) {\n // get the directory of the MTL file as default\n root = mtl.substr(0, mtl.lastIndexOf("/"));\n }\n // downloadMtlTextures returns a Promise that\n // is resolved once all of the images it\n // contains are downloaded. These are then\n // attached to the map data objects\n return Promise.all([Promise.resolve(material), downloadMtlTextures(material, root)]);\n }\n return Promise.all([Promise.resolve(material), undefined]);\n })\n .then((value) => {\n return value[0];\n });\n }\n const parsed = [namePromise, meshPromise, mtlPromise];\n finished.push(Promise.all(parsed));\n }\n return Promise.all(finished).then(ms => {\n // the "finished" promise is a list of name, Mesh instance,\n // and MaterialLibary instance. This unpacks and returns an\n // object mapping name to Mesh (Mesh points to MTL).\n const models = {};\n for (const model of ms) {\n const [name, mesh, mtl] = model;\n mesh.name = name;\n if (mtl) {\n mesh.addMaterialLibrary(mtl);\n }\n models[name] = mesh;\n }\n return models;\n });\n}\n/**\n * Takes in an object of `mesh_name`, `\'/url/to/OBJ/file\'` pairs and a callback\n * function. Each OBJ file will be ajaxed in and automatically converted to\n * an OBJ.Mesh. When all files have successfully downloaded the callback\n * function provided will be called and passed in an object containing\n * the newly created meshes.\n *\n * **Note:** In order to use this function as a way to download meshes, a\n * webserver of some sort must be used.\n *\n * @param {Object} nameAndAttrs an object where the key is the name of the mesh and the value is the url to that mesh\'s OBJ file\n *\n * @param {Function} completionCallback should contain a function that will take one parameter: an object array where the keys will be the unique object name and the value will be a Mesh object\n *\n * @param {Object} meshes In case other meshes are loaded separately or if a previously declared variable is desired to be used, pass in a (possibly empty) json object of the pattern: { \'\': OBJ.Mesh }\n *\n */\nfunction downloadMeshes(nameAndURLs, completionCallback, meshes) {\n if (meshes === undefined) {\n meshes = {};\n }\n const completed = [];\n for (const mesh_name in nameAndURLs) {\n if (!nameAndURLs.hasOwnProperty(mesh_name)) {\n continue;\n }\n const url = nameAndURLs[mesh_name];\n completed.push(fetch(url)\n .then(response => response.text())\n .then(data => {\n return [mesh_name, new _mesh__WEBPACK_IMPORTED_MODULE_0__["default"](data)];\n }));\n }\n Promise.all(completed).then(ms => {\n for (const [name, mesh] of ms) {\n meshes[name] = mesh;\n }\n return completionCallback(meshes);\n });\n}\nfunction _buildBuffer(gl, type, data, itemSize) {\n const buffer = gl.createBuffer();\n const arrayView = type === gl.ARRAY_BUFFER ? Float32Array : Uint16Array;\n gl.bindBuffer(type, buffer);\n gl.bufferData(type, new arrayView(data), gl.STATIC_DRAW);\n buffer.itemSize = itemSize;\n buffer.numItems = data.length / itemSize;\n return buffer;\n}\n/**\n * Takes in the WebGL context and a Mesh, then creates and appends the buffers\n * to the mesh object as attributes.\n *\n * @param {WebGLRenderingContext} gl the `canvas.getContext(\'webgl\')` context instance\n * @param {Mesh} mesh a single `OBJ.Mesh` instance\n *\n * The newly created mesh attributes are:\n *\n * Attrbute | Description\n * :--- | ---\n * **normalBuffer** |contains the model's Vertex Normals\n * normalBuffer.itemSize |set to 3 items\n * normalBuffer.numItems |the total number of vertex normals\n * |\n * **textureBuffer** |contains the model's Texture Coordinates\n * textureBuffer.itemSize |set to 2 items\n * textureBuffer.numItems |the number of texture coordinates\n * |\n * **vertexBuffer** |contains the model's Vertex Position Coordinates (does not include w)\n * vertexBuffer.itemSize |set to 3 items\n * vertexBuffer.numItems |the total number of vertices\n * |\n * **indexBuffer** |contains the indices of the faces\n * indexBuffer.itemSize |is set to 1\n * indexBuffer.numItems |the total number of indices\n *\n * A simple example (a lot of steps are missing, so don\'t copy and paste):\n *\n * const gl = canvas.getContext(\'webgl\'),\n * mesh = OBJ.Mesh(obj_file_data);\n * // compile the shaders and create a shader program\n * const shaderProgram = gl.createProgram();\n * // compilation stuff here\n * ...\n * // make sure you have vertex, vertex normal, and texture coordinate\n * // attributes located in your shaders and attach them to the shader program\n * shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");\n * gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);\n *\n * shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");\n * gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);\n *\n * shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");\n * gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);\n *\n * // create and initialize the vertex, vertex normal, and texture coordinate buffers\n * // and save on to the mesh object\n * OBJ.initMeshBuffers(gl, mesh);\n *\n * // now to render the mesh\n * gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexBuffer);\n * gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, mesh.vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);\n * // it\'s possible that the mesh doesn\'t contain\n * // any texture coordinates (e.g. suzanne.obj in the development branch).\n * // in this case, the texture vertexAttribArray will need to be disabled\n * // before the call to drawElements\n * if(!mesh.textures.length){\n * gl.disableVertexAttribArray(shaderProgram.textureCoordAttribute);\n * }\n * else{\n * // if the texture vertexAttribArray has been previously\n * // disabled, then it needs to be re-enabled\n * gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);\n * gl.bindBuffer(gl.ARRAY_BUFFER, mesh.textureBuffer);\n * gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, mesh.textureBuffer.itemSize, gl.FLOAT, false, 0, 0);\n * }\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, mesh.normalBuffer);\n * gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, mesh.normalBuffer.itemSize, gl.FLOAT, false, 0, 0);\n *\n * gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.mesh.indexBuffer);\n * gl.drawElements(gl.TRIANGLES, model.mesh.indexBuffer.numItems, gl.UNSIGNED_SHORT, 0);\n */\nfunction initMeshBuffers(gl, mesh) {\n mesh.normalBuffer = _buildBuffer(gl, gl.ARRAY_BUFFER, mesh.vertexNormals, 3);\n mesh.textureBuffer = _buildBuffer(gl, gl.ARRAY_BUFFER, mesh.textures, mesh.textureStride);\n mesh.vertexBuffer = _buildBuffer(gl, gl.ARRAY_BUFFER, mesh.vertices, 3);\n mesh.indexBuffer = _buildBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, mesh.indices, 1);\n return mesh;\n}\nfunction deleteMeshBuffers(gl, mesh) {\n gl.deleteBuffer(mesh.normalBuffer);\n gl.deleteBuffer(mesh.textureBuffer);\n gl.deleteBuffer(mesh.vertexBuffer);\n gl.deleteBuffer(mesh.indexBuffer);\n}\n\n\n//# sourceURL=webpack://OBJ/./src/utils.ts?')},0: +/*! exports provided: downloadModels, downloadMeshes, initMeshBuffers, deleteMeshBuffers */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "downloadModels", function() { return downloadModels; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "downloadMeshes", function() { return downloadMeshes; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initMeshBuffers", function() { return initMeshBuffers; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "deleteMeshBuffers", function() { return deleteMeshBuffers; });\n/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mesh */ "./src/mesh.ts");\n/* harmony import */ var _material__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./material */ "./src/material.ts");\n\n\nfunction downloadMtlTextures(mtl, root) {\n const mapAttributes = [\n "mapDiffuse",\n "mapAmbient",\n "mapSpecular",\n "mapDissolve",\n "mapBump",\n "mapDisplacement",\n "mapDecal",\n "mapEmissive",\n ];\n if (!root.endsWith("/")) {\n root += "/";\n }\n const textures = [];\n for (const materialName in mtl.materials) {\n if (!mtl.materials.hasOwnProperty(materialName)) {\n continue;\n }\n const material = mtl.materials[materialName];\n for (const attr of mapAttributes) {\n const mapData = material[attr];\n if (!mapData || !mapData.filename) {\n continue;\n }\n const url = root + mapData.filename;\n textures.push(fetch(url)\n .then(response => {\n if (!response.ok) {\n throw new Error();\n }\n return response.blob();\n })\n .then(function (data) {\n const image = new Image();\n image.src = URL.createObjectURL(data);\n mapData.texture = image;\n return new Promise(resolve => (image.onload = resolve));\n })\n .catch(() => {\n console.error(`Unable to download texture: ${url}`);\n }));\n }\n }\n return Promise.all(textures);\n}\nfunction getMtl(modelOptions) {\n if (!(typeof modelOptions.mtl === "string")) {\n return modelOptions.obj.replace(/\\.obj$/, ".mtl");\n }\n return modelOptions.mtl;\n}\n/**\n * Accepts a list of model request objects and returns a Promise that\n * resolves when all models have been downloaded and parsed.\n *\n * The list of model objects follow this interface:\n * {\n * obj: \'path/to/model.obj\',\n * mtl: true | \'path/to/model.mtl\',\n * downloadMtlTextures: true | false\n * mtlTextureRoot: \'/models/suzanne/maps\'\n * name: \'suzanne\'\n * }\n *\n * The `obj` attribute is required and should be the path to the\n * model\'s .obj file relative to the current repo (absolute URLs are\n * suggested).\n *\n * The `mtl` attribute is optional and can either be a boolean or\n * a path to the model\'s .mtl file relative to the current URL. If\n * the value is `true`, then the path and basename given for the `obj`\n * attribute is used replacing the .obj suffix for .mtl\n * E.g.: {obj: \'models/foo.obj\', mtl: true} would search for \'models/foo.mtl\'\n *\n * The `name` attribute is optional and is a human friendly name to be\n * included with the parsed OBJ and MTL files. If not given, the base .obj\n * filename will be used.\n *\n * The `downloadMtlTextures` attribute is a flag for automatically downloading\n * any images found in the MTL file and attaching them to each Material\n * created from that file. For example, if material.mapDiffuse is set (there\n * was data in the MTL file), then material.mapDiffuse.texture will contain\n * the downloaded image. This option defaults to `true`. By default, the MTL\'s\n * URL will be used to determine the location of the images.\n *\n * The `mtlTextureRoot` attribute is optional and should point to the location\n * on the server that this MTL\'s texture files are located. The default is to\n * use the MTL file\'s location.\n *\n * @returns {Promise} the result of downloading the given list of models. The\n * promise will resolve with an object whose keys are the names of the models\n * and the value is its Mesh object. Each Mesh object will automatically\n * have its addMaterialLibrary() method called to set the given MTL data (if given).\n */\nfunction downloadModels(models) {\n const finished = [];\n for (const model of models) {\n if (!model.obj) {\n throw new Error(\'"obj" attribute of model object not set. The .obj file is required to be set \' +\n "in order to use downloadModels()");\n }\n const options = {\n indicesPerMaterial: !!model.indicesPerMaterial,\n calcTangentsAndBitangents: !!model.calcTangentsAndBitangents,\n };\n // if the name is not provided, dervive it from the given OBJ\n let name = model.name;\n if (!name) {\n const parts = model.obj.split("/");\n name = parts[parts.length - 1].replace(".obj", "");\n }\n const namePromise = Promise.resolve(name);\n const meshPromise = fetch(model.obj)\n .then(response => response.text())\n .then(data => {\n return new _mesh__WEBPACK_IMPORTED_MODULE_0__["default"](data, options);\n });\n let mtlPromise;\n // Download MaterialLibrary file?\n if (model.mtl) {\n const mtl = getMtl(model);\n mtlPromise = fetch(mtl)\n .then(response => response.text())\n .then((data) => {\n const material = new _material__WEBPACK_IMPORTED_MODULE_1__["MaterialLibrary"](data);\n if (model.downloadMtlTextures !== false) {\n let root = model.mtlTextureRoot;\n if (!root) {\n // get the directory of the MTL file as default\n root = mtl.substr(0, mtl.lastIndexOf("/"));\n }\n // downloadMtlTextures returns a Promise that\n // is resolved once all of the images it\n // contains are downloaded. These are then\n // attached to the map data objects\n return Promise.all([Promise.resolve(material), downloadMtlTextures(material, root)]);\n }\n return Promise.all([Promise.resolve(material), undefined]);\n })\n .then((value) => {\n return value[0];\n });\n }\n const parsed = [namePromise, meshPromise, mtlPromise];\n finished.push(Promise.all(parsed));\n }\n return Promise.all(finished).then(ms => {\n // the "finished" promise is a list of name, Mesh instance,\n // and MaterialLibary instance. This unpacks and returns an\n // object mapping name to Mesh (Mesh points to MTL).\n const models = {};\n for (const model of ms) {\n const [name, mesh, mtl] = model;\n mesh.name = name;\n if (mtl) {\n mesh.addMaterialLibrary(mtl);\n }\n models[name] = mesh;\n }\n return models;\n });\n}\n/**\n * Takes in an object of `mesh_name`, `\'/url/to/OBJ/file\'` pairs and a callback\n * function. Each OBJ file will be ajaxed in and automatically converted to\n * an OBJ.Mesh. When all files have successfully downloaded the callback\n * function provided will be called and passed in an object containing\n * the newly created meshes.\n *\n * **Note:** In order to use this function as a way to download meshes, a\n * webserver of some sort must be used.\n *\n * @param {Object} nameAndAttrs an object where the key is the name of the mesh and the value is the url to that mesh\'s OBJ file\n *\n * @param {Function} completionCallback should contain a function that will take one parameter: an object array where the keys will be the unique object name and the value will be a Mesh object\n *\n * @param {Object} meshes In case other meshes are loaded separately or if a previously declared variable is desired to be used, pass in a (possibly empty) json object of the pattern: { \'\': OBJ.Mesh }\n *\n */\nfunction downloadMeshes(nameAndURLs, completionCallback, meshes) {\n if (meshes === undefined) {\n meshes = {};\n }\n const completed = [];\n for (const mesh_name in nameAndURLs) {\n if (!nameAndURLs.hasOwnProperty(mesh_name)) {\n continue;\n }\n const url = nameAndURLs[mesh_name];\n completed.push(fetch(url)\n .then(response => response.text())\n .then(data => {\n return [mesh_name, new _mesh__WEBPACK_IMPORTED_MODULE_0__["default"](data)];\n }));\n }\n Promise.all(completed).then(ms => {\n for (const [name, mesh] of ms) {\n meshes[name] = mesh;\n }\n return completionCallback(meshes);\n });\n}\nfunction _buildBuffer(gl, type, data, itemSize) {\n const buffer = gl.createBuffer();\n const arrayView = type === gl.ARRAY_BUFFER ? Float32Array : Uint16Array;\n gl.bindBuffer(type, buffer);\n gl.bufferData(type, new arrayView(data), gl.STATIC_DRAW);\n buffer.itemSize = itemSize;\n buffer.numItems = data.length / itemSize;\n return buffer;\n}\n/**\n * Takes in the WebGL context and a Mesh, then creates and appends the buffers\n * to the mesh object as attributes.\n *\n * @param {WebGLRenderingContext} gl the `canvas.getContext(\'webgl\')` context instance\n * @param {Mesh} mesh a single `OBJ.Mesh` instance\n *\n * The newly created mesh attributes are:\n *\n * Attrbute | Description\n * :--- | ---\n * **normalBuffer** |contains the model's Vertex Normals\n * normalBuffer.itemSize |set to 3 items\n * normalBuffer.numItems |the total number of vertex normals\n * |\n * **textureBuffer** |contains the model's Texture Coordinates\n * textureBuffer.itemSize |set to 2 items\n * textureBuffer.numItems |the number of texture coordinates\n * |\n * **vertexBuffer** |contains the model's Vertex Position Coordinates (does not include w)\n * vertexBuffer.itemSize |set to 3 items\n * vertexBuffer.numItems |the total number of vertices\n * |\n * **indexBuffer** |contains the indices of the faces\n * indexBuffer.itemSize |is set to 1\n * indexBuffer.numItems |the total number of indices\n *\n * A simple example (a lot of steps are missing, so don\'t copy and paste):\n *\n * const gl = canvas.getContext(\'webgl\'),\n * mesh = OBJ.Mesh(obj_file_data);\n * // compile the shaders and create a shader program\n * const shaderProgram = gl.createProgram();\n * // compilation stuff here\n * ...\n * // make sure you have vertex, vertex normal, and texture coordinate\n * // attributes located in your shaders and attach them to the shader program\n * shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");\n * gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);\n *\n * shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");\n * gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);\n *\n * shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");\n * gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);\n *\n * // create and initialize the vertex, vertex normal, and texture coordinate buffers\n * // and save on to the mesh object\n * OBJ.initMeshBuffers(gl, mesh);\n *\n * // now to render the mesh\n * gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexBuffer);\n * gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, mesh.vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);\n * // it\'s possible that the mesh doesn\'t contain\n * // any texture coordinates (e.g. suzanne.obj in the development branch).\n * // in this case, the texture vertexAttribArray will need to be disabled\n * // before the call to drawElements\n * if(!mesh.textures.length){\n * gl.disableVertexAttribArray(shaderProgram.textureCoordAttribute);\n * }\n * else{\n * // if the texture vertexAttribArray has been previously\n * // disabled, then it needs to be re-enabled\n * gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);\n * gl.bindBuffer(gl.ARRAY_BUFFER, mesh.textureBuffer);\n * gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, mesh.textureBuffer.itemSize, gl.FLOAT, false, 0, 0);\n * }\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, mesh.normalBuffer);\n * gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, mesh.normalBuffer.itemSize, gl.FLOAT, false, 0, 0);\n *\n * gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.mesh.indexBuffer);\n * gl.drawElements(gl.TRIANGLES, model.mesh.indexBuffer.numItems, gl.UNSIGNED_SHORT, 0);\n */\nfunction initMeshBuffers(gl, mesh) {\n mesh.normalBuffer = _buildBuffer(gl, gl.ARRAY_BUFFER, mesh.vertexNormals, 3);\n mesh.textureBuffer = _buildBuffer(gl, gl.ARRAY_BUFFER, mesh.textures, mesh.textureStride);\n mesh.vertexBuffer = _buildBuffer(gl, gl.ARRAY_BUFFER, mesh.vertices, 3);\n mesh.indexBuffer = _buildBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, mesh.indices, 1);\n return mesh;\n}\nfunction deleteMeshBuffers(gl, mesh) {\n gl.deleteBuffer(mesh.normalBuffer);\n gl.deleteBuffer(mesh.textureBuffer);\n gl.deleteBuffer(mesh.vertexBuffer);\n gl.deleteBuffer(mesh.indexBuffer);\n}\n\n\n//# sourceURL=webpack://OBJ/./src/utils.ts?')},0: /*!****************************!*\ !*** multi ./src/index.ts ***! \****************************/ -/*! no static exports found */function(module,exports,__webpack_require__){eval('module.exports = __webpack_require__(/*! /Users/aaron/git/webgl-obj-loader/src/index.ts */"./src/index.ts");\n\n\n//# sourceURL=webpack://OBJ/multi_./src/index.ts?')}})})); \ No newline at end of file +/*! no static exports found */function(module,exports,__webpack_require__){eval('module.exports = __webpack_require__(/*! /home/aaron/google_drive/projects/webgl-obj-loader/src/index.ts */"./src/index.ts");\n\n\n//# sourceURL=webpack://OBJ/multi_./src/index.ts?')}})})); \ No newline at end of file